Subversion Repositories Kolibri OS

Rev

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