Subversion Repositories Kolibri OS

Rev

Rev 1376 | 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: 2212 $
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:
279 serge 638
           and [heap_mutex], 0
321 diamond 639
           pop esi ebx
164 serge 640
           ret
641
endp
642
 
643
restore block_next
644
restore block_prev
645
restore block_list
646
restore block_base
647
restore block_size
648
restore block_flags
649
 
650
;;;;;;;;;;;;;;      USER     ;;;;;;;;;;;;;;;;;
651
 
188 serge 652
HEAP_TOP  equ 0x5FC00000
653
 
164 serge 654
align 4
188 serge 655
proc init_heap
164 serge 656
 
465 serge 657
           mov ebx,[current_slot]
658
           mov eax, [ebx+APPDATA.heap_top]
172 serge 659
           test eax, eax
660
           jz @F
465 serge 661
           sub eax,[ebx+APPDATA.heap_base]
172 serge 662
           sub eax, 4096
663
           ret
664
@@:
465 serge 665
           mov esi, [ebx+APPDATA.mem_size]
188 serge 666
           add esi, 4095
667
           and esi, not 4095
465 serge 668
           mov [ebx+APPDATA.mem_size], esi
188 serge 669
           mov eax, HEAP_TOP
465 serge 670
           mov [ebx+APPDATA.heap_base], esi
671
           mov [ebx+APPDATA.heap_top], eax
164 serge 672
 
188 serge 673
           sub eax, esi
674
           shr esi, 10
675
           mov ecx, eax
164 serge 676
           sub eax, 4096
188 serge 677
           or ecx, FREE_BLOCK
365 serge 678
           mov [page_tabs+esi], ecx
164 serge 679
           ret
680
endp
681
 
682
align 4
683
proc user_alloc stdcall, alloc_size:dword
684
 
662 serge 685
           push ebx
686
           push esi
687
           push edi
688
 
164 serge 689
           mov ecx, [alloc_size]
690
           add ecx, (4095+4096)
691
           and ecx, not 4095
692
 
465 serge 693
           mov ebx, [current_slot]
694
           mov esi, dword [ebx+APPDATA.heap_base]  ; heap_base
695
           mov edi, dword [ebx+APPDATA.heap_top]   ; heap_top
164 serge 696
l_0:
697
           cmp esi, edi
698
           jae m_exit
699
 
700
           mov ebx, esi
701
           shr ebx, 12
365 serge 702
           mov eax, [page_tabs+ebx*4]
620 diamond 703
           test al, FREE_BLOCK
164 serge 704
           jz test_used
705
           and eax, 0xFFFFF000
706
           cmp eax, ecx    ;alloc_size
707
           jb  m_next
940 serge 708
           jz  @f
164 serge 709
 
620 diamond 710
           lea edx, [esi+ecx]
711
           sub eax, ecx
712
           or al, FREE_BLOCK
164 serge 713
           shr edx, 12
365 serge 714
           mov [page_tabs+edx*4], eax
294 diamond 715
@@:
164 serge 716
           or ecx, USED_BLOCK
365 serge 717
           mov [page_tabs+ebx*4], ecx
164 serge 718
           shr ecx, 12
620 diamond 719
           inc ebx
164 serge 720
           dec ecx
620 diamond 721
           jz  .no
164 serge 722
@@:
365 serge 723
           mov dword [page_tabs+ebx*4], 2
164 serge 724
           inc ebx
725
           dec ecx
726
           jnz @B
620 diamond 727
.no:
164 serge 728
 
465 serge 729
           mov     edx, [current_slot]
730
           mov     ebx, [alloc_size]
731
           add     ebx, 0xFFF
732
           and     ebx, not 0xFFF
733
           add     ebx, [edx+APPDATA.mem_size]
734
           call    update_mem_size
294 diamond 735
 
620 diamond 736
           lea eax, [esi+4096]
662 serge 737
 
738
           pop edi
739
           pop esi
740
           pop ebx
164 serge 741
           ret
742
test_used:
620 diamond 743
           test al, USED_BLOCK
164 serge 744
           jz m_exit
745
 
746
           and eax, 0xFFFFF000
620 diamond 747
m_next:
164 serge 748
           add esi, eax
749
           jmp l_0
750
m_exit:
751
           xor eax, eax
662 serge 752
           pop edi
753
           pop esi
754
           pop ebx
164 serge 755
           ret
756
endp
757
 
758
align 4
1289 diamond 759
proc user_alloc_at stdcall, address:dword, alloc_size:dword
760
 
761
           push ebx
762
           push esi
763
           push edi
764
 
765
           mov ebx, [current_slot]
766
           mov edx, [address]
767
           and edx, not 0xFFF
768
           mov [address], edx
769
           sub edx, 0x1000
770
           jb  .error
771
           mov esi, [ebx+APPDATA.heap_base]
772
           mov edi, [ebx+APPDATA.heap_top]
773
           cmp edx, esi
774
           jb  .error
775
.scan:
776
           cmp esi, edi
777
           jae .error
778
           mov ebx, esi
779
           shr ebx, 12
780
           mov eax, [page_tabs+ebx*4]
781
           mov ecx, eax
782
           and ecx, 0xFFFFF000
783
           add ecx, esi
784
           cmp edx, ecx
785
           jb  .found
786
           mov esi, ecx
787
           jmp .scan
788
.error:
789
           xor eax, eax
790
           pop edi
791
           pop esi
792
           pop ebx
793
           ret
794
.found:
795
           test al, FREE_BLOCK
796
           jz  .error
797
           mov eax, ecx
798
           sub eax, edx
799
           sub eax, 0x1000
800
           cmp eax, [alloc_size]
801
           jb  .error
802
 
803
; Here we have 1 big free block which includes requested area.
804
; In general, 3 other blocks must be created instead:
805
; free at [esi, edx);
806
; busy at [edx, edx+0x1000+ALIGN_UP(alloc_size,0x1000));
807
; free at [edx+0x1000+ALIGN_UP(alloc_size,0x1000), ecx)
808
; First or third block (or both) may be absent.
809
           mov eax, edx
810
           sub eax, esi
811
           jz  .nofirst
812
           or  al, FREE_BLOCK
813
           mov [page_tabs+ebx*4], eax
814
.nofirst:
815
           mov eax, [alloc_size]
816
           add eax, 0x1FFF
817
           and eax, not 0xFFF
818
           mov ebx, edx
819
           add edx, eax
820
           shr ebx, 12
821
           or  al, USED_BLOCK
822
           mov [page_tabs+ebx*4], eax
823
           shr eax, 12
824
           dec eax
825
           jz  .second_nofill
826
           inc ebx
827
.fill:
828
           mov dword [page_tabs+ebx*4], 2
829
           inc ebx
830
           dec eax
831
           jnz .fill
832
.second_nofill:
833
           sub ecx, edx
834
           jz  .nothird
835
           or  cl, FREE_BLOCK
836
           mov [page_tabs+ebx*4], ecx
837
.nothird:
838
 
839
           mov     edx, [current_slot]
840
           mov     ebx, [alloc_size]
841
           add     ebx, 0xFFF
842
           and     ebx, not 0xFFF
843
           add     ebx, [edx+APPDATA.mem_size]
844
           call    update_mem_size
845
 
846
           mov eax, [address]
847
 
848
           pop edi
849
           pop esi
850
           pop ebx
851
           ret
852
endp
853
 
854
align 4
164 serge 855
proc user_free stdcall, base:dword
856
 
662 serge 857
           push esi
858
 
164 serge 859
           mov esi, [base]
860
           test esi, esi
861
           jz .exit
862
 
662 serge 863
           push ebx
864
 
294 diamond 865
           xor ebx, ebx
164 serge 866
           shr esi, 12
620 diamond 867
           mov eax, [page_tabs+(esi-1)*4]
546 diamond 868
           test al, USED_BLOCK
620 diamond 869
           jz .cantfree
546 diamond 870
           test al, DONT_FREE_BLOCK
871
           jnz .cantfree
164 serge 872
 
873
           and eax, not 4095
874
           mov ecx, eax
620 diamond 875
           or al, FREE_BLOCK
876
           mov [page_tabs+(esi-1)*4], eax
164 serge 877
           sub ecx, 4096
620 diamond 878
           mov ebx, ecx
164 serge 879
           shr ecx, 12
620 diamond 880
           jz .released
164 serge 881
.release:
188 serge 882
           xor eax, eax
365 serge 883
           xchg eax, [page_tabs+esi*4]
620 diamond 884
           test al, 1
188 serge 885
           jz @F
940 serge 886
           test eax, PG_SHARED
887
           jnz @F
164 serge 888
           call free_page
448 diamond 889
           mov eax, esi
890
           shl eax, 12
891
           invlpg [eax]
188 serge 892
@@:
164 serge 893
           inc esi
894
           dec ecx
895
           jnz .release
620 diamond 896
.released:
662 serge 897
           push edi
898
 
465 serge 899
           mov edx, [current_slot]
900
           mov esi, dword [edx+APPDATA.heap_base]
901
           mov edi, dword [edx+APPDATA.heap_top]
902
           sub ebx, [edx+APPDATA.mem_size]
294 diamond 903
           neg ebx
904
           call update_mem_size
448 diamond 905
           call user_normalize
662 serge 906
           pop edi
907
           pop ebx
908
           pop esi
448 diamond 909
           ret
910
.exit:
911
           xor eax, eax
912
           inc eax
662 serge 913
           pop esi
448 diamond 914
           ret
546 diamond 915
.cantfree:
916
           xor eax, eax
662 serge 917
           pop ebx
918
           pop esi
546 diamond 919
           ret
448 diamond 920
endp
921
 
922
user_normalize:
923
; in: esi=heap_base, edi=heap_top
924
; out: eax=0 <=> OK
925
; destroys: ebx,edx,esi,edi
164 serge 926
           shr esi, 12
927
           shr edi, 12
928
@@:
365 serge 929
           mov eax, [page_tabs+esi*4]
620 diamond 930
           test al, USED_BLOCK
164 serge 931
           jz .test_free
932
           shr eax, 12
933
           add esi, eax
934
           jmp @B
935
.test_free:
620 diamond 936
           test al, FREE_BLOCK
164 serge 937
           jz .err
938
           mov edx, eax
939
           shr edx, 12
940
           add edx, esi
941
           cmp edx, edi
942
           jae .exit
943
 
365 serge 944
           mov ebx, [page_tabs+edx*4]
620 diamond 945
           test bl, USED_BLOCK
164 serge 946
           jz .next_free
947
 
948
           shr ebx, 12
949
           add edx, ebx
950
           mov esi, edx
951
           jmp @B
952
.next_free:
620 diamond 953
           test bl, FREE_BLOCK
164 serge 954
           jz .err
365 serge 955
           and dword [page_tabs+edx*4], 0
164 serge 956
           add eax, ebx
957
           and eax, not 4095
958
           or eax, FREE_BLOCK
365 serge 959
           mov [page_tabs+esi*4], eax
164 serge 960
           jmp @B
961
.exit:
962
           xor eax, eax
963
           inc eax
964
           ret
965
.err:
966
           xor eax, eax
967
           ret
968
 
448 diamond 969
user_realloc:
970
; in: eax = pointer, ebx = new size
971
; out: eax = new pointer or NULL
972
        test    eax, eax
973
        jnz     @f
974
; realloc(NULL,sz) - same as malloc(sz)
975
        push    ebx
976
        call    user_alloc
977
        ret
978
@@:
979
        push    ecx edx
465 serge 980
        lea     ecx, [eax - 0x1000]
448 diamond 981
        shr     ecx, 12
982
        mov     edx, [page_tabs+ecx*4]
620 diamond 983
        test    dl, USED_BLOCK
448 diamond 984
        jnz     @f
985
; attempt to realloc invalid pointer
986
.ret0:
987
        pop     edx ecx
988
        xor     eax, eax
989
        ret
990
@@:
620 diamond 991
        test    dl, DONT_FREE_BLOCK
546 diamond 992
        jnz     .ret0
448 diamond 993
        add     ebx, 0x1FFF
994
        shr     edx, 12
995
        shr     ebx, 12
996
; edx = allocated size, ebx = new size
997
        add     edx, ecx
998
        add     ebx, ecx
999
        cmp     edx, ebx
1000
        jb      .realloc_add
1001
; release part of allocated memory
1002
.loop:
1003
        cmp     edx, ebx
1004
        jz      .release_done
1005
        dec     edx
1006
        xor     eax, eax
1007
        xchg    eax, [page_tabs+edx*4]
1008
        test    al, 1
1009
        jz      .loop
1010
        call    free_page
1011
        mov     eax, edx
1012
        shl     eax, 12
1013
        invlpg  [eax]
1014
        jmp     .loop
1015
.release_done:
1016
        sub     ebx, ecx
1017
        cmp     ebx, 1
1018
        jnz     .nofreeall
1019
        mov     eax, [page_tabs+ecx*4]
1020
        and     eax, not 0xFFF
465 serge 1021
        mov     edx, [current_slot]
1022
        mov     ebx, [APPDATA.mem_size+edx]
448 diamond 1023
        sub     ebx, eax
1024
        add     ebx, 0x1000
1025
        or      al, FREE_BLOCK
1026
        mov     [page_tabs+ecx*4], eax
1027
        push    esi edi
465 serge 1028
        mov     esi, [APPDATA.heap_base+edx]
1029
        mov     edi, [APPDATA.heap_top+edx]
448 diamond 1030
        call    update_mem_size
1031
        call    user_normalize
1032
        pop     edi esi
1033
        jmp     .ret0   ; all freed
1034
.nofreeall:
1035
        sub     edx, ecx
1036
        shl     ebx, 12
1037
        or      ebx, USED_BLOCK
1038
        xchg    [page_tabs+ecx*4], ebx
1039
        shr     ebx, 12
1040
        sub     ebx, edx
1041
        push    ebx ecx edx
465 serge 1042
        mov     edx, [current_slot]
448 diamond 1043
        shl     ebx, 12
465 serge 1044
        sub     ebx, [APPDATA.mem_size+edx]
448 diamond 1045
        neg     ebx
1046
        call    update_mem_size
1047
        pop     edx ecx ebx
465 serge 1048
        lea     eax, [ecx+1]
448 diamond 1049
        shl     eax, 12
1050
        push    eax
823 diamond 1051
        add     ecx, edx
1052
        lea     edx, [ecx+ebx]
448 diamond 1053
        shl     ebx, 12
1054
        jz      .ret
1055
        push    esi
465 serge 1056
        mov     esi, [current_slot]
1057
        mov     esi, [APPDATA.heap_top+esi]
448 diamond 1058
        shr     esi, 12
1059
@@:
1060
        cmp     edx, esi
1061
        jae     .merge_done
1062
        mov     eax, [page_tabs+edx*4]
1063
        test    al, USED_BLOCK
823 diamond 1064
        jnz     .merge_done
448 diamond 1065
        and     dword [page_tabs+edx*4], 0
823 diamond 1066
        shr     eax, 12
1067
        add     edx, eax
1068
        shl     eax, 12
448 diamond 1069
        add     ebx, eax
1070
        jmp     @b
1071
.merge_done:
1072
        pop     esi
1073
        or      ebx, FREE_BLOCK
1074
        mov     [page_tabs+ecx*4], ebx
1075
.ret:
1076
        pop     eax edx ecx
1077
        ret
1078
.realloc_add:
1079
; get some additional memory
465 serge 1080
        mov     eax, [current_slot]
1081
        mov     eax, [APPDATA.heap_top+eax]
448 diamond 1082
        shr     eax, 12
1083
        cmp     edx, eax
1084
        jae     .cant_inplace
1085
        mov     eax, [page_tabs+edx*4]
620 diamond 1086
        test    al, FREE_BLOCK
1087
        jz      .cant_inplace
448 diamond 1088
        shr     eax, 12
1089
        add     eax, edx
620 diamond 1090
        sub     eax, ebx
448 diamond 1091
        jb      .cant_inplace
1092
        jz      @f
1093
        shl     eax, 12
1094
        or      al, FREE_BLOCK
1095
        mov     [page_tabs+ebx*4], eax
1096
@@:
1097
        mov     eax, ebx
1098
        sub     eax, ecx
1099
        shl     eax, 12
1100
        or      al, USED_BLOCK
1101
        mov     [page_tabs+ecx*4], eax
465 serge 1102
        lea     eax, [ecx+1]
448 diamond 1103
        shl     eax, 12
1104
        push    eax
1105
        push    edi
1106
        lea     edi, [page_tabs+edx*4]
1107
        mov     eax, 2
1108
        sub     ebx, edx
1109
        mov     ecx, ebx
1110
        cld
1111
        rep     stosd
1112
        pop     edi
465 serge 1113
        mov     edx, [current_slot]
448 diamond 1114
        shl     ebx, 12
465 serge 1115
        add     ebx, [APPDATA.mem_size+edx]
448 diamond 1116
        call    update_mem_size
1117
        pop     eax edx ecx
1118
        ret
1119
.cant_inplace:
1120
        push    esi edi
465 serge 1121
        mov     eax, [current_slot]
1122
        mov     esi, [APPDATA.heap_base+eax]
1123
        mov     edi, [APPDATA.heap_top+eax]
448 diamond 1124
        shr     esi, 12
1125
        shr     edi, 12
1126
        sub     ebx, ecx
1127
.find_place:
1128
        cmp     esi, edi
1129
        jae     .place_not_found
1130
        mov     eax, [page_tabs+esi*4]
1131
        test    al, FREE_BLOCK
1132
        jz      .next_place
1133
        shr     eax, 12
1134
        cmp     eax, ebx
1135
        jae     .place_found
1136
        add     esi, eax
1137
        jmp     .find_place
1138
.next_place:
1139
        shr     eax, 12
1140
        add     esi, eax
1141
        jmp     .find_place
1142
.place_not_found:
1143
        pop     edi esi
1144
        jmp     .ret0
1145
.place_found:
1146
        sub     eax, ebx
1147
        jz      @f
1148
        push    esi
620 diamond 1149
        add     esi, ebx
448 diamond 1150
        shl     eax, 12
1151
        or      al, FREE_BLOCK
1152
        mov     [page_tabs+esi*4], eax
1153
        pop     esi
1154
@@:
1155
        mov     eax, ebx
1156
        shl     eax, 12
1157
        or      al, USED_BLOCK
1158
        mov     [page_tabs+esi*4], eax
1159
        inc     esi
1160
        mov     eax, esi
1161
        shl     eax, 12
1162
        push    eax
1163
        mov     eax, [page_tabs+ecx*4]
1164
        and     eax, not 0xFFF
1165
        or      al, FREE_BLOCK
1166
        sub     edx, ecx
1167
        mov     [page_tabs+ecx*4], eax
1168
        inc     ecx
620 diamond 1169
        dec     ebx
1170
        dec     edx
1171
        jz      .no
448 diamond 1172
@@:
1173
        xor     eax, eax
1174
        xchg    eax, [page_tabs+ecx*4]
1175
        mov     [page_tabs+esi*4], eax
940 serge 1176
        mov     eax, ecx
1177
        shl     eax, 12
1178
        invlpg  [eax]
620 diamond 1179
        inc     esi
448 diamond 1180
        inc     ecx
1181
        dec     ebx
1182
        dec     edx
1183
        jnz     @b
620 diamond 1184
.no:
448 diamond 1185
        push    ebx
465 serge 1186
        mov     edx, [current_slot]
448 diamond 1187
        shl     ebx, 12
465 serge 1188
        add     ebx, [APPDATA.mem_size+edx]
448 diamond 1189
        call    update_mem_size
1190
        pop     ebx
1191
@@:
1192
        mov     dword [page_tabs+esi*4], 2
1193
        inc     esi
1194
        dec     ebx
1195
        jnz     @b
1196
        pop     eax edi esi edx ecx
1197
        ret
1198
 
278 serge 1199
if 0
164 serge 1200
align 4
1201
proc alloc_dll
1202
           pushf
1203
           cli
1204
           bsf eax, [dll_map]
1205
           jnz .find
1206
           popf
1207
           xor eax, eax
1208
           ret
1209
.find:
1210
           btr [dll_map], eax
1211
           popf
1212
           shl eax, 5
1213
           add eax, dll_tab
1214
           ret
1215
endp
1216
 
1217
align 4
1218
proc alloc_service
1219
           pushf
1220
           cli
1221
           bsf eax, [srv_map]
1222
           jnz .find
1223
           popf
1224
           xor eax, eax
1225
           ret
214 serge 1226
.find:
1227
           btr [srv_map], eax
164 serge 1228
           popf
214 serge 1229
           shl eax,0x02
1230
           lea eax,[srv_tab+eax+eax*8]   ;srv_tab+eax*36
164 serge 1231
           ret
1232
endp
278 serge 1233
 
1234
end if
940 serge 1235
 
1236
 
1237
;;;;;;;;;;;;;;      SHARED      ;;;;;;;;;;;;;;;;;
1238
 
1239
 
1240
; param
1241
;  eax= shm_map object
1242
 
1243
align 4
1244
destroy_smap:
1245
 
1246
           pushfd
1247
           cli
1248
 
945 serge 1249
           push esi
1250
           push edi
940 serge 1251
 
945 serge 1252
           mov edi, eax
1253
           mov esi, [eax+SMAP.parent]
1254
           test esi, esi
1255
           jz .done
940 serge 1256
 
945 serge 1257
           lock dec [esi+SMEM.refcount]
1258
           jnz .done
940 serge 1259
 
945 serge 1260
           mov ecx, [esi+SMEM.bk]
1261
           mov edx, [esi+SMEM.fd]
1262
 
1263
           mov [ecx+SMEM.fd], edx
1264
           mov [edx+SMEM.bk], ecx
1265
 
1266
           stdcall kernel_free, [esi+SMEM.base]
1267
           mov eax, esi
1268
           call free
1269
.done:
1270
           mov eax, edi
940 serge 1271
           call destroy_kernel_object
1272
 
945 serge 1273
           pop edi
1274
           pop esi
940 serge 1275
           popfd
1276
 
1277
           ret
1278
 
1279
E_NOTFOUND      equ  5
1280
E_ACCESS        equ 10
1281
E_NOMEM         equ 30
1282
E_PARAM         equ 33
1283
 
1284
SHM_READ        equ 0
1285
SHM_WRITE       equ 1
1286
 
1287
SHM_ACCESS_MASK equ 3
1288
 
1289
SHM_OPEN        equ (0 shl 2)
1290
SHM_OPEN_ALWAYS equ (1 shl 2)
1291
SHM_CREATE      equ (2 shl 2)
1292
 
1293
SHM_OPEN_MASK   equ (3 shl 2)
1294
 
1295
align 4
1296
proc shmem_open stdcall name:dword, size:dword, access:dword
1297
           locals
1298
              action         dd ?
1299
              owner_access   dd ?
1300
              mapped         dd ?
1301
           endl
1302
 
1303
           push ebx
1304
           push esi
1305
           push edi
1306
 
1307
           mov [mapped], 0
1308
           mov [owner_access], 0
1309
 
1310
           pushfd                      ;mutex required
1311
           cli
1312
 
1313
           mov eax, [access]
1314
           and eax, SHM_OPEN_MASK
1315
           mov [action], eax
1316
 
1213 serge 1317
           mov ebx, [name]
1318
           test ebx, ebx
940 serge 1319
           mov edx, E_PARAM
1213 serge 1320
           jz .fail
940 serge 1321
 
1322
           mov esi, [shmem_list.fd]
1323
align 4
1324
@@:
1325
           cmp esi, shmem_list
1326
           je .not_found
1327
 
943 serge 1328
           lea edx, [esi+SMEM.name] ; link , base, size
1213 serge 1329
           stdcall strncmp, edx, ebx, 32
940 serge 1330
           test eax, eax
1331
           je .found
1332
 
943 serge 1333
           mov esi, [esi+SMEM.fd]
940 serge 1334
           jmp @B
1335
 
1336
.not_found:
1337
           mov eax, [action]
1338
 
1339
           cmp eax, SHM_OPEN
1340
           mov edx, E_NOTFOUND
1213 serge 1341
           je .fail
940 serge 1342
 
1343
           cmp eax, SHM_CREATE
1344
           mov edx, E_PARAM
1345
           je .create_shm
1346
 
1347
           cmp eax, SHM_OPEN_ALWAYS
1213 serge 1348
           jne .fail
940 serge 1349
 
1350
.create_shm:
1351
 
1352
           mov ecx, [size]
1353
           test ecx, ecx
1213 serge 1354
           jz .fail
940 serge 1355
 
1356
           add ecx, 4095
1357
           and ecx, -4096
1358
           mov [size], ecx
1359
 
943 serge 1360
           mov eax, SMEM.sizeof
940 serge 1361
           call malloc
1362
           test eax, eax
1363
           mov esi, eax
1364
           mov edx, E_NOMEM
1213 serge 1365
           jz .fail
940 serge 1366
 
1367
           stdcall kernel_alloc, [size]
1368
           test eax, eax
1369
           mov [mapped], eax
1370
           mov edx, E_NOMEM
1371
           jz .cleanup
1372
 
1373
           mov ecx, [size]
1374
           mov edx, [access]
1375
           and edx, SHM_ACCESS_MASK
1376
 
943 serge 1377
           mov [esi+SMEM.base], eax
1378
           mov [esi+SMEM.size], ecx
1379
           mov [esi+SMEM.access], edx
1380
           mov [esi+SMEM.refcount], 0
1381
           mov [esi+SMEM.name+28], 0
940 serge 1382
 
943 serge 1383
           lea eax, [esi+SMEM.name]
940 serge 1384
           stdcall strncpy, eax, [name], 31
1385
 
1386
           mov eax, [shmem_list.fd]
943 serge 1387
           mov [esi+SMEM.bk], shmem_list
1388
           mov [esi+SMEM.fd], eax
940 serge 1389
 
943 serge 1390
           mov [eax+SMEM.bk], esi
940 serge 1391
           mov [shmem_list.fd], esi
1392
 
1393
           mov [action], SHM_OPEN
1394
           mov [owner_access], SHM_WRITE
1395
 
1396
.found:
1397
           mov eax, [action]
1398
 
1399
           cmp eax, SHM_CREATE
1400
           mov edx, E_ACCESS
1401
           je .exit
1402
 
1403
           cmp eax, SHM_OPEN
1404
           mov edx, E_PARAM
1405
           je .create_map
1406
 
1407
           cmp eax, SHM_OPEN_ALWAYS
1213 serge 1408
           jne .fail
940 serge 1409
 
1410
.create_map:
1411
 
1412
           mov eax, [access]
1413
           and eax, SHM_ACCESS_MASK
943 serge 1414
           cmp eax, [esi+SMEM.access]
940 serge 1415
           mov [access], eax
1416
           mov edx, E_ACCESS
1213 serge 1417
           ja .fail
940 serge 1418
 
1419
           mov ebx, [CURRENT_TASK]
1420
           shl ebx, 5
1421
           mov ebx, [CURRENT_TASK+ebx+4]
943 serge 1422
           mov eax, SMAP.sizeof
940 serge 1423
 
1424
           call create_kernel_object
1425
           test eax, eax
1426
           mov edi, eax
1427
           mov edx, E_NOMEM
1213 serge 1428
           jz .fail
940 serge 1429
 
1213 serge 1430
           inc [esi+SMEM.refcount]
1431
 
943 serge 1432
           mov [edi+SMAP.magic], 'SMAP'
1433
           mov [edi+SMAP.destroy], destroy_smap
1213 serge 1434
           mov [edi+SMAP.parent], esi
943 serge 1435
           mov [edi+SMAP.base], 0
940 serge 1436
 
943 serge 1437
           stdcall user_alloc, [esi+SMEM.size]
940 serge 1438
           test eax, eax
1439
           mov [mapped], eax
1440
           mov edx, E_NOMEM
1441
           jz .cleanup2
1442
 
943 serge 1443
           mov [edi+SMAP.base], eax
940 serge 1444
 
943 serge 1445
           mov ecx, [esi+SMEM.size]
940 serge 1446
           mov [size], ecx
1447
 
1448
           shr ecx, 12
1449
           shr eax, 10
1450
 
943 serge 1451
           mov esi, [esi+SMEM.base]
940 serge 1452
           shr esi, 10
1453
           lea edi, [page_tabs+eax]
1454
           add esi, page_tabs
1455
 
1456
           mov edx, [access]
1457
           or edx, [owner_access]
1458
           shl edx, 1
1459
           or edx, PG_USER+PG_SHARED
1460
@@:
1461
           lodsd
1462
           and eax, 0xFFFFF000
1463
           or eax, edx
1464
           stosd
1465
           loop @B
1466
 
1467
           xor edx, edx
1468
 
1469
           cmp [owner_access], 0
1213 serge 1470
           jne .fail
1471
.exit:
940 serge 1472
           mov edx, [size]
1213 serge 1473
.fail:
940 serge 1474
           mov eax, [mapped]
1475
 
1476
           popfd
1477
           pop edi
1478
           pop esi
1479
           pop ebx
1480
           ret
1481
.cleanup:
1213 serge 1482
           mov [size], edx
940 serge 1483
           mov eax, esi
1484
           call free
1485
           jmp .exit
1486
 
1487
.cleanup2:
1213 serge 1488
           mov [size], edx
940 serge 1489
           mov eax, edi
1490
           call destroy_smap
1491
           jmp .exit
1492
endp
943 serge 1493
 
1494
align 4
1495
proc shmem_close stdcall, name:dword
1496
 
1497
           mov eax, [name]
1498
           test eax, eax
1499
           jz .fail
1500
 
1501
           push esi
1502
           push edi
945 serge 1503
           pushfd
1504
           cli
943 serge 1505
 
1506
           mov esi, [current_slot]
1507
           add esi, APP_OBJ_OFFSET
1508
.next:
1509
           mov eax, [esi+APPOBJ.fd]
1510
           test eax, eax
1511
           jz @F
1512
 
1513
           cmp eax, esi
1514
           mov esi, eax
1515
           je @F
1516
 
1517
           cmp [eax+SMAP.magic], 'SMAP'
1518
           jne .next
1519
 
1520
           mov edi, [eax+SMAP.parent]
1521
           test edi, edi
1522
           jz .next
1523
 
1524
           lea eax, [edi+SMEM.name]
1525
           stdcall strncmp, [name], edi, 32
1526
           test eax, eax
1527
           jne .next
1528
 
945 serge 1529
           stdcall user_free, [esi+SMAP.base]
1530
 
943 serge 1531
           call [esi+APPOBJ.destroy]
1532
@@:
945 serge 1533
           popfd
943 serge 1534
           pop edi
1535
           pop esi
1536
.fail:
1537
           ret
1538
endp