Subversion Repositories Kolibri OS

Rev

Rev 369 | Rev 425 | 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
 
172 serge 617
           shl ebx,8
618
           mov eax, [SLOT_BASE+APPDATA.heap_top+ebx]
380 serge 619
           test eax, eax
172 serge 620
           jz @F
621
           sub eax,[SLOT_BASE+APPDATA.heap_base+ebx]
380 serge 622
           sub eax, 4096
172 serge 623
           ret
624
@@:
625
           mov esi, [SLOT_BASE+APPDATA.mem_size+ebx]
380 serge 626
           add esi, 4095
188 serge 627
           and esi, not 4095
628
           mov [SLOT_BASE+APPDATA.mem_size+ebx], esi
380 serge 629
           mov eax, HEAP_TOP
188 serge 630
           mov [SLOT_BASE+APPDATA.heap_base+ebx], esi
380 serge 631
           mov [SLOT_BASE+APPDATA.heap_top+ebx], eax
632
164 serge 633
 
188 serge 634
           add esi, new_app_base
635
           shr esi, 10
636
           mov ecx, eax
637
           sub eax, 4096
164 serge 638
           or ecx, FREE_BLOCK
188 serge 639
           mov [page_tabs+esi], ecx
365 serge 640
           ret
164 serge 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
380 serge 656
           mov edi, dword [ebx+SLOT_BASE+APPDATA.heap_top]; heap_top
657
           add esi, new_app_base
164 serge 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]
365 serge 666
           test eax, FREE_BLOCK
164 serge 667
           jz test_used
668
           and eax, 0xFFFFF000
669
           cmp eax, ecx    ;alloc_size
670
           jb  m_next
671
	   jz  @f
270 diamond 672
164 serge 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
365 serge 679
214 serge 680
 
294 diamond 681
           or ecx, USED_BLOCK
164 serge 682
           mov [page_tabs+ebx*4], ecx
365 serge 683
           shr ecx, 12
164 serge 684
           dec ecx
685
           inc ebx
686
@@:
687
           mov dword [page_tabs+ebx*4], 2
365 serge 688
           inc ebx
164 serge 689
           dec ecx
690
           jnz @B
691
692
 
294 diamond 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]
380 serge 698
        call    update_mem_size
294 diamond 699
700
 
164 serge 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
 
294 diamond 727
           sub esi, 4096
164 serge 728
           shr esi, 12
729
           mov eax, [page_tabs+esi*4]
365 serge 730
           test eax, USED_BLOCK
164 serge 731
           jz .not_used
188 serge 732
164 serge 733
 
734
           mov ecx, eax
735
           or eax, FREE_BLOCK
736
           mov [page_tabs+esi*4], eax
365 serge 737
           inc esi
164 serge 738
           sub ecx, 4096
739
           shr ecx, 12
740
           mov ebx, ecx
294 diamond 741
.release:
164 serge 742
           xor eax, eax
188 serge 743
           xchg eax, [page_tabs+esi*4]
365 serge 744
           test eax, 1
188 serge 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 edx, [CURRENT_TASK]
294 diamond 753
           shl edx, 8
754
           mov esi, dword [edx+SLOT_BASE+APPDATA.heap_base]; heap_base
380 serge 755
           mov edi, dword [edx+SLOT_BASE+APPDATA.heap_top]; heap_top
756
           sub ebx, [edx+SLOT_BASE+APPDATA.mem_size]
757
           neg ebx
294 diamond 758
           call update_mem_size
759
           add esi, new_app_base
266 serge 760
           add edi, new_app_base
761
           shr esi, 12
164 serge 762
           shr edi, 12
763
@@:
764
           mov eax, [page_tabs+esi*4]
365 serge 765
           test eax, USED_BLOCK
164 serge 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
 
365 serge 780
           test ebx, USED_BLOCK
164 serge 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
365 serge 791
           add eax, ebx
164 serge 792
           and eax, not 4095
793
           or eax, FREE_BLOCK
794
           mov [page_tabs+esi*4], eax
365 serge 795
           jmp @B
164 serge 796
.exit:
797
           xor eax, eax
798
           inc eax
799
           ret
800
.err:
801
           xor eax, eax
802
           ret
803
endp
804
805
 
278 serge 806
align 4
164 serge 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:
214 serge 833
           btr [srv_map], eax
834
           popf
164 serge 835
           shl eax,0x02
214 serge 836
           lea eax,[srv_tab+eax+eax*8]   ;srv_tab+eax*36
837
           ret
164 serge 838
endp
839
278 serge 840
 
841