Subversion Repositories Kolibri OS

Rev

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

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