Subversion Repositories Kolibri OS

Rev

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

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