Subversion Repositories Kolibri OS

Rev

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