Subversion Repositories Kolibri OS

Rev

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