Subversion Repositories Kolibri OS

Rev

Rev 2434 | Rev 3500 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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