Subversion Repositories Kolibri OS

Rev

Rev 663 | Rev 793 | 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: 750 $
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
 
662 serge 540
           push ebx
541
           push edi
542
 
164 serge 543
           mov eax, [size]
206 serge 544
           add eax, 4095
545
           and eax, not 4095;
164 serge 546
           mov [size], eax
547
           and eax, eax
357 serge 548
           jz .err
164 serge 549
           mov ebx, eax
550
           shr ebx, 12
551
           mov [pages_count], ebx
552
 
553
           stdcall alloc_kernel_space, eax
357 serge 554
           test eax, eax
555
           jz .err
164 serge 556
           mov [lin_addr], eax
557
 
558
           mov ecx, [pages_count]
559
           mov edx, eax
560
           mov ebx, ecx
561
 
562
           shr ecx, 3
563
           jz .next
564
 
565
           and ebx, not 7
566
           push ebx
567
           stdcall alloc_pages, ebx
568
           pop ecx                   ; yes ecx!!!
569
           and eax, eax
357 serge 570
           jz .err
164 serge 571
 
572
           mov edi, eax
573
           mov edx, [lin_addr]
574
@@:
575
           stdcall map_page,edx,edi,dword PG_SW
576
           add edx, 0x1000
577
           add edi, 0x1000
578
           dec ecx
579
           jnz @B
580
.next:
581
           mov ecx, [pages_count]
582
           and ecx, 7
583
           jz .end
357 serge 584
@@:
585
           push ecx
164 serge 586
           call alloc_page
587
           pop ecx
588
           test eax, eax
357 serge 589
           jz .err
164 serge 590
 
591
           stdcall map_page,edx,eax,dword PG_SW
592
           add edx, 0x1000
593
           dec ecx
594
           jnz @B
595
.end:
596
           mov eax, [lin_addr]
662 serge 597
           pop edi
598
           pop ebx
164 serge 599
           ret
357 serge 600
.err:
164 serge 601
           xor eax, eax
662 serge 602
           pop edi
603
           pop ebx
164 serge 604
           ret
605
endp
606
 
607
align 4
608
proc kernel_free stdcall, base:dword
321 diamond 609
           push ebx esi
164 serge 610
 
279 serge 611
           mov ebx, heap_mutex
612
           call wait_mutex    ;ebx
613
 
164 serge 614
           mov eax, [base]
357 serge 615
           mov esi, [mem_used.fd]
164 serge 616
@@:
357 serge 617
           cmp esi, mem_used.fd-MEM_LIST_OFFSET
618
           je .fail
164 serge 619
 
620
           cmp [esi+block_base], eax
621
           je .found
357 serge 622
           mov esi, [esi+list_fd]
164 serge 623
           jmp @b
624
.found:
625
           cmp [esi+block_flags], USED_BLOCK
626
           jne .fail
627
 
279 serge 628
           and [heap_mutex], 0
629
 
321 diamond 630
           push ecx
164 serge 631
           mov ecx, [esi+block_size];
281 serge 632
           shr ecx, 12
279 serge 633
           call release_pages   ;eax, ecx
321 diamond 634
           pop ecx
164 serge 635
           stdcall free_kernel_space, [base]
321 diamond 636
           pop esi ebx
279 serge 637
           ret
164 serge 638
.fail:
279 serge 639
           and [heap_mutex], 0
321 diamond 640
           pop esi ebx
164 serge 641
           ret
642
endp
643
 
644
restore block_next
645
restore block_prev
646
restore block_list
647
restore block_base
648
restore block_size
649
restore block_flags
650
 
651
;;;;;;;;;;;;;;      USER     ;;;;;;;;;;;;;;;;;
652
 
188 serge 653
HEAP_TOP  equ 0x5FC00000
654
 
164 serge 655
align 4
188 serge 656
proc init_heap
164 serge 657
 
465 serge 658
           mov ebx,[current_slot]
659
           mov eax, [ebx+APPDATA.heap_top]
172 serge 660
           test eax, eax
661
           jz @F
465 serge 662
           sub eax,[ebx+APPDATA.heap_base]
172 serge 663
           sub eax, 4096
664
           ret
665
@@:
465 serge 666
           mov esi, [ebx+APPDATA.mem_size]
188 serge 667
           add esi, 4095
668
           and esi, not 4095
465 serge 669
           mov [ebx+APPDATA.mem_size], esi
188 serge 670
           mov eax, HEAP_TOP
465 serge 671
           mov [ebx+APPDATA.heap_base], esi
672
           mov [ebx+APPDATA.heap_top], eax
164 serge 673
 
188 serge 674
           sub eax, esi
675
           shr esi, 10
676
           mov ecx, eax
164 serge 677
           sub eax, 4096
188 serge 678
           or ecx, FREE_BLOCK
365 serge 679
           mov [page_tabs+esi], ecx
164 serge 680
           ret
681
endp
682
 
683
align 4
684
proc user_alloc stdcall, alloc_size:dword
685
 
662 serge 686
           push ebx
687
           push esi
688
           push edi
689
 
164 serge 690
           mov ecx, [alloc_size]
691
           add ecx, (4095+4096)
692
           and ecx, not 4095
693
 
465 serge 694
           mov ebx, [current_slot]
695
           mov esi, dword [ebx+APPDATA.heap_base]  ; heap_base
696
           mov edi, dword [ebx+APPDATA.heap_top]   ; heap_top
164 serge 697
l_0:
698
           cmp esi, edi
699
           jae m_exit
700
 
701
           mov ebx, esi
702
           shr ebx, 12
365 serge 703
           mov eax, [page_tabs+ebx*4]
620 diamond 704
           test al, FREE_BLOCK
164 serge 705
           jz test_used
706
           and eax, 0xFFFFF000
707
           cmp eax, ecx    ;alloc_size
708
           jb  m_next
270 diamond 709
	   jz  @f
164 serge 710
 
620 diamond 711
           lea edx, [esi+ecx]
712
           sub eax, ecx
713
           or al, FREE_BLOCK
164 serge 714
           shr edx, 12
365 serge 715
           mov [page_tabs+edx*4], eax
294 diamond 716
@@:
164 serge 717
           or ecx, USED_BLOCK
365 serge 718
           mov [page_tabs+ebx*4], ecx
164 serge 719
           shr ecx, 12
620 diamond 720
           inc ebx
164 serge 721
           dec ecx
620 diamond 722
           jz  .no
164 serge 723
@@:
365 serge 724
           mov dword [page_tabs+ebx*4], 2
164 serge 725
           inc ebx
726
           dec ecx
727
           jnz @B
620 diamond 728
.no:
164 serge 729
 
465 serge 730
           mov     edx, [current_slot]
731
           mov     ebx, [alloc_size]
732
           add     ebx, 0xFFF
733
           and     ebx, not 0xFFF
734
           add     ebx, [edx+APPDATA.mem_size]
735
           call    update_mem_size
294 diamond 736
 
620 diamond 737
           lea eax, [esi+4096]
662 serge 738
 
739
           pop edi
740
           pop esi
741
           pop ebx
164 serge 742
           ret
743
test_used:
620 diamond 744
           test al, USED_BLOCK
164 serge 745
           jz m_exit
746
 
747
           and eax, 0xFFFFF000
620 diamond 748
m_next:
164 serge 749
           add esi, eax
750
           jmp l_0
751
m_exit:
752
           xor eax, eax
662 serge 753
           pop edi
754
           pop esi
755
           pop ebx
164 serge 756
           ret
757
endp
758
 
759
align 4
760
proc user_free stdcall, base:dword
761
 
662 serge 762
           push esi
763
 
164 serge 764
           mov esi, [base]
765
           test esi, esi
766
           jz .exit
767
 
662 serge 768
           push ebx
769
 
294 diamond 770
           xor ebx, ebx
164 serge 771
           shr esi, 12
620 diamond 772
           mov eax, [page_tabs+(esi-1)*4]
546 diamond 773
           test al, USED_BLOCK
620 diamond 774
           jz .cantfree
546 diamond 775
           test al, DONT_FREE_BLOCK
776
           jnz .cantfree
164 serge 777
 
778
           and eax, not 4095
779
           mov ecx, eax
620 diamond 780
           or al, FREE_BLOCK
781
           mov [page_tabs+(esi-1)*4], eax
164 serge 782
           sub ecx, 4096
620 diamond 783
           mov ebx, ecx
164 serge 784
           shr ecx, 12
620 diamond 785
           jz .released
164 serge 786
.release:
188 serge 787
           xor eax, eax
365 serge 788
           xchg eax, [page_tabs+esi*4]
620 diamond 789
           test al, 1
188 serge 790
           jz @F
164 serge 791
           call free_page
448 diamond 792
           mov eax, esi
793
           shl eax, 12
794
           invlpg [eax]
188 serge 795
@@:
164 serge 796
           inc esi
797
           dec ecx
798
           jnz .release
620 diamond 799
.released:
662 serge 800
           push edi
801
 
465 serge 802
           mov edx, [current_slot]
803
           mov esi, dword [edx+APPDATA.heap_base]
804
           mov edi, dword [edx+APPDATA.heap_top]
805
           sub ebx, [edx+APPDATA.mem_size]
294 diamond 806
           neg ebx
807
           call update_mem_size
448 diamond 808
           call user_normalize
662 serge 809
           pop edi
810
           pop ebx
811
           pop esi
448 diamond 812
           ret
813
.exit:
814
           xor eax, eax
815
           inc eax
662 serge 816
           pop esi
448 diamond 817
           ret
546 diamond 818
.cantfree:
819
           xor eax, eax
662 serge 820
           pop ebx
821
           pop esi
546 diamond 822
           ret
448 diamond 823
endp
824
 
825
user_normalize:
826
; in: esi=heap_base, edi=heap_top
827
; out: eax=0 <=> OK
828
; destroys: ebx,edx,esi,edi
164 serge 829
           shr esi, 12
830
           shr edi, 12
831
@@:
365 serge 832
           mov eax, [page_tabs+esi*4]
620 diamond 833
           test al, USED_BLOCK
164 serge 834
           jz .test_free
835
           shr eax, 12
836
           add esi, eax
837
           jmp @B
838
.test_free:
620 diamond 839
           test al, FREE_BLOCK
164 serge 840
           jz .err
841
           mov edx, eax
842
           shr edx, 12
843
           add edx, esi
844
           cmp edx, edi
845
           jae .exit
846
 
365 serge 847
           mov ebx, [page_tabs+edx*4]
620 diamond 848
           test bl, USED_BLOCK
164 serge 849
           jz .next_free
850
 
851
           shr ebx, 12
852
           add edx, ebx
853
           mov esi, edx
854
           jmp @B
855
.next_free:
620 diamond 856
           test bl, FREE_BLOCK
164 serge 857
           jz .err
365 serge 858
           and dword [page_tabs+edx*4], 0
164 serge 859
           add eax, ebx
860
           and eax, not 4095
861
           or eax, FREE_BLOCK
365 serge 862
           mov [page_tabs+esi*4], eax
164 serge 863
           jmp @B
864
.exit:
865
           xor eax, eax
866
           inc eax
867
           ret
868
.err:
869
           xor eax, eax
870
           ret
871
 
448 diamond 872
user_realloc:
873
; in: eax = pointer, ebx = new size
874
; out: eax = new pointer or NULL
875
        test    eax, eax
876
        jnz     @f
877
; realloc(NULL,sz) - same as malloc(sz)
878
        push    ebx
879
        call    user_alloc
880
        ret
881
@@:
882
        push    ecx edx
465 serge 883
        lea     ecx, [eax - 0x1000]
448 diamond 884
        shr     ecx, 12
885
        mov     edx, [page_tabs+ecx*4]
620 diamond 886
        test    dl, USED_BLOCK
448 diamond 887
        jnz     @f
888
; attempt to realloc invalid pointer
889
.ret0:
890
        pop     edx ecx
891
        xor     eax, eax
892
        ret
893
@@:
620 diamond 894
        test    dl, DONT_FREE_BLOCK
546 diamond 895
        jnz     .ret0
448 diamond 896
        add     ebx, 0x1FFF
897
        shr     edx, 12
898
        shr     ebx, 12
899
; edx = allocated size, ebx = new size
900
        add     edx, ecx
901
        add     ebx, ecx
902
        cmp     edx, ebx
903
        jb      .realloc_add
904
; release part of allocated memory
905
.loop:
906
        cmp     edx, ebx
907
        jz      .release_done
908
        dec     edx
909
        xor     eax, eax
910
        xchg    eax, [page_tabs+edx*4]
911
        test    al, 1
912
        jz      .loop
913
        call    free_page
914
        mov     eax, edx
915
        shl     eax, 12
916
        invlpg  [eax]
917
        jmp     .loop
918
.release_done:
919
        sub     ebx, ecx
920
        cmp     ebx, 1
921
        jnz     .nofreeall
922
        mov     eax, [page_tabs+ecx*4]
923
        and     eax, not 0xFFF
465 serge 924
        mov     edx, [current_slot]
925
        mov     ebx, [APPDATA.mem_size+edx]
448 diamond 926
        sub     ebx, eax
927
        add     ebx, 0x1000
928
        or      al, FREE_BLOCK
929
        mov     [page_tabs+ecx*4], eax
930
        push    esi edi
465 serge 931
        mov     esi, [APPDATA.heap_base+edx]
932
        mov     edi, [APPDATA.heap_top+edx]
448 diamond 933
        call    update_mem_size
934
        call    user_normalize
935
        pop     edi esi
936
        jmp     .ret0   ; all freed
937
.nofreeall:
938
        sub     edx, ecx
939
        shl     ebx, 12
940
        or      ebx, USED_BLOCK
941
        xchg    [page_tabs+ecx*4], ebx
942
        shr     ebx, 12
943
        sub     ebx, edx
944
        push    ebx ecx edx
465 serge 945
        mov     edx, [current_slot]
448 diamond 946
        shl     ebx, 12
465 serge 947
        sub     ebx, [APPDATA.mem_size+edx]
448 diamond 948
        neg     ebx
949
        call    update_mem_size
950
        pop     edx ecx ebx
465 serge 951
        lea     eax, [ecx+1]
448 diamond 952
        shl     eax, 12
953
        push    eax
954
        add     ecx, ebx
955
        add     edx, ecx
956
        shl     ebx, 12
957
        jz      .ret
958
        push    esi
465 serge 959
        mov     esi, [current_slot]
960
        mov     esi, [APPDATA.heap_top+esi]
448 diamond 961
        shr     esi, 12
962
@@:
963
        cmp     edx, esi
964
        jae     .merge_done
965
        mov     eax, [page_tabs+edx*4]
966
        test    al, USED_BLOCK
967
        jz      .merge_done
968
        and     dword [page_tabs+edx*4], 0
969
        and     eax, not 0xFFF
970
        add     ebx, eax
971
        add     edx, eax
972
        jmp     @b
973
.merge_done:
974
        pop     esi
975
        or      ebx, FREE_BLOCK
976
        mov     [page_tabs+ecx*4], ebx
977
.ret:
978
        pop     eax edx ecx
979
        ret
980
.realloc_add:
981
; get some additional memory
465 serge 982
        mov     eax, [current_slot]
983
        mov     eax, [APPDATA.heap_top+eax]
448 diamond 984
        shr     eax, 12
985
        cmp     edx, eax
986
        jae     .cant_inplace
987
        mov     eax, [page_tabs+edx*4]
620 diamond 988
        test    al, FREE_BLOCK
989
        jz      .cant_inplace
448 diamond 990
        shr     eax, 12
991
        add     eax, edx
620 diamond 992
        sub     eax, ebx
448 diamond 993
        jb      .cant_inplace
994
        jz      @f
995
        shl     eax, 12
996
        or      al, FREE_BLOCK
997
        mov     [page_tabs+ebx*4], eax
998
@@:
999
        mov     eax, ebx
1000
        sub     eax, ecx
1001
        shl     eax, 12
1002
        or      al, USED_BLOCK
1003
        mov     [page_tabs+ecx*4], eax
465 serge 1004
        lea     eax, [ecx+1]
448 diamond 1005
        shl     eax, 12
1006
        push    eax
1007
        push    edi
1008
        lea     edi, [page_tabs+edx*4]
1009
        mov     eax, 2
1010
        sub     ebx, edx
1011
        mov     ecx, ebx
1012
        cld
1013
        rep     stosd
1014
        pop     edi
465 serge 1015
        mov     edx, [current_slot]
448 diamond 1016
        shl     ebx, 12
465 serge 1017
        add     ebx, [APPDATA.mem_size+edx]
448 diamond 1018
        call    update_mem_size
1019
        pop     eax edx ecx
1020
        ret
1021
.cant_inplace:
1022
        push    esi edi
465 serge 1023
        mov     eax, [current_slot]
1024
        mov     esi, [APPDATA.heap_base+eax]
1025
        mov     edi, [APPDATA.heap_top+eax]
448 diamond 1026
        shr     esi, 12
1027
        shr     edi, 12
1028
        sub     ebx, ecx
1029
.find_place:
1030
        cmp     esi, edi
1031
        jae     .place_not_found
1032
        mov     eax, [page_tabs+esi*4]
1033
        test    al, FREE_BLOCK
1034
        jz      .next_place
1035
        shr     eax, 12
1036
        cmp     eax, ebx
1037
        jae     .place_found
1038
        add     esi, eax
1039
        jmp     .find_place
1040
.next_place:
1041
        shr     eax, 12
1042
        add     esi, eax
1043
        jmp     .find_place
1044
.place_not_found:
1045
        pop     edi esi
1046
        jmp     .ret0
1047
.place_found:
1048
        sub     eax, ebx
1049
        jz      @f
1050
        push    esi
620 diamond 1051
        add     esi, ebx
448 diamond 1052
        shl     eax, 12
1053
        or      al, FREE_BLOCK
1054
        mov     [page_tabs+esi*4], eax
1055
        pop     esi
1056
@@:
1057
        mov     eax, ebx
1058
        shl     eax, 12
1059
        or      al, USED_BLOCK
1060
        mov     [page_tabs+esi*4], eax
1061
        inc     esi
1062
        mov     eax, esi
1063
        shl     eax, 12
1064
        push    eax
1065
        mov     eax, [page_tabs+ecx*4]
1066
        and     eax, not 0xFFF
1067
        or      al, FREE_BLOCK
1068
        sub     edx, ecx
1069
        mov     [page_tabs+ecx*4], eax
1070
        inc     ecx
620 diamond 1071
        dec     ebx
1072
        dec     edx
1073
        jz      .no
448 diamond 1074
@@:
1075
        xor     eax, eax
1076
        xchg    eax, [page_tabs+ecx*4]
1077
        mov     [page_tabs+esi*4], eax
1078
	mov     eax, ecx
1079
	shl     eax, 12
1080
	invlpg  [eax]
620 diamond 1081
        inc     esi
448 diamond 1082
        inc     ecx
1083
        dec     ebx
1084
        dec     edx
1085
        jnz     @b
620 diamond 1086
.no:
448 diamond 1087
        push    ebx
465 serge 1088
        mov     edx, [current_slot]
448 diamond 1089
        shl     ebx, 12
465 serge 1090
        add     ebx, [APPDATA.mem_size+edx]
448 diamond 1091
        call    update_mem_size
1092
        pop     ebx
1093
@@:
1094
        mov     dword [page_tabs+esi*4], 2
1095
        inc     esi
1096
        dec     ebx
1097
        jnz     @b
1098
        pop     eax edi esi edx ecx
1099
        ret
1100
 
278 serge 1101
if 0
164 serge 1102
align 4
1103
proc alloc_dll
1104
           pushf
1105
           cli
1106
           bsf eax, [dll_map]
1107
           jnz .find
1108
           popf
1109
           xor eax, eax
1110
           ret
1111
.find:
1112
           btr [dll_map], eax
1113
           popf
1114
           shl eax, 5
1115
           add eax, dll_tab
1116
           ret
1117
endp
1118
 
1119
align 4
1120
proc alloc_service
1121
           pushf
1122
           cli
1123
           bsf eax, [srv_map]
1124
           jnz .find
1125
           popf
1126
           xor eax, eax
1127
           ret
214 serge 1128
.find:
1129
           btr [srv_map], eax
164 serge 1130
           popf
214 serge 1131
           shl eax,0x02
1132
           lea eax,[srv_tab+eax+eax*8]   ;srv_tab+eax*36
164 serge 1133
           ret
1134
endp
278 serge 1135
 
1136
end if