Subversion Repositories Kolibri OS

Rev

Rev 419 | 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
 
369 serge 149
;  eax= required size
150
;
151
; retval
152
;  edi= memory block descriptor
153
;  ebx= descriptor index
154
155
 
164 serge 156
get_block:
369 serge 157
           mov ecx, eax
164 serge 158
           shr ecx, 12
369 serge 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
164 serge 166
           or edx, -1
369 serge 167
164 serge 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]
369 serge 177
.find:
178
           bsf edi, edx
179
           jz .high_mask
164 serge 180
           add ebx, edi
369 serge 181
           mov edi, [mem_block_list+ebx*4]
182
.check_size:
183
           cmp eax, [edi+block_size]
184
           ja .next
185
           ret
164 serge 186
187
 
188
           add esi, 4
189
           cmp esi, mem_block_mask+8
369 serge 190
           jae .err
191
           add ebx, 32
164 serge 192
           mov edx, [esi]
369 serge 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
164 serge 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]
254 serge 221
           shl eax, 5
164 serge 222
           add eax, [mem_block_arr]
223
           dec [free_blocks]
170 serge 224
           ret
164 serge 225
endp
226
227
 
228
           mov dword [eax], 0
357 serge 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
 
164 serge 238
           shr eax, 5
239
240
 
241
           bts [ebx], eax
242
           inc [free_blocks]
170 serge 243
           shr eax, 3
164 serge 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
206 serge 263
           and eax, not 4095
264
           mov [size], eax
164 serge 265
279 serge 266
 
267
           call wait_mutex    ;ebx
268
269
 
170 serge 270
           ja .error
271
164 serge 272
 
369 serge 273
           test edi, edi
274
           jz .error
164 serge 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
357 serge 296
           mov [esi+list_bk], 0
297
           and eax, eax
164 serge 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_fd], edx
357 serge 329
           test edx, edx
164 serge 330
           jz @f
331
           mov [edx+list_bk], edi
357 serge 332
@@:
164 serge 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
357 serge 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
 
164 serge 344
           mov eax, [esi+block_base]
345
           mov ebx, [size]
170 serge 346
           sub [heap_free], ebx
347
           and [heap_mutex], 0
279 serge 348
           ret
164 serge 349
.m_eq_size:
350
           remove_from_list edi
351
           mov [mem_block_list+ebx*4], edx
192 serge 352
           and edx, edx
164 serge 353
           jnz @f
354
           btr [mem_block_mask], ebx
192 serge 355
@@:
164 serge 356
           mov ecx, mem_used.fd-MEM_LIST_OFFSET
357 serge 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
 
164 serge 364
           mov eax, [edi+block_base]
365
           mov ebx, [size]
170 serge 366
           sub [heap_free], ebx
367
           and [heap_mutex], 0
279 serge 368
           ret
164 serge 369
.error:
370
           xor eax, eax
371
           mov [heap_mutex], eax
279 serge 372
           ret
164 serge 373
endp
374
375
 
376
proc free_kernel_space stdcall uses ebx ecx edx esi edi, base:dword
321 diamond 377
164 serge 378
 
279 serge 379
           call wait_mutex    ;ebx
380
381
 
164 serge 382
           mov esi, [mem_used.fd]
357 serge 383
@@:
164 serge 384
           cmp esi, mem_used.fd-MEM_LIST_OFFSET
357 serge 385
           je .fail
386
164 serge 387
 
388
           je .found
389
           mov esi, [esi+list_fd]
357 serge 390
           jmp @b
164 serge 391
.found:
392
           cmp [esi+block_flags], USED_BLOCK
393
           jne .fail
394
395
 
170 serge 396
           add [heap_free], eax
397
398
 
164 serge 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
357 serge 463
           test esi, esi
164 serge 464
           jz @f
465
           mov [esi+list_bk], edi
357 serge 466
@@:
164 serge 467
           bts [mem_block_mask], eax
468
.m_eq:
469
           xor eax, eax
470
           mov [heap_mutex], eax
279 serge 471
           dec eax
321 diamond 472
           ret
164 serge 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
357 serge 482
           test edi, edi
164 serge 483
           jz @f
484
           mov [edi+list_bk], esi
357 serge 485
@@:
164 serge 486
           bts [mem_block_mask], eax
487
           mov [esi+block_flags],FREE_BLOCK
488
           xor eax, eax
489
           mov [heap_mutex], eax
279 serge 490
           dec eax
321 diamond 491
           ret
164 serge 492
.fail:
493
           xor eax, eax
494
           mov [heap_mutex], eax
279 serge 495
           ret
164 serge 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
206 serge 507
           and eax, not 4095;
508
           mov [size], eax
164 serge 509
           and eax, eax
510
           jz .err
357 serge 511
           mov ebx, eax
164 serge 512
           shr ebx, 12
513
           mov [pages_count], ebx
514
515
 
516
           test eax, eax
357 serge 517
           jz .err
518
           mov [lin_addr], eax
164 serge 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
357 serge 533
164 serge 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
@@:
357 serge 547
           push ecx
548
           call alloc_page
164 serge 549
           pop ecx
550
           test eax, eax
551
           jz .err
357 serge 552
164 serge 553
 
554
           add edx, 0x1000
555
           dec ecx
556
           jnz @B
557
.end:
558
           mov eax, [lin_addr]
559
           ret
560
.err:
357 serge 561
           xor eax, eax
164 serge 562
           ret
563
endp
564
565
 
566
proc kernel_free stdcall, base:dword
567
           push ebx esi
321 diamond 568
164 serge 569
 
279 serge 570
           call wait_mutex    ;ebx
571
572
 
164 serge 573
           mov esi, [mem_used.fd]
357 serge 574
@@:
164 serge 575
           cmp esi, mem_used.fd-MEM_LIST_OFFSET
357 serge 576
           je .fail
577
164 serge 578
 
579
           je .found
580
           mov esi, [esi+list_fd]
357 serge 581
           jmp @b
164 serge 582
.found:
583
           cmp [esi+block_flags], USED_BLOCK
584
           jne .fail
585
586
 
279 serge 587
588
 
321 diamond 589
           mov ecx, [esi+block_size];
164 serge 590
           shr ecx, 12
281 serge 591
           call release_pages   ;eax, ecx
279 serge 592
           pop ecx
321 diamond 593
           stdcall free_kernel_space, [base]
164 serge 594
           pop esi ebx
321 diamond 595
           ret
279 serge 596
.fail:
164 serge 597
           and [heap_mutex], 0
279 serge 598
           pop esi ebx
321 diamond 599
           ret
164 serge 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
 
188 serge 612
613
 
164 serge 614
proc init_heap
188 serge 615
164 serge 616
 
427 serge 617
           mov eax, [ebx+APPDATA.heap_top]
618
           test eax, eax
172 serge 619
           jz @F
620
           sub eax,[ebx+APPDATA.heap_base]
427 serge 621
           sub eax, 4096
172 serge 622
           ret
623
@@:
624
           mov esi, [ebx+APPDATA.mem_size]
427 serge 625
           add esi, 4095
188 serge 626
           and esi, not 4095
627
           mov [ebx+APPDATA.mem_size], esi
427 serge 628
           mov eax, HEAP_TOP
188 serge 629
           mov [ebx+APPDATA.heap_base], esi
427 serge 630
           mov [ebx+APPDATA.heap_top], eax
631
164 serge 632
 
188 serge 633
       ;    add esi, new_app_base
419 serge 634
           shr esi, 10
188 serge 635
           mov ecx, eax
636
           sub eax, 4096
164 serge 637
           or ecx, FREE_BLOCK
188 serge 638
           mov [page_tabs+esi], ecx
365 serge 639
           ret
164 serge 640
.exit:
641
           xor eax, eax
642
           ret
643
endp
644
645
 
646
proc user_alloc stdcall, alloc_size:dword
647
648
 
649
           add ecx, (4095+4096)
650
           and ecx, not 4095
651
652
 
427 serge 653
           mov esi, dword [ebx+APPDATA.heap_base]  ; heap_base
654
           mov edi, dword [ebx+APPDATA.heap_top]   ; heap_top
655
l_0:
164 serge 656
           cmp esi, edi
657
           jae m_exit
658
659
 
660
           shr ebx, 12
661
           mov eax, [page_tabs+ebx*4]
365 serge 662
           test eax, FREE_BLOCK
164 serge 663
           jz test_used
664
           and eax, 0xFFFFF000
665
           cmp eax, ecx    ;alloc_size
666
           jb  m_next
667
	   jz  @f
270 diamond 668
164 serge 669
 
670
           add edx, ecx
671
           sub eax, ecx;
672
           or eax, FREE_BLOCK
673
           shr edx, 12
674
           mov [page_tabs+edx*4], eax
365 serge 675
@@:
294 diamond 676
           or ecx, USED_BLOCK
164 serge 677
           mov [page_tabs+ebx*4], ecx
365 serge 678
           shr ecx, 12
164 serge 679
           dec ecx
680
           inc ebx
681
@@:
682
           mov dword [page_tabs+ebx*4], 2
365 serge 683
           inc ebx
164 serge 684
           dec ecx
685
           jnz @B
686
687
 
427 serge 688
           mov     ebx, [alloc_size]
689
           add     ebx, 0xFFF
690
           and     ebx, not 0xFFF
691
           add     ebx, [edx+APPDATA.mem_size]
692
           call    update_mem_size
693
294 diamond 694
 
164 serge 695
           add eax, 4096
696
           ret
697
m_next:
698
           add esi, eax
699
           jmp l_0
700
test_used:
701
           test eax, USED_BLOCK
702
           jz m_exit
703
704
 
705
           add esi, eax
706
           jmp l_0
707
m_exit:
708
           xor eax, eax
709
           ret
710
endp
711
712
 
713
proc user_free stdcall, base:dword
714
715
 
716
           test esi, esi
717
           jz .exit
718
719
 
294 diamond 720
           sub esi, 4096
164 serge 721
           shr esi, 12
722
           mov eax, [page_tabs+esi*4]
365 serge 723
           test eax, USED_BLOCK
164 serge 724
           jz .not_used
188 serge 725
164 serge 726
 
727
           mov ecx, eax
728
           or eax, FREE_BLOCK
729
           mov [page_tabs+esi*4], eax
365 serge 730
           inc esi
164 serge 731
           sub ecx, 4096
732
           shr ecx, 12
733
           mov ebx, ecx
294 diamond 734
.release:
164 serge 735
           xor eax, eax
188 serge 736
           xchg eax, [page_tabs+esi*4]
365 serge 737
           test eax, 1
188 serge 738
           jz @F
739
           call free_page
164 serge 740
@@:
188 serge 741
           inc esi
164 serge 742
           dec ecx
743
           jnz .release
744
.not_used:
188 serge 745
           mov edx, [current_slot]
427 serge 746
           mov esi, dword [edx+APPDATA.heap_base]
747
           mov edi, dword [edx+APPDATA.heap_top]
748
           sub ebx, [edx+APPDATA.mem_size]
749
           neg ebx
294 diamond 750
           call update_mem_size
751
           shr esi, 12
164 serge 752
           shr edi, 12
753
@@:
754
           mov eax, [page_tabs+esi*4]
365 serge 755
           test eax, USED_BLOCK
164 serge 756
           jz .test_free
757
           shr eax, 12
758
           add esi, eax
759
           jmp @B
760
.test_free:
761
           test eax, FREE_BLOCK
762
           jz .err
763
           mov edx, eax
764
           shr edx, 12
765
           add edx, esi
766
           cmp edx, edi
767
           jae .exit
768
769
 
365 serge 770
           test ebx, USED_BLOCK
164 serge 771
           jz .next_free
772
773
 
774
           add edx, ebx
775
           mov esi, edx
776
           jmp @B
777
.next_free:
778
           test ebx, FREE_BLOCK
779
           jz .err
780
           and dword [page_tabs+edx*4], 0
365 serge 781
           add eax, ebx
164 serge 782
           and eax, not 4095
783
           or eax, FREE_BLOCK
784
           mov [page_tabs+esi*4], eax
365 serge 785
           jmp @B
164 serge 786
.exit:
787
           xor eax, eax
788
           inc eax
789
           ret
790
.err:
791
           xor eax, eax
792
           ret
793
endp
794
795
 
278 serge 796
align 4
164 serge 797
proc alloc_dll
798
           pushf
799
           cli
800
           bsf eax, [dll_map]
801
           jnz .find
802
           popf
803
           xor eax, eax
804
           ret
805
.find:
806
           btr [dll_map], eax
807
           popf
808
           shl eax, 5
809
           add eax, dll_tab
810
           ret
811
endp
812
813
 
814
proc alloc_service
815
           pushf
816
           cli
817
           bsf eax, [srv_map]
818
           jnz .find
819
           popf
820
           xor eax, eax
821
           ret
822
.find:
214 serge 823
           btr [srv_map], eax
824
           popf
164 serge 825
           shl eax,0x02
214 serge 826
           lea eax,[srv_tab+eax+eax*8]   ;srv_tab+eax*36
827
           ret
164 serge 828
endp
829
278 serge 830
 
831