Subversion Repositories Kolibri OS

Rev

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

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