Subversion Repositories Kolibri OS

Rev

Rev 843 | Rev 859 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
431 serge 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
164 serge 7
 
593 mikedld 8
$Revision: 854 $
9
 
10
 
164 serge 11
struc MEM_BLOCK
12
{  .next_block  dd ?
13
   .prev_block  dd ? ;+4
357 serge 14
   .list_fd     dd ? ;+8
15
   .list_bk     dd ? ;+12
164 serge 16
   .base        dd ? ;+16
17
   .size        dd ? ;+20
18
   .flags       dd ? ;+24
19
   .handle      dd ? ;+28
20
}
21
 
357 serge 22
MEM_LIST_OFFSET equ  8
164 serge 23
FREE_BLOCK      equ  4
24
USED_BLOCK      equ  8
546 diamond 25
DONT_FREE_BLOCK equ  10h
164 serge 26
 
27
virtual at 0
28
  MEM_BLOCK MEM_BLOCK
29
end virtual
30
 
31
MEM_BLOCK_SIZE equ 8*4
32
 
33
block_next   equ MEM_BLOCK.next_block
34
block_prev   equ MEM_BLOCK.prev_block
357 serge 35
list_fd      equ MEM_BLOCK.list_fd
36
list_bk      equ MEM_BLOCK.list_bk
164 serge 37
block_base   equ MEM_BLOCK.base
38
block_size   equ MEM_BLOCK.size
39
block_flags  equ MEM_BLOCK.flags
40
 
41
macro calc_index op
42
{          shr op, 12
43
           dec op
44
           cmp op, 63
45
           jna @f
46
           mov op, 63
47
@@:
48
}
49
 
50
macro remove_from_list op
357 serge 51
{          mov edx, [op+list_fd]
52
           mov ecx, [op+list_bk]
164 serge 53
           test edx, edx
54
           jz @f
357 serge 55
           mov [edx+list_bk], ecx
164 serge 56
@@:
57
           test ecx, ecx
58
           jz @f
357 serge 59
           mov [ecx+list_fd], edx
164 serge 60
@@:
357 serge 61
           mov [op+list_fd],0
62
           mov [op+list_bk],0
164 serge 63
}
64
 
65
macro remove_from_free op
66
{
67
           remove_from_list op
68
 
69
           mov eax, [op+block_size]
70
           calc_index eax
71
           cmp [mem_block_list+eax*4], op
72
           jne @f
73
           mov [mem_block_list+eax*4], edx
74
@@:
75
           cmp [mem_block_list+eax*4], 0
76
           jne @f
77
           btr [mem_block_mask], eax
78
@@:
79
}
80
 
81
macro remove_from_used op
82
{
357 serge 83
           mov edx, [op+list_fd]
84
           mov ecx, [op+list_bk]
85
           mov [edx+list_bk], ecx
86
           mov [ecx+list_fd], edx
87
           mov [op+list_fd], 0
88
           mov [op+list_bk], 0
164 serge 89
}
90
 
91
align 4
839 serge 92
init_kernel_heap:
164 serge 93
 
94
           mov ecx, 64/4
95
           mov edi, mem_block_list
96
           xor eax, eax
97
           cld
98
           rep stosd
99
 
100
           mov ecx, 512/4
101
           mov edi, mem_block_map
102
           not eax
103
           rep stosd
104
 
841 serge 105
           mov ecx, 128*1024
106
           fastcall _balloc
839 serge 107
 
164 serge 108
           mov [mem_block_start], mem_block_map
109
           mov [mem_block_end], mem_block_map+512
839 serge 110
           mov [mem_block_arr], eax
164 serge 111
 
839 serge 112
           mov ebx, mem_used.fd-MEM_LIST_OFFSET
113
           mov [mem_used.fd], ebx
114
           mov [mem_used.bk], ebx
357 serge 115
 
839 serge 116
           xor edx, edx
164 serge 117
 
839 serge 118
           mov [eax+block_next], edx
119
           mov [eax+block_prev], edx
120
           mov [eax+list_fd], edx
121
           mov [eax+list_bk], edx
122
           mov [eax+block_base], HEAP_BASE
123
           mov [eax+block_size], page_tabs-HEAP_BASE
124
           mov [eax+block_flags], FREE_BLOCK
164 serge 125
 
839 serge 126
           mov [heap_size], page_tabs-HEAP_BASE
127
           mov [heap_free], page_tabs-HEAP_BASE
164 serge 128
 
839 serge 129
           mov [mem_block_mask], edx
164 serge 130
           mov [mem_block_mask+4],0x80000000
131
 
839 serge 132
           mov [mem_block_list+63*4], eax
133
           mov byte [mem_block_map], 0xFE
279 serge 134
           and [heap_mutex], 0
839 serge 135
           mov [heap_blocks], 4096
136
           mov [free_blocks], 4096
164 serge 137
           ret
138
 
369 serge 139
; param
140
;  eax= required size
141
;
142
; retval
143
;  edi= memory block descriptor
144
;  ebx= descriptor index
145
 
164 serge 146
align 4
819 serge 147
get_small_block:
164 serge 148
           mov ecx, eax
369 serge 149
           shr ecx, 12
150
           dec ecx
151
           cmp ecx, 63
152
           jle .get_index
153
           mov ecx, 63
154
.get_index:
155
           lea esi, [mem_block_mask]
164 serge 156
           xor ebx, ebx
369 serge 157
           or edx, -1
164 serge 158
 
159
           cmp ecx, 32
160
           jb .bit_test
161
 
162
           sub ecx, 32
163
           add ebx, 32
164
           add esi, 4
165
.bit_test:
166
           shl edx, cl
369 serge 167
           and edx, [esi]
168
.find:
169
           bsf edi, edx
164 serge 170
           jz .high_mask
369 serge 171
           add ebx, edi
172
           mov edi, [mem_block_list+ebx*4]
173
.check_size:
174
           cmp eax, [edi+block_size]
175
           ja .next
164 serge 176
           ret
177
 
178
.high_mask:
179
           add esi, 4
369 serge 180
           cmp esi, mem_block_mask+8
181
           jae .err
164 serge 182
           add ebx, 32
369 serge 183
           mov edx, [esi]
184
           jmp .find
185
.next:
186
           mov edi, [edi+list_fd]
187
           test edi, edi
188
           jnz .check_size
189
.err:
190
           xor edi, edi
164 serge 191
           ret
837 serge 192
; param
193
;  eax= required size
194
;
195
; retval
196
;  edi= memory block descriptor
197
;  ebx= descriptor index
198
align 4
199
get_large_block:
200
           mov edx, -1
201
           mov ecx, eax
202
           shr ecx, 22
203
           dec ecx
204
           cmp ecx, 31
205
           jle .get_index
206
           mov ecx, 31
207
.get_index:
208
           shl edx, cl
209
           and edx, [large_block_mask]
210
.find:
211
           bsf edi, edx
212
           mov ebx, edi
213
           mov edi, [large_block_list+edi*4]
214
.check_size:
215
           cmp eax, [edi+block_size]
216
           ja .next
217
           ret
218
.next:
219
           mov edi, [edi+list_fd]
220
           test edi, edi
221
           jnz .check_size
222
.fail:
223
           xor edi, edi
224
           ret
164 serge 225
 
226
align 4
819 serge 227
alloc_mem_block:
164 serge 228
 
229
           mov ebx, [mem_block_start]
230
           mov ecx, [mem_block_end]
231
.l1:
232
           bsf eax,[ebx];
233
           jnz found
234
           add ebx,4
235
           cmp ebx, ecx
236
           jb .l1
237
           xor eax,eax
238
           ret
239
 
240
found:
241
           btr [ebx], eax
242
           mov [mem_block_start],ebx
243
           sub ebx, mem_block_map
254 serge 244
           lea eax,[eax+ebx*8]
164 serge 245
           shl eax, 5
246
           add eax, [mem_block_arr]
170 serge 247
           dec [free_blocks]
164 serge 248
           ret
819 serge 249
align 4
250
free_mem_block:
357 serge 251
           mov dword [eax], 0
252
           mov dword [eax+4], 0
253
           mov dword [eax+8], 0
254
           mov dword [eax+12], 0
255
           mov dword [eax+16], 0
256
;           mov dword [eax+20], 0
257
           mov dword [eax+24], 0
258
           mov dword [eax+28], 0
259
 
164 serge 260
           sub eax, [mem_block_arr]
261
           shr eax, 5
262
 
263
           mov ebx, mem_block_map
264
           bts [ebx], eax
170 serge 265
           inc [free_blocks]
164 serge 266
           shr eax, 3
267
           and eax, not 3
268
           add eax, ebx
269
           cmp [mem_block_start], eax
270
           ja @f
271
           ret
272
@@:
273
           mov [mem_block_start], eax
274
	   ret
275
.err:
276
           xor eax, eax
277
	   ret
278
 
279
align 4
280
proc alloc_kernel_space stdcall, size:dword
281
           local block_ind:DWORD
282
 
660 serge 283
           push ebx
284
           push esi
285
           push edi
286
 
164 serge 287
           mov eax, [size]
206 serge 288
           add eax, 4095
289
           and eax, not 4095
164 serge 290
           mov [size], eax
279 serge 291
 
292
           mov ebx, heap_mutex
293
           call wait_mutex    ;ebx
294
 
170 serge 295
           cmp eax, [heap_free]
296
           ja .error
164 serge 297
 
819 serge 298
           call get_small_block ; eax
369 serge 299
           test edi, edi
164 serge 300
           jz .error
301
 
302
           cmp [edi+block_flags], FREE_BLOCK
303
           jne .error
304
 
305
           mov [block_ind], ebx   ;index of allocated block
306
 
307
           mov eax, [edi+block_size]
308
           cmp eax, [size]
309
           je .m_eq_size
310
 
311
           call alloc_mem_block
839 serge 312
           test eax, eax
164 serge 313
           jz .error
314
 
315
           mov esi, eax           ;esi - splitted block
316
 
317
           mov [esi+block_next], edi
318
           mov eax, [edi+block_prev]
319
           mov [esi+block_prev], eax
320
           mov [edi+block_prev], esi
357 serge 321
           mov [esi+list_fd], 0
322
           mov [esi+list_bk], 0
839 serge 323
           test eax, eax
164 serge 324
           jz @f
325
           mov [eax+block_next], esi
326
@@:
327
           mov ebx, [edi+block_base]
328
           mov [esi+block_base], ebx
329
           mov edx, [size]
330
           mov [esi+block_size], edx
331
           add [edi+block_base], edx
332
           sub [edi+block_size], edx
333
 
334
           mov eax, [edi+block_size]
335
           shr eax, 12
336
           sub eax, 1
337
           cmp eax, 63
338
           jna @f
339
           mov eax, 63
340
@@:
341
           cmp eax, [block_ind]
342
           je .m_eq_ind
343
 
192 serge 344
           remove_from_list edi
164 serge 345
 
346
           mov ecx, [block_ind]
211 serge 347
           mov [mem_block_list+ecx*4], edx
164 serge 348
 
211 serge 349
           test edx, edx
164 serge 350
           jnz @f
351
           btr [mem_block_mask], ecx
352
@@:
353
           mov edx, [mem_block_list+eax*4]
357 serge 354
           mov [edi+list_fd], edx
164 serge 355
           test edx, edx
356
           jz @f
357 serge 357
           mov [edx+list_bk], edi
164 serge 358
@@:
359
           mov [mem_block_list+eax*4], edi
360
           bts [mem_block_mask], eax
361
.m_eq_ind:
357 serge 362
           mov ecx, mem_used.fd-MEM_LIST_OFFSET
363
           mov edx, [ecx+list_fd]
364
           mov [esi+list_fd], edx
365
           mov [esi+list_bk], ecx
366
           mov [ecx+list_fd], esi
367
           mov [edx+list_bk], esi
368
 
164 serge 369
           mov [esi+block_flags], USED_BLOCK
370
           mov eax, [esi+block_base]
170 serge 371
           mov ebx, [size]
372
           sub [heap_free], ebx
279 serge 373
           and [heap_mutex], 0
660 serge 374
           pop edi
375
           pop esi
376
           pop ebx
164 serge 377
           ret
378
.m_eq_size:
379
           remove_from_list edi
192 serge 380
           mov [mem_block_list+ebx*4], edx
164 serge 381
           and edx, edx
382
           jnz @f
192 serge 383
           btr [mem_block_mask], ebx
164 serge 384
@@:
357 serge 385
           mov ecx, mem_used.fd-MEM_LIST_OFFSET
386
           mov edx, [ecx+list_fd]
387
           mov [edi+list_fd], edx
388
           mov [edi+list_bk], ecx
389
           mov [ecx+list_fd], edi
390
           mov [edx+list_bk], edi
391
 
164 serge 392
           mov [edi+block_flags], USED_BLOCK
393
           mov eax, [edi+block_base]
170 serge 394
           mov ebx, [size]
395
           sub [heap_free], ebx
279 serge 396
           and [heap_mutex], 0
660 serge 397
           pop edi
398
           pop esi
399
           pop ebx
164 serge 400
           ret
401
.error:
402
           xor eax, eax
279 serge 403
           mov [heap_mutex], eax
660 serge 404
           pop edi
405
           pop esi
406
           pop ebx
164 serge 407
           ret
408
endp
409
 
410
align 4
321 diamond 411
proc free_kernel_space stdcall uses ebx ecx edx esi edi, base:dword
660 serge 412
           push ebx
413
           push esi
414
           push edi
279 serge 415
           mov ebx, heap_mutex
416
           call wait_mutex    ;ebx
417
 
164 serge 418
           mov eax, [base]
357 serge 419
           mov esi, [mem_used.fd]
164 serge 420
@@:
357 serge 421
           cmp esi, mem_used.fd-MEM_LIST_OFFSET
422
           je .fail
164 serge 423
 
424
           cmp [esi+block_base], eax
425
           je .found
357 serge 426
           mov esi, [esi+list_fd]
164 serge 427
           jmp @b
428
.found:
429
           cmp [esi+block_flags], USED_BLOCK
430
           jne .fail
431
 
170 serge 432
           mov eax, [esi+block_size]
433
           add [heap_free], eax
434
 
164 serge 435
           mov edi, [esi+block_next]
436
           test edi, edi
437
           jz .prev
438
 
439
           cmp [edi+block_flags], FREE_BLOCK
440
           jne .prev
441
 
442
           remove_from_free edi
443
 
444
           mov edx, [edi+block_next]
445
           mov [esi+block_next], edx
446
           test edx, edx
447
           jz @f
448
 
449
           mov [edx+block_prev], esi
450
@@:
451
           mov ecx, [edi+block_size]
452
           add [esi+block_size], ecx
453
 
454
           mov eax, edi
455
           call free_mem_block
456
.prev:
457
           mov edi, [esi+block_prev]
458
           test edi, edi
459
           jz .insert
460
 
461
           cmp [edi+block_flags], FREE_BLOCK
462
           jne .insert
463
 
464
           remove_from_used esi
465
 
466
           mov edx, [esi+block_next]
467
           mov [edi+block_next], edx
468
           test edx, edx
469
           jz @f
470
           mov [edx+block_prev], edi
471
@@:
472
           mov eax, esi
473
           call free_mem_block
474
 
475
           mov ecx, [edi+block_size]
476
           mov eax, [esi+block_size]
477
           add eax, ecx
478
           mov [edi+block_size], eax
479
 
480
           calc_index eax
481
           calc_index ecx
482
           cmp eax, ecx
483
           je .m_eq
484
 
485
           push ecx
486
           remove_from_list edi
487
           pop ecx
488
 
489
           cmp [mem_block_list+ecx*4], edi
490
           jne @f
491
           mov [mem_block_list+ecx*4], edx
492
@@:
493
           cmp [mem_block_list+ecx*4], 0
494
           jne @f
495
           btr [mem_block_mask], ecx
496
@@:
497
           mov esi, [mem_block_list+eax*4]
498
           mov [mem_block_list+eax*4], edi
357 serge 499
           mov [edi+list_fd], esi
164 serge 500
           test esi, esi
501
           jz @f
357 serge 502
           mov [esi+list_bk], edi
164 serge 503
@@:
504
           bts [mem_block_mask], eax
505
.m_eq:
506
           xor eax, eax
279 serge 507
           mov [heap_mutex], eax
321 diamond 508
           dec eax
660 serge 509
           pop edi
510
           pop esi
511
           pop ebx
164 serge 512
           ret
513
.insert:
514
           remove_from_used esi
515
 
516
           mov eax, [esi+block_size]
517
           calc_index eax
518
 
519
           mov edi, [mem_block_list+eax*4]
520
           mov [mem_block_list+eax*4], esi
357 serge 521
           mov [esi+list_fd], edi
164 serge 522
           test edi, edi
523
           jz @f
357 serge 524
           mov [edi+list_bk], esi
164 serge 525
@@:
526
           bts [mem_block_mask], eax
527
           mov [esi+block_flags],FREE_BLOCK
528
           xor eax, eax
279 serge 529
           mov [heap_mutex], eax
321 diamond 530
           dec eax
660 serge 531
           pop edi
532
           pop esi
533
           pop ebx
164 serge 534
           ret
535
.fail:
536
           xor eax, eax
279 serge 537
           mov [heap_mutex], eax
660 serge 538
           pop edi
539
           pop esi
540
           pop ebx
164 serge 541
           ret
542
endp
543
 
544
align 4
545
proc kernel_alloc stdcall, size:dword
546
           locals
547
             lin_addr    dd ?
548
             pages_count dd ?
549
           endl
550
 
662 serge 551
           push ebx
552
           push edi
553
 
164 serge 554
           mov eax, [size]
206 serge 555
           add eax, 4095
556
           and eax, not 4095;
164 serge 557
           mov [size], eax
558
           and eax, eax
357 serge 559
           jz .err
164 serge 560
           mov ebx, eax
561
           shr ebx, 12
562
           mov [pages_count], ebx
563
 
564
           stdcall alloc_kernel_space, eax
357 serge 565
           test eax, eax
566
           jz .err
164 serge 567
           mov [lin_addr], eax
568
 
569
           mov ecx, [pages_count]
570
           mov edx, eax
571
           mov ebx, ecx
572
 
573
           shr ecx, 3
574
           jz .next
575
 
576
           and ebx, not 7
577
           push ebx
854 serge 578
           stdcall _alloc_pages, ebx
164 serge 579
           pop ecx                   ; yes ecx!!!
843 serge 580
           test eax, eax
357 serge 581
           jz .err
164 serge 582
 
583
           mov edi, eax
584
           mov edx, [lin_addr]
585
@@:
586
           stdcall map_page,edx,edi,dword PG_SW
587
           add edx, 0x1000
588
           add edi, 0x1000
589
           dec ecx
590
           jnz @B
591
.next:
592
           mov ecx, [pages_count]
593
           and ecx, 7
594
           jz .end
357 serge 595
@@:
596
           push ecx
854 serge 597
           call _alloc_page
164 serge 598
           pop ecx
599
           test eax, eax
357 serge 600
           jz .err
164 serge 601
 
602
           stdcall map_page,edx,eax,dword PG_SW
603
           add edx, 0x1000
604
           dec ecx
605
           jnz @B
606
.end:
607
           mov eax, [lin_addr]
662 serge 608
           pop edi
609
           pop ebx
164 serge 610
           ret
357 serge 611
.err:
164 serge 612
           xor eax, eax
662 serge 613
           pop edi
614
           pop ebx
164 serge 615
           ret
616
endp
617
 
618
align 4
619
proc kernel_free stdcall, base:dword
321 diamond 620
           push ebx esi
164 serge 621
 
279 serge 622
           mov ebx, heap_mutex
623
           call wait_mutex    ;ebx
624
 
164 serge 625
           mov eax, [base]
357 serge 626
           mov esi, [mem_used.fd]
164 serge 627
@@:
357 serge 628
           cmp esi, mem_used.fd-MEM_LIST_OFFSET
629
           je .fail
164 serge 630
 
631
           cmp [esi+block_base], eax
632
           je .found
357 serge 633
           mov esi, [esi+list_fd]
164 serge 634
           jmp @b
635
.found:
636
           cmp [esi+block_flags], USED_BLOCK
637
           jne .fail
638
 
279 serge 639
           and [heap_mutex], 0
640
 
321 diamond 641
           push ecx
164 serge 642
           mov ecx, [esi+block_size];
281 serge 643
           shr ecx, 12
279 serge 644
           call release_pages   ;eax, ecx
321 diamond 645
           pop ecx
164 serge 646
           stdcall free_kernel_space, [base]
321 diamond 647
           pop esi ebx
279 serge 648
           ret
164 serge 649
.fail:
279 serge 650
           and [heap_mutex], 0
321 diamond 651
           pop esi ebx
164 serge 652
           ret
653
endp
654
 
837 serge 655
 
656
align 4
657
proc alloc_large stdcall, size:dword
658
           local block_ind:DWORD
659
 
660
           push ebx
661
           push esi
662
           push edi
663
 
664
           mov eax, [size]
665
           add eax, 0x3FFFFF
666
           and eax, not 0x3FFFFF
667
           mov [size], eax
668
 
669
         ;  mov ebx, heap_mutex
670
         ;  call wait_mutex    ;ebx
671
 
672
         ;  cmp eax, [heap_free]
673
         ;  ja .error
674
 
675
           call get_large_block ; eax
676
           test edi, edi
677
           jz .error
678
 
679
           cmp [edi+block_flags], FREE_BLOCK
680
           jne .error
681
 
682
           mov [block_ind], ebx   ;index of allocated block
683
 
684
           mov eax, [edi+block_size]
685
           cmp eax, [size]
686
           je .m_eq_size
687
 
688
           call alloc_mem_block
689
           and eax, eax
690
           jz .error
691
 
692
           mov esi, eax           ;esi - splitted block
693
 
694
           mov [esi+block_next], edi
695
           mov eax, [edi+block_prev]
696
           mov [esi+block_prev], eax
697
           mov [edi+block_prev], esi
698
           mov [esi+list_fd], 0
699
           mov [esi+list_bk], 0
700
           test eax, eax
701
           jz @f
702
           mov [eax+block_next], esi
703
@@:
704
           mov ebx, [edi+block_base]
705
           mov [esi+block_base], ebx
706
           mov edx, [size]
707
           mov [esi+block_size], edx
708
           add [edi+block_base], edx
709
           sub [edi+block_size], edx
710
 
711
           mov eax, [edi+block_size]
712
           shr eax, 22
713
           dec eax
714
           cmp eax, 31
715
           jna @f
716
           mov eax, 31
717
@@:
718
           cmp eax, [block_ind]
719
           je .m_eq_ind
720
 
721
           remove_from_list edi
722
 
723
           mov ecx, [block_ind]
724
           mov [large_block_list+ecx*4], edx
725
 
726
           test edx, edx
727
           jnz @f
728
           btr [large_block_mask], ecx
729
@@:
730
           mov edx, [large_block_list+eax*4]
731
           mov [edi+list_fd], edx
732
           test edx, edx
733
           jz @f
734
           mov [edx+list_bk], edi
735
@@:
736
           mov [large_block_list+eax*4], edi
737
           bts [large_block_mask], eax
738
.m_eq_ind:
739
           mov ecx, mem_used.fd-MEM_LIST_OFFSET
740
           mov edx, [ecx+list_fd]
741
           mov [esi+list_fd], edx
742
           mov [esi+list_bk], ecx
743
           mov [ecx+list_fd], esi
744
           mov [edx+list_bk], esi
745
 
746
           mov [esi+block_flags], USED_BLOCK
747
           mov eax, [esi+block_base]
748
           mov ebx, [size]
749
           sub [heap_free], ebx
750
           and [heap_mutex], 0
751
           pop edi
752
           pop esi
753
           pop ebx
754
           ret
755
.m_eq_size:
756
           remove_from_list edi
757
           mov [large_block_list+ebx*4], edx
758
           and edx, edx
759
           jnz @f
760
           btr [large_block_mask], ebx
761
@@:
762
           mov ecx, mem_used.fd-MEM_LIST_OFFSET
763
           mov edx, [ecx+list_fd]
764
           mov [edi+list_fd], edx
765
           mov [edi+list_bk], ecx
766
           mov [ecx+list_fd], edi
767
           mov [edx+list_bk], edi
768
 
769
           mov [edi+block_flags], USED_BLOCK
770
           mov eax, [edi+block_base]
771
           mov ebx, [size]
772
           sub [heap_free], ebx
773
           and [heap_mutex], 0
774
           pop edi
775
           pop esi
776
           pop ebx
777
           ret
778
.error:
779
           xor eax, eax
780
           mov [heap_mutex], eax
781
           pop edi
782
           pop esi
783
           pop ebx
784
           ret
785
endp
786
 
164 serge 787
restore block_next
788
restore block_prev
789
restore block_list
790
restore block_base
791
restore block_size
792
restore block_flags
793
 
794
;;;;;;;;;;;;;;      USER     ;;;;;;;;;;;;;;;;;
795
 
188 serge 796
HEAP_TOP  equ 0x5FC00000
797
 
164 serge 798
align 4
188 serge 799
proc init_heap
164 serge 800
 
465 serge 801
           mov ebx,[current_slot]
802
           mov eax, [ebx+APPDATA.heap_top]
172 serge 803
           test eax, eax
804
           jz @F
465 serge 805
           sub eax,[ebx+APPDATA.heap_base]
172 serge 806
           sub eax, 4096
807
           ret
808
@@:
465 serge 809
           mov esi, [ebx+APPDATA.mem_size]
188 serge 810
           add esi, 4095
811
           and esi, not 4095
465 serge 812
           mov [ebx+APPDATA.mem_size], esi
188 serge 813
           mov eax, HEAP_TOP
465 serge 814
           mov [ebx+APPDATA.heap_base], esi
815
           mov [ebx+APPDATA.heap_top], eax
164 serge 816
 
188 serge 817
           sub eax, esi
818
           shr esi, 10
819
           mov ecx, eax
164 serge 820
           sub eax, 4096
188 serge 821
           or ecx, FREE_BLOCK
365 serge 822
           mov [page_tabs+esi], ecx
164 serge 823
           ret
824
endp
825
 
826
align 4
827
proc user_alloc stdcall, alloc_size:dword
828
 
662 serge 829
           push ebx
830
           push esi
831
           push edi
832
 
164 serge 833
           mov ecx, [alloc_size]
834
           add ecx, (4095+4096)
835
           and ecx, not 4095
836
 
465 serge 837
           mov ebx, [current_slot]
838
           mov esi, dword [ebx+APPDATA.heap_base]  ; heap_base
839
           mov edi, dword [ebx+APPDATA.heap_top]   ; heap_top
164 serge 840
l_0:
841
           cmp esi, edi
842
           jae m_exit
843
 
844
           mov ebx, esi
845
           shr ebx, 12
365 serge 846
           mov eax, [page_tabs+ebx*4]
620 diamond 847
           test al, FREE_BLOCK
164 serge 848
           jz test_used
849
           and eax, 0xFFFFF000
850
           cmp eax, ecx    ;alloc_size
851
           jb  m_next
270 diamond 852
	   jz  @f
164 serge 853
 
620 diamond 854
           lea edx, [esi+ecx]
855
           sub eax, ecx
856
           or al, FREE_BLOCK
164 serge 857
           shr edx, 12
365 serge 858
           mov [page_tabs+edx*4], eax
294 diamond 859
@@:
164 serge 860
           or ecx, USED_BLOCK
365 serge 861
           mov [page_tabs+ebx*4], ecx
164 serge 862
           shr ecx, 12
620 diamond 863
           inc ebx
164 serge 864
           dec ecx
620 diamond 865
           jz  .no
164 serge 866
@@:
365 serge 867
           mov dword [page_tabs+ebx*4], 2
164 serge 868
           inc ebx
869
           dec ecx
870
           jnz @B
620 diamond 871
.no:
164 serge 872
 
465 serge 873
           mov     edx, [current_slot]
874
           mov     ebx, [alloc_size]
875
           add     ebx, 0xFFF
876
           and     ebx, not 0xFFF
877
           add     ebx, [edx+APPDATA.mem_size]
878
           call    update_mem_size
294 diamond 879
 
620 diamond 880
           lea eax, [esi+4096]
662 serge 881
 
882
           pop edi
883
           pop esi
884
           pop ebx
164 serge 885
           ret
886
test_used:
620 diamond 887
           test al, USED_BLOCK
164 serge 888
           jz m_exit
889
 
890
           and eax, 0xFFFFF000
620 diamond 891
m_next:
164 serge 892
           add esi, eax
893
           jmp l_0
894
m_exit:
895
           xor eax, eax
662 serge 896
           pop edi
897
           pop esi
898
           pop ebx
164 serge 899
           ret
900
endp
901
 
902
align 4
903
proc user_free stdcall, base:dword
904
 
662 serge 905
           push esi
906
 
164 serge 907
           mov esi, [base]
908
           test esi, esi
909
           jz .exit
910
 
662 serge 911
           push ebx
912
 
294 diamond 913
           xor ebx, ebx
164 serge 914
           shr esi, 12
620 diamond 915
           mov eax, [page_tabs+(esi-1)*4]
546 diamond 916
           test al, USED_BLOCK
620 diamond 917
           jz .cantfree
546 diamond 918
           test al, DONT_FREE_BLOCK
919
           jnz .cantfree
164 serge 920
 
921
           and eax, not 4095
922
           mov ecx, eax
620 diamond 923
           or al, FREE_BLOCK
924
           mov [page_tabs+(esi-1)*4], eax
164 serge 925
           sub ecx, 4096
620 diamond 926
           mov ebx, ecx
164 serge 927
           shr ecx, 12
620 diamond 928
           jz .released
164 serge 929
.release:
188 serge 930
           xor eax, eax
365 serge 931
           xchg eax, [page_tabs+esi*4]
620 diamond 932
           test al, 1
188 serge 933
           jz @F
164 serge 934
           call free_page
448 diamond 935
           mov eax, esi
936
           shl eax, 12
937
           invlpg [eax]
188 serge 938
@@:
164 serge 939
           inc esi
940
           dec ecx
941
           jnz .release
620 diamond 942
.released:
662 serge 943
           push edi
944
 
465 serge 945
           mov edx, [current_slot]
946
           mov esi, dword [edx+APPDATA.heap_base]
947
           mov edi, dword [edx+APPDATA.heap_top]
948
           sub ebx, [edx+APPDATA.mem_size]
294 diamond 949
           neg ebx
950
           call update_mem_size
448 diamond 951
           call user_normalize
662 serge 952
           pop edi
953
           pop ebx
954
           pop esi
448 diamond 955
           ret
956
.exit:
957
           xor eax, eax
958
           inc eax
662 serge 959
           pop esi
448 diamond 960
           ret
546 diamond 961
.cantfree:
962
           xor eax, eax
662 serge 963
           pop ebx
964
           pop esi
546 diamond 965
           ret
448 diamond 966
endp
967
 
968
user_normalize:
969
; in: esi=heap_base, edi=heap_top
970
; out: eax=0 <=> OK
971
; destroys: ebx,edx,esi,edi
164 serge 972
           shr esi, 12
973
           shr edi, 12
974
@@:
365 serge 975
           mov eax, [page_tabs+esi*4]
620 diamond 976
           test al, USED_BLOCK
164 serge 977
           jz .test_free
978
           shr eax, 12
979
           add esi, eax
980
           jmp @B
981
.test_free:
620 diamond 982
           test al, FREE_BLOCK
164 serge 983
           jz .err
984
           mov edx, eax
985
           shr edx, 12
986
           add edx, esi
987
           cmp edx, edi
988
           jae .exit
989
 
365 serge 990
           mov ebx, [page_tabs+edx*4]
620 diamond 991
           test bl, USED_BLOCK
164 serge 992
           jz .next_free
993
 
994
           shr ebx, 12
995
           add edx, ebx
996
           mov esi, edx
997
           jmp @B
998
.next_free:
620 diamond 999
           test bl, FREE_BLOCK
164 serge 1000
           jz .err
365 serge 1001
           and dword [page_tabs+edx*4], 0
164 serge 1002
           add eax, ebx
1003
           and eax, not 4095
1004
           or eax, FREE_BLOCK
365 serge 1005
           mov [page_tabs+esi*4], eax
164 serge 1006
           jmp @B
1007
.exit:
1008
           xor eax, eax
1009
           inc eax
1010
           ret
1011
.err:
1012
           xor eax, eax
1013
           ret
1014
 
448 diamond 1015
user_realloc:
1016
; in: eax = pointer, ebx = new size
1017
; out: eax = new pointer or NULL
1018
        test    eax, eax
1019
        jnz     @f
1020
; realloc(NULL,sz) - same as malloc(sz)
1021
        push    ebx
1022
        call    user_alloc
1023
        ret
1024
@@:
1025
        push    ecx edx
465 serge 1026
        lea     ecx, [eax - 0x1000]
448 diamond 1027
        shr     ecx, 12
1028
        mov     edx, [page_tabs+ecx*4]
620 diamond 1029
        test    dl, USED_BLOCK
448 diamond 1030
        jnz     @f
1031
; attempt to realloc invalid pointer
1032
.ret0:
1033
        pop     edx ecx
1034
        xor     eax, eax
1035
        ret
1036
@@:
620 diamond 1037
        test    dl, DONT_FREE_BLOCK
546 diamond 1038
        jnz     .ret0
448 diamond 1039
        add     ebx, 0x1FFF
1040
        shr     edx, 12
1041
        shr     ebx, 12
1042
; edx = allocated size, ebx = new size
1043
        add     edx, ecx
1044
        add     ebx, ecx
1045
        cmp     edx, ebx
1046
        jb      .realloc_add
1047
; release part of allocated memory
1048
.loop:
1049
        cmp     edx, ebx
1050
        jz      .release_done
1051
        dec     edx
1052
        xor     eax, eax
1053
        xchg    eax, [page_tabs+edx*4]
1054
        test    al, 1
1055
        jz      .loop
1056
        call    free_page
1057
        mov     eax, edx
1058
        shl     eax, 12
1059
        invlpg  [eax]
1060
        jmp     .loop
1061
.release_done:
1062
        sub     ebx, ecx
1063
        cmp     ebx, 1
1064
        jnz     .nofreeall
1065
        mov     eax, [page_tabs+ecx*4]
1066
        and     eax, not 0xFFF
465 serge 1067
        mov     edx, [current_slot]
1068
        mov     ebx, [APPDATA.mem_size+edx]
448 diamond 1069
        sub     ebx, eax
1070
        add     ebx, 0x1000
1071
        or      al, FREE_BLOCK
1072
        mov     [page_tabs+ecx*4], eax
1073
        push    esi edi
465 serge 1074
        mov     esi, [APPDATA.heap_base+edx]
1075
        mov     edi, [APPDATA.heap_top+edx]
448 diamond 1076
        call    update_mem_size
1077
        call    user_normalize
1078
        pop     edi esi
1079
        jmp     .ret0   ; all freed
1080
.nofreeall:
1081
        sub     edx, ecx
1082
        shl     ebx, 12
1083
        or      ebx, USED_BLOCK
1084
        xchg    [page_tabs+ecx*4], ebx
1085
        shr     ebx, 12
1086
        sub     ebx, edx
1087
        push    ebx ecx edx
465 serge 1088
        mov     edx, [current_slot]
448 diamond 1089
        shl     ebx, 12
465 serge 1090
        sub     ebx, [APPDATA.mem_size+edx]
448 diamond 1091
        neg     ebx
1092
        call    update_mem_size
1093
        pop     edx ecx ebx
465 serge 1094
        lea     eax, [ecx+1]
448 diamond 1095
        shl     eax, 12
1096
        push    eax
823 diamond 1097
        add     ecx, edx
1098
        lea     edx, [ecx+ebx]
448 diamond 1099
        shl     ebx, 12
1100
        jz      .ret
1101
        push    esi
465 serge 1102
        mov     esi, [current_slot]
1103
        mov     esi, [APPDATA.heap_top+esi]
448 diamond 1104
        shr     esi, 12
1105
@@:
1106
        cmp     edx, esi
1107
        jae     .merge_done
1108
        mov     eax, [page_tabs+edx*4]
1109
        test    al, USED_BLOCK
823 diamond 1110
        jnz     .merge_done
448 diamond 1111
        and     dword [page_tabs+edx*4], 0
823 diamond 1112
        shr     eax, 12
1113
        add     edx, eax
1114
        shl     eax, 12
448 diamond 1115
        add     ebx, eax
1116
        jmp     @b
1117
.merge_done:
1118
        pop     esi
1119
        or      ebx, FREE_BLOCK
1120
        mov     [page_tabs+ecx*4], ebx
1121
.ret:
1122
        pop     eax edx ecx
1123
        ret
1124
.realloc_add:
1125
; get some additional memory
465 serge 1126
        mov     eax, [current_slot]
1127
        mov     eax, [APPDATA.heap_top+eax]
448 diamond 1128
        shr     eax, 12
1129
        cmp     edx, eax
1130
        jae     .cant_inplace
1131
        mov     eax, [page_tabs+edx*4]
620 diamond 1132
        test    al, FREE_BLOCK
1133
        jz      .cant_inplace
448 diamond 1134
        shr     eax, 12
1135
        add     eax, edx
620 diamond 1136
        sub     eax, ebx
448 diamond 1137
        jb      .cant_inplace
1138
        jz      @f
1139
        shl     eax, 12
1140
        or      al, FREE_BLOCK
1141
        mov     [page_tabs+ebx*4], eax
1142
@@:
1143
        mov     eax, ebx
1144
        sub     eax, ecx
1145
        shl     eax, 12
1146
        or      al, USED_BLOCK
1147
        mov     [page_tabs+ecx*4], eax
465 serge 1148
        lea     eax, [ecx+1]
448 diamond 1149
        shl     eax, 12
1150
        push    eax
1151
        push    edi
1152
        lea     edi, [page_tabs+edx*4]
1153
        mov     eax, 2
1154
        sub     ebx, edx
1155
        mov     ecx, ebx
1156
        cld
1157
        rep     stosd
1158
        pop     edi
465 serge 1159
        mov     edx, [current_slot]
448 diamond 1160
        shl     ebx, 12
465 serge 1161
        add     ebx, [APPDATA.mem_size+edx]
448 diamond 1162
        call    update_mem_size
1163
        pop     eax edx ecx
1164
        ret
1165
.cant_inplace:
1166
        push    esi edi
465 serge 1167
        mov     eax, [current_slot]
1168
        mov     esi, [APPDATA.heap_base+eax]
1169
        mov     edi, [APPDATA.heap_top+eax]
448 diamond 1170
        shr     esi, 12
1171
        shr     edi, 12
1172
        sub     ebx, ecx
1173
.find_place:
1174
        cmp     esi, edi
1175
        jae     .place_not_found
1176
        mov     eax, [page_tabs+esi*4]
1177
        test    al, FREE_BLOCK
1178
        jz      .next_place
1179
        shr     eax, 12
1180
        cmp     eax, ebx
1181
        jae     .place_found
1182
        add     esi, eax
1183
        jmp     .find_place
1184
.next_place:
1185
        shr     eax, 12
1186
        add     esi, eax
1187
        jmp     .find_place
1188
.place_not_found:
1189
        pop     edi esi
1190
        jmp     .ret0
1191
.place_found:
1192
        sub     eax, ebx
1193
        jz      @f
1194
        push    esi
620 diamond 1195
        add     esi, ebx
448 diamond 1196
        shl     eax, 12
1197
        or      al, FREE_BLOCK
1198
        mov     [page_tabs+esi*4], eax
1199
        pop     esi
1200
@@:
1201
        mov     eax, ebx
1202
        shl     eax, 12
1203
        or      al, USED_BLOCK
1204
        mov     [page_tabs+esi*4], eax
1205
        inc     esi
1206
        mov     eax, esi
1207
        shl     eax, 12
1208
        push    eax
1209
        mov     eax, [page_tabs+ecx*4]
1210
        and     eax, not 0xFFF
1211
        or      al, FREE_BLOCK
1212
        sub     edx, ecx
1213
        mov     [page_tabs+ecx*4], eax
1214
        inc     ecx
620 diamond 1215
        dec     ebx
1216
        dec     edx
1217
        jz      .no
448 diamond 1218
@@:
1219
        xor     eax, eax
1220
        xchg    eax, [page_tabs+ecx*4]
1221
        mov     [page_tabs+esi*4], eax
1222
	mov     eax, ecx
1223
	shl     eax, 12
1224
	invlpg  [eax]
620 diamond 1225
        inc     esi
448 diamond 1226
        inc     ecx
1227
        dec     ebx
1228
        dec     edx
1229
        jnz     @b
620 diamond 1230
.no:
448 diamond 1231
        push    ebx
465 serge 1232
        mov     edx, [current_slot]
448 diamond 1233
        shl     ebx, 12
465 serge 1234
        add     ebx, [APPDATA.mem_size+edx]
448 diamond 1235
        call    update_mem_size
1236
        pop     ebx
1237
@@:
1238
        mov     dword [page_tabs+esi*4], 2
1239
        inc     esi
1240
        dec     ebx
1241
        jnz     @b
1242
        pop     eax edi esi edx ecx
1243
        ret
1244
 
278 serge 1245
if 0
164 serge 1246
align 4
1247
proc alloc_dll
1248
           pushf
1249
           cli
1250
           bsf eax, [dll_map]
1251
           jnz .find
1252
           popf
1253
           xor eax, eax
1254
           ret
1255
.find:
1256
           btr [dll_map], eax
1257
           popf
1258
           shl eax, 5
1259
           add eax, dll_tab
1260
           ret
1261
endp
1262
 
1263
align 4
1264
proc alloc_service
1265
           pushf
1266
           cli
1267
           bsf eax, [srv_map]
1268
           jnz .find
1269
           popf
1270
           xor eax, eax
1271
           ret
214 serge 1272
.find:
1273
           btr [srv_map], eax
164 serge 1274
           popf
214 serge 1275
           shl eax,0x02
1276
           lea eax,[srv_tab+eax+eax*8]   ;srv_tab+eax*36
164 serge 1277
           ret
1278
endp
278 serge 1279
 
1280
end if