Subversion Repositories Kolibri OS

Rev

Rev 2465 | Rev 3908 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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