Subversion Repositories Kolibri OS

Rev

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