Subversion Repositories Kolibri OS

Rev

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