Subversion Repositories Kolibri OS

Rev

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