Subversion Repositories Kolibri OS

Rev

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

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