Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
164 serge 1
 
2
{  .next_block  dd ?
3
   .prev_block  dd ? ;+4
4
   .list_fd     dd ? ;+8
357 serge 5
   .list_bk     dd ? ;+12
6
   .base        dd ? ;+16
164 serge 7
   .size        dd ? ;+20
8
   .flags       dd ? ;+24
9
   .handle      dd ? ;+28
10
}
11
12
 
357 serge 13
FREE_BLOCK      equ  4
164 serge 14
USED_BLOCK      equ  8
15
16
 
17
  MEM_BLOCK MEM_BLOCK
18
end virtual
19
20
 
21
22
 
23
block_prev   equ MEM_BLOCK.prev_block
24
list_fd      equ MEM_BLOCK.list_fd
357 serge 25
list_bk      equ MEM_BLOCK.list_bk
26
block_base   equ MEM_BLOCK.base
164 serge 27
block_size   equ MEM_BLOCK.size
28
block_flags  equ MEM_BLOCK.flags
29
30
 
31
{          shr op, 12
32
           dec op
33
           cmp op, 63
34
           jna @f
35
           mov op, 63
36
@@:
37
}
38
39
 
40
{          mov edx, [op+list_fd]
357 serge 41
           mov ecx, [op+list_bk]
42
           test edx, edx
164 serge 43
           jz @f
44
           mov [edx+list_bk], ecx
357 serge 45
@@:
164 serge 46
           test ecx, ecx
47
           jz @f
48
           mov [ecx+list_fd], edx
357 serge 49
@@:
164 serge 50
           mov [op+list_fd],0
357 serge 51
           mov [op+list_bk],0
52
}
164 serge 53
54
 
55
{
56
           remove_from_list op
57
58
 
59
           calc_index eax
60
           cmp [mem_block_list+eax*4], op
61
           jne @f
62
           mov [mem_block_list+eax*4], edx
63
@@:
64
           cmp [mem_block_list+eax*4], 0
65
           jne @f
66
           btr [mem_block_mask], eax
67
@@:
68
}
69
70
 
71
{
72
           mov edx, [op+list_fd]
357 serge 73
           mov ecx, [op+list_bk]
74
           mov [edx+list_bk], ecx
75
           mov [ecx+list_fd], edx
76
           mov [op+list_fd], 0
77
           mov [op+list_bk], 0
78
}
164 serge 79
80
 
81
proc init_kernel_heap
82
83
 
84
           mov edi, mem_block_list
85
           xor eax, eax
86
           cld
87
           rep stosd
88
89
 
90
           mov edi, mem_block_map
91
           not eax
92
           rep stosd
93
94
 
95
           mov [mem_block_end], mem_block_map+512
96
           mov [mem_block_arr], HEAP_BASE
97
98
 
357 serge 99
           mov [mem_used.fd], eax
100
           mov [mem_used.bk], eax
101
102
 
164 serge 103
           mov ecx, 32
104
           mov edx, eax
105
           mov edi, HEAP_BASE
106
.l1:
107
           stdcall map_page,edi,edx,PG_SW
108
           add edi, 0x1000
109
           add edx, 0x1000
110
           dec ecx
111
           jnz .l1
112
113
 
114
           mov ebx, HEAP_BASE+MEM_BLOCK_SIZE
357 serge 115
           xor eax, eax
164 serge 116
           mov [edi+block_next], ebx
117
           mov [edi+block_prev], eax
118
           mov [edi+list_fd], eax
357 serge 119
           mov [edi+list_bk], eax
120
           mov [edi+block_base], HEAP_BASE
164 serge 121
           mov [edi+block_size], 4096*MEM_BLOCK_SIZE
122
           mov [edi+block_flags], USED_BLOCK
123
124
 
125
           mov [ebx+block_prev], eax
126
           mov [ebx+list_fd], eax
357 serge 127
           mov [ebx+list_bk], eax
128
           mov [ebx+block_base], HEAP_BASE+4096*MEM_BLOCK_SIZE
164 serge 129
130
 
131
           sub ecx, HEAP_BASE + 4096*MEM_BLOCK_SIZE
212 serge 132
           mov [heap_size], ecx
170 serge 133
           mov [heap_free], ecx
134
           mov [ebx+block_size], ecx
164 serge 135
           mov [ebx+block_flags], FREE_BLOCK
136
137
 
138
           mov [mem_block_mask+4],0x80000000
139
140
 
141
           mov byte [mem_block_map], 0xFC
142
           and [heap_mutex], 0
279 serge 143
           mov [heap_blocks], 4095
170 serge 144
           mov [free_blocks], 4095
145
           ret
164 serge 146
endp
147
148
 
149
proc get_block stdcall, index:dword
150
151
 
152
           mov ecx, [index]
153
           cmp ecx, eax
154
           jna @f
155
           ;cmova ecx, eax
156
           mov ecx, eax
157
@@:
158
           xor esi, esi
159
           xor ebx, ebx
160
           xor edx, edx
161
           not edx
162
163
 
164
           jb .bit_test
165
166
 
167
           add ebx, 32
168
           add esi, 4
169
170
 
171
           shl edx, cl
172
           and edx, [mem_block_mask+esi]
173
           jz .high_mask
174
           bsf eax, edx
175
           add ebx, eax
176
           mov eax, [mem_block_list+ebx*4]
177
           ret
178
179
 
180
181
 
182
           add ebx, 32
183
           test esi, 0xFFFFFFF8
184
           jnz .big_error
185
           mov edx, [mem_block_mask+esi]
186
           and edx, edx
187
           jz .high_mask
188
           bsf eax, edx
189
           add ebx, eax
190
           mov eax, [mem_block_list+ebx*4]
191
           ret
192
193
 
194
           xor eax, eax
195
           ret
196
endp
197
198
 
199
proc alloc_mem_block
200
201
 
202
           mov ecx, [mem_block_end]
203
.l1:
204
           bsf eax,[ebx];
205
           jnz found
206
           add ebx,4
207
           cmp ebx, ecx
208
           jb .l1
209
           xor eax,eax
210
           ret
211
212
 
213
           btr [ebx], eax
214
           mov [mem_block_start],ebx
215
           sub ebx, mem_block_map
216
           lea eax,[eax+ebx*8]
254 serge 217
           shl eax, 5
164 serge 218
           add eax, [mem_block_arr]
219
           dec [free_blocks]
170 serge 220
           ret
164 serge 221
endp
222
223
 
224
           mov dword [eax], 0
357 serge 225
           mov dword [eax+4], 0
226
           mov dword [eax+8], 0
227
           mov dword [eax+12], 0
228
           mov dword [eax+16], 0
229
;           mov dword [eax+20], 0
230
           mov dword [eax+24], 0
231
           mov dword [eax+28], 0
232
233
 
164 serge 234
           shr eax, 5
235
236
 
237
           bts [ebx], eax
238
           inc [free_blocks]
170 serge 239
           shr eax, 3
164 serge 240
           and eax, not 3
241
           add eax, ebx
242
           cmp [mem_block_start], eax
243
           ja @f
244
           ret
245
@@:
246
           mov [mem_block_start], eax
247
	   ret
248
.err:
249
           xor eax, eax
250
	   ret
251
endp
252
253
 
254
proc alloc_kernel_space stdcall, size:dword
255
           local block_ind:DWORD
256
257
 
258
           add eax, 4095
206 serge 259
           and eax, not 4095
260
           mov [size], eax
164 serge 261
279 serge 262
 
263
           call wait_mutex    ;ebx
264
265
 
170 serge 266
           ja .error
267
164 serge 268
 
269
           sub eax, 1
270
271
 
272
273
 
274
           test eax, eax
279 serge 275
           jz .error
164 serge 276
277
 
278
279
 
280
           jne .error
281
282
 
283
284
 
285
           cmp eax, [size]
286
           je .m_eq_size
287
288
 
289
           and eax, eax
290
           jz .error
291
292
 
293
294
 
295
           mov eax, [edi+block_prev]
296
           mov [esi+block_prev], eax
297
           mov [edi+block_prev], esi
298
           mov [esi+list_fd], 0
357 serge 299
           mov [esi+list_bk], 0
300
           and eax, eax
164 serge 301
           jz @f
302
           mov [eax+block_next], esi
303
@@:
304
           mov ebx, [edi+block_base]
305
           mov [esi+block_base], ebx
306
           mov edx, [size]
307
           mov [esi+block_size], edx
308
           add [edi+block_base], edx
309
           sub [edi+block_size], edx
310
311
 
312
           shr eax, 12
313
           sub eax, 1
314
           cmp eax, 63
315
           jna @f
316
           mov eax, 63
317
@@:
318
           cmp eax, [block_ind]
319
           je .m_eq_ind
320
321
 
192 serge 322
164 serge 323
 
324
           mov [mem_block_list+ecx*4], edx
211 serge 325
164 serge 326
 
211 serge 327
           jnz @f
164 serge 328
           btr [mem_block_mask], ecx
329
@@:
330
           mov edx, [mem_block_list+eax*4]
331
           mov [edi+list_fd], edx
357 serge 332
           test edx, edx
164 serge 333
           jz @f
334
           mov [edx+list_bk], edi
357 serge 335
@@:
164 serge 336
           mov [mem_block_list+eax*4], edi
337
           bts [mem_block_mask], eax
338
.m_eq_ind:
339
           mov ecx, mem_used.fd-MEM_LIST_OFFSET
357 serge 340
           mov edx, [ecx+list_fd]
341
           mov [esi+list_fd], edx
342
           mov [esi+list_bk], ecx
343
           mov [ecx+list_fd], esi
344
           mov [edx+list_bk], esi
345
346
 
164 serge 347
           mov eax, [esi+block_base]
348
           mov ebx, [size]
170 serge 349
           sub [heap_free], ebx
350
           and [heap_mutex], 0
279 serge 351
           ret
164 serge 352
.m_eq_size:
353
           remove_from_list edi
354
           mov [mem_block_list+ebx*4], edx
192 serge 355
           and edx, edx
164 serge 356
           jnz @f
357
           btr [mem_block_mask], ebx
192 serge 358
@@:
164 serge 359
           mov ecx, mem_used.fd-MEM_LIST_OFFSET
357 serge 360
           mov edx, [ecx+list_fd]
361
           mov [edi+list_fd], edx
362
           mov [edi+list_bk], ecx
363
           mov [ecx+list_fd], edi
364
           mov [edx+list_bk], edi
365
366
 
164 serge 367
           mov eax, [edi+block_base]
368
           mov ebx, [size]
170 serge 369
           sub [heap_free], ebx
370
           and [heap_mutex], 0
279 serge 371
           ret
164 serge 372
.error:
373
           xor eax, eax
374
           mov [heap_mutex], eax
279 serge 375
           ret
164 serge 376
endp
377
378
 
379
proc free_kernel_space stdcall uses ebx ecx edx esi edi, base:dword
321 diamond 380
164 serge 381
 
279 serge 382
           call wait_mutex    ;ebx
383
384
 
164 serge 385
           mov esi, [mem_used.fd]
357 serge 386
@@:
164 serge 387
           cmp esi, mem_used.fd-MEM_LIST_OFFSET
357 serge 388
           je .fail
389
164 serge 390
 
391
           je .found
392
           mov esi, [esi+list_fd]
357 serge 393
           jmp @b
164 serge 394
.found:
395
           cmp [esi+block_flags], USED_BLOCK
396
           jne .fail
397
398
 
170 serge 399
           add [heap_free], eax
400
401
 
164 serge 402
           test edi, edi
403
           jz .prev
404
405
 
406
           jne .prev
407
408
 
409
410
 
411
           mov [esi+block_next], edx
412
           test edx, edx
413
           jz @f
414
415
 
416
@@:
417
           mov ecx, [edi+block_size]
418
           add [esi+block_size], ecx
419
420
 
421
           call free_mem_block
422
.prev:
423
           mov edi, [esi+block_prev]
424
           test edi, edi
425
           jz .insert
426
427
 
428
           jne .insert
429
430
 
431
432
 
433
           mov [edi+block_next], edx
434
           test edx, edx
435
           jz @f
436
           mov [edx+block_prev], edi
437
@@:
438
           mov eax, esi
439
           call free_mem_block
440
441
 
442
           mov eax, [esi+block_size]
443
           add eax, ecx
444
           mov [edi+block_size], eax
445
446
 
447
           calc_index ecx
448
           cmp eax, ecx
449
           je .m_eq
450
451
 
452
           remove_from_list edi
453
           pop ecx
454
455
 
456
           jne @f
457
           mov [mem_block_list+ecx*4], edx
458
@@:
459
           cmp [mem_block_list+ecx*4], 0
460
           jne @f
461
           btr [mem_block_mask], ecx
462
@@:
463
           mov esi, [mem_block_list+eax*4]
464
           mov [mem_block_list+eax*4], edi
465
           mov [edi+list_fd], esi
357 serge 466
           test esi, esi
164 serge 467
           jz @f
468
           mov [esi+list_bk], edi
357 serge 469
@@:
164 serge 470
           bts [mem_block_mask], eax
471
.m_eq:
472
           xor eax, eax
473
           mov [heap_mutex], eax
279 serge 474
           dec eax
321 diamond 475
           ret
164 serge 476
.insert:
477
           remove_from_used esi
478
479
 
480
           calc_index eax
481
482
 
483
           mov [mem_block_list+eax*4], esi
484
           mov [esi+list_fd], edi
357 serge 485
           test edi, edi
164 serge 486
           jz @f
487
           mov [edi+list_bk], esi
357 serge 488
@@:
164 serge 489
           bts [mem_block_mask], eax
490
           mov [esi+block_flags],FREE_BLOCK
491
           xor eax, eax
492
           mov [heap_mutex], eax
279 serge 493
           dec eax
321 diamond 494
           ret
164 serge 495
.fail:
496
           xor eax, eax
497
           mov [heap_mutex], eax
279 serge 498
           ret
164 serge 499
endp
500
501
 
502
proc kernel_alloc stdcall, size:dword
503
           locals
504
             lin_addr    dd ?
505
             pages_count dd ?
506
           endl
507
508
 
509
           add eax, 4095
206 serge 510
           and eax, not 4095;
511
           mov [size], eax
164 serge 512
           and eax, eax
513
           jz .err
357 serge 514
           mov ebx, eax
164 serge 515
           shr ebx, 12
516
           mov [pages_count], ebx
517
518
 
519
           test eax, eax
357 serge 520
           jz .err
521
           mov [lin_addr], eax
164 serge 522
523
 
524
           mov edx, eax
525
           mov ebx, ecx
526
527
 
528
           jz .next
529
530
 
531
           push ebx
532
           stdcall alloc_pages, ebx
533
           pop ecx                   ; yes ecx!!!
534
           and eax, eax
535
           jz .err
357 serge 536
164 serge 537
 
538
           mov edx, [lin_addr]
539
@@:
540
           stdcall map_page,edx,edi,dword PG_SW
541
           add edx, 0x1000
542
           add edi, 0x1000
543
           dec ecx
544
           jnz @B
545
.next:
546
           mov ecx, [pages_count]
547
           and ecx, 7
548
           jz .end
549
@@:
357 serge 550
           push ecx
551
           call alloc_page
164 serge 552
           pop ecx
553
           test eax, eax
554
           jz .err
357 serge 555
164 serge 556
 
557
           add edx, 0x1000
558
           dec ecx
559
           jnz @B
560
.end:
561
           mov eax, [lin_addr]
562
           ret
563
.err:
357 serge 564
           xor eax, eax
164 serge 565
           ret
566
endp
567
568
 
569
proc kernel_free stdcall, base:dword
570
           push ebx esi
321 diamond 571
164 serge 572
 
279 serge 573
           call wait_mutex    ;ebx
574
575
 
164 serge 576
           mov esi, [mem_used.fd]
357 serge 577
@@:
164 serge 578
           cmp esi, mem_used.fd-MEM_LIST_OFFSET
357 serge 579
           je .fail
580
164 serge 581
 
582
           je .found
583
           mov esi, [esi+list_fd]
357 serge 584
           jmp @b
164 serge 585
.found:
586
           cmp [esi+block_flags], USED_BLOCK
587
           jne .fail
588
589
 
279 serge 590
591
 
321 diamond 592
           mov ecx, [esi+block_size];
164 serge 593
           shr ecx, 12
281 serge 594
           call release_pages   ;eax, ecx
279 serge 595
           pop ecx
321 diamond 596
           stdcall free_kernel_space, [base]
164 serge 597
           pop esi ebx
321 diamond 598
           ret
279 serge 599
.fail:
164 serge 600
           and [heap_mutex], 0
279 serge 601
           pop esi ebx
321 diamond 602
           ret
164 serge 603
endp
604
605
 
606
restore block_prev
607
restore block_list
608
restore block_base
609
restore block_size
610
restore block_flags
611
612
 
613
614
 
188 serge 615
616
 
164 serge 617
proc init_heap
188 serge 618
164 serge 619
 
172 serge 620
           shl ebx,8
621
           mov eax, [PROC_BASE+APPDATA.heap_top+ebx]
622
           test eax, eax
623
           jz @F
624
           sub eax,[PROC_BASE+APPDATA.heap_base+ebx]
625
           sub eax, 4096
626
           ret
627
@@:
628
           mov esi, [PROC_BASE+APPDATA.mem_size+ebx]
629
           add esi, 4095
188 serge 630
           and esi, not 4095
631
           mov [PROC_BASE+APPDATA.mem_size+ebx], esi
294 diamond 632
           mov eax, HEAP_TOP
188 serge 633
           mov [PROC_BASE+APPDATA.heap_base+ebx], esi
172 serge 634
           mov [PROC_BASE+APPDATA.heap_top+ebx], eax
188 serge 635
164 serge 636
 
188 serge 637
           add esi, new_app_base
638
           shr esi, 10
639
           mov ecx, eax
640
           sub eax, 4096
164 serge 641
           or ecx, FREE_BLOCK
188 serge 642
           mov [page_tabs+esi], ecx
365 serge 643
           ret
164 serge 644
.exit:
645
           xor eax, eax
646
           ret
647
endp
648
649
 
650
proc user_alloc stdcall, alloc_size:dword
651
652
 
653
           add ecx, (4095+4096)
654
           and ecx, not 4095
655
656
 
657
           shl ebx, 8
658
           mov esi, dword [ebx+PROC_BASE+APPDATA.heap_base]; heap_base
172 serge 659
           mov edi, dword [ebx+PROC_BASE+APPDATA.heap_top]; heap_top
660
           add esi, new_app_base
164 serge 661
           add edi, new_app_base
662
l_0:
663
           cmp esi, edi
664
           jae m_exit
665
666
 
667
           shr ebx, 12
668
           mov eax, [page_tabs+ebx*4]
365 serge 669
           test eax, FREE_BLOCK
164 serge 670
           jz test_used
671
           and eax, 0xFFFFF000
672
           cmp eax, ecx    ;alloc_size
673
           jb  m_next
674
	   jz  @f
270 diamond 675
164 serge 676
 
677
           add edx, ecx
678
           sub eax, ecx;
679
           or eax, FREE_BLOCK
680
           shr edx, 12
681
           mov [page_tabs+edx*4], eax
365 serge 682
214 serge 683
 
294 diamond 684
           or ecx, USED_BLOCK
164 serge 685
           mov [page_tabs+ebx*4], ecx
365 serge 686
           shr ecx, 12
164 serge 687
           dec ecx
688
           inc ebx
689
@@:
690
           mov dword [page_tabs+ebx*4], 2
365 serge 691
           inc ebx
164 serge 692
           dec ecx
693
           jnz @B
694
695
 
294 diamond 696
        shl     edx, 8
697
        mov     ebx, [alloc_size]
698
        add     ebx, 0xFFF
699
        and     ebx, not 0xFFF
700
        add     ebx, [PROC_BASE+APPDATA.mem_size+edx]
701
        call    update_mem_size
702
703
 
164 serge 704
           add eax, 4096
705
           sub eax, new_app_base
706
           ret
707
m_next:
708
           add esi, eax
709
           jmp l_0
710
test_used:
711
           test eax, USED_BLOCK
712
           jz m_exit
713
714
 
715
           add esi, eax
716
           jmp l_0
717
m_exit:
718
           xor eax, eax
719
           ret
720
endp
721
722
 
723
proc user_free stdcall, base:dword
724
725
 
726
           test esi, esi
727
           jz .exit
728
729
 
294 diamond 730
           sub esi, 4096
164 serge 731
           shr esi, 12
732
           mov eax, [page_tabs+esi*4]
365 serge 733
           test eax, USED_BLOCK
164 serge 734
           jz .not_used
188 serge 735
164 serge 736
 
737
           mov ecx, eax
738
           or eax, FREE_BLOCK
739
           mov [page_tabs+esi*4], eax
365 serge 740
           inc esi
164 serge 741
           sub ecx, 4096
742
           shr ecx, 12
743
           mov ebx, ecx
294 diamond 744
.release:
164 serge 745
           xor eax, eax
188 serge 746
           xchg eax, [page_tabs+esi*4]
365 serge 747
           test eax, 1
188 serge 748
           jz @F
749
           call free_page
164 serge 750
@@:
188 serge 751
           inc esi
164 serge 752
           dec ecx
753
           jnz .release
754
.not_used:
188 serge 755
           mov edx, [CURRENT_TASK]
294 diamond 756
           shl edx, 8
757
           mov esi, dword [edx+PROC_BASE+APPDATA.heap_base]; heap_base
758
           mov edi, dword [edx+PROC_BASE+APPDATA.heap_top]; heap_top
759
           sub ebx, [edx+PROC_BASE+APPDATA.mem_size]
760
           neg ebx
761
           call update_mem_size
762
           add esi, new_app_base
266 serge 763
           add edi, new_app_base
764
           shr esi, 12
164 serge 765
           shr edi, 12
766
@@:
767
           mov eax, [page_tabs+esi*4]
365 serge 768
           test eax, USED_BLOCK
164 serge 769
           jz .test_free
770
           shr eax, 12
771
           add esi, eax
772
           jmp @B
773
.test_free:
774
           test eax, FREE_BLOCK
775
           jz .err
776
           mov edx, eax
777
           shr edx, 12
778
           add edx, esi
779
           cmp edx, edi
780
           jae .exit
781
782
 
365 serge 783
           test ebx, USED_BLOCK
164 serge 784
           jz .next_free
785
786
 
787
           add edx, ebx
788
           mov esi, edx
789
           jmp @B
790
.next_free:
791
           test ebx, FREE_BLOCK
792
           jz .err
793
           and dword [page_tabs+edx*4], 0
365 serge 794
           add eax, ebx
164 serge 795
           and eax, not 4095
796
           or eax, FREE_BLOCK
797
           mov [page_tabs+esi*4], eax
365 serge 798
           jmp @B
164 serge 799
.exit:
800
           xor eax, eax
801
           inc eax
802
           ret
803
.err:
804
           xor eax, eax
805
           ret
806
endp
807
808
 
278 serge 809
align 4
164 serge 810
proc alloc_dll
811
           pushf
812
           cli
813
           bsf eax, [dll_map]
814
           jnz .find
815
           popf
816
           xor eax, eax
817
           ret
818
.find:
819
           btr [dll_map], eax
820
           popf
821
           shl eax, 5
822
           add eax, dll_tab
823
           ret
824
endp
825
826
 
827
proc alloc_service
828
           pushf
829
           cli
830
           bsf eax, [srv_map]
831
           jnz .find
832
           popf
833
           xor eax, eax
834
           ret
835
.find:
214 serge 836
           btr [srv_map], eax
837
           popf
164 serge 838
           shl eax,0x02
214 serge 839
           lea eax,[srv_tab+eax+eax*8]   ;srv_tab+eax*36
840
           ret
164 serge 841
endp
842
278 serge 843
 
844