Subversion Repositories Kolibri OS

Rev

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