Subversion Repositories Kolibri OS

Rev

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

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