Subversion Repositories Kolibri OS

Rev

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

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