Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
1 ha 1
if ~defined memmanager_inc
2
memmanager_inc_fix:
3
memmanager_inc fix memmanager_inc_fix
4
;for testing in applications
5
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6
;; Memory allocator for MenuetOS kernel
7
;; Andrey Halyavin, halyavin@land.ru 2005
8
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9
 
10
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
11
;; heap block structure -
12
;; you can handle several ranges of
13
;; pages simultaneosly.
14
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
15
.heap_linear_address   equ 0
16
.heap_block_size       equ 4
17
.heap_physical_address equ 8
18
.heap_reserved         equ 12
19
.heap_block_info       equ 16
20
max_heaps equ 8
21
.range_info            equ 36
22
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
23
;; memory manager data
24
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
32 halyavin 25
uglobal
26
  MEM_heap_block    rd .heap_block_info*max_heaps/4
27
  MEM_heap_count    rd 1
28
  MEM_cli_count     rd 1
29
  MEM_cli_prev      rd 1
30
  MEM_FreeSpace     rd 1
39 halyavin 31
;  MEM_AllSpace      rd 1
32 halyavin 32
endg
1 ha 33
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
34
;;MEM_Init
35
;;Initialize memory manager structures.
36
;;Must be called first.
37
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
38
MEM_Init:
39
    push  eax
40
    xor   eax,eax
41
    mov   [MEM_cli_prev],eax     ;init value = 0
42
    dec   eax
43
    mov   [MEM_cli_count],eax    ;init value = -1
44
    pop   eax
45
    ret
46
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
47
;;MEM_Heap_Lock
48
;;Wait until all operations with heap will be finished.
49
;;Between MEM_Heap_Lock and MEM_Heap_UnLock operations
50
;;with heap are forbidden.
51
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
52
MEM_Heap_Lock:
53
    pushfd
54
    cli
55
    inc   dword [MEM_cli_count]
56
    jz    MEM_Heap_First_Lock
57
    add   esp,4
58
    ret
59
MEM_Heap_First_Lock:             ;save interrupt flag
60
    shr  dword [esp],9
61
    and  dword [esp],1
62
    pop  dword [MEM_cli_prev]
63
    ret
64
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
65
;;MEM_Heap_UnLock
66
;;After this routine operations with heap are allowed.
67
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
68
MEM_Heap_UnLock:
69
    dec   dword [MEM_cli_count]
70
    js    MEM_Heap_UnLock_last
71
    ret
72
MEM_Heap_UnLock_last:
73
    cmp   dword [MEM_cli_prev],0 ;restore saved interrupt flag
74
    jz    MEM_Heap_UnLock_No_sti
75
    sti
76
MEM_Heap_UnLock_No_sti:
77
    ret
78
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
79
;;MEM_Add_Heap
80
;;Add new range to memory manager.
81
;;eax - linear address
82
;;ebx - size in pages
83
;;ecx - physical address
84
;;Result:
85
;; eax=1 - success
86
;; eax=0 - failed
87
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
88
MEM_Add_Heap:
89
    push  edx
90
    call  MEM_Heap_Lock
91
    mov   edx,[MEM_heap_count]
92
    cmp   edx,max_heaps
93
    jz    MEM_Add_Heap_Error
94
    inc   dword [MEM_heap_count]
95
    shl   edx,4
96
    mov   [MEM_heap_block+edx+.heap_linear_address],eax
97
    mov   [MEM_heap_block+edx+.heap_block_size],ebx
98
    shl   dword [MEM_heap_block+edx+.heap_block_size],12
99
    mov   [MEM_heap_block+edx+.heap_physical_address],ecx
100
    lea   edx,[4*ebx+.range_info+4095]   ;calculate space for page info table
101
    and   edx,0xFFFFF000
32 halyavin 102
 
103
    push  edi
104
    mov   edi,edx
105
    shr   edi,12
106
    sub   edi,ebx                ;edi=-free space
107
    sub   [MEM_FreeSpace],edi
39 halyavin 108
;    sub   [MEM_AllSpace],edi
32 halyavin 109
 
1 ha 110
    mov   [eax],eax
111
    add   [eax],edx              ;first 4 bytes - pointer to first free page
112
;clean page info area
113
    lea   edi,[eax+4]
114
    mov   ecx,edx
115
    shr   ecx,2
116
    push  eax
117
    xor   eax,eax
118
    rep   stosd
119
    pop   eax
120
    pop   edi
121
;create free pages list.
122
    mov   ecx,[eax]
123
    shl   ebx,12
124
    add   eax,ebx                ;eax - address after block
125
MEM_Add_Heap_loop:
126
    add   ecx,4096
127
    mov   [ecx-4096],ecx         ;set forward pointer
128
    cmp   ecx,eax
129
    jnz   MEM_Add_Heap_loop
130
    mov   dword [ecx-4096],0     ;set end of list
131
MEM_Add_Heap_ret:
132
    call  MEM_Heap_UnLock
133
    pop   edx
134
    ret
135
MEM_Add_Heap_Error:
136
    xor   eax,eax
137
    jmp   MEM_Add_Heap_ret
138
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
139
;;MEM_Get_Physical_Address
140
;;Translate linear address to physical address
141
;;Parameters:
142
;; eax - linear address
143
;;Result:
144
;; eax - physical address
145
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
146
if used MEM_Get_Physical_Address
147
MEM_Get_Physical_Address:
148
    push   ecx
149
    call   MEM_Heap_Lock
150
    mov    ecx,[MEM_heap_count]
151
    dec    ecx
152
    shl    ecx,4
153
MEM_Get_Physical_Address_loop:
154
    sub    eax,[MEM_heap_block+ecx+.heap_linear_address]
155
    jl     MEM_Get_Physical_Address_next
156
    cmp    eax,[MEM_heap_block+ecx+.heap_block_size]
157
    jge    MEM_Get_Physical_Address_next
158
    add    eax,[MEM_heap_block+ecx+.heap_physical_address]
159
    jmp    MEM_Get_Physical_Address_loopend
160
MEM_Get_Physical_Address_next:
161
    add    eax,[MEM_heap_block+ecx+.heap_linear_address]
162
    sub    ecx,16
163
    jns    MEM_Get_Physical_Address_loop
164
    xor    eax,eax               ;address not found
165
MEM_Get_Physical_Address_loopend:
166
    call   MEM_Heap_UnLock
167
    pop    ecx
168
    ret
169
end if
170
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
171
;;MEM_Get_Linear_Address
172
;;Translate physical address to linear address.
173
;;Parameters:
174
;; eax - physical address
175
;;Result:
176
;; eax - linear address
177
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
178
if used MEM_Get_Linear_Address
179
MEM_Get_Linear_Address:
180
    push   ecx
181
    call   MEM_Heap_Lock
182
    mov    ecx,[MEM_heap_count]
183
    dec    ecx
184
    shl    ecx,4
185
MEM_Get_Linear_Address_loop:
186
    sub    eax,[MEM_heap_block+ecx+.heap_physical_address]
187
    jl     MEM_Get_Linear_Address_Next
188
    cmp    eax,[MEM_heap_block+ecx+.heap_block_size]
189
    jge    MEM_Get_Linear_Address_Next
190
    add    eax,[MEM_heap_block+ecx+.heap_linear_address]
191
    call   MEM_Heap_UnLock
192
    pop    ecx
193
    ret
194
MEM_Get_Linear_Address_Next:
195
    add    eax,[MEM_heap_block+ecx+.heap_physical_address]
196
    sub    ecx,16
197
    jns    MEM_Get_Linear_Address_loop
198
    call   MEM_Heap_UnLock
199
    pop    ecx
200
    xor    eax,eax               ;address not found
201
    ret
202
end if
203
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
204
;;MEM_Alloc_Page
205
;;Allocate and add reference to page
206
;;Result:
207
;; eax<>0 - physical address of page
208
;; eax=0  - not enough memory
209
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
210
if used MEM_Alloc_Page
211
MEM_Alloc_Page:
212
    push   ecx
213
    call   MEM_Heap_Lock
214
    mov    ecx,[MEM_heap_count]
215
    dec    ecx
216
    shl    ecx,4
217
MEM_Alloc_Page_loop:
218
    push   ecx
219
    mov    ecx,[MEM_heap_block+ecx+.heap_linear_address]
220
    cmp    dword [ecx],0
221
    jz     MEM_Alloc_Page_loopend
222
    mov    eax,[ecx]
223
    push   dword [eax]
224
    pop    dword [ecx]
225
    sub    eax,ecx
226
    push   eax
227
    shr    eax,10
228
    mov    word [ecx+.range_info+eax],1
229
    pop    eax
230
    pop    ecx
231
    add    eax,[MEM_heap_block+ecx+.heap_physical_address]
32 halyavin 232
    dec    [MEM_FreeSpace]
1 ha 233
    jmp    MEM_Alloc_Page_ret
234
MEM_Alloc_Page_loopend:
235
    pop    ecx
236
    sub    ecx,16
237
    jns    MEM_Alloc_Page_loop
238
    xor    eax,eax
239
MEM_Alloc_Page_ret:
240
    call   MEM_Heap_UnLock
241
    pop    ecx
242
    ret
243
end if
244
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
245
;;MEM_Alloc_Page_Linear
246
;;Allocate and add reference to page
247
;;Result:
248
;; eax<>0 - linear address of page
249
;; eax=0  - not enough memory
250
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
251
if used MEM_Alloc_Page_Linear
252
MEM_Alloc_Page_Linear:
253
    push  ecx
254
    call  MEM_Heap_Lock
255
    mov   ecx,[MEM_heap_count]
256
    dec   ecx
257
    shl   ecx,4
258
MEM_Alloc_Page_Linear_loop:
259
    push  ecx
260
    mov   ecx,[MEM_heap_block+ecx+.heap_linear_address]
261
    cmp   dword [ecx],0
262
    jz    MEM_Alloc_Page_Linear_loopend
263
    mov   eax,[ecx]
264
    push  dword [eax]
265
    pop   dword [ecx]
266
    push  eax
267
    sub   eax,ecx
268
    shr   eax,10
269
    mov   word [ecx+.range_info+eax],1
270
    pop   eax
271
    pop   ecx
32 halyavin 272
    dec   [MEM_FreeSpace]
1 ha 273
    jmp   MEM_Alloc_Page_Linear_ret
274
MEM_Alloc_Page_Linear_loopend:
275
    pop   ecx
276
    sub   ecx,16
277
    jns   MEM_Alloc_Page_Linear_loop
278
    xor   eax,eax
279
MEM_Alloc_Page_Linear_ret:
280
    call  MEM_Heap_UnLock
281
    pop   ecx
282
    ret
283
end if
284
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
285
;;MEM_Free_Page
286
;;Remove reference and free page if number of
287
;;references is equal to 0
288
;;Parameters:
289
;;  eax - physical address of page
290
;;Result:
291
;;  eax - 1 success
292
;;  eax - 0 failed
293
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
39 halyavin 294
if (used MEM_Free_Page) | (used MEM_Free_Page_Linear)
1 ha 295
MEM_Free_Page:
296
    test  eax,eax
297
    jz    MEM_Free_Page_Zero
298
    test  eax,0xFFF
299
    jnz   MEM_Free_Page_Not_Aligned
300
    push  ebx
301
    push  ecx
302
    push  edx
303
    call  MEM_Heap_Lock
304
    mov   ecx,[MEM_heap_count]
305
    dec   ecx
306
    shl   ecx,4
307
MEM_Free_Page_Heap_loop:
308
    sub   eax,[MEM_heap_block+ecx+.heap_physical_address]
309
    js    MEM_Free_Page_Heap_loopnext
310
    cmp   eax,[MEM_heap_block+ecx+.heap_block_size]
311
    jl    MEM_Free_Page_Heap_loopend
312
MEM_Free_Page_Heap_loopnext:
313
    add   eax,[MEM_heap_block+ecx+.heap_physical_address]
314
    sub   ecx,16
315
    jns   MEM_Free_Page_Heap_loop
316
    xor   eax,eax
317
    inc   eax
318
    jmp   MEM_Free_Page_ret
319
MEM_Free_Page_Heap_loopend:
320
    mov   ecx,[MEM_heap_block+ecx+.heap_linear_address]
321
    mov   ebx,eax
322
    add   eax,ecx
323
    shr   ebx,10
324
    mov   edx,[ecx+.range_info+ebx]
325
    test  edx,0x80000000
326
    jnz   MEM_Free_Page_Bucket
327
    test  dx,dx
328
    jz    MEM_Free_Page_Error
329
    dec   word [ecx+.range_info+ebx]
330
    jnz   MEM_Free_Page_OK
331
MEM_Free_Page_Bucket:
332
    push  dword [ecx]
333
    mov   [ecx],eax
334
    pop   dword [eax]
335
    mov   dword [ecx+.range_info+ebx],0
32 halyavin 336
    inc   [MEM_FreeSpace]
1 ha 337
MEM_Free_Page_OK:
338
    mov   eax,1
339
MEM_Free_Page_ret:
340
    call  MEM_Heap_UnLock
341
    pop   edx
342
    pop   ecx
343
    pop   ebx
344
    ret
345
MEM_Free_Page_Error:
346
    xor   eax,eax
347
    jmp   MEM_Free_Page_ret
348
MEM_Free_Page_Zero:
349
    inc   eax
350
    ret
351
MEM_Free_Page_Not_Aligned:
352
    xor   eax,eax
353
    ret
354
end if
355
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
356
;;MEM_Free_Page_Linear
357
;;Remove reference and free page if number of
358
;;references is equal to 0
359
;;Parameters:
360
;;  eax - linear address of page
361
;;Result:
362
;;  eax - 1 success
363
;;  eax - 0 failed
364
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
365
if used MEM_Free_Page_Linear
366
MEM_Free_Page_Linear:
367
    test  eax,eax
39 halyavin 368
    jz    MEM_Free_Page_Zero
1 ha 369
    test  eax,0xFFF
39 halyavin 370
    jnz   MEM_Free_Page_Not_Aligned
1 ha 371
    push  ebx
372
    push  ecx
373
    push  edx
374
    call  MEM_Heap_Lock
375
    mov   ecx,[MEM_heap_count]
376
    dec   ecx
377
    shl   ecx,4
378
 
379
MEM_Free_Page_Linear_Heap_loop:
380
    sub   eax,[MEM_heap_block+ecx+.heap_linear_address]
381
    js    MEM_Free_Page_Linear_Heap_loopnext
382
    cmp   eax,[MEM_heap_block+ecx+.heap_block_size]
39 halyavin 383
    jl    MEM_Free_Page_Heap_loopend
1 ha 384
MEM_Free_Page_Linear_Heap_loopnext:
385
    add   eax,[MEM_heap_block+ecx+.heap_linear_address]
386
    sub   ecx,16
387
    jns   MEM_Free_Page_Linear_Heap_loop
388
    xor   eax,eax
389
    inc   eax
39 halyavin 390
    jmp   MEM_Free_Page_ret
1 ha 391
end if
392
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
393
;;MEM_Alloc_Pages
394
;;Allocates set of pages.
395
;;Parameters:
396
;; eax - number of pages
397
;; ebx - buffer for physical addresses
398
;;Result:
399
;; eax - number of allocated pages
400
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
401
if used MEM_Alloc_Pages
402
MEM_Alloc_Pages:
403
    push  eax
404
    push  ebx
405
    push  ecx
406
    mov   ecx,eax
407
    test  ecx,ecx
408
    jz    MEM_Alloc_Pages_ret
409
MEM_Alloc_Pages_loop:
410
    call  MEM_Alloc_Page
411
    test  eax,eax
412
    jz    MEM_Alloc_Pages_ret
413
    mov   [ebx],eax
414
    add   ebx,4
415
    dec   ecx
416
    jnz   MEM_Alloc_Pages_loop
417
MEM_Alloc_Pages_ret:
418
    sub   [esp+8],ecx
419
    pop   ecx
420
    pop   ebx
421
    pop   eax
422
    ret
423
end if
424
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
425
;;MEM_Alloc_Pages_Linear
426
;;Allocates set of pages.
427
;;Parameters:
428
;; eax - number of pages
429
;; ebx - buffer for linear addresses
430
;;Result:
431
;; eax - number of allocated pages
432
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
433
if used MEM_Alloc_Pages_Linear
434
MEM_Alloc_Pages_Linear:
435
    push  eax
436
    push  ebx
437
    push  ecx
438
    mov   ecx,eax
439
    test  ecx,ecx
440
    jz    MEM_Alloc_Pages_Linear_ret
441
MEM_Alloc_Pages_Linear_loop:
442
    call  MEM_Alloc_Page_Linear
443
    test  eax,eax
444
    jz    MEM_Alloc_Pages_Linear_ret
445
    mov   [ebx],eax
446
    add   ebx,4
447
    dec   ecx
448
    jnz   MEM_Alloc_Pages_Linear_loop
449
MEM_Alloc_Pages_Linear_ret:
450
    sub   [esp+8],ecx
451
    pop   ecx
452
    pop   ebx
453
    pop   eax
454
    ret
455
end if
456
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
457
;;MEM_Free_Pages
458
;;Parameters:
459
;; eax - number of pages
460
;; ebx - array of addresses
461
;;Result:
462
;; eax=1 - succcess
463
;; eax=0 - failed
464
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
465
if used MEM_Free_Pages
466
MEM_Free_Pages:
467
    push  ebx
468
    push  ecx
469
    mov   ecx,eax
470
    test  ecx,ecx
471
    jz    MEM_Free_Pages_ret
472
MEM_Free_Pages_loop:
473
    mov   eax,[ebx]
474
    call  MEM_Free_Page
475
    add   ebx,4
476
    test  eax,eax
477
    jz    MEM_Free_Pages_ret
478
    dec   ecx
479
    jnz   MEM_Free_Pages_loop
480
MEM_Free_Pages_ret:
481
    pop   ecx
482
    pop   ebx
483
    ret
484
end if
485
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
486
;;MEM_Free_Pages_Linear
487
;;Parameters:
488
;; eax - number of pages
489
;; ebx - array of addresses
490
;;Result:
491
;; eax=1 - succcess
492
;; eax=0 - failed
493
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
494
if used MEM_Free_Pages_Linear
495
MEM_Free_Pages_Linear:
496
    push  ebx
497
    push  ecx
498
    mov   ecx,eax
499
    test  ecx,ecx
500
    jz    MEM_Free_Pages_Linear_ret
501
MEM_Free_Pages_Linear_loop:
502
    mov   eax,[ebx]
503
    call  MEM_Free_Page_Linear
504
    add   ebx,4
505
    test  eax,eax
506
    jz    MEM_Free_Pages_Linear_ret
507
    dec   ecx
508
    jnz   MEM_Free_Pages_Linear_loop
509
MEM_Free_Pages_Linear_ret:
510
    pop   ecx
511
    pop   ebx
512
    ret
513
end if
514
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
515
;;MEM_Get_Heap_Number
516
;;Calculate number of heap which pointer belongs to.
517
;;Parameter:
518
;; eax - address
519
;;Result:
520
;; ecx - number of heap*16.
521
;; eax=0 if address not found.
522
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
523
if used MEM_Get_Heap_Number
524
MEM_Get_Heap_Number:
525
    call  MEM_Heap_Lock
526
    mov   ecx,[MEM_heap_count]
527
    dec   ecx
528
    shl   ecx,4
529
MEM_Get_Heap_loop:
530
    sub   eax,[MEM_heap_block+ecx+.heap_physical_address]
531
    jl    MEM_Get_Heap_loopnext
532
    cmp   eax,[MEM_heap_block+ecx+.heap_block_size]
533
    jl    MEM_Get_Heap_loopend
534
MEM_Get_Heap_loopnext:
535
    add   eax,[MEM_heap_block+ecx+.heap_physical_address]
536
    sub   ecx,16
537
    jns   MEM_Get_Heap_loop
538
    call  MEM_Heap_UnLock
539
    xor   eax,eax
540
    ret
541
MEM_Get_Heap_loopend:
542
    add   eax,[MEM_heap_block+ecx+.heap_physical_address]
543
    call  MEM_Heap_UnLock
544
    ret
545
end if
546
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
547
;;MEM_Get_Heap_Number_Linear
548
;;Calculate number of heap which pointer belongs to.
549
;;Parameter:
550
;; eax - address
551
;;Result:
552
;; ecx - number of heap*16.
553
;; eax=0 if address not found.
554
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
555
if used MEM_Get_Heap_Number_Linear
556
MEM_Get_Heap_Number_Linear:
557
    call  MEM_Heap_Lock
558
    mov   ecx,[MEM_heap_count]
559
    dec   ecx
560
    shl   ecx,4
561
MEM_Get_Heap_Linear_loop:
562
    sub   eax,[MEM_heap_block+ecx+.heap_linear_address]
563
    jl    MEM_Get_Heap_Linear_loopnext
564
    cmp   eax,[MEM_heap_block+ecx+.heap_block_size]
565
    jl    MEM_Get_Heap_Linear_loopend
566
MEM_Get_Heap_Linear_loopnext:
567
    add   eax,[MEM_heap_block+ecx+.heap_linear_address]
568
    sub   ecx,16
569
    jns   MEM_Get_Heap_Linear_loop
570
    call  MEM_Heap_UnLock
571
    xor   eax,eax
572
    ret
573
MEM_Get_Heap_Linear_loopend:
574
    add   eax,[MEM_heap_block+ecx+.heap_linear_address]
575
    call  MEM_Heap_UnLock
576
    ret
577
end if
578
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
579
;;MEM_Alloc
580
;;Allocate small region.
581
;;Parameters:
582
;; eax - size (0
583
;;Result:
584
;; eax - linear address
585
;; eax=0 - not enough memory
586
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
587
if used MEM_Alloc
588
MEM_Alloc:
589
;find chain
590
    test  eax,eax
591
    jng   MEM_Alloc_Wrong_Size
592
    cmp   eax,4096
593
    jg    MEM_Alloc_Wrong_Size
594
    push  ebx
595
    push  ecx
596
    push  edx
597
    push  esi
598
    dec   eax
599
    shr   eax,4
600
    xor   edx,edx
601
MEM_Alloc_Find_Size:
602
    add   edx,4
603
    shr   eax,1
604
    jnz   MEM_Alloc_Find_Size
605
MEM_Alloc_Size_Found:
606
    mov   ecx,edx
607
    shr   ecx,2
608
    add   ecx,4
609
    mov   eax,1
610
    shl   eax,cl
611
    mov   esi,eax
612
;esi - block size
613
;edx - offset
614
    call  MEM_Heap_Lock
615
    mov   ecx,[MEM_heap_count]
616
    dec   ecx
617
    shl   ecx,4
618
MEM_Alloc_Find_Heap:
619
    mov   eax,[MEM_heap_block+ecx+.heap_linear_address]
620
    cmp   dword [eax+edx],0
621
    jnz   MEM_Alloc_Use_Existing
622
    sub   ecx,16
623
    jns   MEM_Alloc_Find_Heap
624
;create new bucket page
625
    call  MEM_Alloc_Page_Linear
626
    call  MEM_Get_Heap_Number_Linear
627
    mov   ecx,[MEM_heap_block+ecx+.heap_linear_address]
628
    mov   [ecx+edx],eax
629
    lea   ebx,[eax+4096]
630
MEM_Alloc_List_loop:
631
    mov   [eax],eax
632
    mov   [eax+4],eax
633
    add   [eax],esi
634
    sub   [eax+4],esi
635
    add   eax,esi
636
    cmp   eax,ebx
637
    jnz   MEM_Alloc_List_loop
638
    sub   ebx,esi
639
    mov   dword [ebx],0
640
    sub   eax,4096
641
    mov   dword [eax+4],0
642
    mov   eax,ecx
643
 
644
MEM_Alloc_Use_Existing:
645
    mov   ebx,eax
646
    mov   eax,[eax+edx]
647
    mov   ecx,[eax]
648
    mov   [ebx+edx],ecx
649
    test  ecx,ecx
650
    jz    MEM_Alloc_Became_Empty
651
    mov   dword [ecx+4],0
652
MEM_Alloc_Became_Empty:
653
    mov   ecx,eax
654
    sub   ecx,ebx
655
    shr   ecx,10
656
    and   ecx,0xFFFFFFFC
657
    inc   byte [ebx+.range_info+ecx+2]
658
    shr   edx,2
659
    add   edx,128
660
    dec   edx
661
    mov   [ebx+.range_info+ecx+3],dl
662
 
663
MEM_Alloc_ret:
664
    call  MEM_Heap_UnLock
665
    pop   esi
666
    pop   edx
667
    pop   ecx
668
    pop   ebx
669
    ret
670
MEM_Alloc_Wrong_Size:
671
    xor   eax,eax
672
    ret
673
end if
674
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
675
;;MEM_Free
676
;;Parameters:
677
;; eax - linear address
678
;;Result:
679
;; eax=1 - success
680
;; eax=0 - failed
681
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
682
if used MEM_Free
683
MEM_Free:
684
    test  eax,eax
685
    jz    MEM_Free_Zero
686
    push  ebx
687
    push  ecx
688
    push  edx
689
    push  esi
690
    push  edi
691
    push  ebp
692
    call  MEM_Heap_Lock
693
    call  MEM_Get_Heap_Number_Linear
694
    test  eax,eax
695
    jz    MEM_Free_ret
696
    mov   edx,eax
697
    mov   ecx,[MEM_heap_block+ecx+.heap_linear_address]
698
    sub   edx,ecx
699
    shr   edx,10
700
    and   edx,0xFFFFFFFC
701
    mov   ebx,[ecx+.range_info+edx]
702
    mov   esi,ebx
703
    shr   esi,24
704
    sub   esi,128
705
    mov   edi,[ecx+4+4*esi]
706
    mov   [eax],edi
707
    mov   dword [eax+4],0
708
    test  edi,edi
709
    jz    MEM_Free_Empty_List
710
    mov   [edi+4],eax
711
MEM_Free_Empty_List:
712
    mov   [ecx+4+4*esi],eax
713
    sub   ebx,0x10000
714
    mov   [ecx+.range_info+edx],ebx
715
    test  ebx,0xFF0000
716
    jnz   MEM_Free_ret
717
;delete empty blocks on the page
718
    lea   edx,[esi+5]
719
    and   eax,0xFFFFF000
720
    mov   edi,eax
721
    mov   eax,1
722
    xchg  ecx,edx
723
    shl   eax,cl
724
    mov   ecx,edx
725
    mov   edx,eax
726
;edx - size of block
727
;edi - start of page
728
    mov   eax,edi
729
    lea   ebx,[eax+4096]
730
MEM_Free_Block_loop:
731
    cmp   dword [eax+4],0
732
    jnz   MEM_Free_Block_Not_First
733
    mov   ebp,dword [eax]
734
    mov   [ecx+4+4*esi],ebp
735
    test  ebp,ebp
736
    jz    MEM_Free_Block_Last
737
    mov   dword [ebp+4],0
738
MEM_Free_Block_Last:
739
    jmp   MEM_Free_Block_loop_end
740
MEM_Free_Block_Not_First:
741
    mov   ebp,dword [eax]
742
    push  ebp
743
    mov   ebp,dword [eax+4]
744
    pop   dword [ebp]
745
    mov   ebp,dword [eax]
746
    test  ebp,ebp
747
    jz    MEM_Free_Block_loop_end
748
    push  dword [eax+4]
749
    pop   dword [ebp+4]
750
;    jmp   MEM_Free_Block_loop_end
751
MEM_Free_Block_loop_end:
752
    add   eax,edx
753
    cmp   eax,ebx
754
    jnz   MEM_Free_Block_loop
755
    mov   eax,edi
756
    call  MEM_Free_Page_Linear
757
MEM_Free_ret:
758
    call  MEM_Heap_UnLock
759
    pop   ebp
760
    pop   edi
761
    pop   esi
762
    pop   edx
763
    pop   ecx
764
    pop   ebx
765
    ret
766
MEM_Free_Zero:
767
    inc   eax
768
    ret
769
end if
770
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
771
;;MEM_Add_Reference
772
;; eax - physical address of page
773
;;Result:
774
;; eax=1 - success
775
;; eax=0 - failed
776
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
777
if used MEM_Add_Reference
778
MEM_Add_Reference:
779
    push  ebx
780
    push  ecx
781
    call  MEM_Heap_Lock
782
    call  MEM_Get_Heap_Number
783
    test  eax,eax
784
    jz    MEM_Add_Reference_ret
785
    sub   eax,[MEM_heap_block+ecx+.heap_physical_address]
786
    mov   ecx,[MEM_heap_block+ecx+.heap_linear_address]
787
    shr   eax,10
788
    and   eax,0xFFFFFFFC
789
    test  dword [ecx+eax+.range_info],0x80000000
790
    jnz   MEM_Add_Reference_failed
791
    inc   dword [ecx+eax+.range_info]
792
MEM_Add_Reference_ret:
793
    call  MEM_Heap_UnLock
794
    pop   ecx
795
    pop   ebx
796
    ret
797
MEM_Add_Reference_failed:
798
    xor   eax,eax
799
    jmp   MEM_Add_Reference_ret
800
end if
801
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
802
;;MEM_Add_Reference_Linear
803
;; eax - linear address of page
804
;;Result:
805
;; eax=1 - success
806
;; eax=0 - failed
807
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
808
if used MEM_Add_Reference_Linear
809
MEM_Add_Reference_Linear:
810
    push  ebx
811
    push  ecx
812
    call  MEM_Heap_Lock
813
    call  MEM_Get_Heap_Number_Linear
814
    test  eax,eax
815
    jz    MEM_Add_Reference_Linear_ret
816
    mov   ecx,[MEM_heap_block+ecx+.heap_linear_address]
817
    sub   eax,ecx
818
    shr   eax,10
819
    and   eax,0xFFFFFFFC
820
    test  dword [ecx+eax+.range_info],0x80000000
821
    jnz   MEM_Add_Reference_Linear_failed
822
    inc   dword [ecx+eax+.range_info]
823
    mov   eax,1
824
MEM_Add_Reference_Linear_ret:
825
    call  MEM_Heap_UnLock
826
    pop   ecx
827
    pop   ebx
828
    ret
829
MEM_Add_Reference_Linear_failed:
830
    xor   eax,eax
831
    jmp   MEM_Add_Reference_Linear_ret
832
end if
833
end if ;memmanager.inc