Subversion Repositories Kolibri OS

Rev

Rev 278 | 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, base:dword
369
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
           not eax
164 serge 464
           ret
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
           not eax
164 serge 483
           ret
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
560
 
279 serge 561
           call wait_mutex    ;ebx
562
563
 
164 serge 564
           mov esi, [mem_used_list]
565
@@:
566
           test esi, esi
567
           jz .fail
568
569
 
570
           je .found
571
           mov esi, [esi+list_next]
572
           jmp @b
573
.found:
574
           cmp [esi+block_flags], USED_BLOCK
575
           jne .fail
576
577
 
279 serge 578
579
 
164 serge 580
581
 
279 serge 582
           stdcall free_kernel_space, [base]
164 serge 583
           ret
279 serge 584
.fail:
164 serge 585
           and [heap_mutex], 0
279 serge 586
           ret
164 serge 587
endp
588
589
 
590
restore block_prev
591
restore block_list
592
restore block_base
593
restore block_size
594
restore block_flags
595
596
 
597
598
 
188 serge 599
600
 
164 serge 601
proc init_heap
188 serge 602
164 serge 603
 
172 serge 604
           shl ebx,8
605
           mov eax, [PROC_BASE+APPDATA.heap_top+ebx]
606
           test eax, eax
607
           jz @F
608
           sub eax,[PROC_BASE+APPDATA.heap_base+ebx]
609
           sub eax, 4096
610
           ret
611
@@:
612
           mov esi, [PROC_BASE+APPDATA.mem_size+ebx]
613
           add esi, 4095
188 serge 614
           and esi, not 4095
615
           mov eax, HEAP_TOP
616
           mov [PROC_BASE+APPDATA.heap_base+ebx], esi
172 serge 617
           mov [PROC_BASE+APPDATA.heap_top+ebx], eax
188 serge 618
164 serge 619
 
188 serge 620
           add esi, new_app_base
621
           shr esi, 10
622
           mov ecx, eax
623
           sub eax, 4096
164 serge 624
           or ecx, FREE_BLOCK
188 serge 625
           mov [pages_tab+esi], ecx
626
           ret
164 serge 627
.exit:
628
           xor eax, eax
629
           ret
630
endp
631
632
 
633
proc user_alloc stdcall, alloc_size:dword
634
635
 
636
           add ecx, (4095+4096)
637
           and ecx, not 4095
638
639
 
640
           shl ebx, 8
641
           mov esi, dword [ebx+PROC_BASE+APPDATA.heap_base]; heap_base
172 serge 642
           mov edi, dword [ebx+PROC_BASE+APPDATA.heap_top]; heap_top
643
           add esi, new_app_base
164 serge 644
           add edi, new_app_base
645
646
 
647
           cmp esi, edi
648
           jae m_exit
649
650
 
651
           shr ebx, 12
652
           mov eax, [pages_tab+ebx*4]
653
           test eax, FREE_BLOCK
654
           jz test_used
655
           and eax, 0xFFFFF000
656
           cmp eax, ecx    ;alloc_size
657
           jb  m_next
658
	   jz  @f
270 diamond 659
164 serge 660
 
661
           add edx, ecx
662
           sub eax, ecx;
663
           or eax, FREE_BLOCK
664
           shr edx, 12
665
           mov [pages_tab+edx*4], eax
666
214 serge 667
 
270 diamond 668
           or ecx, USED_BLOCK
164 serge 669
           mov [pages_tab+ebx*4], ecx
670
           shr ecx, 12
671
           dec ecx
672
           inc ebx
673
@@:
674
           mov dword [pages_tab+ebx*4], 2
675
           inc ebx
676
           dec ecx
677
           jnz @B
678
679
 
680
           add eax, 4096
681
           sub eax, new_app_base
682
           ret
683
m_next:
684
           add esi, eax
685
           jmp l_0
686
test_used:
687
           test eax, USED_BLOCK
688
           jz m_exit
689
690
 
691
           add esi, eax
692
           jmp l_0
693
m_exit:
694
           xor eax, eax
695
           ret
696
endp
697
698
 
699
proc user_free stdcall, base:dword
700
701
 
702
           test esi, esi
703
           jz .exit
704
705
 
706
           shr esi, 12
707
           mov eax, [pages_tab+esi*4]
708
           test eax, USED_BLOCK
709
           jz .not_used
188 serge 710
164 serge 711
 
712
           mov ecx, eax
713
           or eax, FREE_BLOCK
714
           mov [pages_tab+esi*4], eax
715
           inc esi
716
           sub ecx, 4096
717
           shr ecx, 12
718
.release:
719
           xor eax, eax
188 serge 720
           xchg eax, [pages_tab+esi*4]
721
           test eax, 1
722
           jz @F
723
           call free_page
164 serge 724
@@:
188 serge 725
           inc esi
164 serge 726
           dec ecx
727
           jnz .release
728
.not_used:
188 serge 729
           mov ebx, [CURRENT_TASK]
164 serge 730
           shl ebx, 8
731
           mov esi, dword [ebx+PROC_BASE+APPDATA.heap_base]; heap_base
172 serge 732
           mov edi, dword [ebx+PROC_BASE+APPDATA.heap_top]; heap_top
733
           add esi, new_app_base
266 serge 734
           add edi, new_app_base
735
           shr esi, 12
164 serge 736
           shr edi, 12
737
@@:
738
           mov eax, [pages_tab+esi*4]
739
           test eax, USED_BLOCK
740
           jz .test_free
741
           shr eax, 12
742
           add esi, eax
743
           jmp @B
744
.test_free:
745
           test eax, FREE_BLOCK
746
           jz .err
747
           mov edx, eax
748
           shr edx, 12
749
           add edx, esi
750
           cmp edx, edi
751
           jae .exit
752
753
 
754
           test ebx, USED_BLOCK
755
           jz .next_free
756
757
 
758
           add edx, ebx
759
           mov esi, edx
760
           jmp @B
761
.next_free:
762
           test ebx, FREE_BLOCK
763
           jz .err
764
           and dword [pages_tab+edx*4], 0
765
           add eax, ebx
766
           and eax, not 4095
767
           or eax, FREE_BLOCK
768
           mov [pages_tab+esi*4], eax
769
           jmp @B
770
.exit:
771
           xor eax, eax
772
           inc eax
773
           ret
774
.err:
775
           xor eax, eax
776
           ret
777
endp
778
779
 
278 serge 780
align 4
164 serge 781
proc alloc_dll
782
           pushf
783
           cli
784
           bsf eax, [dll_map]
785
           jnz .find
786
           popf
787
           xor eax, eax
788
           ret
789
.find:
790
           btr [dll_map], eax
791
           popf
792
           shl eax, 5
793
           add eax, dll_tab
794
           ret
795
endp
796
797
 
798
proc alloc_service
799
           pushf
800
           cli
801
           bsf eax, [srv_map]
802
           jnz .find
803
           popf
804
           xor eax, eax
805
           ret
806
.find:
214 serge 807
           btr [srv_map], eax
808
           popf
164 serge 809
           shl eax,0x02
214 serge 810
           lea eax,[srv_tab+eax+eax*8]   ;srv_tab+eax*36
811
           ret
164 serge 812
endp
813
278 serge 814
 
815