Subversion Repositories Kolibri OS

Rev

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

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