38,507 → 38,11 |
block_size equ MEM_BLOCK.size |
block_flags equ MEM_BLOCK.flags |
|
macro calc_index op |
{ shr op, 12 |
dec op |
cmp op, 63 |
jna @f |
mov op, 63 |
@@: |
} |
|
macro remove_from_list op |
{ mov edx, [op+list_fd] |
mov ecx, [op+list_bk] |
test edx, edx |
jz @f |
mov [edx+list_bk], ecx |
@@: |
test ecx, ecx |
jz @f |
mov [ecx+list_fd], edx |
@@: |
mov [op+list_fd],0 |
mov [op+list_bk],0 |
} |
|
macro remove_from_free op |
{ |
remove_from_list op |
|
mov eax, [op+block_size] |
calc_index eax |
cmp [mem_block_list+eax*4], op |
jne @f |
mov [mem_block_list+eax*4], edx |
@@: |
cmp [mem_block_list+eax*4], 0 |
jne @f |
btr [mem_block_mask], eax |
@@: |
} |
|
macro remove_from_used op |
{ |
mov edx, [op+list_fd] |
mov ecx, [op+list_bk] |
mov [edx+list_bk], ecx |
mov [ecx+list_fd], edx |
mov [op+list_fd], 0 |
mov [op+list_bk], 0 |
} |
|
align 4 |
init_kernel_heap: |
|
mov ecx, 64/4 |
mov edi, mem_block_list |
xor eax, eax |
cld |
rep stosd |
|
mov ecx, 512/4 |
mov edi, mem_block_map |
not eax |
rep stosd |
|
mov ecx, 128*1024 |
fastcall _balloc |
|
mov [mem_block_start], mem_block_map |
mov [mem_block_end], mem_block_map+512 |
mov [mem_block_arr], eax |
|
mov ebx, mem_used.fd-MEM_LIST_OFFSET |
mov [mem_used.fd], ebx |
mov [mem_used.bk], ebx |
|
xor edx, edx |
|
mov [eax+block_next], edx |
mov [eax+block_prev], edx |
mov [eax+list_fd], edx |
mov [eax+list_bk], edx |
mov [eax+block_base], HEAP_BASE |
mov [eax+block_size], page_tabs-HEAP_BASE |
mov [eax+block_flags], FREE_BLOCK |
|
mov [heap_size], page_tabs-HEAP_BASE |
mov [heap_free], page_tabs-HEAP_BASE |
|
mov [mem_block_mask], edx |
mov [mem_block_mask+4],0x80000000 |
|
mov [mem_block_list+63*4], eax |
mov byte [mem_block_map], 0xFE |
and [heap_mutex], 0 |
mov [heap_blocks], 4096 |
mov [free_blocks], 4096 |
ret |
|
; param |
; eax= required size |
; |
; retval |
; edi= memory block descriptor |
; ebx= descriptor index |
|
align 4 |
get_small_block: |
mov ecx, eax |
shr ecx, 12 |
dec ecx |
cmp ecx, 63 |
jle .get_index |
mov ecx, 63 |
.get_index: |
lea esi, [mem_block_mask] |
xor ebx, ebx |
or edx, -1 |
|
cmp ecx, 32 |
jb .bit_test |
|
sub ecx, 32 |
add ebx, 32 |
add esi, 4 |
.bit_test: |
shl edx, cl |
and edx, [esi] |
.find: |
bsf edi, edx |
jz .high_mask |
add ebx, edi |
mov edi, [mem_block_list+ebx*4] |
.check_size: |
cmp eax, [edi+block_size] |
ja .next |
ret |
|
.high_mask: |
add esi, 4 |
cmp esi, mem_block_mask+8 |
jae .err |
add ebx, 32 |
mov edx, [esi] |
jmp .find |
.next: |
mov edi, [edi+list_fd] |
test edi, edi |
jnz .check_size |
.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: |
|
mov ebx, [mem_block_start] |
mov ecx, [mem_block_end] |
.l1: |
bsf eax,[ebx]; |
jnz found |
add ebx,4 |
cmp ebx, ecx |
jb .l1 |
xor eax,eax |
ret |
|
found: |
btr [ebx], eax |
mov [mem_block_start],ebx |
sub ebx, mem_block_map |
lea eax,[eax+ebx*8] |
shl eax, 5 |
add eax, [mem_block_arr] |
dec [free_blocks] |
ret |
align 4 |
free_mem_block: |
mov dword [eax], 0 |
mov dword [eax+4], 0 |
mov dword [eax+8], 0 |
mov dword [eax+12], 0 |
mov dword [eax+16], 0 |
; mov dword [eax+20], 0 |
mov dword [eax+24], 0 |
mov dword [eax+28], 0 |
|
sub eax, [mem_block_arr] |
shr eax, 5 |
|
mov ebx, mem_block_map |
bts [ebx], eax |
inc [free_blocks] |
shr eax, 3 |
and eax, not 3 |
add eax, ebx |
cmp [mem_block_start], eax |
ja @f |
ret |
@@: |
mov [mem_block_start], eax |
ret |
.err: |
xor eax, eax |
ret |
|
align 4 |
proc alloc_kernel_space stdcall, size:dword |
local block_ind:DWORD |
|
push ebx |
push esi |
push edi |
|
mov eax, [size] |
add eax, 4095 |
and eax, not 4095 |
mov [size], eax |
|
mov ebx, heap_mutex |
call wait_mutex ;ebx |
|
cmp eax, [heap_free] |
ja .error |
|
call get_small_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 |
test 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, 12 |
sub eax, 1 |
cmp eax, 63 |
jna @f |
mov eax, 63 |
@@: |
cmp eax, [block_ind] |
je .m_eq_ind |
|
remove_from_list edi |
|
mov ecx, [block_ind] |
mov [mem_block_list+ecx*4], edx |
|
test edx, edx |
jnz @f |
btr [mem_block_mask], ecx |
@@: |
mov edx, [mem_block_list+eax*4] |
mov [edi+list_fd], edx |
test edx, edx |
jz @f |
mov [edx+list_bk], edi |
@@: |
mov [mem_block_list+eax*4], edi |
bts [mem_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 [mem_block_list+ebx*4], edx |
and edx, edx |
jnz @f |
btr [mem_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 |
|
align 4 |
proc free_kernel_space stdcall uses ebx ecx edx esi edi, base:dword |
push ebx |
push esi |
push edi |
mov ebx, heap_mutex |
call wait_mutex ;ebx |
|
mov eax, [base] |
mov esi, [mem_used.fd] |
@@: |
cmp esi, mem_used.fd-MEM_LIST_OFFSET |
je .fail |
|
cmp [esi+block_base], eax |
je .found |
mov esi, [esi+list_fd] |
jmp @b |
.found: |
cmp [esi+block_flags], USED_BLOCK |
jne .fail |
|
mov eax, [esi+block_size] |
add [heap_free], eax |
|
mov edi, [esi+block_next] |
test edi, edi |
jz .prev |
|
cmp [edi+block_flags], FREE_BLOCK |
jne .prev |
|
remove_from_free edi |
|
mov edx, [edi+block_next] |
mov [esi+block_next], edx |
test edx, edx |
jz @f |
|
mov [edx+block_prev], esi |
@@: |
mov ecx, [edi+block_size] |
add [esi+block_size], ecx |
|
mov eax, edi |
call free_mem_block |
.prev: |
mov edi, [esi+block_prev] |
test edi, edi |
jz .insert |
|
cmp [edi+block_flags], FREE_BLOCK |
jne .insert |
|
remove_from_used esi |
|
mov edx, [esi+block_next] |
mov [edi+block_next], edx |
test edx, edx |
jz @f |
mov [edx+block_prev], edi |
@@: |
mov eax, esi |
call free_mem_block |
|
mov ecx, [edi+block_size] |
mov eax, [esi+block_size] |
add eax, ecx |
mov [edi+block_size], eax |
|
calc_index eax |
calc_index ecx |
cmp eax, ecx |
je .m_eq |
|
push ecx |
remove_from_list edi |
pop ecx |
|
cmp [mem_block_list+ecx*4], edi |
jne @f |
mov [mem_block_list+ecx*4], edx |
@@: |
cmp [mem_block_list+ecx*4], 0 |
jne @f |
btr [mem_block_mask], ecx |
@@: |
mov esi, [mem_block_list+eax*4] |
mov [mem_block_list+eax*4], edi |
mov [edi+list_fd], esi |
test esi, esi |
jz @f |
mov [esi+list_bk], edi |
@@: |
bts [mem_block_mask], eax |
.m_eq: |
xor eax, eax |
mov [heap_mutex], eax |
dec eax |
pop edi |
pop esi |
pop ebx |
ret |
.insert: |
remove_from_used esi |
|
mov eax, [esi+block_size] |
calc_index eax |
|
mov edi, [mem_block_list+eax*4] |
mov [mem_block_list+eax*4], esi |
mov [esi+list_fd], edi |
test edi, edi |
jz @f |
mov [edi+list_bk], esi |
@@: |
bts [mem_block_mask], eax |
mov [esi+block_flags],FREE_BLOCK |
xor eax, eax |
mov [heap_mutex], eax |
dec eax |
pop edi |
pop esi |
pop ebx |
ret |
.fail: |
xor eax, eax |
mov [heap_mutex], eax |
pop edi |
pop esi |
pop ebx |
ret |
endp |
|
align 4 |
555,8 → 59,9 |
add eax, 4095 |
and eax, not 4095; |
mov [size], eax |
and eax, eax |
test eax, eax |
jz .err |
|
mov ebx, eax |
shr ebx, 12 |
mov [pages_count], ebx |
617,173 → 122,12 |
|
align 4 |
proc kernel_free stdcall, base:dword |
push ebx esi |
|
mov ebx, heap_mutex |
call wait_mutex ;ebx |
|
mov eax, [base] |
mov esi, [mem_used.fd] |
@@: |
cmp esi, mem_used.fd-MEM_LIST_OFFSET |
je .fail |
|
cmp [esi+block_base], eax |
je .found |
mov esi, [esi+list_fd] |
jmp @b |
.found: |
cmp [esi+block_flags], USED_BLOCK |
jne .fail |
|
and [heap_mutex], 0 |
|
push ecx |
mov ecx, [esi+block_size]; |
shr ecx, 12 |
call release_pages ;eax, ecx |
pop ecx |
stdcall free_kernel_space, [base] |
pop esi ebx |
ret |
.fail: |
and [heap_mutex], 0 |
pop esi ebx |
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 |