Subversion Repositories Kolibri OS

Rev

Rev 9900 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2288 clevermous 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
10051 ace_dent 3
;; Copyright (C) KolibriOS team 2004-2024. All rights reserved. ;;
2288 clevermous 4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
8
 
2384 hidnplayr 9
struct  MEM_BLOCK
10
        list            LHEAD
11
        next_block      dd ? ;+8
12
        prev_block      dd ? ;+4
13
        base            dd ? ;+16
14
        size            dd ? ;+20
15
        flags           dd ? ;+24
16
        handle          dd ? ;+28
17
ends
2288 clevermous 18
 
7965 hidnplayr 19
MEM_BLOCK_RESERVED  = 0x02      ; Will be allocated on first access (lazy allocation)
20
MEM_BLOCK_FREE      = 0x04
21
MEM_BLOCK_USED      = 0x08
22
MEM_BLOCK_DONT_FREE = 0x10
2288 clevermous 23
 
24
macro calc_index op
25
{          shr op, 12
26
        dec     op
27
        cmp     op, 63
28
        jna     @f
29
        mov     op, 63
30
@@:
31
}
32
 
33
align 4
34
md:
35
.add_to_used:
7965 hidnplayr 36
        mov     eax, [esi + MEM_BLOCK.base]
37
        mov     ebx, [esi + MEM_BLOCK.base]
2288 clevermous 38
        shr     ebx, 6
39
        add     eax, ebx
40
        shr     ebx, 6
41
        add     eax, ebx
42
        shr     eax, 12
43
        and     eax, 63
7965 hidnplayr 44
        inc     [mem_hash_cnt + eax*4]
2288 clevermous 45
 
7965 hidnplayr 46
        lea     ecx, [mem_used_list + eax*8]
3246 Serge 47
        list_add esi, ecx
7965 hidnplayr 48
        mov     [esi + MEM_BLOCK.flags], MEM_BLOCK_USED
49
        mov     eax, [esi + MEM_BLOCK.size]
2288 clevermous 50
        sub     [heap_free], eax
51
        ret
52
align 4
53
.find_used:
54
        mov     ecx, eax
55
        mov     ebx, eax
56
        shr     ebx, 6
57
        add     ecx, ebx
58
        shr     ebx, 6
59
        add     ecx, ebx
60
        shr     ecx, 12
61
        and     ecx, 63
62
 
7965 hidnplayr 63
        lea     ebx, [mem_used_list + ecx*8]
2288 clevermous 64
        mov     esi, ebx
65
.next:
7965 hidnplayr 66
        mov     esi, [esi + MEM_BLOCK.list.next]
2288 clevermous 67
        cmp     esi, ebx
68
        je      .fail
69
 
7965 hidnplayr 70
        cmp     eax, [esi + MEM_BLOCK.base]
2288 clevermous 71
        jne     .next
72
 
73
        ret
74
.fail:
75
        xor     esi, esi
76
        ret
77
 
78
align 4
79
.del_from_used:
80
        call    .find_used
81
        test    esi, esi
82
        jz      .done
83
 
7965 hidnplayr 84
        cmp     [esi + MEM_BLOCK.flags], MEM_BLOCK_USED
2288 clevermous 85
        jne     .fatal
86
 
7965 hidnplayr 87
        dec     [mem_hash_cnt + ecx*4]
3246 Serge 88
        list_del esi
2288 clevermous 89
.done:
90
        ret
91
.fatal:                            ;FIXME panic here
92
        xor     esi, esi
93
        ret
94
 
95
;Initial heap state
96
;
7965 hidnplayr 97
; + heap_size               terminator        MEM_BLOCK_USED
98
; + 4096*MEM_BLOCK.sizeof   free space        MEM_BLOCK_FREE
99
;HEAP_BASE                heap_descriptors  MEM_BLOCK_USED
2288 clevermous 100
;
101
 
102
align 4
103
proc init_kernel_heap
104
 
105
        mov     ecx, 64
106
        mov     edi, mem_block_list
7965 hidnplayr 107
  @@:
2288 clevermous 108
        mov     eax, edi
109
        stosd
110
        stosd
111
        loop    @B
112
 
113
        mov     ecx, 64
114
        mov     edi, mem_used_list
7965 hidnplayr 115
  @@:
2288 clevermous 116
        mov     eax, edi
117
        stosd
118
        stosd
119
        loop    @B
120
 
121
        stdcall alloc_pages, dword 32
4424 Serge 122
 
5356 serge 123
        or      eax, PG_SWR
4424 Serge 124
        mov     ebx, HEAP_BASE
2288 clevermous 125
        mov     ecx, 32
4424 Serge 126
        call    commit_pages
2288 clevermous 127
 
128
        mov     edi, HEAP_BASE                     ;descriptors
7965 hidnplayr 129
        mov     ebx, HEAP_BASE + sizeof.MEM_BLOCK      ;free space
130
        mov     ecx, HEAP_BASE + sizeof.MEM_BLOCK*2    ;terminator
2288 clevermous 131
 
132
        xor     eax, eax
7965 hidnplayr 133
        mov     [edi + MEM_BLOCK.next_block], ebx
134
        mov     [edi + MEM_BLOCK.prev_block], eax
135
        mov     [edi + MEM_BLOCK.list.next], eax
136
        mov     [edi + MEM_BLOCK.list.prev], eax
137
        mov     [edi + MEM_BLOCK.base], HEAP_BASE
9900 Doczom 138
        mov     [edi + MEM_BLOCK.size], PAGE_SIZE * sizeof.MEM_BLOCK
7965 hidnplayr 139
        mov     [edi + MEM_BLOCK.flags], MEM_BLOCK_USED
2288 clevermous 140
 
7965 hidnplayr 141
        mov     [ecx + MEM_BLOCK.next_block], eax
142
        mov     [ecx + MEM_BLOCK.prev_block], ebx
143
        mov     [ecx + MEM_BLOCK.list.next], eax
144
        mov     [ecx + MEM_BLOCK.list.prev], eax
145
        mov     [ecx + MEM_BLOCK.base], eax
146
        mov     [ecx + MEM_BLOCK.size], eax
147
        mov     [ecx + MEM_BLOCK.flags], MEM_BLOCK_USED
2288 clevermous 148
 
7965 hidnplayr 149
        mov     [ebx + MEM_BLOCK.next_block], ecx
150
        mov     [ebx + MEM_BLOCK.prev_block], edi
9900 Doczom 151
        mov     [ebx + MEM_BLOCK.base], HEAP_BASE + PAGE_SIZE * sizeof.MEM_BLOCK
2288 clevermous 152
 
153
        mov     ecx, [pg_data.kernel_pages]
154
        shl     ecx, 12
9900 Doczom 155
        sub     ecx, HEAP_BASE-OS_BASE + PAGE_SIZE * sizeof.MEM_BLOCK
2288 clevermous 156
        mov     [heap_size], ecx
157
        mov     [heap_free], ecx
7965 hidnplayr 158
        mov     [ebx + MEM_BLOCK.size], ecx
159
        mov     [ebx + MEM_BLOCK.flags], MEM_BLOCK_FREE
2288 clevermous 160
 
161
        mov     [mem_block_mask], eax
7965 hidnplayr 162
        mov     [mem_block_mask + 4], 0x80000000
2288 clevermous 163
 
7965 hidnplayr 164
        mov     ecx, mem_block_list + 63*8
3246 Serge 165
        list_add ebx, ecx
2288 clevermous 166
 
9900 Doczom 167
        mov     ecx, PAGE_SIZE -3-1
7965 hidnplayr 168
        mov     eax, HEAP_BASE + sizeof.MEM_BLOCK*4
2288 clevermous 169
 
7965 hidnplayr 170
        mov     [next_memblock], HEAP_BASE + sizeof.MEM_BLOCK *3
171
 @@:
9715 Doczom 172
        mov     [eax - sizeof.MEM_BLOCK], eax
2384 hidnplayr 173
        add     eax, sizeof.MEM_BLOCK
2288 clevermous 174
        loop    @B
175
 
9715 Doczom 176
        mov     dword[eax - sizeof.MEM_BLOCK], 0
2288 clevermous 177
 
178
        mov     ecx, heap_mutex
179
        call    mutex_init
180
        mov     [heap_blocks], 4094
181
        mov     [free_blocks], 4093
182
        ret
183
endp
184
 
185
; param
186
;  eax= required size
187
;
188
; retval
189
;  edi= memory block descriptor
190
;  ebx= descriptor index
191
 
192
align 4
193
get_small_block:
194
        mov     ecx, eax
195
        shr     ecx, 12
196
        dec     ecx
197
        cmp     ecx, 63
198
        jle     .get_index
199
        mov     ecx, 63
7965 hidnplayr 200
  .get_index:
2288 clevermous 201
        lea     esi, [mem_block_mask]
202
        xor     ebx, ebx
203
        or      edx, -1
204
 
205
        cmp     ecx, 32
206
        jb      .bit_test
207
 
208
        sub     ecx, 32
209
        add     ebx, 32
210
        add     esi, 4
7965 hidnplayr 211
  .bit_test:
2288 clevermous 212
        shl     edx, cl
213
        and     edx, [esi]
7965 hidnplayr 214
  .find:
2288 clevermous 215
        bsf     edi, edx
216
        jz      .high_mask
217
        add     ebx, edi
7965 hidnplayr 218
        lea     ecx, [mem_block_list + ebx*8]
2288 clevermous 219
        mov     edi, ecx
7965 hidnplayr 220
  .next:
221
        mov     edi, [edi + MEM_BLOCK.list.next]
2288 clevermous 222
        cmp     edi, ecx
223
        je      .err
7965 hidnplayr 224
        cmp     eax, [edi + MEM_BLOCK.size]
2288 clevermous 225
        ja      .next
226
        ret
7965 hidnplayr 227
  .err:
2288 clevermous 228
        xor     edi, edi
229
        ret
230
 
7965 hidnplayr 231
  .high_mask:
2288 clevermous 232
        add     esi, 4
7965 hidnplayr 233
        cmp     esi, mem_block_mask + 8
2288 clevermous 234
        jae     .err
235
        add     ebx, 32
236
        mov     edx, [esi]
237
        jmp     .find
238
 
239
 
240
align 4
241
free_mem_block:
7965 hidnplayr 242
 
2288 clevermous 243
        mov     ebx, [next_memblock]
244
        mov     [eax], ebx
245
        mov     [next_memblock], eax
7965 hidnplayr 246
 
2288 clevermous 247
        xor     ebx, ebx
7965 hidnplayr 248
        mov     dword[eax + 4], ebx
249
        mov     dword[eax + 8], ebx
250
        mov     dword[eax + 12], ebx
251
        mov     dword[eax + 16], ebx
252
;           mov dword[eax + 20], 0     ;don't clear block size
253
        mov     dword[eax + 24], ebx
254
        mov     dword[eax + 28], ebx
2288 clevermous 255
 
256
        inc     [free_blocks]
7965 hidnplayr 257
 
2288 clevermous 258
        ret
259
 
260
align 4
261
proc alloc_kernel_space stdcall, size:dword
262
           local block_ind:DWORD
263
 
264
        push    ebx
265
        push    esi
266
        push    edi
267
 
268
        mov     eax, [size]
9900 Doczom 269
        add     eax, PAGE_SIZE-1
270
        and     eax, -PAGE_SIZE
2288 clevermous 271
        mov     [size], eax
272
 
273
        cmp     eax, [heap_free]
274
        ja      .error
275
 
4391 clevermous 276
        spin_lock_irqsave heap_mutex
2288 clevermous 277
 
278
        mov     eax, [size]
279
 
280
        call    get_small_block ; eax
281
        test    edi, edi
282
        jz      .error_unlock
283
 
7965 hidnplayr 284
        cmp     [edi + MEM_BLOCK.flags], MEM_BLOCK_FREE
2288 clevermous 285
        jne     .error_unlock
286
 
287
        mov     [block_ind], ebx  ;index of allocated block
288
 
7965 hidnplayr 289
        mov     eax, [edi + MEM_BLOCK.size]
2288 clevermous 290
        cmp     eax, [size]
291
        je      .m_eq_size
292
 
293
        mov     esi, [next_memblock]    ;new memory block
294
        test    esi, esi
295
        jz      .error_unlock
296
 
297
        dec     [free_blocks]
298
        mov     eax, [esi]
299
        mov     [next_memblock], eax
300
 
7965 hidnplayr 301
        mov     [esi + MEM_BLOCK.next_block], edi
302
        mov     eax, [edi + MEM_BLOCK.prev_block]
303
        mov     [esi + MEM_BLOCK.prev_block], eax
304
        mov     [edi + MEM_BLOCK.prev_block], esi
305
        mov     [esi + MEM_BLOCK.list.next], 0
306
        mov     [esi + MEM_BLOCK.list.prev], 0
307
        mov     [eax + MEM_BLOCK.next_block], esi
2288 clevermous 308
 
7965 hidnplayr 309
        mov     ebx, [edi + MEM_BLOCK.base]
310
        mov     [esi + MEM_BLOCK.base], ebx
2288 clevermous 311
        mov     edx, [size]
7965 hidnplayr 312
        mov     [esi + MEM_BLOCK.size], edx
313
        add     [edi + MEM_BLOCK.base], edx
314
        sub     [edi + MEM_BLOCK.size], edx
2288 clevermous 315
 
7965 hidnplayr 316
        mov     eax, [edi + MEM_BLOCK.size]
4391 clevermous 317
        calc_index eax
2288 clevermous 318
        cmp     eax, [block_ind]
319
        je      .add_used
320
 
4391 clevermous 321
        list_del edi
2288 clevermous 322
 
323
        mov     ecx, [block_ind]
7965 hidnplayr 324
        lea     edx, [mem_block_list + ecx*8]
2288 clevermous 325
        cmp     edx, [edx]
326
        jnz     @f
327
        btr     [mem_block_mask], ecx
328
@@:
329
        bts     [mem_block_mask], eax
7965 hidnplayr 330
        lea     edx, [mem_block_list + eax*8]  ;edx= list head
4391 clevermous 331
        list_add edi, edx
2288 clevermous 332
.add_used:
333
 
334
        call    md.add_to_used
335
 
4391 clevermous 336
        spin_unlock_irqrestore heap_mutex
7965 hidnplayr 337
        mov     eax, [esi + MEM_BLOCK.base]
2288 clevermous 338
        pop     edi
339
        pop     esi
340
        pop     ebx
341
        ret
342
 
343
.m_eq_size:
4391 clevermous 344
        list_del edi
7965 hidnplayr 345
        lea     edx, [mem_block_list + ebx*8]
2288 clevermous 346
        cmp     edx, [edx]
347
        jnz     @f
348
        btr     [mem_block_mask], ebx
349
@@:
350
        mov     esi, edi
351
        jmp     .add_used
352
 
353
.error_unlock:
4391 clevermous 354
        spin_unlock_irqrestore heap_mutex
2288 clevermous 355
.error:
356
        xor     eax, eax
357
        pop     edi
358
        pop     esi
359
        pop     ebx
360
        ret
361
endp
362
 
363
align 4
364
proc free_kernel_space stdcall uses ebx ecx edx esi edi, base:dword
365
 
4391 clevermous 366
        spin_lock_irqsave heap_mutex
2288 clevermous 367
 
368
        mov     eax, [base]
369
 
370
        call    md.del_from_used
371
        test    esi, esi
372
        jz      .fail
373
 
7965 hidnplayr 374
        mov     eax, [esi + MEM_BLOCK.size]
2288 clevermous 375
        add     [heap_free], eax
376
 
7965 hidnplayr 377
        mov     edi, [esi + MEM_BLOCK.next_block]
378
        cmp     [edi + MEM_BLOCK.flags], MEM_BLOCK_FREE
2288 clevermous 379
        jne     .prev
380
 
3246 Serge 381
        list_del edi
2288 clevermous 382
 
7965 hidnplayr 383
        mov     edx, [edi + MEM_BLOCK.next_block]
384
        mov     [esi + MEM_BLOCK.next_block], edx
385
        mov     [edx + MEM_BLOCK.prev_block], esi
386
        mov     ecx, [edi + MEM_BLOCK.size]
387
        add     [esi + MEM_BLOCK.size], ecx
2288 clevermous 388
 
3246 Serge 389
        calc_index ecx
2288 clevermous 390
 
7965 hidnplayr 391
        lea     edx, [mem_block_list + ecx*8]
2288 clevermous 392
        cmp     edx, [edx]
393
        jne     @F
394
        btr     [mem_block_mask], ecx
395
@@:
396
        mov     eax, edi
397
        call    free_mem_block
398
.prev:
7965 hidnplayr 399
        mov     edi, [esi + MEM_BLOCK.prev_block]
400
        cmp     [edi + MEM_BLOCK.flags], MEM_BLOCK_FREE
2288 clevermous 401
        jne     .insert
402
 
7965 hidnplayr 403
        mov     edx, [esi + MEM_BLOCK.next_block]
404
        mov     [edi + MEM_BLOCK.next_block], edx
405
        mov     [edx + MEM_BLOCK.prev_block], edi
2288 clevermous 406
 
407
        mov     eax, esi
408
        call    free_mem_block
409
 
7965 hidnplayr 410
        mov     ecx, [edi + MEM_BLOCK.size]
411
        mov     eax, [esi + MEM_BLOCK.size]
2288 clevermous 412
        add     eax, ecx
7965 hidnplayr 413
        mov     [edi + MEM_BLOCK.size], eax
2288 clevermous 414
 
3246 Serge 415
        calc_index eax                     ;new index
416
        calc_index ecx                     ;old index
2288 clevermous 417
        cmp     eax, ecx
418
        je      .m_eq
419
 
420
        push    ecx
3246 Serge 421
        list_del edi
2288 clevermous 422
        pop     ecx
423
 
7965 hidnplayr 424
        lea     edx, [mem_block_list + ecx*8]
2288 clevermous 425
        cmp     edx, [edx]
426
        jne     .add_block
427
        btr     [mem_block_mask], ecx
3246 Serge 428
 
2288 clevermous 429
.add_block:
430
        bts     [mem_block_mask], eax
7965 hidnplayr 431
        lea     edx, [mem_block_list + eax*8]
3246 Serge 432
        list_add edi, edx
2288 clevermous 433
.m_eq:
4391 clevermous 434
        spin_unlock_irqrestore heap_mutex
2288 clevermous 435
        xor     eax, eax
436
        not     eax
437
        ret
438
.insert:
7965 hidnplayr 439
        mov     [esi + MEM_BLOCK.flags], MEM_BLOCK_FREE
440
        mov     eax, [esi + MEM_BLOCK.size]
3246 Serge 441
        calc_index eax
2288 clevermous 442
        mov     edi, esi
443
        jmp     .add_block
444
 
445
.fail:
4391 clevermous 446
        spin_unlock_irqrestore heap_mutex
2288 clevermous 447
        xor     eax, eax
448
        ret
449
endp
450
 
451
align 4
452
proc kernel_alloc stdcall, size:dword
3246 Serge 453
        locals
454
          lin_addr    dd ?
455
          pages_count dd ?
456
        endl
2288 clevermous 457
 
458
        push    ebx
459
        push    edi
460
 
461
        mov     eax, [size]
9900 Doczom 462
        add     eax, PAGE_SIZE-1
463
        and     eax, -PAGE_SIZE;
2288 clevermous 464
        mov     [size], eax
465
        and     eax, eax
466
        jz      .err
467
        mov     ebx, eax
468
        shr     ebx, 12
469
        mov     [pages_count], ebx
470
 
471
        stdcall alloc_kernel_space, eax
4424 Serge 472
        mov     [lin_addr], eax
473
        mov     ebx, [pages_count]
2288 clevermous 474
        test    eax, eax
475
        jz      .err
476
 
477
        mov     edx, eax
478
 
4424 Serge 479
        shr     ebx, 3
480
        jz      .tail
2288 clevermous 481
 
4424 Serge 482
        shl     ebx, 3
2288 clevermous 483
        stdcall alloc_pages, ebx
4424 Serge 484
        test    eax, eax
2288 clevermous 485
        jz      .err
486
 
4424 Serge 487
        mov     ecx, ebx
7965 hidnplayr 488
        or      eax, PG_GLOBAL + PG_SWR
4424 Serge 489
        mov     ebx, [lin_addr]
490
        call    commit_pages
491
 
492
        mov     edx, ebx                    ; this dirty hack
493
.tail:
494
        mov     ebx, [pages_count]
495
        and     ebx, 7
2288 clevermous 496
        jz      .end
497
@@:
498
        call    alloc_page
499
        test    eax, eax
500
        jz      .err
501
 
7965 hidnplayr 502
        stdcall map_page, edx, eax, dword (PG_GLOBAL + PG_SWR)
9900 Doczom 503
        add     edx, PAGE_SIZE
4424 Serge 504
        dec     ebx
2288 clevermous 505
        jnz     @B
506
.end:
507
        mov     eax, [lin_addr]
508
        pop     edi
509
        pop     ebx
510
        ret
511
.err:
512
        xor     eax, eax
513
        pop     edi
514
        pop     ebx
515
        ret
516
endp
517
 
518
align 4
519
proc kernel_free stdcall, base:dword
520
 
521
        push    ebx esi
522
 
4391 clevermous 523
        spin_lock_irqsave heap_mutex
2288 clevermous 524
 
525
        mov     eax, [base]
526
        call    md.find_used
527
 
7965 hidnplayr 528
        cmp     [esi + MEM_BLOCK.flags], MEM_BLOCK_USED
2288 clevermous 529
        jne     .fail
530
 
4391 clevermous 531
        spin_unlock_irqrestore heap_mutex
2288 clevermous 532
 
7965 hidnplayr 533
        mov     eax, [esi + MEM_BLOCK.base]
534
        mov     ecx, [esi + MEM_BLOCK.size]
2288 clevermous 535
        shr     ecx, 12
536
        call    release_pages   ;eax, ecx
537
        stdcall free_kernel_space, [base]
538
        pop     esi ebx
539
        ret
540
.fail:
4391 clevermous 541
        spin_unlock_irqrestore heap_mutex
2288 clevermous 542
        xor     eax, eax
543
        pop     esi ebx
544
        ret
545
endp
546
 
5130 serge 547
;;;;;;;;;;;;;;      USER HEAP     ;;;;;;;;;;;;;;;;;
2288 clevermous 548
 
7136 dunkaist 549
HEAP_TOP  = 0x80000000
2288 clevermous 550
 
551
align 4
552
proc init_heap
553
 
5130 serge 554
        mov     ebx, [current_process]
7965 hidnplayr 555
        mov     eax, [ebx + PROC.heap_top]
2288 clevermous 556
        test    eax, eax
557
        jz      @F
7965 hidnplayr 558
        sub     eax, [ebx + PROC.heap_base]
5130 serge 559
        sub     eax, PAGE_SIZE
2288 clevermous 560
        ret
561
@@:
7965 hidnplayr 562
        lea     ecx, [ebx + PROC.heap_lock]
5130 serge 563
        call    mutex_init
564
 
7965 hidnplayr 565
        mov     esi, [ebx + PROC.mem_used]
9900 Doczom 566
        add     esi, PAGE_SIZE-1
567
        and     esi, -PAGE_SIZE
7965 hidnplayr 568
        mov     [ebx + PROC.mem_used], esi
2288 clevermous 569
        mov     eax, HEAP_TOP
7965 hidnplayr 570
        mov     [ebx + PROC.heap_base], esi
571
        mov     [ebx + PROC.heap_top], eax
2288 clevermous 572
 
573
        sub     eax, esi
574
        shr     esi, 10
575
        mov     ecx, eax
5130 serge 576
        sub     eax, PAGE_SIZE
7965 hidnplayr 577
        or      ecx, MEM_BLOCK_FREE
578
        mov     [page_tabs + esi], ecx
2288 clevermous 579
        ret
580
endp
581
 
582
align 4
583
proc user_alloc stdcall, alloc_size:dword
7965 hidnplayr 584
 
6893 pathoswith 585
        push    ebx esi edi
7965 hidnplayr 586
 
6974 0CodErr 587
        mov     ebx, [current_process]
7965 hidnplayr 588
        lea     ecx, [ebx + PROC.heap_lock]
5130 serge 589
        call    mutex_lock
7965 hidnplayr 590
 
2288 clevermous 591
        mov     ecx, [alloc_size]
7965 hidnplayr 592
        add     ecx, (4095 + PAGE_SIZE)
9900 Doczom 593
        and     ecx, -PAGE_SIZE
7965 hidnplayr 594
        mov     esi, [ebx + PROC.heap_base]
595
        mov     edi, [ebx + PROC.heap_top]
596
  .scan:
2288 clevermous 597
        cmp     esi, edi
5130 serge 598
        jae     .m_exit
2288 clevermous 599
 
600
        mov     ebx, esi
601
        shr     ebx, 12
7965 hidnplayr 602
        mov     eax, [page_tabs + ebx*4]
603
        test    al, MEM_BLOCK_FREE
5130 serge 604
        jz      .test_used
9900 Doczom 605
        and     eax, -PAGE_SIZE
2288 clevermous 606
        cmp     eax, ecx   ;alloc_size
5130 serge 607
        jb      .m_next
2288 clevermous 608
        jz      @f
609
 
7965 hidnplayr 610
        lea     edx, [esi + ecx]
2288 clevermous 611
        sub     eax, ecx
7965 hidnplayr 612
        or      al, MEM_BLOCK_FREE
2288 clevermous 613
        shr     edx, 12
7965 hidnplayr 614
        mov     [page_tabs + edx*4], eax
615
  @@:
616
        or      ecx, MEM_BLOCK_USED
617
        mov     [page_tabs + ebx*4], ecx
2288 clevermous 618
        shr     ecx, 12
619
        inc     ebx
620
        dec     ecx
621
        jz      .no
7965 hidnplayr 622
  @@:
623
        mov     dword [page_tabs + ebx*4], MEM_BLOCK_RESERVED
2288 clevermous 624
        inc     ebx
625
        dec     ecx
626
        jnz     @B
7965 hidnplayr 627
  .no:
2288 clevermous 628
 
5130 serge 629
        mov     edx, [current_process]
2288 clevermous 630
        mov     ebx, [alloc_size]
9900 Doczom 631
        add     ebx, PAGE_SIZE-1
632
        and     ebx, -PAGE_SIZE
7965 hidnplayr 633
        add     [edx + PROC.mem_used], ebx
2288 clevermous 634
 
7965 hidnplayr 635
        lea     ecx, [edx + PROC.heap_lock]
5130 serge 636
        call    mutex_unlock
637
 
9900 Doczom 638
        lea     eax, [esi + PAGE_SIZE]
2288 clevermous 639
 
640
        pop     edi
641
        pop     esi
642
        pop     ebx
643
        ret
5130 serge 644
.test_used:
7965 hidnplayr 645
        test    al, MEM_BLOCK_USED
5130 serge 646
        jz      .m_exit
2288 clevermous 647
 
9900 Doczom 648
        and     eax, -PAGE_SIZE
5130 serge 649
.m_next:
2288 clevermous 650
        add     esi, eax
5130 serge 651
        jmp     .scan
652
.m_exit:
653
        mov     ecx, [current_process]
7965 hidnplayr 654
        lea     ecx, [ecx + PROC.heap_lock]
5130 serge 655
        call    mutex_unlock
656
 
2288 clevermous 657
        xor     eax, eax
658
        pop     edi
659
        pop     esi
660
        pop     ebx
661
        ret
662
endp
663
 
664
align 4
665
proc user_alloc_at stdcall, address:dword, alloc_size:dword
666
 
667
        push    ebx
668
        push    esi
669
        push    edi
670
 
5130 serge 671
        mov     ebx, [current_process]
7965 hidnplayr 672
        lea     ecx, [ebx + PROC.heap_lock]
5130 serge 673
        call    mutex_lock
674
 
2288 clevermous 675
        mov     edx, [address]
9900 Doczom 676
        and     edx, -PAGE_SIZE
2288 clevermous 677
        mov     [address], edx
9900 Doczom 678
        sub     edx, PAGE_SIZE
2288 clevermous 679
        jb      .error
7965 hidnplayr 680
        mov     esi, [ebx + PROC.heap_base]
681
        mov     edi, [ebx + PROC.heap_top]
2288 clevermous 682
        cmp     edx, esi
683
        jb      .error
684
.scan:
685
        cmp     esi, edi
686
        jae     .error
687
        mov     ebx, esi
688
        shr     ebx, 12
7965 hidnplayr 689
        mov     eax, [page_tabs + ebx*4]
2288 clevermous 690
        mov     ecx, eax
9900 Doczom 691
        and     ecx, -PAGE_SIZE
2288 clevermous 692
        add     ecx, esi
693
        cmp     edx, ecx
694
        jb      .found
695
        mov     esi, ecx
696
        jmp     .scan
697
.error:
5130 serge 698
        mov     ecx, [current_process]
7965 hidnplayr 699
        lea     ecx, [ecx + PROC.heap_lock]
5130 serge 700
        call    mutex_unlock
701
 
2288 clevermous 702
        xor     eax, eax
703
        pop     edi
704
        pop     esi
705
        pop     ebx
706
        ret
707
.found:
7965 hidnplayr 708
        test    al, MEM_BLOCK_FREE
2288 clevermous 709
        jz      .error
710
        mov     eax, ecx
711
        sub     eax, edx
9900 Doczom 712
        sub     eax, PAGE_SIZE
2288 clevermous 713
        cmp     eax, [alloc_size]
714
        jb      .error
715
 
716
; Here we have 1 big free block which includes requested area.
717
; In general, 3 other blocks must be created instead:
718
; free at [esi, edx);
7965 hidnplayr 719
; busy at [edx, edx + 0x1000 + ALIGN_UP(alloc_size,0x1000));
720
; free at [edx + 0x1000 + ALIGN_UP(alloc_size,0x1000), ecx)
2288 clevermous 721
; First or third block (or both) may be absent.
722
        mov     eax, edx
723
        sub     eax, esi
724
        jz      .nofirst
7965 hidnplayr 725
        or      al, MEM_BLOCK_FREE
726
        mov     [page_tabs + ebx*4], eax
727
  .nofirst:
2288 clevermous 728
        mov     eax, [alloc_size]
729
        add     eax, 0x1FFF
9900 Doczom 730
        and     eax, -PAGE_SIZE
2288 clevermous 731
        mov     ebx, edx
732
        add     edx, eax
733
        shr     ebx, 12
7965 hidnplayr 734
        or      al, MEM_BLOCK_USED
735
        mov     [page_tabs + ebx*4], eax
2288 clevermous 736
        shr     eax, 12
737
        dec     eax
738
        jz      .second_nofill
739
        inc     ebx
7965 hidnplayr 740
  .fill:
741
        mov     dword [page_tabs + ebx*4], MEM_BLOCK_RESERVED
2288 clevermous 742
        inc     ebx
743
        dec     eax
744
        jnz     .fill
3246 Serge 745
 
7965 hidnplayr 746
  .second_nofill:
2288 clevermous 747
        sub     ecx, edx
748
        jz      .nothird
7965 hidnplayr 749
        or      cl, MEM_BLOCK_FREE
750
        mov     [page_tabs + ebx*4], ecx
3246 Serge 751
 
7965 hidnplayr 752
  .nothird:
5130 serge 753
        mov     edx, [current_process]
2288 clevermous 754
        mov     ebx, [alloc_size]
9900 Doczom 755
        add     ebx, PAGE_SIZE-1
756
        and     ebx, -PAGE_SIZE
7965 hidnplayr 757
        add     [edx + PROC.mem_used], ebx
2288 clevermous 758
 
7965 hidnplayr 759
        lea     ecx, [edx + PROC.heap_lock]
5130 serge 760
        call    mutex_unlock
761
 
2288 clevermous 762
        mov     eax, [address]
763
 
764
        pop     edi
765
        pop     esi
766
        pop     ebx
767
        ret
768
endp
769
 
770
align 4
771
proc user_free stdcall, base:dword
772
 
773
        push    esi
774
 
775
        mov     esi, [base]
776
        test    esi, esi
5130 serge 777
        jz      .fail
2288 clevermous 778
 
779
        push    ebx
780
 
5130 serge 781
        mov     ebx, [current_process]
7965 hidnplayr 782
        lea     ecx, [ebx + PROC.heap_lock]
5130 serge 783
        call    mutex_lock
784
 
2288 clevermous 785
        xor     ebx, ebx
786
        shr     esi, 12
7965 hidnplayr 787
        mov     eax, [page_tabs + (esi-1)*4]
788
        test    al, MEM_BLOCK_USED
2288 clevermous 789
        jz      .cantfree
7965 hidnplayr 790
        test    al, MEM_BLOCK_DONT_FREE
2288 clevermous 791
        jnz     .cantfree
792
 
9900 Doczom 793
        and     eax, -PAGE_SIZE
2288 clevermous 794
        mov     ecx, eax
7965 hidnplayr 795
        or      al, MEM_BLOCK_FREE
796
        mov     [page_tabs + (esi-1)*4], eax
9900 Doczom 797
        sub     ecx, PAGE_SIZE
2288 clevermous 798
        mov     ebx, ecx
799
        shr     ecx, 12
800
        jz      .released
7965 hidnplayr 801
  .release:
2288 clevermous 802
        xor     eax, eax
7965 hidnplayr 803
        xchg    eax, [page_tabs + esi*4]
2288 clevermous 804
        test    al, 1
805
        jz      @F
806
        test    eax, PG_SHARED
807
        jnz     @F
808
        call    free_page
809
        mov     eax, esi
810
        shl     eax, 12
811
        invlpg  [eax]
7965 hidnplayr 812
  @@:
2288 clevermous 813
        inc     esi
814
        dec     ecx
815
        jnz     .release
3246 Serge 816
 
7965 hidnplayr 817
 .released:
2288 clevermous 818
        push    edi
819
 
5130 serge 820
        mov     edx, [current_process]
7965 hidnplayr 821
        lea     ecx, [edx + PROC.heap_lock]
822
        mov     esi, dword [edx + PROC.heap_base]
823
        mov     edi, dword [edx + PROC.heap_top]
824
        sub     ebx, [edx + PROC.mem_used]
2288 clevermous 825
        neg     ebx
7965 hidnplayr 826
        mov     [edx + PROC.mem_used], ebx
2288 clevermous 827
        call    user_normalize
828
        pop     edi
7965 hidnplayr 829
 .exit:
5130 serge 830
        call    mutex_unlock
831
 
2288 clevermous 832
        xor     eax, eax
833
        inc     eax
5130 serge 834
        pop     ebx
2288 clevermous 835
        pop     esi
836
        ret
5130 serge 837
 
7965 hidnplayr 838
  .cantfree:
5130 serge 839
        mov     ecx, [current_process]
7965 hidnplayr 840
        lea     ecx, [ecx + PROC.heap_lock]
5130 serge 841
        jmp     .exit
7965 hidnplayr 842
  .fail:
2288 clevermous 843
        xor     eax, eax
844
        pop     esi
845
        ret
846
endp
847
 
2400 Serge 848
 
849
align 4
850
proc user_unmap stdcall, base:dword, offset:dword, size:dword
851
 
852
        push    ebx
853
 
854
        mov     ebx, [base]             ; must be valid pointer
855
        test    ebx, ebx
856
        jz      .error
857
 
858
        mov     edx, [offset]           ; check offset
859
        add     edx, ebx                ; must be below 2Gb app limit
860
        js      .error
861
 
862
        shr     ebx, 12                 ; chek block attributes
7965 hidnplayr 863
        lea     ebx, [page_tabs + ebx*4]
9715 Doczom 864
        mov     eax, [ebx - 4]          ; block attributes
7965 hidnplayr 865
        test    al, MEM_BLOCK_USED
2400 Serge 866
        jz      .error
7965 hidnplayr 867
        test    al, MEM_BLOCK_DONT_FREE
2400 Serge 868
        jnz     .error
869
 
870
        shr     edx, 12
7965 hidnplayr 871
        lea     edx, [page_tabs + edx*4]  ; unmap offset
2400 Serge 872
 
873
        mov     ecx, [size]
9900 Doczom 874
        add     ecx, PAGE_SIZE-1
2400 Serge 875
        shr     ecx, 12                 ; unmap size in pages
876
 
7965 hidnplayr 877
        shr     eax, 12                 ; block size  +  1 page
878
        lea     ebx, [ebx + eax*4-4]      ; block end ptr
879
        lea     eax, [edx + ecx*4]        ; unmap end ptr
2400 Serge 880
 
881
        cmp     eax, ebx                ; check for overflow
882
        ja      .error
883
 
884
        mov     ebx, [offset]
9900 Doczom 885
        and     ebx, -PAGE_SIZE         ; is it required ?
3798 Serge 886
        add     ebx, [base]
2400 Serge 887
 
7965 hidnplayr 888
  .unmap:
2400 Serge 889
        mov     eax, [edx]              ; get page addres
890
        test    al, 1                   ; page mapped ?
891
        jz      @F
892
        test    eax, PG_SHARED          ; page shared ?
893
        jnz     @F
7965 hidnplayr 894
        mov     dword[edx], MEM_BLOCK_RESERVED
2400 Serge 895
                                        ; mark page as reserved
896
        invlpg  [ebx]                   ; when we start using
897
        call    free_page               ; empty c-o-w page instead this ?
7965 hidnplayr 898
  @@:
9900 Doczom 899
        add     ebx, PAGE_SIZE
2400 Serge 900
        add     edx, 4
901
        dec     ecx
902
        jnz     .unmap
903
 
904
        pop     ebx
905
        or      al, 1                   ; return non zero on success
906
        ret
907
.error:
908
        pop     ebx
909
        xor     eax, eax                ; something wrong
910
        ret
911
endp
912
 
913
align 4
2288 clevermous 914
user_normalize:
915
; in: esi=heap_base, edi=heap_top
916
; out: eax=0 <=> OK
917
; destroys: ebx,edx,esi,edi
918
        shr     esi, 12
919
        shr     edi, 12
920
@@:
7965 hidnplayr 921
        mov     eax, [page_tabs + esi*4]
922
        test    al, MEM_BLOCK_USED
2288 clevermous 923
        jz      .test_free
924
        shr     eax, 12
925
        add     esi, eax
926
        jmp     @B
927
.test_free:
7965 hidnplayr 928
        test    al, MEM_BLOCK_FREE
2288 clevermous 929
        jz      .err
930
        mov     edx, eax
931
        shr     edx, 12
932
        add     edx, esi
933
        cmp     edx, edi
934
        jae     .exit
935
 
7965 hidnplayr 936
        mov     ebx, [page_tabs + edx*4]
937
        test    bl, MEM_BLOCK_USED
2288 clevermous 938
        jz      .next_free
939
 
940
        shr     ebx, 12
941
        add     edx, ebx
942
        mov     esi, edx
943
        jmp     @B
944
.next_free:
7965 hidnplayr 945
        test    bl, MEM_BLOCK_FREE
2288 clevermous 946
        jz      .err
7965 hidnplayr 947
        and     dword[page_tabs + edx*4], 0
2288 clevermous 948
        add     eax, ebx
9900 Doczom 949
        and     eax, -PAGE_SIZE
7965 hidnplayr 950
        or      eax, MEM_BLOCK_FREE
951
        mov     [page_tabs + esi*4], eax
2288 clevermous 952
        jmp     @B
953
.exit:
954
        xor     eax, eax
955
        inc     eax
956
        ret
957
.err:
958
        xor     eax, eax
959
        ret
960
 
961
user_realloc:
962
; in: eax = pointer, ebx = new size
963
; out: eax = new pointer or NULL
964
        test    eax, eax
965
        jnz     @f
966
; realloc(NULL,sz) - same as malloc(sz)
967
        push    ebx
968
        call    user_alloc
969
        ret
970
@@:
971
        push    ecx edx
5130 serge 972
 
973
        push    eax
974
        mov     ecx, [current_process]
7965 hidnplayr 975
        lea     ecx, [ecx + PROC.heap_lock]
5130 serge 976
        call    mutex_lock
977
        pop     eax
978
 
9900 Doczom 979
        lea     ecx, [eax - PAGE_SIZE]
2288 clevermous 980
        shr     ecx, 12
7965 hidnplayr 981
        mov     edx, [page_tabs + ecx*4]
982
        test    dl, MEM_BLOCK_USED
2288 clevermous 983
        jnz     @f
984
; attempt to realloc invalid pointer
985
.ret0:
5130 serge 986
        mov     ecx, [current_process]
7965 hidnplayr 987
        lea     ecx, [ecx + PROC.heap_lock]
5130 serge 988
        call    mutex_unlock
989
 
2288 clevermous 990
        pop     edx ecx
991
        xor     eax, eax
992
        ret
993
@@:
7965 hidnplayr 994
        test    dl, MEM_BLOCK_DONT_FREE
2288 clevermous 995
        jnz     .ret0
996
        add     ebx, 0x1FFF
997
        shr     edx, 12
998
        shr     ebx, 12
999
; edx = allocated size, ebx = new size
1000
        add     edx, ecx
1001
        add     ebx, ecx
1002
        cmp     edx, ebx
1003
        jb      .realloc_add
1004
; release part of allocated memory
1005
.loop:
1006
        cmp     edx, ebx
1007
        jz      .release_done
1008
        dec     edx
1009
        xor     eax, eax
7965 hidnplayr 1010
        xchg    eax, [page_tabs + edx*4]
2288 clevermous 1011
        test    al, 1
1012
        jz      .loop
1013
        call    free_page
1014
        mov     eax, edx
1015
        shl     eax, 12
1016
        invlpg  [eax]
1017
        jmp     .loop
1018
.release_done:
1019
        sub     ebx, ecx
1020
        cmp     ebx, 1
1021
        jnz     .nofreeall
7965 hidnplayr 1022
        mov     eax, [page_tabs + ecx*4]
9900 Doczom 1023
        and     eax, -PAGE_SIZE
5130 serge 1024
        mov     edx, [current_process]
7965 hidnplayr 1025
        mov     ebx, [edx + PROC.mem_used]
2288 clevermous 1026
        sub     ebx, eax
9900 Doczom 1027
        add     ebx, PAGE_SIZE
7965 hidnplayr 1028
        or      al, MEM_BLOCK_FREE
1029
        mov     [page_tabs + ecx*4], eax
2288 clevermous 1030
        push    esi edi
7965 hidnplayr 1031
        mov     esi, [edx + PROC.heap_base]
1032
        mov     edi, [edx + PROC.heap_top]
1033
        mov     [edx + PROC.mem_used], ebx
2288 clevermous 1034
        call    user_normalize
1035
        pop     edi esi
1036
        jmp     .ret0   ; all freed
1037
.nofreeall:
1038
        sub     edx, ecx
1039
        shl     ebx, 12
7965 hidnplayr 1040
        or      ebx, MEM_BLOCK_USED
1041
        xchg    [page_tabs + ecx*4], ebx
2288 clevermous 1042
        shr     ebx, 12
1043
        sub     ebx, edx
1044
        push    ebx ecx edx
5130 serge 1045
        mov     edx, [current_process]
2288 clevermous 1046
        shl     ebx, 12
7965 hidnplayr 1047
        sub     ebx, [edx + PROC.mem_used]
2288 clevermous 1048
        neg     ebx
7965 hidnplayr 1049
        mov     [edx + PROC.mem_used], ebx
2288 clevermous 1050
        pop     edx ecx ebx
7965 hidnplayr 1051
        lea     eax, [ecx + 1]
2288 clevermous 1052
        shl     eax, 12
1053
        push    eax
1054
        add     ecx, edx
7965 hidnplayr 1055
        lea     edx, [ecx + ebx]
2288 clevermous 1056
        shl     ebx, 12
1057
        jz      .ret
1058
        push    esi
5130 serge 1059
        mov     esi, [current_process]
7965 hidnplayr 1060
        mov     esi, [esi + PROC.heap_top]
2288 clevermous 1061
        shr     esi, 12
1062
@@:
1063
        cmp     edx, esi
1064
        jae     .merge_done
7965 hidnplayr 1065
        mov     eax, [page_tabs + edx*4]
1066
        test    al, MEM_BLOCK_USED
2288 clevermous 1067
        jnz     .merge_done
7965 hidnplayr 1068
        and     dword [page_tabs + edx*4], 0
2288 clevermous 1069
        shr     eax, 12
1070
        add     edx, eax
1071
        shl     eax, 12
1072
        add     ebx, eax
1073
        jmp     @b
1074
.merge_done:
1075
        pop     esi
7965 hidnplayr 1076
        or      ebx, MEM_BLOCK_FREE
1077
        mov     [page_tabs + ecx*4], ebx
2288 clevermous 1078
.ret:
5130 serge 1079
        mov     ecx, [current_process]
7965 hidnplayr 1080
        lea     ecx, [ecx + PROC.heap_lock]
5130 serge 1081
        call    mutex_unlock
2288 clevermous 1082
        pop     eax edx ecx
1083
        ret
5130 serge 1084
 
2288 clevermous 1085
.realloc_add:
1086
; get some additional memory
5130 serge 1087
        mov     eax, [current_process]
7965 hidnplayr 1088
        mov     eax, [eax + PROC.heap_top]
2288 clevermous 1089
        shr     eax, 12
1090
        cmp     edx, eax
1091
        jae     .cant_inplace
7965 hidnplayr 1092
        mov     eax, [page_tabs + edx*4]
1093
        test    al, MEM_BLOCK_FREE
2288 clevermous 1094
        jz      .cant_inplace
1095
        shr     eax, 12
1096
        add     eax, edx
1097
        sub     eax, ebx
1098
        jb      .cant_inplace
1099
        jz      @f
1100
        shl     eax, 12
7965 hidnplayr 1101
        or      al, MEM_BLOCK_FREE
1102
        mov     [page_tabs + ebx*4], eax
2288 clevermous 1103
@@:
1104
        mov     eax, ebx
1105
        sub     eax, ecx
1106
        shl     eax, 12
7965 hidnplayr 1107
        or      al, MEM_BLOCK_USED
1108
        mov     [page_tabs + ecx*4], eax
1109
        lea     eax, [ecx + 1]
2288 clevermous 1110
        shl     eax, 12
1111
        push    eax
1112
        push    edi
7965 hidnplayr 1113
        lea     edi, [page_tabs + edx*4]
2288 clevermous 1114
        mov     eax, 2
1115
        sub     ebx, edx
1116
        mov     ecx, ebx
1117
        cld
1118
        rep stosd
1119
        pop     edi
5130 serge 1120
        mov     edx, [current_process]
2288 clevermous 1121
        shl     ebx, 12
7965 hidnplayr 1122
        add     [edx + PROC.mem_used], ebx
5130 serge 1123
 
1124
        mov     ecx, [current_process]
7965 hidnplayr 1125
        lea     ecx, [ecx + PROC.heap_lock]
5130 serge 1126
        call    mutex_unlock
2288 clevermous 1127
        pop     eax edx ecx
1128
        ret
5130 serge 1129
 
2288 clevermous 1130
.cant_inplace:
1131
        push    esi edi
5130 serge 1132
        mov     eax, [current_process]
7965 hidnplayr 1133
        mov     esi, [eax + PROC.heap_base]
1134
        mov     edi, [eax + PROC.heap_top]
2288 clevermous 1135
        shr     esi, 12
1136
        shr     edi, 12
1137
        sub     ebx, ecx
1138
.find_place:
1139
        cmp     esi, edi
1140
        jae     .place_not_found
7965 hidnplayr 1141
        mov     eax, [page_tabs + esi*4]
1142
        test    al, MEM_BLOCK_FREE
2288 clevermous 1143
        jz      .next_place
1144
        shr     eax, 12
1145
        cmp     eax, ebx
1146
        jae     .place_found
1147
        add     esi, eax
1148
        jmp     .find_place
1149
.next_place:
1150
        shr     eax, 12
1151
        add     esi, eax
1152
        jmp     .find_place
1153
.place_not_found:
1154
        pop     edi esi
1155
        jmp     .ret0
1156
.place_found:
1157
        sub     eax, ebx
1158
        jz      @f
1159
        push    esi
1160
        add     esi, ebx
1161
        shl     eax, 12
7965 hidnplayr 1162
        or      al, MEM_BLOCK_FREE
1163
        mov     [page_tabs + esi*4], eax
2288 clevermous 1164
        pop     esi
1165
@@:
1166
        mov     eax, ebx
1167
        shl     eax, 12
7965 hidnplayr 1168
        or      al, MEM_BLOCK_USED
1169
        mov     [page_tabs + esi*4], eax
2288 clevermous 1170
        inc     esi
1171
        mov     eax, esi
1172
        shl     eax, 12
1173
        push    eax
7965 hidnplayr 1174
        mov     eax, [page_tabs + ecx*4]
9900 Doczom 1175
        and     eax, -PAGE_SIZE
7965 hidnplayr 1176
        or      al, MEM_BLOCK_FREE
2288 clevermous 1177
        sub     edx, ecx
7965 hidnplayr 1178
        mov     [page_tabs + ecx*4], eax
2288 clevermous 1179
        inc     ecx
1180
        dec     ebx
1181
        dec     edx
1182
        jz      .no
1183
@@:
1184
        xor     eax, eax
7965 hidnplayr 1185
        xchg    eax, [page_tabs + ecx*4]
1186
        mov     [page_tabs + esi*4], eax
2288 clevermous 1187
        mov     eax, ecx
1188
        shl     eax, 12
1189
        invlpg  [eax]
1190
        inc     esi
1191
        inc     ecx
1192
        dec     ebx
1193
        dec     edx
1194
        jnz     @b
1195
.no:
1196
        push    ebx
5130 serge 1197
        mov     edx, [current_process]
2288 clevermous 1198
        shl     ebx, 12
7965 hidnplayr 1199
        add     [edx + PROC.mem_used], ebx
2288 clevermous 1200
        pop     ebx
1201
@@:
7965 hidnplayr 1202
        mov     dword [page_tabs + esi*4], MEM_BLOCK_RESERVED
2288 clevermous 1203
        inc     esi
1204
        dec     ebx
1205
        jnz     @b
5130 serge 1206
 
1207
        mov     ecx, [current_process]
7965 hidnplayr 1208
        lea     ecx, [ecx + PROC.heap_lock]
5130 serge 1209
        call    mutex_unlock
2288 clevermous 1210
        pop     eax edi esi edx ecx
1211
        ret
1212
 
1213
 
1214
 
5130 serge 1215
;;;;;;;;;;;;;;      SHARED MEMORY     ;;;;;;;;;;;;;;;;;
2288 clevermous 1216
 
1217
 
1218
; param
1219
;  eax= shm_map object
1220
 
1221
align 4
1222
destroy_smap:
1223
 
1224
        pushfd
1225
        cli
1226
 
1227
        push    esi
1228
        push    edi
1229
 
1230
        mov     edi, eax
7965 hidnplayr 1231
        mov     esi, [eax + SMAP.parent]
2288 clevermous 1232
        test    esi, esi
1233
        jz      .done
1234
 
7965 hidnplayr 1235
        lock dec [esi + SMEM.refcount]
2288 clevermous 1236
        jnz     .done
1237
 
7965 hidnplayr 1238
        mov     ecx, [esi + SMEM.bk]
1239
        mov     edx, [esi + SMEM.fd]
2288 clevermous 1240
 
7965 hidnplayr 1241
        mov     [ecx + SMEM.fd], edx
1242
        mov     [edx + SMEM.bk], ecx
2288 clevermous 1243
 
7965 hidnplayr 1244
        stdcall kernel_free, [esi + SMEM.base]
2288 clevermous 1245
        mov     eax, esi
1246
        call    free
1247
.done:
1248
        mov     eax, edi
1249
        call    destroy_kernel_object
1250
 
1251
        pop     edi
1252
        pop     esi
1253
        popfd
1254
 
1255
        ret
1256
 
7136 dunkaist 1257
E_NOTFOUND      =  5
1258
E_ACCESS        = 10
1259
E_NOMEM         = 30
1260
E_PARAM         = 33
2288 clevermous 1261
 
7136 dunkaist 1262
SHM_READ        = 0
1263
SHM_WRITE       = 1
2288 clevermous 1264
 
7136 dunkaist 1265
SHM_ACCESS_MASK = 3
2288 clevermous 1266
 
7136 dunkaist 1267
SHM_OPEN        = 0 shl 2
1268
SHM_OPEN_ALWAYS = 1 shl 2
1269
SHM_CREATE      = 2 shl 2
2288 clevermous 1270
 
7136 dunkaist 1271
SHM_OPEN_MASK   = 3 shl 2
2288 clevermous 1272
 
1273
align 4
1274
proc shmem_open stdcall name:dword, size:dword, access:dword
3246 Serge 1275
        locals
1276
           action         dd ?
1277
           owner_access   dd ?
1278
           mapped         dd ?
1279
        endl
2288 clevermous 1280
 
1281
        push    ebx
1282
        push    esi
1283
        push    edi
1284
 
1285
        mov     [mapped], 0
1286
        mov     [owner_access], 0
1287
 
1288
        pushfd                         ;mutex required
1289
        cli
1290
 
1291
        mov     eax, [access]
1292
        and     eax, SHM_OPEN_MASK
1293
        mov     [action], eax
1294
 
1295
        mov     ebx, [name]
1296
        test    ebx, ebx
1297
        mov     edx, E_PARAM
1298
        jz      .fail
1299
 
1300
        mov     esi, [shmem_list.fd]
1301
align 4
1302
@@:
1303
        cmp     esi, shmem_list
1304
        je      .not_found
1305
 
7965 hidnplayr 1306
        lea     edx, [esi + SMEM.name]; link , base, size
2288 clevermous 1307
        stdcall strncmp, edx, ebx, 32
1308
        test    eax, eax
1309
        je      .found
1310
 
7965 hidnplayr 1311
        mov     esi, [esi + SMEM.fd]
2288 clevermous 1312
        jmp     @B
1313
 
1314
.not_found:
1315
        mov     eax, [action]
1316
 
1317
        cmp     eax, SHM_OPEN
1318
        mov     edx, E_NOTFOUND
1319
        je      .fail
1320
 
1321
        cmp     eax, SHM_CREATE
1322
        mov     edx, E_PARAM
1323
        je      .create_shm
1324
 
1325
        cmp     eax, SHM_OPEN_ALWAYS
1326
        jne     .fail
1327
 
1328
.create_shm:
1329
 
1330
        mov     ecx, [size]
1331
        test    ecx, ecx
1332
        jz      .fail
1333
 
9900 Doczom 1334
        add     ecx, PAGE_SIZE-1
1335
        and     ecx, -PAGE_SIZE
2288 clevermous 1336
        mov     [size], ecx
1337
 
2384 hidnplayr 1338
        mov     eax, sizeof.SMEM
2288 clevermous 1339
        call    malloc
1340
        test    eax, eax
1341
        mov     esi, eax
1342
        mov     edx, E_NOMEM
1343
        jz      .fail
1344
 
1345
        stdcall kernel_alloc, [size]
1346
        test    eax, eax
1347
        mov     [mapped], eax
1348
        mov     edx, E_NOMEM
1349
        jz      .cleanup
1350
 
1351
        mov     ecx, [size]
1352
        mov     edx, [access]
1353
        and     edx, SHM_ACCESS_MASK
1354
 
7965 hidnplayr 1355
        mov     [esi + SMEM.base], eax
1356
        mov     [esi + SMEM.size], ecx
1357
        mov     [esi + SMEM.access], edx
1358
        mov     [esi + SMEM.refcount], 0
1359
        mov     [esi + SMEM.name + 28], 0
2288 clevermous 1360
 
7965 hidnplayr 1361
        lea     eax, [esi + SMEM.name]
2288 clevermous 1362
        stdcall strncpy, eax, [name], 31
1363
 
1364
        mov     eax, [shmem_list.fd]
7965 hidnplayr 1365
        mov     [esi + SMEM.bk], shmem_list
1366
        mov     [esi + SMEM.fd], eax
2288 clevermous 1367
 
7965 hidnplayr 1368
        mov     [eax + SMEM.bk], esi
2288 clevermous 1369
        mov     [shmem_list.fd], esi
1370
 
1371
        mov     [action], SHM_OPEN
1372
        mov     [owner_access], SHM_WRITE
1373
 
1374
.found:
1375
        mov     eax, [action]
1376
 
1377
        cmp     eax, SHM_CREATE
1378
        mov     edx, E_ACCESS
1379
        je      .exit
1380
 
1381
        cmp     eax, SHM_OPEN
1382
        mov     edx, E_PARAM
1383
        je      .create_map
1384
 
1385
        cmp     eax, SHM_OPEN_ALWAYS
1386
        jne     .fail
1387
 
1388
.create_map:
1389
 
1390
        mov     eax, [access]
1391
        and     eax, SHM_ACCESS_MASK
7965 hidnplayr 1392
        cmp     eax, [esi + SMEM.access]
2288 clevermous 1393
        mov     [access], eax
1394
        mov     edx, E_ACCESS
1395
        ja      .fail
1396
 
9828 Doczom 1397
        mov     ebx, [current_slot]
1398
        mov     ebx, [ebx + APPDATA.tid]
2384 hidnplayr 1399
        mov     eax, sizeof.SMAP
2288 clevermous 1400
 
1401
        call    create_kernel_object
1402
        test    eax, eax
1403
        mov     edi, eax
1404
        mov     edx, E_NOMEM
1405
        jz      .fail
1406
 
7965 hidnplayr 1407
        inc     [esi + SMEM.refcount]
2288 clevermous 1408
 
7965 hidnplayr 1409
        mov     [edi + SMAP.magic], 'SMAP'
1410
        mov     [edi + SMAP.destroy], destroy_smap
1411
        mov     [edi + SMAP.parent], esi
1412
        mov     [edi + SMAP.base], 0
2288 clevermous 1413
 
7965 hidnplayr 1414
        stdcall user_alloc, [esi + SMEM.size]
2288 clevermous 1415
        test    eax, eax
1416
        mov     [mapped], eax
1417
        mov     edx, E_NOMEM
1418
        jz      .cleanup2
1419
 
7965 hidnplayr 1420
        mov     [edi + SMAP.base], eax
2288 clevermous 1421
 
7965 hidnplayr 1422
        mov     ecx, [esi + SMEM.size]
2288 clevermous 1423
        mov     [size], ecx
1424
 
1425
        shr     ecx, 12
1426
        shr     eax, 10
1427
 
7965 hidnplayr 1428
        mov     esi, [esi + SMEM.base]
2288 clevermous 1429
        shr     esi, 10
7965 hidnplayr 1430
        lea     edi, [page_tabs + eax]
2288 clevermous 1431
        add     esi, page_tabs
1432
 
1433
        mov     edx, [access]
1434
        or      edx, [owner_access]
1435
        shl     edx, 1
7965 hidnplayr 1436
        or      edx, PG_SHARED + PG_UR
2288 clevermous 1437
@@:
1438
        lodsd
9900 Doczom 1439
        and     eax, -PAGE_SIZE
2288 clevermous 1440
        or      eax, edx
1441
        stosd
1442
        loop    @B
1443
 
1444
        xor     edx, edx
1445
 
1446
        cmp     [owner_access], 0
1447
        jne     .fail
1448
.exit:
1449
        mov     edx, [size]
1450
.fail:
1451
        mov     eax, [mapped]
1452
 
1453
        popfd
1454
        pop     edi
1455
        pop     esi
1456
        pop     ebx
1457
        ret
1458
.cleanup:
1459
        mov     [size], edx
1460
        mov     eax, esi
1461
        call    free
1462
        jmp     .exit
1463
 
1464
.cleanup2:
1465
        mov     [size], edx
1466
        mov     eax, edi
1467
        call    destroy_smap
1468
        jmp     .exit
1469
endp
1470
 
1471
align 4
1472
proc shmem_close stdcall, name:dword
1473
 
1474
        mov     eax, [name]
1475
        test    eax, eax
1476
        jz      .fail
1477
 
9405 Coldy 1478
        push    ebx ; Added
2288 clevermous 1479
        push    esi
1480
        push    edi
1481
        pushfd
1482
        cli
1483
 
1484
        mov     esi, [current_slot]
1485
        add     esi, APP_OBJ_OFFSET
9405 Coldy 1486
        mov     ebx, esi ; Fixed endless loop bug with not existing name (part 1)
2288 clevermous 1487
.next:
7965 hidnplayr 1488
        mov     eax, [esi + APPOBJ.fd]
2288 clevermous 1489
        test    eax, eax
1490
        jz      @F
1491
 
9405 Coldy 1492
        cmp     eax, ebx ;esi ; Fixed endless loop bug with not existing name (part 2)
1493
        je      @F            ; Small optimization
2288 clevermous 1494
        mov     esi, eax
9405 Coldy 1495
        ;je      @F
2288 clevermous 1496
 
7965 hidnplayr 1497
        cmp     [eax + SMAP.magic], 'SMAP'
2288 clevermous 1498
        jne     .next
1499
 
7965 hidnplayr 1500
        mov     edi, [eax + SMAP.parent]
2288 clevermous 1501
        test    edi, edi
1502
        jz      .next
1503
 
7965 hidnplayr 1504
        lea     edi, [edi + SMEM.name]
2288 clevermous 1505
        stdcall strncmp, [name], edi, 32
1506
        test    eax, eax
1507
        jne     .next
1508
 
7965 hidnplayr 1509
        stdcall user_free, [esi + SMAP.base]
2288 clevermous 1510
 
1511
        mov     eax, esi
7965 hidnplayr 1512
        call    [esi + APPOBJ.destroy]
2288 clevermous 1513
@@:
1514
        popfd
1515
        pop     edi
1516
        pop     esi
9405 Coldy 1517
        pop     ebx ; Added
2288 clevermous 1518
.fail:
1519
        ret
1520
endp
7965 hidnplayr 1521
 
7967 hidnplayr 1522
 
1523
 
1524
proc    user_ring stdcall, size:dword
1525
 
1526
locals
1527
        virt_ptr        dd ?
1528
        phys_ptr        dd ?
1529
        num_pages       dd ?
1530
endl
1531
 
1532
; Size must be an exact multiple of pagesize
7968 hidnplayr 1533
        mov     eax, [size]
7967 hidnplayr 1534
        test    eax, PAGE_SIZE-1
1535
        jnz     .exit
1536
 
1537
; We must have at least one complete page
1538
        shr     eax, 12
1539
        jz      .exit
1540
        mov     [num_pages], eax
1541
 
1542
; Allocate double the virtual memory
1543
        mov     eax, [size]
1544
        shl     eax, 1
1545
        jz      .exit
1546
        stdcall user_alloc, eax
1547
        test    eax, eax
1548
        jz      .exit
1549
        mov     [virt_ptr], eax
1550
 
1551
; Now allocate physical memory
1552
        stdcall alloc_pages, [num_pages]
1553
        test    eax, eax
1554
        jz      .exit_free_virt
1555
        mov     [phys_ptr], eax
1556
 
1557
; Map first half of virtual memory to physical memory
1558
        push    ecx esi edi
1559
        mov     ecx, [num_pages]
1560
        mov     esi, [virt_ptr]
1561
        mov     edi, [phys_ptr]
1562
  .loop1:
1563
        stdcall map_page, esi, edi, PG_UWR
1564
        add     esi, PAGE_SIZE
1565
        add     edi, PAGE_SIZE
1566
        dec     ecx
1567
        jnz     .loop1
1568
 
1569
; Map second half of virtual memory to same physical memory
7968 hidnplayr 1570
        mov     ecx, [num_pages]
7967 hidnplayr 1571
        mov     edi, [phys_ptr]
1572
  .loop2:
1573
        stdcall map_page, esi, edi, PG_UWR
1574
        add     esi, PAGE_SIZE
1575
        add     edi, PAGE_SIZE
1576
        dec     ecx
1577
        jnz     .loop2
1578
        pop     edi esi ecx
1579
 
1580
        mov     eax, [virt_ptr]
1581
        ret
1582
 
1583
  .exit_free_virt:
1584
        stdcall user_free, [virt_ptr]
1585
 
1586
  .exit:
1587
        xor     eax, eax
1588
        ret
1589
 
10051 ace_dent 1590
endp