Subversion Repositories Kolibri OS

Rev

Rev 593 | Rev 660 | 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: 620 $
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]
212 serge 142
           sub ecx, HEAP_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
369 serge 167
get_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
212
 
213
align 4
214
proc alloc_mem_block
215
 
216
           mov ebx, [mem_block_start]
217
           mov ecx, [mem_block_end]
218
.l1:
219
           bsf eax,[ebx];
220
           jnz found
221
           add ebx,4
222
           cmp ebx, ecx
223
           jb .l1
224
           xor eax,eax
225
           ret
226
 
227
found:
228
           btr [ebx], eax
229
           mov [mem_block_start],ebx
230
           sub ebx, mem_block_map
254 serge 231
           lea eax,[eax+ebx*8]
164 serge 232
           shl eax, 5
233
           add eax, [mem_block_arr]
170 serge 234
           dec [free_blocks]
164 serge 235
           ret
236
endp
237
 
238
proc free_mem_block
357 serge 239
           mov dword [eax], 0
240
           mov dword [eax+4], 0
241
           mov dword [eax+8], 0
242
           mov dword [eax+12], 0
243
           mov dword [eax+16], 0
244
;           mov dword [eax+20], 0
245
           mov dword [eax+24], 0
246
           mov dword [eax+28], 0
247
 
164 serge 248
           sub eax, [mem_block_arr]
249
           shr eax, 5
250
 
251
           mov ebx, mem_block_map
252
           bts [ebx], eax
170 serge 253
           inc [free_blocks]
164 serge 254
           shr eax, 3
255
           and eax, not 3
256
           add eax, ebx
257
           cmp [mem_block_start], eax
258
           ja @f
259
           ret
260
@@:
261
           mov [mem_block_start], eax
262
	   ret
263
.err:
264
           xor eax, eax
265
	   ret
266
endp
267
 
268
align 4
269
proc alloc_kernel_space stdcall, size:dword
270
           local block_ind:DWORD
271
 
272
           mov eax, [size]
206 serge 273
           add eax, 4095
274
           and eax, not 4095
164 serge 275
           mov [size], eax
279 serge 276
 
277
           mov ebx, heap_mutex
278
           call wait_mutex    ;ebx
279
 
170 serge 280
           cmp eax, [heap_free]
281
           ja .error
164 serge 282
 
369 serge 283
           call get_block ; eax
284
           test edi, edi
164 serge 285
           jz .error
286
 
287
           cmp [edi+block_flags], FREE_BLOCK
288
           jne .error
289
 
290
           mov [block_ind], ebx   ;index of allocated block
291
 
292
           mov eax, [edi+block_size]
293
           cmp eax, [size]
294
           je .m_eq_size
295
 
296
           call alloc_mem_block
297
           and eax, eax
298
           jz .error
299
 
300
           mov esi, eax           ;esi - splitted block
301
 
302
           mov [esi+block_next], edi
303
           mov eax, [edi+block_prev]
304
           mov [esi+block_prev], eax
305
           mov [edi+block_prev], esi
357 serge 306
           mov [esi+list_fd], 0
307
           mov [esi+list_bk], 0
164 serge 308
           and eax, eax
309
           jz @f
310
           mov [eax+block_next], esi
311
@@:
312
           mov ebx, [edi+block_base]
313
           mov [esi+block_base], ebx
314
           mov edx, [size]
315
           mov [esi+block_size], edx
316
           add [edi+block_base], edx
317
           sub [edi+block_size], edx
318
 
319
           mov eax, [edi+block_size]
320
           shr eax, 12
321
           sub eax, 1
322
           cmp eax, 63
323
           jna @f
324
           mov eax, 63
325
@@:
326
           cmp eax, [block_ind]
327
           je .m_eq_ind
328
 
192 serge 329
           remove_from_list edi
164 serge 330
 
331
           mov ecx, [block_ind]
211 serge 332
           mov [mem_block_list+ecx*4], edx
164 serge 333
 
211 serge 334
           test edx, edx
164 serge 335
           jnz @f
336
           btr [mem_block_mask], ecx
337
@@:
338
           mov edx, [mem_block_list+eax*4]
357 serge 339
           mov [edi+list_fd], edx
164 serge 340
           test edx, edx
341
           jz @f
357 serge 342
           mov [edx+list_bk], edi
164 serge 343
@@:
344
           mov [mem_block_list+eax*4], edi
345
           bts [mem_block_mask], eax
346
.m_eq_ind:
357 serge 347
           mov ecx, mem_used.fd-MEM_LIST_OFFSET
348
           mov edx, [ecx+list_fd]
349
           mov [esi+list_fd], edx
350
           mov [esi+list_bk], ecx
351
           mov [ecx+list_fd], esi
352
           mov [edx+list_bk], esi
353
 
164 serge 354
           mov [esi+block_flags], USED_BLOCK
355
           mov eax, [esi+block_base]
170 serge 356
           mov ebx, [size]
357
           sub [heap_free], ebx
279 serge 358
           and [heap_mutex], 0
164 serge 359
           ret
360
.m_eq_size:
361
           remove_from_list edi
192 serge 362
           mov [mem_block_list+ebx*4], edx
164 serge 363
           and edx, edx
364
           jnz @f
192 serge 365
           btr [mem_block_mask], ebx
164 serge 366
@@:
357 serge 367
           mov ecx, mem_used.fd-MEM_LIST_OFFSET
368
           mov edx, [ecx+list_fd]
369
           mov [edi+list_fd], edx
370
           mov [edi+list_bk], ecx
371
           mov [ecx+list_fd], edi
372
           mov [edx+list_bk], edi
373
 
164 serge 374
           mov [edi+block_flags], USED_BLOCK
375
           mov eax, [edi+block_base]
170 serge 376
           mov ebx, [size]
377
           sub [heap_free], ebx
279 serge 378
           and [heap_mutex], 0
164 serge 379
           ret
380
.error:
381
           xor eax, eax
279 serge 382
           mov [heap_mutex], eax
164 serge 383
           ret
384
endp
385
 
386
align 4
321 diamond 387
proc free_kernel_space stdcall uses ebx ecx edx esi edi, base:dword
164 serge 388
 
279 serge 389
           mov ebx, heap_mutex
390
           call wait_mutex    ;ebx
391
 
164 serge 392
           mov eax, [base]
357 serge 393
           mov esi, [mem_used.fd]
164 serge 394
@@:
357 serge 395
           cmp esi, mem_used.fd-MEM_LIST_OFFSET
396
           je .fail
164 serge 397
 
398
           cmp [esi+block_base], eax
399
           je .found
357 serge 400
           mov esi, [esi+list_fd]
164 serge 401
           jmp @b
402
.found:
403
           cmp [esi+block_flags], USED_BLOCK
404
           jne .fail
405
 
170 serge 406
           mov eax, [esi+block_size]
407
           add [heap_free], eax
408
 
164 serge 409
           mov edi, [esi+block_next]
410
           test edi, edi
411
           jz .prev
412
 
413
           cmp [edi+block_flags], FREE_BLOCK
414
           jne .prev
415
 
416
           remove_from_free edi
417
 
418
           mov edx, [edi+block_next]
419
           mov [esi+block_next], edx
420
           test edx, edx
421
           jz @f
422
 
423
           mov [edx+block_prev], esi
424
@@:
425
           mov ecx, [edi+block_size]
426
           add [esi+block_size], ecx
427
 
428
           mov eax, edi
429
           call free_mem_block
430
.prev:
431
           mov edi, [esi+block_prev]
432
           test edi, edi
433
           jz .insert
434
 
435
           cmp [edi+block_flags], FREE_BLOCK
436
           jne .insert
437
 
438
           remove_from_used esi
439
 
440
           mov edx, [esi+block_next]
441
           mov [edi+block_next], edx
442
           test edx, edx
443
           jz @f
444
           mov [edx+block_prev], edi
445
@@:
446
           mov eax, esi
447
           call free_mem_block
448
 
449
           mov ecx, [edi+block_size]
450
           mov eax, [esi+block_size]
451
           add eax, ecx
452
           mov [edi+block_size], eax
453
 
454
           calc_index eax
455
           calc_index ecx
456
           cmp eax, ecx
457
           je .m_eq
458
 
459
           push ecx
460
           remove_from_list edi
461
           pop ecx
462
 
463
           cmp [mem_block_list+ecx*4], edi
464
           jne @f
465
           mov [mem_block_list+ecx*4], edx
466
@@:
467
           cmp [mem_block_list+ecx*4], 0
468
           jne @f
469
           btr [mem_block_mask], ecx
470
@@:
471
           mov esi, [mem_block_list+eax*4]
472
           mov [mem_block_list+eax*4], edi
357 serge 473
           mov [edi+list_fd], esi
164 serge 474
           test esi, esi
475
           jz @f
357 serge 476
           mov [esi+list_bk], edi
164 serge 477
@@:
478
           bts [mem_block_mask], eax
479
.m_eq:
480
           xor eax, eax
279 serge 481
           mov [heap_mutex], eax
321 diamond 482
           dec eax
164 serge 483
           ret
484
.insert:
485
           remove_from_used esi
486
 
487
           mov eax, [esi+block_size]
488
           calc_index eax
489
 
490
           mov edi, [mem_block_list+eax*4]
491
           mov [mem_block_list+eax*4], esi
357 serge 492
           mov [esi+list_fd], edi
164 serge 493
           test edi, edi
494
           jz @f
357 serge 495
           mov [edi+list_bk], esi
164 serge 496
@@:
497
           bts [mem_block_mask], eax
498
           mov [esi+block_flags],FREE_BLOCK
499
           xor eax, eax
279 serge 500
           mov [heap_mutex], eax
321 diamond 501
           dec eax
164 serge 502
           ret
503
.fail:
504
           xor eax, eax
279 serge 505
           mov [heap_mutex], eax
164 serge 506
           ret
507
endp
508
 
509
align 4
510
proc kernel_alloc stdcall, size:dword
511
           locals
512
             lin_addr    dd ?
513
             pages_count dd ?
514
           endl
515
 
516
           mov eax, [size]
206 serge 517
           add eax, 4095
518
           and eax, not 4095;
164 serge 519
           mov [size], eax
520
           and eax, eax
357 serge 521
           jz .err
164 serge 522
           mov ebx, eax
523
           shr ebx, 12
524
           mov [pages_count], ebx
525
 
526
           stdcall alloc_kernel_space, eax
357 serge 527
           test eax, eax
528
           jz .err
164 serge 529
           mov [lin_addr], eax
530
 
531
           mov ecx, [pages_count]
532
           mov edx, eax
533
           mov ebx, ecx
534
 
535
           shr ecx, 3
536
           jz .next
537
 
538
           and ebx, not 7
539
           push ebx
540
           stdcall alloc_pages, ebx
541
           pop ecx                   ; yes ecx!!!
542
           and eax, eax
357 serge 543
           jz .err
164 serge 544
 
545
           mov edi, eax
546
           mov edx, [lin_addr]
547
@@:
548
           stdcall map_page,edx,edi,dword PG_SW
549
           add edx, 0x1000
550
           add edi, 0x1000
551
           dec ecx
552
           jnz @B
553
.next:
554
           mov ecx, [pages_count]
555
           and ecx, 7
556
           jz .end
357 serge 557
@@:
558
           push ecx
164 serge 559
           call alloc_page
560
           pop ecx
561
           test eax, eax
357 serge 562
           jz .err
164 serge 563
 
564
           stdcall map_page,edx,eax,dword PG_SW
565
           add edx, 0x1000
566
           dec ecx
567
           jnz @B
568
.end:
569
           mov eax, [lin_addr]
570
           ret
357 serge 571
.err:
164 serge 572
           xor eax, eax
573
           ret
574
endp
575
 
576
align 4
577
proc kernel_free stdcall, base:dword
321 diamond 578
           push ebx esi
164 serge 579
 
279 serge 580
           mov ebx, heap_mutex
581
           call wait_mutex    ;ebx
582
 
164 serge 583
           mov eax, [base]
357 serge 584
           mov esi, [mem_used.fd]
164 serge 585
@@:
357 serge 586
           cmp esi, mem_used.fd-MEM_LIST_OFFSET
587
           je .fail
164 serge 588
 
589
           cmp [esi+block_base], eax
590
           je .found
357 serge 591
           mov esi, [esi+list_fd]
164 serge 592
           jmp @b
593
.found:
594
           cmp [esi+block_flags], USED_BLOCK
595
           jne .fail
596
 
279 serge 597
           and [heap_mutex], 0
598
 
321 diamond 599
           push ecx
164 serge 600
           mov ecx, [esi+block_size];
281 serge 601
           shr ecx, 12
279 serge 602
           call release_pages   ;eax, ecx
321 diamond 603
           pop ecx
164 serge 604
           stdcall free_kernel_space, [base]
321 diamond 605
           pop esi ebx
279 serge 606
           ret
164 serge 607
.fail:
279 serge 608
           and [heap_mutex], 0
321 diamond 609
           pop esi ebx
164 serge 610
           ret
611
endp
612
 
613
restore block_next
614
restore block_prev
615
restore block_list
616
restore block_base
617
restore block_size
618
restore block_flags
619
 
620
;;;;;;;;;;;;;;      USER     ;;;;;;;;;;;;;;;;;
621
 
188 serge 622
HEAP_TOP  equ 0x5FC00000
623
 
164 serge 624
align 4
188 serge 625
proc init_heap
164 serge 626
 
465 serge 627
           mov ebx,[current_slot]
628
           mov eax, [ebx+APPDATA.heap_top]
172 serge 629
           test eax, eax
630
           jz @F
465 serge 631
           sub eax,[ebx+APPDATA.heap_base]
172 serge 632
           sub eax, 4096
633
           ret
634
@@:
465 serge 635
           mov esi, [ebx+APPDATA.mem_size]
188 serge 636
           add esi, 4095
637
           and esi, not 4095
465 serge 638
           mov [ebx+APPDATA.mem_size], esi
188 serge 639
           mov eax, HEAP_TOP
465 serge 640
           mov [ebx+APPDATA.heap_base], esi
641
           mov [ebx+APPDATA.heap_top], eax
164 serge 642
 
188 serge 643
           sub eax, esi
465 serge 644
       ;    add esi, new_app_base
188 serge 645
           shr esi, 10
646
           mov ecx, eax
164 serge 647
           sub eax, 4096
188 serge 648
           or ecx, FREE_BLOCK
365 serge 649
           mov [page_tabs+esi], ecx
164 serge 650
           ret
651
endp
652
 
653
align 4
654
proc user_alloc stdcall, alloc_size:dword
655
 
656
           mov ecx, [alloc_size]
657
           add ecx, (4095+4096)
658
           and ecx, not 4095
659
 
465 serge 660
           mov ebx, [current_slot]
661
           mov esi, dword [ebx+APPDATA.heap_base]  ; heap_base
662
           mov edi, dword [ebx+APPDATA.heap_top]   ; heap_top
164 serge 663
l_0:
664
           cmp esi, edi
665
           jae m_exit
666
 
667
           mov ebx, esi
668
           shr ebx, 12
365 serge 669
           mov eax, [page_tabs+ebx*4]
620 diamond 670
           test al, FREE_BLOCK
164 serge 671
           jz test_used
672
           and eax, 0xFFFFF000
673
           cmp eax, ecx    ;alloc_size
674
           jb  m_next
270 diamond 675
	   jz  @f
164 serge 676
 
620 diamond 677
           lea edx, [esi+ecx]
678
           sub eax, ecx
679
           or al, FREE_BLOCK
164 serge 680
           shr edx, 12
365 serge 681
           mov [page_tabs+edx*4], eax
294 diamond 682
@@:
164 serge 683
           or ecx, USED_BLOCK
365 serge 684
           mov [page_tabs+ebx*4], ecx
164 serge 685
           shr ecx, 12
620 diamond 686
           inc ebx
164 serge 687
           dec ecx
620 diamond 688
           jz  .no
164 serge 689
@@:
365 serge 690
           mov dword [page_tabs+ebx*4], 2
164 serge 691
           inc ebx
692
           dec ecx
693
           jnz @B
620 diamond 694
.no:
164 serge 695
 
465 serge 696
           mov     edx, [current_slot]
697
           mov     ebx, [alloc_size]
698
           add     ebx, 0xFFF
699
           and     ebx, not 0xFFF
700
           add     ebx, [edx+APPDATA.mem_size]
701
           call    update_mem_size
294 diamond 702
 
620 diamond 703
           lea eax, [esi+4096]
164 serge 704
           ret
705
test_used:
620 diamond 706
           test al, USED_BLOCK
164 serge 707
           jz m_exit
708
 
709
           and eax, 0xFFFFF000
620 diamond 710
m_next:
164 serge 711
           add esi, eax
712
           jmp l_0
713
m_exit:
714
           xor eax, eax
715
           ret
716
endp
717
 
718
align 4
719
proc user_free stdcall, base:dword
720
 
721
           mov esi, [base]
722
           test esi, esi
723
           jz .exit
724
 
294 diamond 725
           xor ebx, ebx
164 serge 726
           shr esi, 12
620 diamond 727
           mov eax, [page_tabs+(esi-1)*4]
546 diamond 728
           test al, USED_BLOCK
620 diamond 729
           jz .cantfree
546 diamond 730
           test al, DONT_FREE_BLOCK
731
           jnz .cantfree
164 serge 732
 
733
           and eax, not 4095
734
           mov ecx, eax
620 diamond 735
           or al, FREE_BLOCK
736
           mov [page_tabs+(esi-1)*4], eax
164 serge 737
           sub ecx, 4096
620 diamond 738
           mov ebx, ecx
164 serge 739
           shr ecx, 12
620 diamond 740
           jz .released
164 serge 741
.release:
188 serge 742
           xor eax, eax
365 serge 743
           xchg eax, [page_tabs+esi*4]
620 diamond 744
           test al, 1
188 serge 745
           jz @F
164 serge 746
           call free_page
448 diamond 747
           mov eax, esi
748
           shl eax, 12
749
           invlpg [eax]
188 serge 750
@@:
164 serge 751
           inc esi
752
           dec ecx
753
           jnz .release
620 diamond 754
.released:
465 serge 755
           mov edx, [current_slot]
756
           mov esi, dword [edx+APPDATA.heap_base]
757
           mov edi, dword [edx+APPDATA.heap_top]
758
           sub ebx, [edx+APPDATA.mem_size]
294 diamond 759
           neg ebx
760
           call update_mem_size
448 diamond 761
           call user_normalize
762
           ret
763
.exit:
764
           xor eax, eax
765
           inc eax
766
           ret
546 diamond 767
.cantfree:
768
           xor eax, eax
769
           ret
448 diamond 770
endp
771
 
772
user_normalize:
773
; in: esi=heap_base, edi=heap_top
774
; out: eax=0 <=> OK
775
; destroys: ebx,edx,esi,edi
164 serge 776
           shr esi, 12
777
           shr edi, 12
778
@@:
365 serge 779
           mov eax, [page_tabs+esi*4]
620 diamond 780
           test al, USED_BLOCK
164 serge 781
           jz .test_free
782
           shr eax, 12
783
           add esi, eax
784
           jmp @B
785
.test_free:
620 diamond 786
           test al, FREE_BLOCK
164 serge 787
           jz .err
788
           mov edx, eax
789
           shr edx, 12
790
           add edx, esi
791
           cmp edx, edi
792
           jae .exit
793
 
365 serge 794
           mov ebx, [page_tabs+edx*4]
620 diamond 795
           test bl, USED_BLOCK
164 serge 796
           jz .next_free
797
 
798
           shr ebx, 12
799
           add edx, ebx
800
           mov esi, edx
801
           jmp @B
802
.next_free:
620 diamond 803
           test bl, FREE_BLOCK
164 serge 804
           jz .err
365 serge 805
           and dword [page_tabs+edx*4], 0
164 serge 806
           add eax, ebx
807
           and eax, not 4095
808
           or eax, FREE_BLOCK
365 serge 809
           mov [page_tabs+esi*4], eax
164 serge 810
           jmp @B
811
.exit:
812
           xor eax, eax
813
           inc eax
814
           ret
815
.err:
816
           xor eax, eax
817
           ret
818
 
448 diamond 819
user_realloc:
820
; in: eax = pointer, ebx = new size
821
; out: eax = new pointer or NULL
822
        test    eax, eax
823
        jnz     @f
824
; realloc(NULL,sz) - same as malloc(sz)
825
        push    ebx
826
        call    user_alloc
827
        ret
828
@@:
829
        push    ecx edx
465 serge 830
        lea     ecx, [eax - 0x1000]
448 diamond 831
        shr     ecx, 12
832
        mov     edx, [page_tabs+ecx*4]
620 diamond 833
        test    dl, USED_BLOCK
448 diamond 834
        jnz     @f
835
; attempt to realloc invalid pointer
836
.ret0:
837
        pop     edx ecx
838
        xor     eax, eax
839
        ret
840
@@:
620 diamond 841
        test    dl, DONT_FREE_BLOCK
546 diamond 842
        jnz     .ret0
448 diamond 843
        add     ebx, 0x1FFF
844
        shr     edx, 12
845
        shr     ebx, 12
846
; edx = allocated size, ebx = new size
847
        add     edx, ecx
848
        add     ebx, ecx
849
        cmp     edx, ebx
850
        jb      .realloc_add
851
; release part of allocated memory
852
.loop:
853
        cmp     edx, ebx
854
        jz      .release_done
855
        dec     edx
856
        xor     eax, eax
857
        xchg    eax, [page_tabs+edx*4]
858
        test    al, 1
859
        jz      .loop
860
        call    free_page
861
        mov     eax, edx
862
        shl     eax, 12
863
        invlpg  [eax]
864
        jmp     .loop
865
.release_done:
866
        sub     ebx, ecx
867
        cmp     ebx, 1
868
        jnz     .nofreeall
869
        mov     eax, [page_tabs+ecx*4]
870
        and     eax, not 0xFFF
465 serge 871
        mov     edx, [current_slot]
872
        mov     ebx, [APPDATA.mem_size+edx]
448 diamond 873
        sub     ebx, eax
874
        add     ebx, 0x1000
875
        or      al, FREE_BLOCK
876
        mov     [page_tabs+ecx*4], eax
877
        push    esi edi
465 serge 878
        mov     esi, [APPDATA.heap_base+edx]
879
        mov     edi, [APPDATA.heap_top+edx]
448 diamond 880
        call    update_mem_size
881
        call    user_normalize
882
        pop     edi esi
883
        jmp     .ret0   ; all freed
884
.nofreeall:
885
        sub     edx, ecx
886
        shl     ebx, 12
887
        or      ebx, USED_BLOCK
888
        xchg    [page_tabs+ecx*4], ebx
889
        shr     ebx, 12
890
        sub     ebx, edx
891
        push    ebx ecx edx
465 serge 892
        mov     edx, [current_slot]
448 diamond 893
        shl     ebx, 12
465 serge 894
        sub     ebx, [APPDATA.mem_size+edx]
448 diamond 895
        neg     ebx
896
        call    update_mem_size
897
        pop     edx ecx ebx
465 serge 898
        lea     eax, [ecx+1]
448 diamond 899
        shl     eax, 12
900
        push    eax
901
        add     ecx, ebx
902
        add     edx, ecx
903
        shl     ebx, 12
904
        jz      .ret
905
        push    esi
465 serge 906
        mov     esi, [current_slot]
907
        mov     esi, [APPDATA.heap_top+esi]
448 diamond 908
        shr     esi, 12
909
@@:
910
        cmp     edx, esi
911
        jae     .merge_done
912
        mov     eax, [page_tabs+edx*4]
913
        test    al, USED_BLOCK
914
        jz      .merge_done
915
        and     dword [page_tabs+edx*4], 0
916
        and     eax, not 0xFFF
917
        add     ebx, eax
918
        add     edx, eax
919
        jmp     @b
920
.merge_done:
921
        pop     esi
922
        or      ebx, FREE_BLOCK
923
        mov     [page_tabs+ecx*4], ebx
924
.ret:
925
        pop     eax edx ecx
926
        ret
927
.realloc_add:
928
; get some additional memory
465 serge 929
        mov     eax, [current_slot]
930
        mov     eax, [APPDATA.heap_top+eax]
448 diamond 931
        shr     eax, 12
932
        cmp     edx, eax
933
        jae     .cant_inplace
934
        mov     eax, [page_tabs+edx*4]
620 diamond 935
        test    al, FREE_BLOCK
936
        jz      .cant_inplace
448 diamond 937
        shr     eax, 12
938
        add     eax, edx
620 diamond 939
        sub     eax, ebx
448 diamond 940
        jb      .cant_inplace
941
        jz      @f
942
        shl     eax, 12
943
        or      al, FREE_BLOCK
944
        mov     [page_tabs+ebx*4], eax
945
@@:
946
        mov     eax, ebx
947
        sub     eax, ecx
948
        shl     eax, 12
949
        or      al, USED_BLOCK
950
        mov     [page_tabs+ecx*4], eax
465 serge 951
        lea     eax, [ecx+1]
448 diamond 952
        shl     eax, 12
953
        push    eax
954
        push    edi
955
        lea     edi, [page_tabs+edx*4]
956
        mov     eax, 2
957
        sub     ebx, edx
958
        mov     ecx, ebx
959
        cld
960
        rep     stosd
961
        pop     edi
465 serge 962
        mov     edx, [current_slot]
448 diamond 963
        shl     ebx, 12
465 serge 964
        add     ebx, [APPDATA.mem_size+edx]
448 diamond 965
        call    update_mem_size
966
        pop     eax edx ecx
967
        ret
968
.cant_inplace:
969
        push    esi edi
465 serge 970
        mov     eax, [current_slot]
971
        mov     esi, [APPDATA.heap_base+eax]
972
        mov     edi, [APPDATA.heap_top+eax]
448 diamond 973
        shr     esi, 12
974
        shr     edi, 12
975
        sub     ebx, ecx
976
.find_place:
977
        cmp     esi, edi
978
        jae     .place_not_found
979
        mov     eax, [page_tabs+esi*4]
980
        test    al, FREE_BLOCK
981
        jz      .next_place
982
        shr     eax, 12
983
        cmp     eax, ebx
984
        jae     .place_found
985
        add     esi, eax
986
        jmp     .find_place
987
.next_place:
988
        shr     eax, 12
989
        add     esi, eax
990
        jmp     .find_place
991
.place_not_found:
992
        pop     edi esi
993
        jmp     .ret0
994
.place_found:
995
        sub     eax, ebx
996
        jz      @f
997
        push    esi
620 diamond 998
        add     esi, ebx
448 diamond 999
        shl     eax, 12
1000
        or      al, FREE_BLOCK
1001
        mov     [page_tabs+esi*4], eax
1002
        pop     esi
1003
@@:
1004
        mov     eax, ebx
1005
        shl     eax, 12
1006
        or      al, USED_BLOCK
1007
        mov     [page_tabs+esi*4], eax
1008
        inc     esi
1009
        mov     eax, esi
1010
        shl     eax, 12
1011
        push    eax
1012
        mov     eax, [page_tabs+ecx*4]
1013
        and     eax, not 0xFFF
1014
        or      al, FREE_BLOCK
1015
        sub     edx, ecx
1016
        mov     [page_tabs+ecx*4], eax
1017
        inc     ecx
620 diamond 1018
        dec     ebx
1019
        dec     edx
1020
        jz      .no
448 diamond 1021
@@:
1022
        xor     eax, eax
1023
        xchg    eax, [page_tabs+ecx*4]
1024
        mov     [page_tabs+esi*4], eax
1025
	mov     eax, ecx
1026
	shl     eax, 12
1027
	invlpg  [eax]
620 diamond 1028
        inc     esi
448 diamond 1029
        inc     ecx
1030
        dec     ebx
1031
        dec     edx
1032
        jnz     @b
620 diamond 1033
.no:
448 diamond 1034
        push    ebx
465 serge 1035
        mov     edx, [current_slot]
448 diamond 1036
        shl     ebx, 12
465 serge 1037
        add     ebx, [APPDATA.mem_size+edx]
448 diamond 1038
        call    update_mem_size
1039
        pop     ebx
1040
@@:
1041
        mov     dword [page_tabs+esi*4], 2
1042
        inc     esi
1043
        dec     ebx
1044
        jnz     @b
1045
        pop     eax edi esi edx ecx
1046
        ret
1047
 
278 serge 1048
if 0
164 serge 1049
align 4
1050
proc alloc_dll
1051
           pushf
1052
           cli
1053
           bsf eax, [dll_map]
1054
           jnz .find
1055
           popf
1056
           xor eax, eax
1057
           ret
1058
.find:
1059
           btr [dll_map], eax
1060
           popf
1061
           shl eax, 5
1062
           add eax, dll_tab
1063
           ret
1064
endp
1065
 
1066
align 4
1067
proc alloc_service
1068
           pushf
1069
           cli
1070
           bsf eax, [srv_map]
1071
           jnz .find
1072
           popf
1073
           xor eax, eax
1074
           ret
214 serge 1075
.find:
1076
           btr [srv_map], eax
164 serge 1077
           popf
214 serge 1078
           shl eax,0x02
1079
           lea eax,[srv_tab+eax+eax*8]   ;srv_tab+eax*36
164 serge 1080
           ret
1081
endp
278 serge 1082
 
1083
end if