Subversion Repositories Kolibri OS

Rev

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

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