Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 9047 → Rev 9048

/kernel/branches/kolibrios-pe-clevermouse/core/heap.inc
23,8 → 23,13
MEM_BLOCK_USED = 0x08
MEM_BLOCK_DONT_FREE = 0x10
 
LAZY_ALLOC_PAGE = 2
LAZY_ALLOC_UNREADABLE = 20h
LAZY_ALLOC_UNWRITABLE = 40h
 
macro calc_index op
{ shr op, 12
{
shr op, 12
dec op
cmp op, 63
jna @f
561,35 → 566,42
sub eax, PAGE_SIZE
ret
@@:
lea ecx, [ebx + PROC.heap_lock]
call mutex_init
 
mov esi, [ebx + PROC.mem_used]
add esi, 4095
and esi, not 4095
mov [ebx + PROC.mem_used], esi
mov edx, [ebx+PROC.mem_used]
add edx, 4095
and edx, not 4095
mov [ebx+PROC.mem_used], edx
mov eax, HEAP_TOP
mov [ebx + PROC.heap_base], esi
mov [ebx+PROC.heap_base], edx
mov [ebx + PROC.heap_top], eax
 
sub eax, esi
shr esi, 10
sub eax, edx
shr edx, 10
mov ecx, eax
sub eax, PAGE_SIZE
or ecx, MEM_BLOCK_FREE
mov [page_tabs + esi], ecx
mov [page_tabs + edx], ecx
ret
endp
 
align 4
proc user_alloc stdcall, alloc_size:dword
proc user_alloc ;stdcall, alloc_size:dword
mov ecx, [current_process]
add ecx, PROC.heap_lock
call mutex_lock
stdcall user_alloc_nolock, [esp+4]
push eax
mov ecx, [current_process]
add ecx, PROC.heap_lock
call mutex_unlock
pop eax
ret 4
endp
 
proc user_alloc_nolock stdcall, alloc_size:dword
push ebx esi edi
 
mov ebx, [current_process]
lea ecx, [ebx + PROC.heap_lock]
call mutex_lock
 
mov ecx, [alloc_size]
add ecx, (4095 + PAGE_SIZE)
and ecx, not 4095
628,15 → 640,6
jnz @B
.no:
 
mov edx, [current_process]
mov ebx, [alloc_size]
add ebx, 0xFFF
and ebx, not 0xFFF
add [edx + PROC.mem_used], ebx
 
lea ecx, [edx + PROC.heap_lock]
call mutex_unlock
 
lea eax, [esi + 4096]
 
pop edi
652,9 → 655,6
add esi, eax
jmp .scan
.m_exit:
mov ecx, [current_process]
lea ecx, [ecx + PROC.heap_lock]
call mutex_unlock
 
xor eax, eax
pop edi
664,15 → 664,25
endp
 
align 4
proc user_alloc_at stdcall, address:dword, alloc_size:dword
proc user_alloc_at ;stdcall, address:dword, alloc_size:dword
mov ecx, [current_process]
add ecx, PROC.heap_lock
call mutex_lock
stdcall user_alloc_at_nolock, [esp+8], [esp+8]
push eax
mov ecx, [current_process]
add ecx, PROC.heap_lock
call mutex_unlock
pop eax
ret 8
endp
 
proc user_alloc_at_nolock stdcall, address:dword, alloc_size:dword
push ebx
push esi
push edi
 
mov ebx, [current_process]
lea ecx, [ebx + PROC.heap_lock]
call mutex_lock
 
mov edx, [address]
and edx, not 0xFFF
697,9 → 707,6
mov esi, ecx
jmp .scan
.error:
mov ecx, [current_process]
lea ecx, [ecx + PROC.heap_lock]
call mutex_unlock
 
xor eax, eax
pop edi
752,15 → 759,6
mov [page_tabs + ebx*4], ecx
 
.nothird:
mov edx, [current_process]
mov ebx, [alloc_size]
add ebx, 0xFFF
and ebx, not 0xFFF
add [edx + PROC.mem_used], ebx
 
lea ecx, [edx + PROC.heap_lock]
call mutex_unlock
 
mov eax, [address]
 
pop edi
775,8 → 773,6
push esi
 
mov esi, [base]
test esi, esi
jz .fail
 
push ebx
 
786,6 → 782,7
 
xor ebx, ebx
shr esi, 12
jz .cantfree
mov eax, [page_tabs + (esi-1)*4]
test al, MEM_BLOCK_USED
jz .cantfree
792,6 → 789,11
test al, MEM_BLOCK_DONT_FREE
jnz .cantfree
 
push 0
virtual at esp
.num_released_pages dd ?
end virtual
 
and eax, not 4095
mov ecx, eax
or al, MEM_BLOCK_FREE
801,16 → 803,18
shr ecx, 12
jz .released
.release:
xor eax, eax
xchg eax, [page_tabs + esi*4]
test al, 1
jz @F
test eax, PG_SHARED
jnz @F
call free_page
mov edx, [page_tabs+esi*4]
mov dword [page_tabs+esi*4], 0
mov eax, esi
shl eax, 12
invlpg [eax]
test dl, 1
jz @F
inc [.num_released_pages]
test edx, PG_SHARED
jnz @f
mov eax, edx
call free_page
@@:
inc esi
dec ecx
817,17 → 821,13
jnz .release
 
.released:
push edi
 
pop eax ; .num_released_pages
shl eax, 12
mov edx, [current_process]
lea ecx, [edx + PROC.heap_lock]
mov esi, dword [edx + PROC.heap_base]
mov edi, dword [edx + PROC.heap_top]
sub ebx, [edx + PROC.mem_used]
neg ebx
mov [edx + PROC.mem_used], ebx
sub [edx + PROC.mem_used], eax
call user_normalize
pop edi
.exit:
call mutex_unlock
 
850,18 → 850,21
 
align 4
proc user_unmap stdcall, base:dword, offset:dword, size:dword
mov ecx, [current_process]
add ecx, PROC.heap_lock
call mutex_lock
 
push ebx
 
mov ebx, [base] ; must be valid pointer
test ebx, ebx
jz .error
 
mov edx, [offset] ; check offset
add edx, ebx ; must be below 2Gb app limit
jc .error
js .error
 
shr ebx, 12 ; chek block attributes
jz .error
lea ebx, [page_tabs + ebx*4]
mov eax, [ebx-4] ; block attributes
test al, MEM_BLOCK_USED
887,36 → 890,63
and ebx, not 4095 ; is it required ?
add ebx, [base]
 
push 0
virtual at esp
.num_released_pages dd ?
end virtual
 
.unmap:
mov eax, [edx] ; get page addres
test al, 1 ; page mapped ?
jz @F
jz .next
test eax, PG_SHARED ; page shared ?
jnz @F
mov dword[edx], MEM_BLOCK_RESERVED
jnz .next
inc [.num_released_pages]
mov dword [edx], LAZY_ALLOC_PAGE
; mark page as reserved
test eax, PG_READ
jnz @f
or dword [edx], LAZY_ALLOC_UNREADABLE
@@:
test eax, PG_WRITE
jnz @f
or dword [edx], LAZY_ALLOC_UNWRITABLE
@@:
invlpg [ebx] ; when we start using
call free_page ; empty c-o-w page instead this ?
@@:
add ebx, 4096 ; PAGESIZE?
.next:
add ebx, 4096
add edx, 4
dec ecx
jnz .unmap
 
pop eax ; .num_released_pages
pop ebx
or al, 1 ; return non zero on success
shl eax, 12
mov ecx, [current_process]
sub [ecx+PROC.mem_used], eax
push eax
add ecx, PROC.heap_lock
call mutex_unlock
pop eax ; return number of released bytes
ret
.error:
pop ebx
mov ecx, [current_process]
add ecx, PROC.heap_lock
call mutex_unlock
xor eax, eax ; something wrong
dec eax
ret
endp
 
align 4
user_normalize:
; in: esi=heap_base, edi=heap_top
proc user_normalize uses esi edi
; in: edx->PROC
; out: eax=0 <=> OK
; destroys: ebx,edx,esi,edi
; destroys: ebx,edx
mov esi, dword [edx+PROC.heap_base]
mov edi, dword [edx+PROC.heap_top]
shr esi, 12
shr edi, 12
@@:
959,6 → 989,7
.err:
xor eax, eax
ret
endp
 
user_realloc:
; in: eax = pointer, ebx = new size
1004,37 → 1035,43
cmp edx, ebx
jb .realloc_add
; release part of allocated memory
push edx
push 0
virtual at esp
.num_released_pages dd ?
end virtual
.loop:
cmp edx, ebx
jz .release_done
dec edx
xor eax, eax
xchg eax, [page_tabs + edx*4]
push dword [page_tabs + edx*4]
mov dword [page_tabs + edx*4], 0
mov eax, edx
shl eax, 12
invlpg [eax]
pop eax
test al, 1
jz .loop
inc [.num_released_pages]
test eax, PG_SHARED
jnz .loop
call free_page
mov eax, edx
shl eax, 12
invlpg [eax]
jmp .loop
.release_done:
pop eax ; .num_released_pages
mov edx, [current_process]
shl eax, 12
sub [edx+PROC.mem_used], eax
pop edx
sub ebx, ecx
cmp ebx, 1
jnz .nofreeall
mov eax, [page_tabs + ecx*4]
and eax, not 0xFFF
mov edx, [current_process]
mov ebx, [edx + PROC.mem_used]
sub ebx, eax
add ebx, 0x1000
or al, MEM_BLOCK_FREE
mov [page_tabs + ecx*4], eax
push esi edi
mov esi, [edx + PROC.heap_base]
mov edi, [edx + PROC.heap_top]
mov [edx + PROC.mem_used], ebx
mov edx, [current_process]
call user_normalize
pop edi esi
jmp .ret0 ; all freed
.nofreeall:
sub edx, ecx
1043,13 → 1080,6
xchg [page_tabs + ecx*4], ebx
shr ebx, 12
sub ebx, edx
push ebx ecx edx
mov edx, [current_process]
shl ebx, 12
sub ebx, [edx + PROC.mem_used]
neg ebx
mov [edx + PROC.mem_used], ebx
pop edx ecx ebx
lea eax, [ecx + 1]
shl eax, 12
push eax
1119,9 → 1149,6
cld
rep stosd
pop edi
mov edx, [current_process]
shl ebx, 12
add [edx + PROC.mem_used], ebx
 
mov ecx, [current_process]
lea ecx, [ecx + PROC.heap_lock]
1195,11 → 1222,6
dec edx
jnz @b
.no:
push ebx
mov edx, [current_process]
shl ebx, 12
add [edx + PROC.mem_used], ebx
pop ebx
@@:
mov dword [page_tabs + esi*4], MEM_BLOCK_RESERVED
inc esi
1218,25 → 1240,48
 
 
; param
; eax= shm_map object
; edi= shm_map object
; [esp+4] = process
 
align 4
destroy_smap:
 
pushfd
cli
 
proc destroy_smap ;stdcall, process:dword
push esi
push edi
mov esi, [edi+SMAP.parent]
cmp [edi+SMAP.type], SMAP_TYPE_SMEM
jz .smem
mov ecx, [esp+8]
add ecx, PROC.heap_lock
call mutex_lock
stdcall release_pemap, [esp+8]
mov ecx, [esp+8]
add ecx, PROC.heap_lock
call mutex_unlock
sub ecx, PROC.heap_lock
cmp ecx, [current_process]
jnz @f
stdcall user_free, [edi+SMAP.base]
@@:
call dereference_pe
jmp .common
.smem:
mov eax, [current_process]
cmp [esp+8], eax
jnz @f
stdcall user_free, [edi+SMAP.base]
@@:
call dereference_smem
.common:
mov eax, edi
call free
pop esi
ret 4
endp
 
mov edi, eax
mov esi, [eax + SMAP.parent]
test esi, esi
jz .done
proc dereference_smem
mov ecx, shmem_list_mutex
call mutex_lock
dec [esi+SMEM.refcount]
jnz mutex_unlock
 
lock dec [esi + SMEM.refcount]
jnz .done
 
mov ecx, [esi + SMEM.bk]
mov edx, [esi + SMEM.fd]
 
1243,18 → 1288,14
mov [ecx + SMEM.fd], edx
mov [edx + SMEM.bk], ecx
 
mov ecx, shmem_list_mutex
call mutex_unlock
 
stdcall kernel_free, [esi + SMEM.base]
mov eax, esi
call free
.done:
mov eax, edi
call destroy_kernel_object
 
pop edi
pop esi
popfd
 
ret
endp
 
E_NOTFOUND = 5
E_ACCESS = 10
1273,23 → 1314,17
SHM_OPEN_MASK = 3 shl 2
 
align 4
proc shmem_open stdcall name:dword, size:dword, access:dword
proc shmem_open stdcall uses ebx esi edi, name:dword, size:dword, access:dword
locals
action dd ?
owner_access dd ?
mapped dd ?
edx_ret dd ?
endl
 
push ebx
push esi
push edi
 
mov [mapped], 0
mov [owner_access], 0
 
pushfd ;mutex required
cli
 
mov eax, [access]
and eax, SHM_OPEN_MASK
mov [action], eax
1296,9 → 1331,12
 
mov ebx, [name]
test ebx, ebx
mov edx, E_PARAM
jz .fail
mov [edx_ret], E_PARAM
jz .exit
 
mov ecx, shmem_list_mutex
call mutex_lock
 
mov esi, [shmem_list.fd]
align 4
@@:
1316,22 → 1354,22
.not_found:
mov eax, [action]
 
mov [edx_ret], E_NOTFOUND
cmp eax, SHM_OPEN
mov edx, E_NOTFOUND
je .fail
je .exit_unlock
 
mov [edx_ret], E_PARAM
cmp eax, SHM_CREATE
mov edx, E_PARAM
je .create_shm
 
cmp eax, SHM_OPEN_ALWAYS
jne .fail
jne .exit_unlock
 
.create_shm:
 
mov ecx, [size]
test ecx, ecx
jz .fail
jz .exit_unlock
 
add ecx, 4095
and ecx, -4096
1341,13 → 1379,11
call malloc
test eax, eax
mov esi, eax
mov edx, E_NOMEM
jz .fail
mov [edx_ret], E_NOMEM
jz .exit_unlock
 
stdcall kernel_alloc, [size]
test eax, eax
mov [mapped], eax
mov edx, E_NOMEM
jz .cleanup
 
mov ecx, [size]
1376,16 → 1412,16
.found:
mov eax, [action]
 
mov [edx_ret], E_ACCESS
cmp eax, SHM_CREATE
mov edx, E_ACCESS
je .exit
je .exit_unlock
 
mov [edx_ret], E_PARAM
cmp eax, SHM_OPEN
mov edx, E_PARAM
je .create_map
 
cmp eax, SHM_OPEN_ALWAYS
jne .fail
jne .exit_unlock
 
.create_map:
 
1393,37 → 1429,43
and eax, SHM_ACCESS_MASK
cmp eax, [esi + SMEM.access]
mov [access], eax
mov edx, E_ACCESS
ja .fail
mov [edx_ret], E_ACCESS
ja .exit_unlock
 
mov ebx, [current_slot_idx]
shl ebx, BSF sizeof.TASKDATA
mov ebx, [TASK_TABLE + ebx + TASKDATA.pid]
inc [esi+SMEM.refcount]
mov ecx, shmem_list_mutex
call mutex_unlock
 
mov eax, sizeof.SMAP
 
call create_kernel_object
call malloc
test eax, eax
mov edi, eax
mov edx, E_NOMEM
jz .fail
mov [edx_ret], E_NOMEM
jz .cleanup2
 
inc [esi + SMEM.refcount]
 
mov [edi + SMAP.magic], 'SMAP'
mov [edi + SMAP.destroy], destroy_smap
mov [edi+SMAP.type], SMAP_TYPE_SMEM
mov [edi + SMAP.parent], esi
mov [edi + SMAP.base], 0
mov ecx, [current_process]
add ecx, PROC.heap_lock
call mutex_lock
 
stdcall user_alloc, [esi + SMEM.size]
stdcall user_alloc_nolock, [esi+SMEM.size]
test eax, eax
mov [mapped], eax
mov edx, E_NOMEM
jz .cleanup2
jz .cleanup3
 
mov [edi + SMAP.base], eax
mov ecx, [current_process]
mov edx, [ecx+PROC.smap_list+SMAP.bk]
add ecx, PROC.smap_list
mov [edi+SMAP.fd], ecx
mov [edi+SMAP.bk], edx
mov [ecx+SMAP.bk], edi
mov [edx+SMAP.fd], edi
 
mov ecx, [esi + SMEM.size]
mov [size], ecx
mov [edi + SMAP.size], ecx
mov [edx_ret], ecx
 
shr ecx, 12
shr eax, 10
1430,44 → 1472,51
 
mov esi, [esi + SMEM.base]
shr esi, 10
lea edi, [page_tabs + eax]
add esi, page_tabs
 
xor ebx, ebx
mov edx, [access]
or edx, [owner_access]
shl edx, 1
or edx, PG_SHARED + PG_UR
@@:
lodsd
and eax, 0xFFFFF000
or eax, edx
stosd
loop @B
mov edi, [page_tabs+esi+ebx*4]
and edi, 0xFFFFF000
or edi, edx
mov [page_tabs+eax+ebx*4], edi
inc ebx
dec ecx
jnz @B
 
xor edx, edx
mov ecx, [current_process]
shl ebx, 12
add [ecx+PROC.mem_used], ebx
add ecx, PROC.heap_lock
call mutex_unlock
 
cmp [owner_access], 0
jne .fail
jz .exit
mov [edx_ret], 0
 
.exit:
mov edx, [size]
.fail:
mov eax, [mapped]
 
popfd
pop edi
pop esi
pop ebx
mov edx, [edx_ret]
ret
.cleanup:
mov [size], edx
mov eax, esi
call free
.exit_unlock:
mov ecx, shmem_list_mutex
call mutex_unlock
jmp .exit
 
.cleanup3:
mov ecx, [current_process]
add ecx, PROC.heap_lock
call mutex_unlock
mov eax, edi
call free
.cleanup2:
mov [size], edx
mov eax, edi
call destroy_smap
call dereference_smem
jmp .exit
endp
 
1474,48 → 1523,54
align 4
proc shmem_close stdcall, name:dword
 
mov eax, [name]
test eax, eax
cmp [name], 0
jz .fail
 
push esi
push edi
pushfd
cli
 
mov esi, [current_slot]
add esi, APP_OBJ_OFFSET
mov ecx, [current_process]
lea edi, [ecx+PROC.smap_list]
add ecx, PROC.heap_lock
call mutex_lock
mov esi, edi
 
.next:
mov eax, [esi + APPOBJ.fd]
test eax, eax
jz @F
mov edi, [edi+SMAP.fd]
cmp edi, esi
je .notfound
 
cmp eax, esi
mov esi, eax
je @F
 
cmp [eax + SMAP.magic], 'SMAP'
cmp [edi + SMAP.type], SMAP_TYPE_SMEM
jne .next
 
mov edi, [eax + SMAP.parent]
test edi, edi
jz .next
mov eax, [edi + SMAP.parent]
add eax, SMEM.name
 
lea edi, [edi + SMEM.name]
stdcall strncmp, [name], edi, 32
stdcall strncmp, [name], eax, 32
test eax, eax
jne .next
 
stdcall user_free, [esi + SMAP.base]
mov eax, [edi+SMAP.fd]
mov edx, [edi+SMAP.bk]
mov [eax+SMAP.bk], edx
mov [edx+SMAP.fd], eax
 
mov eax, esi
call [esi + APPOBJ.destroy]
@@:
popfd
mov ecx, [current_process]
add ecx, PROC.heap_lock
call mutex_unlock
 
stdcall destroy_smap, [current_process]
 
.exit:
pop edi
pop esi
.fail:
ret
.notfound:
mov ecx, [current_process]
add ecx, PROC.heap_lock
call mutex_unlock
jmp .exit
endp