Subversion Repositories Kolibri OS

Rev

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

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