Subversion Repositories Kolibri OS

Rev

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