209,6 → 209,39 |
.err: |
xor edi, edi |
ret |
; param |
; eax= required size |
; |
; retval |
; edi= memory block descriptor |
; ebx= descriptor index |
align 4 |
get_large_block: |
mov edx, -1 |
mov ecx, eax |
shr ecx, 22 |
dec ecx |
cmp ecx, 31 |
jle .get_index |
mov ecx, 31 |
.get_index: |
shl edx, cl |
and edx, [large_block_mask] |
.find: |
bsf edi, edx |
mov ebx, edi |
mov edi, [large_block_list+edi*4] |
.check_size: |
cmp eax, [edi+block_size] |
ja .next |
ret |
.next: |
mov edi, [edi+list_fd] |
test edi, edi |
jnz .check_size |
.fail: |
xor edi, edi |
ret |
|
align 4 |
alloc_mem_block: |
639,6 → 672,138 |
ret |
endp |
|
|
align 4 |
proc alloc_large stdcall, size:dword |
local block_ind:DWORD |
|
push ebx |
push esi |
push edi |
|
mov eax, [size] |
add eax, 0x3FFFFF |
and eax, not 0x3FFFFF |
mov [size], eax |
|
; mov ebx, heap_mutex |
; call wait_mutex ;ebx |
|
; cmp eax, [heap_free] |
; ja .error |
|
call get_large_block ; eax |
test edi, edi |
jz .error |
|
cmp [edi+block_flags], FREE_BLOCK |
jne .error |
|
mov [block_ind], ebx ;index of allocated block |
|
mov eax, [edi+block_size] |
cmp eax, [size] |
je .m_eq_size |
|
call alloc_mem_block |
and eax, eax |
jz .error |
|
mov esi, eax ;esi - splitted block |
|
mov [esi+block_next], edi |
mov eax, [edi+block_prev] |
mov [esi+block_prev], eax |
mov [edi+block_prev], esi |
mov [esi+list_fd], 0 |
mov [esi+list_bk], 0 |
test eax, eax |
jz @f |
mov [eax+block_next], esi |
@@: |
mov ebx, [edi+block_base] |
mov [esi+block_base], ebx |
mov edx, [size] |
mov [esi+block_size], edx |
add [edi+block_base], edx |
sub [edi+block_size], edx |
|
mov eax, [edi+block_size] |
shr eax, 22 |
dec eax |
cmp eax, 31 |
jna @f |
mov eax, 31 |
@@: |
cmp eax, [block_ind] |
je .m_eq_ind |
|
remove_from_list edi |
|
mov ecx, [block_ind] |
mov [large_block_list+ecx*4], edx |
|
test edx, edx |
jnz @f |
btr [large_block_mask], ecx |
@@: |
mov edx, [large_block_list+eax*4] |
mov [edi+list_fd], edx |
test edx, edx |
jz @f |
mov [edx+list_bk], edi |
@@: |
mov [large_block_list+eax*4], edi |
bts [large_block_mask], eax |
.m_eq_ind: |
mov ecx, mem_used.fd-MEM_LIST_OFFSET |
mov edx, [ecx+list_fd] |
mov [esi+list_fd], edx |
mov [esi+list_bk], ecx |
mov [ecx+list_fd], esi |
mov [edx+list_bk], esi |
|
mov [esi+block_flags], USED_BLOCK |
mov eax, [esi+block_base] |
mov ebx, [size] |
sub [heap_free], ebx |
and [heap_mutex], 0 |
pop edi |
pop esi |
pop ebx |
ret |
.m_eq_size: |
remove_from_list edi |
mov [large_block_list+ebx*4], edx |
and edx, edx |
jnz @f |
btr [large_block_mask], ebx |
@@: |
mov ecx, mem_used.fd-MEM_LIST_OFFSET |
mov edx, [ecx+list_fd] |
mov [edi+list_fd], edx |
mov [edi+list_bk], ecx |
mov [ecx+list_fd], edi |
mov [edx+list_bk], edi |
|
mov [edi+block_flags], USED_BLOCK |
mov eax, [edi+block_base] |
mov ebx, [size] |
sub [heap_free], ebx |
and [heap_mutex], 0 |
pop edi |
pop esi |
pop ebx |
ret |
.error: |
xor eax, eax |
mov [heap_mutex], eax |
pop edi |
pop esi |
pop ebx |
ret |
endp |
|
restore block_next |
restore block_prev |
restore block_list |