Subversion Repositories Kolibri OS

Rev

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