Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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