Subversion Repositories Kolibri OS

Rev

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

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