Subversion Repositories Kolibri OS

Rev

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