forked from KolibriOS/kolibrios
mem_free
git-svn-id: svn://kolibrios.org@886 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
5a66f7d299
commit
bc6cebbf4b
@ -67,7 +67,6 @@ proc get_int_handler stdcall, irq:dword
|
|||||||
.err:
|
.err:
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
ret
|
ret
|
||||||
|
|
||||||
endp
|
endp
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
@ -179,6 +178,7 @@ align 16
|
|||||||
cmp dword [esp + 32], 8
|
cmp dword [esp + 32], 8
|
||||||
mov al, 0x20
|
mov al, 0x20
|
||||||
jb @f
|
jb @f
|
||||||
|
|
||||||
out 0xa0, al
|
out 0xa0, al
|
||||||
@@:
|
@@:
|
||||||
out 0x20, al
|
out 0x20, al
|
||||||
@ -195,6 +195,7 @@ proc get_notify stdcall, p_ev:dword
|
|||||||
mov ebx,[current_slot]
|
mov ebx,[current_slot]
|
||||||
test dword [ebx+APPDATA.event_mask],EVENT_NOTIFY
|
test dword [ebx+APPDATA.event_mask],EVENT_NOTIFY
|
||||||
jz @f
|
jz @f
|
||||||
|
|
||||||
and dword [ebx+APPDATA.event_mask], not EVENT_NOTIFY
|
and dword [ebx+APPDATA.event_mask], not EVENT_NOTIFY
|
||||||
mov edi, [p_ev]
|
mov edi, [p_ev]
|
||||||
mov dword [edi], EV_INTR
|
mov dword [edi], EV_INTR
|
||||||
@ -465,6 +466,7 @@ proc get_coff_sym stdcall, pSym:dword,count:dword, sz_sym:dword
|
|||||||
add [pSym], 18
|
add [pSym], 18
|
||||||
dec [count]
|
dec [count]
|
||||||
jnz @b
|
jnz @b
|
||||||
|
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
ret
|
ret
|
||||||
.ok:
|
.ok:
|
||||||
@ -474,11 +476,10 @@ proc get_coff_sym stdcall, pSym:dword,count:dword, sz_sym:dword
|
|||||||
endp
|
endp
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
proc get_curr_task
|
get_curr_task:
|
||||||
mov eax,[CURRENT_TASK]
|
mov eax,[CURRENT_TASK]
|
||||||
shl eax, 8
|
shl eax, 8
|
||||||
ret
|
ret
|
||||||
endp
|
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
proc get_fileinfo stdcall, file_name:dword, info:dword
|
proc get_fileinfo stdcall, file_name:dword, info:dword
|
||||||
@ -612,7 +613,10 @@ proc load_file stdcall, file_name:dword
|
|||||||
|
|
||||||
mov [file2], eax
|
mov [file2], eax
|
||||||
stdcall unpack, [file], eax
|
stdcall unpack, [file], eax
|
||||||
stdcall kernel_free, [file]
|
|
||||||
|
mov ecx, [file]
|
||||||
|
call @mem_free@4
|
||||||
|
|
||||||
mov eax, [file2]
|
mov eax, [file2]
|
||||||
mov ebx, [file_size]
|
mov ebx, [file_size]
|
||||||
.exit:
|
.exit:
|
||||||
@ -844,6 +848,7 @@ proc load_driver stdcall, driver_name:dword
|
|||||||
call @mem_alloc@8
|
call @mem_alloc@8
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz .fail
|
jz .fail
|
||||||
|
|
||||||
mov [img_base], eax
|
mov [img_base], eax
|
||||||
|
|
||||||
mov edi, eax
|
mov edi, eax
|
||||||
@ -1015,7 +1020,6 @@ proc load_library stdcall, file_name:dword
|
|||||||
jmp .next
|
jmp .next
|
||||||
.copy:
|
.copy:
|
||||||
add esi, edx
|
add esi, edx
|
||||||
; add edi, new_app_base
|
|
||||||
mov ecx, [eax+CFS.SizeOfRawData]
|
mov ecx, [eax+CFS.SizeOfRawData]
|
||||||
cld
|
cld
|
||||||
rep movsb
|
rep movsb
|
||||||
|
@ -112,7 +112,7 @@ kernel_export:
|
|||||||
dd szReleasePages , release_pages
|
dd szReleasePages , release_pages
|
||||||
|
|
||||||
dd szFreeKernelSpace , free_kernel_space ;stdcall
|
dd szFreeKernelSpace , free_kernel_space ;stdcall
|
||||||
dd szHeapAlloc , @heap_alloc@8 ;fastcall
|
dd szHeapAlloc , @mem_alloc@8 ;fastcall
|
||||||
dd szKernelFree , kernel_free ;stdcall
|
dd szKernelFree , kernel_free ;stdcall
|
||||||
dd szUserAlloc , user_alloc ;stdcall
|
dd szUserAlloc , user_alloc ;stdcall
|
||||||
dd szUserFree , user_free ;stdcall
|
dd szUserFree , user_free ;stdcall
|
||||||
|
@ -13,33 +13,42 @@ typedef struct
|
|||||||
addr_t base;
|
addr_t base;
|
||||||
size_t size;
|
size_t size;
|
||||||
void* parent;
|
void* parent;
|
||||||
u32_t reserved;
|
u32_t state;
|
||||||
}md_t;
|
}md_t;
|
||||||
|
|
||||||
|
#define MD_FREE 1
|
||||||
|
#define MD_USED 2
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
SPINLOCK_DECLARE(lock); /**< this lock protects everything below */
|
SPINLOCK_DECLARE(lock); /**< this lock protects everything below */
|
||||||
|
|
||||||
u32_t availmask;
|
u32_t availmask;
|
||||||
link_t list[32];
|
link_t free[32];
|
||||||
|
|
||||||
|
link_t used;
|
||||||
}heap_t;
|
}heap_t;
|
||||||
|
|
||||||
|
|
||||||
slab_cache_t *md_slab;
|
slab_cache_t *md_slab;
|
||||||
slab_cache_t *phm_slab;
|
slab_cache_t *phm_slab;
|
||||||
|
|
||||||
|
|
||||||
heap_t lheap;
|
heap_t lheap;
|
||||||
heap_t sheap;
|
heap_t sheap;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static inline void _set_lmask(count_t idx)
|
static inline void _set_lmask(count_t idx)
|
||||||
{ asm volatile ("bts DWORD PTR [_lheap], %0"::"r"(idx):"cc"); }
|
{ asm volatile ("bts %0, _lheap"::"r"(idx):"cc"); }
|
||||||
|
|
||||||
static inline void _reset_lmask(count_t idx)
|
static inline void _reset_lmask(count_t idx)
|
||||||
{ asm volatile ("btr DWORD PTR [_lheap], %0"::"r"(idx):"cc"); }
|
{ asm volatile ("btr %0, _lheap"::"r"(idx):"cc"); }
|
||||||
|
|
||||||
static inline void _set_smask(count_t idx)
|
static inline void _set_smask(count_t idx)
|
||||||
{ asm volatile ("bts DWORD PTR [_sheap], %0"::"r"(idx):"cc"); }
|
{ asm volatile ("bts %0, _sheap"::"r"(idx):"cc"); }
|
||||||
|
|
||||||
static inline void _reset_smask(count_t idx)
|
static inline void _reset_smask(count_t idx)
|
||||||
{ asm volatile ("btr DWORD PTR [_sheap], %0"::"r"(idx):"cc"); }
|
{ asm volatile ("btr %0, _sheap"::"r"(idx):"cc"); }
|
||||||
|
|
||||||
|
|
||||||
int __fastcall init_heap(addr_t base, size_t size)
|
int __fastcall init_heap(addr_t base, size_t size)
|
||||||
@ -54,10 +63,14 @@ int __fastcall init_heap(addr_t base, size_t size)
|
|||||||
|
|
||||||
for (i = 0; i < 32; i++)
|
for (i = 0; i < 32; i++)
|
||||||
{
|
{
|
||||||
list_initialize(&lheap.list[i]);
|
list_initialize(&lheap.free[i]);
|
||||||
list_initialize(&sheap.list[i]);
|
list_initialize(&sheap.free[i]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
list_initialize(&lheap.used);
|
||||||
|
list_initialize(&sheap.used);
|
||||||
|
|
||||||
|
|
||||||
md_slab = slab_cache_create(sizeof(md_t), 32,NULL,NULL,SLAB_CACHE_MAGDEFERRED);
|
md_slab = slab_cache_create(sizeof(md_t), 32,NULL,NULL,SLAB_CACHE_MAGDEFERRED);
|
||||||
|
|
||||||
md = (md_t*)slab_alloc(md_slab,0);
|
md = (md_t*)slab_alloc(md_slab,0);
|
||||||
@ -66,9 +79,9 @@ int __fastcall init_heap(addr_t base, size_t size)
|
|||||||
md->base = base;
|
md->base = base;
|
||||||
md->size = size;
|
md->size = size;
|
||||||
md->parent = NULL;
|
md->parent = NULL;
|
||||||
md->reserved = 0;
|
md->state = MD_FREE;
|
||||||
|
|
||||||
list_prepend(&md->link, &lheap.list[31]);
|
list_prepend(&md->link, &lheap.free[31]);
|
||||||
lheap.availmask = 0x80000000;
|
lheap.availmask = 0x80000000;
|
||||||
sheap.availmask = 0x00000000;
|
sheap.availmask = 0x00000000;
|
||||||
|
|
||||||
@ -93,8 +106,8 @@ md_t* __fastcall find_large_md(size_t size)
|
|||||||
{
|
{
|
||||||
if(idx0 == 31)
|
if(idx0 == 31)
|
||||||
{
|
{
|
||||||
md_t *tmp = (md_t*)lheap.list[31].next;
|
md_t *tmp = (md_t*)lheap.free[31].next;
|
||||||
while((link_t*)tmp != &lheap.list[31])
|
while((link_t*)tmp != &lheap.free[31])
|
||||||
{
|
{
|
||||||
if(tmp->size >= size)
|
if(tmp->size >= size)
|
||||||
{
|
{
|
||||||
@ -110,39 +123,44 @@ md_t* __fastcall find_large_md(size_t size)
|
|||||||
{
|
{
|
||||||
idx0 = _bsf(mask);
|
idx0 = _bsf(mask);
|
||||||
|
|
||||||
ASSERT( !list_empty(&lheap.list[idx0]))
|
ASSERT( !list_empty(&lheap.free[idx0]))
|
||||||
|
|
||||||
md = (md_t*)lheap.list[idx0].next;
|
md = (md_t*)lheap.free[idx0].next;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
ASSERT(md->state == MD_FREE);
|
||||||
|
|
||||||
list_remove((link_t*)md);
|
list_remove((link_t*)md);
|
||||||
if(list_empty(&lheap.list[idx0]))
|
if(list_empty(&lheap.free[idx0]))
|
||||||
_reset_lmask(idx0);
|
_reset_lmask(idx0);
|
||||||
|
|
||||||
if(md->size > size)
|
if(md->size > size)
|
||||||
{
|
{
|
||||||
count_t idx1;
|
count_t idx1;
|
||||||
md_t *new_md = (md_t*)slab_alloc(md_slab,0);
|
md_t *new_md = (md_t*)slab_alloc(md_slab,0); /* FIXME check */
|
||||||
|
|
||||||
link_initialize(&new_md->link);
|
link_initialize(&new_md->link);
|
||||||
list_insert(&new_md->adj, &md->adj);
|
list_insert(&new_md->adj, &md->adj);
|
||||||
|
|
||||||
new_md->base = md->base;
|
new_md->base = md->base;
|
||||||
new_md->size = size;
|
new_md->size = size;
|
||||||
|
new_md->state = MD_USED;
|
||||||
|
|
||||||
md->base+= size;
|
md->base+= size;
|
||||||
md->size-= size;
|
md->size-= size;
|
||||||
|
|
||||||
idx1 = (md->size>>22) - 1 < 32 ? (md->size>>22) - 1 : 31;
|
idx1 = (md->size>>22) - 1 < 32 ? (md->size>>22) - 1 : 31;
|
||||||
|
|
||||||
list_prepend(&md->link, &lheap.list[idx1]);
|
list_prepend(&md->link, &lheap.free[idx1]);
|
||||||
_set_lmask(idx1);
|
_set_lmask(idx1);
|
||||||
|
|
||||||
return new_md;
|
return new_md;
|
||||||
}
|
};
|
||||||
|
md->state = MD_USED;
|
||||||
|
|
||||||
return md;
|
return md;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,8 +186,10 @@ md_t* __fastcall find_small_md(size_t size)
|
|||||||
{
|
{
|
||||||
if(idx0 == 31)
|
if(idx0 == 31)
|
||||||
{
|
{
|
||||||
md_t *tmp = (md_t*)sheap.list[31].next;
|
ASSERT( !list_empty(&sheap.free[31]));
|
||||||
while((link_t*)tmp != &sheap.list[31])
|
|
||||||
|
md_t *tmp = (md_t*)sheap.free[31].next;
|
||||||
|
while((link_t*)tmp != &sheap.free[31])
|
||||||
{
|
{
|
||||||
if(tmp->size >= size)
|
if(tmp->size >= size)
|
||||||
{
|
{
|
||||||
@ -182,8 +202,10 @@ md_t* __fastcall find_small_md(size_t size)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
idx0 = _bsf(mask);
|
idx0 = _bsf(mask);
|
||||||
ASSERT( !list_empty(&sheap.list[idx0]))
|
|
||||||
md = (md_t*)sheap.list[idx0].next;
|
ASSERT( !list_empty(&sheap.free[idx0]));
|
||||||
|
|
||||||
|
md = (md_t*)sheap.free[idx0].next;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -191,8 +213,10 @@ md_t* __fastcall find_small_md(size_t size)
|
|||||||
{
|
{
|
||||||
DBG("remove md %x\n", md);
|
DBG("remove md %x\n", md);
|
||||||
|
|
||||||
|
ASSERT(md->state==MD_FREE);
|
||||||
|
|
||||||
list_remove((link_t*)md);
|
list_remove((link_t*)md);
|
||||||
if(list_empty(&sheap.list[idx0]))
|
if(list_empty(&sheap.free[idx0]))
|
||||||
_reset_smask(idx0);
|
_reset_smask(idx0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -208,19 +232,20 @@ md_t* __fastcall find_small_md(size_t size)
|
|||||||
return NULL;
|
return NULL;
|
||||||
};
|
};
|
||||||
|
|
||||||
md = (md_t*)slab_alloc(md_slab,0);
|
md = (md_t*)slab_alloc(md_slab,0); /* FIXME check */
|
||||||
|
|
||||||
link_initialize(&md->link);
|
link_initialize(&md->link);
|
||||||
list_initialize(&md->adj);
|
list_initialize(&md->adj);
|
||||||
md->base = lmd->base;
|
md->base = lmd->base;
|
||||||
md->size = lmd->size;
|
md->size = lmd->size;
|
||||||
md->parent = lmd;
|
md->parent = lmd;
|
||||||
md->reserved = 0;
|
md->state = MD_USED;
|
||||||
};
|
};
|
||||||
|
|
||||||
if(md->size > size)
|
if(md->size > size)
|
||||||
{
|
{
|
||||||
count_t idx1;
|
count_t idx1;
|
||||||
md_t *new_md = (md_t*)slab_alloc(md_slab,0);
|
md_t *new_md = (md_t*)slab_alloc(md_slab,0); /* FIXME check */
|
||||||
|
|
||||||
link_initialize(&new_md->link);
|
link_initialize(&new_md->link);
|
||||||
list_insert(&new_md->adj, &md->adj);
|
list_insert(&new_md->adj, &md->adj);
|
||||||
@ -228,26 +253,27 @@ md_t* __fastcall find_small_md(size_t size)
|
|||||||
new_md->base = md->base;
|
new_md->base = md->base;
|
||||||
new_md->size = size;
|
new_md->size = size;
|
||||||
new_md->parent = md->parent;
|
new_md->parent = md->parent;
|
||||||
new_md->reserved = 0;
|
new_md->state = MD_USED;
|
||||||
|
|
||||||
md->base+= size;
|
md->base+= size;
|
||||||
md->size-= size;
|
md->size-= size;
|
||||||
|
md->state = MD_FREE;
|
||||||
|
|
||||||
idx1 = (md->size>>12) - 1 < 32 ? (md->size>>12) - 1 : 31;
|
idx1 = (md->size>>12) - 1 < 32 ? (md->size>>12) - 1 : 31;
|
||||||
|
|
||||||
DBG("insert md %x, base %x size %x idx %x\n", md,md->base, md->size,idx1);
|
DBG("insert md %x, base %x size %x idx %x\n", md,md->base, md->size,idx1);
|
||||||
|
|
||||||
if( idx1 < 31)
|
if( idx1 < 31)
|
||||||
list_prepend(&md->link, &sheap.list[idx1]);
|
list_prepend(&md->link, &sheap.free[idx1]);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if( list_empty(&sheap.list[31]))
|
if( list_empty(&sheap.free[31]))
|
||||||
list_prepend(&md->link, &sheap.list[31]);
|
list_prepend(&md->link, &sheap.free[31]);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
md_t *tmp = (md_t*)sheap.list[31].next;
|
md_t *tmp = (md_t*)sheap.free[31].next;
|
||||||
|
|
||||||
while((link_t*)tmp != &sheap.list[31])
|
while((link_t*)tmp != &sheap.free[31])
|
||||||
{
|
{
|
||||||
if(md->base < tmp->base)
|
if(md->base < tmp->base)
|
||||||
break;
|
break;
|
||||||
@ -262,11 +288,93 @@ md_t* __fastcall find_small_md(size_t size)
|
|||||||
safe_sti(efl);
|
safe_sti(efl);
|
||||||
|
|
||||||
return new_md;
|
return new_md;
|
||||||
}
|
};
|
||||||
|
|
||||||
|
md->state = MD_USED;
|
||||||
|
|
||||||
safe_sti(efl);
|
safe_sti(efl);
|
||||||
|
|
||||||
return md;
|
return md;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void __fastcall free_small_md(md_t *md)
|
||||||
|
{
|
||||||
|
eflags_t efl ;
|
||||||
|
md_t *fd;
|
||||||
|
md_t *bk;
|
||||||
|
count_t idx;
|
||||||
|
|
||||||
|
efl = safe_cli();
|
||||||
|
spinlock_lock(&sheap.lock);
|
||||||
|
|
||||||
|
if( !list_empty(&md->adj))
|
||||||
|
{
|
||||||
|
bk = (md_t*)md->adj.prev;
|
||||||
|
fd = (md_t*)md->adj.next;
|
||||||
|
|
||||||
|
if(fd->state == MD_FREE)
|
||||||
|
{
|
||||||
|
idx = (fd->size>>12) - 1 < 32 ? (fd->size>>12) - 1 : 31;
|
||||||
|
|
||||||
|
list_remove((link_t*)fd);
|
||||||
|
if(list_empty(&sheap.free[idx]))
|
||||||
|
_reset_smask(idx);
|
||||||
|
|
||||||
|
md->size+= fd->size;
|
||||||
|
md->adj.next = fd->adj.next;
|
||||||
|
md->adj.next->prev = (link_t*)md;
|
||||||
|
slab_free(md_slab, fd);
|
||||||
|
};
|
||||||
|
if(bk->state == MD_FREE)
|
||||||
|
{
|
||||||
|
idx = (bk->size>>12) - 1 < 32 ? (bk->size>>12) - 1 : 31;
|
||||||
|
|
||||||
|
list_remove((link_t*)bk);
|
||||||
|
if(list_empty(&sheap.free[idx]))
|
||||||
|
_reset_smask(idx);
|
||||||
|
|
||||||
|
bk->size+= md->size;
|
||||||
|
bk->adj.next = md->adj.next;
|
||||||
|
bk->adj.next->prev = (link_t*)bk;
|
||||||
|
slab_free(md_slab, md);
|
||||||
|
md = fd;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
md->state = MD_FREE;
|
||||||
|
|
||||||
|
idx = (md->size>>12) - 1 < 32 ? (md->size>>12) - 1 : 31;
|
||||||
|
|
||||||
|
_set_smask(idx);
|
||||||
|
|
||||||
|
if( idx < 31)
|
||||||
|
list_prepend(&md->link, &sheap.free[idx]);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( list_empty(&sheap.free[31]))
|
||||||
|
list_prepend(&md->link, &sheap.free[31]);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
md_t *tmp = (md_t*)sheap.free[31].next;
|
||||||
|
|
||||||
|
while((link_t*)tmp != &sheap.free[31])
|
||||||
|
{
|
||||||
|
if(md->base < tmp->base)
|
||||||
|
break;
|
||||||
|
tmp = (md_t*)tmp->link.next;
|
||||||
|
}
|
||||||
|
list_insert(&md->link, &tmp->link);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
spinlock_unlock(&sheap.lock);
|
||||||
|
safe_sti(efl);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define page_tabs 0xDF800000
|
||||||
|
|
||||||
|
/*
|
||||||
phismem_t* __fastcall phis_alloc(count_t count)
|
phismem_t* __fastcall phis_alloc(count_t count)
|
||||||
{
|
{
|
||||||
phismem_t *phm;
|
phismem_t *phm;
|
||||||
@ -289,8 +397,6 @@ phismem_t* __fastcall phis_alloc(count_t count)
|
|||||||
return phm;
|
return phm;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define page_tabs 0xDF800000
|
|
||||||
|
|
||||||
void map_phm(addr_t base, phismem_t *phm, u32_t mapflags)
|
void map_phm(addr_t base, phismem_t *phm, u32_t mapflags)
|
||||||
{
|
{
|
||||||
count_t count;
|
count_t count;
|
||||||
@ -317,27 +423,17 @@ void map_phm(addr_t base, phismem_t *phm, u32_t mapflags)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
void * __fastcall mem_alloc(size_t size, u32_t flags)
|
void * __fastcall mem_alloc(size_t size, u32_t flags)
|
||||||
{
|
{
|
||||||
|
eflags_t efl;
|
||||||
|
|
||||||
md_t *md;
|
md_t *md;
|
||||||
phismem_t *phm;
|
|
||||||
|
|
||||||
size = (size+4095)&~4095;
|
DBG("\nmem_alloc: %x bytes\n", size);
|
||||||
|
|
||||||
md = find_small_md(size);
|
ASSERT(size != 0);
|
||||||
if( md )
|
|
||||||
{
|
|
||||||
phm = phis_alloc(size>>12);
|
|
||||||
map_phm(md->base , phm, flags);
|
|
||||||
return (void*)md->base;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
};
|
|
||||||
|
|
||||||
void * __fastcall heap_alloc(size_t size, u32_t flags)
|
|
||||||
{
|
|
||||||
md_t *md;
|
|
||||||
|
|
||||||
size = (size+4095)&~4095;
|
size = (size+4095)&~4095;
|
||||||
|
|
||||||
@ -345,6 +441,8 @@ void * __fastcall heap_alloc(size_t size, u32_t flags)
|
|||||||
|
|
||||||
if( md )
|
if( md )
|
||||||
{
|
{
|
||||||
|
ASSERT(md->state == MD_USED);
|
||||||
|
|
||||||
if( flags & PG_MAP )
|
if( flags & PG_MAP )
|
||||||
{
|
{
|
||||||
count_t tmp = size >> 12;
|
count_t tmp = size >> 12;
|
||||||
@ -356,10 +454,10 @@ void * __fastcall heap_alloc(size_t size, u32_t flags)
|
|||||||
addr_t frame;
|
addr_t frame;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
asm volatile ("bsr %0, %1":"=&r"(order):"r"(tmp):"cc");
|
asm volatile ("bsr %1, %0":"=&r"(order):"r"(tmp):"cc");
|
||||||
asm volatile ("btr %0, %1" :"=r"(tmp):"r"(order):"cc");
|
asm volatile ("btr %1, %0" :"=r"(tmp):"r"(order):"cc");
|
||||||
|
|
||||||
frame = core_alloc(order) | flags;
|
frame = core_alloc(order) | flags; /* FIXME check */
|
||||||
|
|
||||||
size = (1 << order);
|
size = (1 << order);
|
||||||
while(size--)
|
while(size--)
|
||||||
@ -369,10 +467,86 @@ void * __fastcall heap_alloc(size_t size, u32_t flags)
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
DBG("alloc_heap: %x size %x\n\n",md->base, size);
|
|
||||||
|
efl = safe_cli();
|
||||||
|
spinlock_lock(&sheap.lock);
|
||||||
|
|
||||||
|
if( list_empty(&sheap.used) )
|
||||||
|
list_prepend(&md->link, &sheap.used);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
md_t *tmp = (md_t*)sheap.used.next;
|
||||||
|
|
||||||
|
while((link_t*)tmp != &sheap.used)
|
||||||
|
{
|
||||||
|
if(md->base < tmp->base)
|
||||||
|
break;
|
||||||
|
tmp = (md_t*)tmp->link.next;
|
||||||
|
}
|
||||||
|
list_insert(&md->link, &tmp->link);
|
||||||
|
};
|
||||||
|
|
||||||
|
spinlock_unlock(&sheap.lock);
|
||||||
|
safe_sti(efl);
|
||||||
|
|
||||||
|
DBG("allocate: %x size %x\n\n",md->base, size);
|
||||||
return (void*)md->base;
|
return (void*)md->base;
|
||||||
};
|
};
|
||||||
return NULL;
|
return NULL;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void __fastcall mem_free(void *mem)
|
||||||
|
{
|
||||||
|
eflags_t efl;
|
||||||
|
|
||||||
|
md_t *tmp;
|
||||||
|
md_t *md = NULL;
|
||||||
|
|
||||||
|
DBG("mem_free: %x\n",mem);
|
||||||
|
|
||||||
|
ASSERT( mem != 0 );
|
||||||
|
ASSERT( ((addr_t)mem & 0xFFF) == 0 );
|
||||||
|
ASSERT( ! list_empty(&sheap.used));
|
||||||
|
|
||||||
|
efl = safe_cli();
|
||||||
|
|
||||||
|
tmp = (md_t*)sheap.used.next;
|
||||||
|
|
||||||
|
while((link_t*)tmp != &sheap.used)
|
||||||
|
{
|
||||||
|
if( tmp->base == (addr_t)mem )
|
||||||
|
{
|
||||||
|
md = tmp;
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
tmp = (md_t*)tmp->link.next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( md )
|
||||||
|
{
|
||||||
|
DBG("\tmd: %x base: %x size: %x\n",md, md->base, md->size);
|
||||||
|
|
||||||
|
ASSERT(md->state == MD_USED);
|
||||||
|
|
||||||
|
count_t tmp = md->size >> 12;
|
||||||
|
addr_t *pte = &((addr_t*)page_tabs)[md->base>>12];
|
||||||
|
|
||||||
|
while(tmp--)
|
||||||
|
{
|
||||||
|
*pte++ = 0;
|
||||||
|
asm volatile (
|
||||||
|
"invlpg (%0)"
|
||||||
|
:
|
||||||
|
:"r" (mem) );
|
||||||
|
mem+= 4096;
|
||||||
|
};
|
||||||
|
list_remove((link_t*)md);
|
||||||
|
free_small_md( md );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DBG("\tERROR: invalid base address: %x\n", mem);
|
||||||
|
};
|
||||||
|
|
||||||
|
safe_sti(efl);
|
||||||
|
};
|
||||||
|
@ -16,7 +16,7 @@ zone_t z_core;
|
|||||||
static inline u32_t save_edx(void)
|
static inline u32_t save_edx(void)
|
||||||
{
|
{
|
||||||
u32_t val;
|
u32_t val;
|
||||||
asm volatile ("mov %0, edx":"=r"(val));
|
asm volatile ("movl %%edx, %0":"=r"(val));
|
||||||
return val;
|
return val;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -524,9 +524,9 @@ static inline int to_order(count_t arg)
|
|||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
asm volatile (
|
asm volatile (
|
||||||
"xor eax, eax \n\t"
|
"xorl %eax, %eax \n\t"
|
||||||
"bsr eax, edx \n\t"
|
"bsr %edx, %eax \n\t"
|
||||||
"inc eax"
|
"incl %eax"
|
||||||
:"=a" (n)
|
:"=a" (n)
|
||||||
:"d"(arg)
|
:"d"(arg)
|
||||||
);
|
);
|
||||||
|
@ -20,8 +20,6 @@ static slab_t *slab_create();
|
|||||||
|
|
||||||
static slab_cache_t * slab_cache_alloc();
|
static slab_cache_t * slab_cache_alloc();
|
||||||
|
|
||||||
void slab_free(slab_cache_t *cache, void *obj);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocate frames for slab space and initialize
|
* Allocate frames for slab space and initialize
|
||||||
@ -313,22 +311,22 @@ static count_t slab_obj_destroy(slab_cache_t *cache, void *obj,
|
|||||||
/** Return object to cache, use slab if known */
|
/** Return object to cache, use slab if known */
|
||||||
static void _slab_free(slab_cache_t *cache, void *obj, slab_t *slab)
|
static void _slab_free(slab_cache_t *cache, void *obj, slab_t *slab)
|
||||||
{
|
{
|
||||||
// ipl_t ipl;
|
eflags_t efl;
|
||||||
|
|
||||||
// ipl = interrupts_disable();
|
efl = safe_cli();
|
||||||
|
|
||||||
// if ((cache->flags & SLAB_CACHE_NOMAGAZINE) \
|
// if ((cache->flags & SLAB_CACHE_NOMAGAZINE) \
|
||||||
|| magazine_obj_put(cache, obj)) {
|
// || magazine_obj_put(cache, obj)) {
|
||||||
|
|
||||||
slab_obj_destroy(cache, obj, slab);
|
slab_obj_destroy(cache, obj, slab);
|
||||||
|
|
||||||
// }
|
// }
|
||||||
// interrupts_restore(ipl);
|
safe_sti(efl);
|
||||||
// atomic_dec(&cache->allocated_objs);
|
atomic_dec(&cache->allocated_objs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return slab object to cache */
|
/** Return slab object to cache */
|
||||||
void slab_free(slab_cache_t *cache, void *obj)
|
void __fastcall slab_free(slab_cache_t *cache, void *obj)
|
||||||
{
|
{
|
||||||
_slab_free(cache, obj, NULL);
|
_slab_free(cache, obj, NULL);
|
||||||
}
|
}
|
||||||
|
@ -187,7 +187,6 @@ proc fs_execute
|
|||||||
loop .copy_process_name_loop
|
loop .copy_process_name_loop
|
||||||
.copy_process_name_done:
|
.copy_process_name_done:
|
||||||
|
|
||||||
|
|
||||||
mov ebx, cr3
|
mov ebx, cr3
|
||||||
mov [save_cr3], ebx
|
mov [save_cr3], ebx
|
||||||
|
|
||||||
@ -218,7 +217,7 @@ end if
|
|||||||
|
|
||||||
; release only virtual space, not phisical memory
|
; release only virtual space, not phisical memory
|
||||||
|
|
||||||
stdcall free_kernel_space, [file_base]
|
stdcall free_kernel_space, [file_base] ;
|
||||||
lea eax, [hdr_cmdline]
|
lea eax, [hdr_cmdline]
|
||||||
lea ebx, [cmdline]
|
lea ebx, [cmdline]
|
||||||
lea ecx, [filename]
|
lea ecx, [filename]
|
||||||
@ -415,7 +414,6 @@ proc create_app_space stdcall, app_size:dword,img_base:dword,img_size:dword
|
|||||||
mov eax, edi
|
mov eax, edi
|
||||||
call set_cr3
|
call set_cr3
|
||||||
|
|
||||||
|
|
||||||
mov edx, [app_tabs]
|
mov edx, [app_tabs]
|
||||||
mov edi, master_tab
|
mov edi, master_tab
|
||||||
@@:
|
@@:
|
||||||
@ -504,8 +502,10 @@ proc destroy_page_table stdcall, pg_tab:dword
|
|||||||
mov eax, [esi]
|
mov eax, [esi]
|
||||||
test eax, 1
|
test eax, 1
|
||||||
jz .next
|
jz .next
|
||||||
|
|
||||||
test eax, 1 shl 9
|
test eax, 1 shl 9
|
||||||
jnz .next ;skip shared pages
|
jnz .next ;skip shared pages
|
||||||
|
|
||||||
call free_page
|
call free_page
|
||||||
.next:
|
.next:
|
||||||
add esi, 4
|
add esi, 4
|
||||||
@ -530,9 +530,11 @@ proc destroy_app_space stdcall, pg_dir:dword
|
|||||||
shl ecx,5
|
shl ecx,5
|
||||||
cmp byte [CURRENT_TASK+ecx+0xa],9 ;if process running?
|
cmp byte [CURRENT_TASK+ecx+0xa],9 ;if process running?
|
||||||
jz @f ;skip empty slots
|
jz @f ;skip empty slots
|
||||||
|
|
||||||
shl ecx,3
|
shl ecx,3
|
||||||
cmp [SLOT_BASE+ecx+0xB8],ebx ;compare page directory addresses
|
cmp [SLOT_BASE+ecx+0xB8],ebx ;compare page directory addresses
|
||||||
jnz @f
|
jnz @f
|
||||||
|
|
||||||
inc edx ;thread found
|
inc edx ;thread found
|
||||||
@@:
|
@@:
|
||||||
inc eax
|
inc eax
|
||||||
@ -858,6 +860,7 @@ proc new_sys_threads
|
|||||||
.wait_lock:
|
.wait_lock:
|
||||||
cmp [application_table_status],0
|
cmp [application_table_status],0
|
||||||
je .get_lock
|
je .get_lock
|
||||||
|
|
||||||
call change_task
|
call change_task
|
||||||
jmp .wait_lock
|
jmp .wait_lock
|
||||||
|
|
||||||
@ -930,6 +933,7 @@ wait_mutex:
|
|||||||
.do_wait:
|
.do_wait:
|
||||||
cmp dword [ebx],0
|
cmp dword [ebx],0
|
||||||
je .get_lock
|
je .get_lock
|
||||||
|
|
||||||
call change_task
|
call change_task
|
||||||
jmp .do_wait
|
jmp .do_wait
|
||||||
.get_lock:
|
.get_lock:
|
||||||
@ -937,6 +941,7 @@ wait_mutex:
|
|||||||
xchg eax, [ebx]
|
xchg eax, [ebx]
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jnz .do_wait
|
jnz .do_wait
|
||||||
|
|
||||||
pop ebx
|
pop ebx
|
||||||
pop eax
|
pop eax
|
||||||
ret
|
ret
|
||||||
@ -1101,13 +1106,12 @@ proc set_app_params stdcall,slot:dword, params:dword,\
|
|||||||
; set if debuggee
|
; set if debuggee
|
||||||
test byte [flags], 1
|
test byte [flags], 1
|
||||||
jz .no_debug
|
jz .no_debug
|
||||||
|
|
||||||
inc ecx ; process state - suspended
|
inc ecx ; process state - suspended
|
||||||
mov eax,[CURRENT_TASK]
|
mov eax,[CURRENT_TASK]
|
||||||
mov [SLOT_BASE+ebx*8+APPDATA.debugger_slot],eax
|
mov [SLOT_BASE+ebx*8+APPDATA.debugger_slot],eax
|
||||||
.no_debug:
|
.no_debug:
|
||||||
mov [CURRENT_TASK+ebx+TASKDATA.state], cl
|
mov [CURRENT_TASK+ebx+TASKDATA.state], cl
|
||||||
;mov esi,new_process_running
|
|
||||||
;call sys_msg_board_str ;output information about succefull startup
|
|
||||||
DEBUGF 1,"%s",new_process_running
|
DEBUGF 1,"%s",new_process_running
|
||||||
ret
|
ret
|
||||||
endp
|
endp
|
||||||
|
@ -36,17 +36,17 @@ typedef struct atomic {
|
|||||||
|
|
||||||
static inline void atomic_inc(atomic_t *val) {
|
static inline void atomic_inc(atomic_t *val) {
|
||||||
#ifdef USE_SMP
|
#ifdef USE_SMP
|
||||||
asm volatile ("lock inc %0\n" : "+m" (val->count));
|
asm volatile ("lock incl %0\n" : "+m" (val->count));
|
||||||
#else
|
#else
|
||||||
asm volatile ("inc %0\n" : "+m" (val->count));
|
asm volatile ("incl %0\n" : "+m" (val->count));
|
||||||
#endif /* USE_SMP */
|
#endif /* USE_SMP */
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void atomic_dec(atomic_t *val) {
|
static inline void atomic_dec(atomic_t *val) {
|
||||||
#ifdef USE_SMP
|
#ifdef USE_SMP
|
||||||
asm volatile ("lock dec %0\n" : "+m" (val->count));
|
asm volatile ("lock decl %0\n" : "+m" (val->count));
|
||||||
#else
|
#else
|
||||||
asm volatile ("dec %0\n" : "+m" (val->count));
|
asm volatile ("decl %0\n" : "+m" (val->count));
|
||||||
#endif /* USE_SMP */
|
#endif /* USE_SMP */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,22 +98,20 @@ static inline void atomic_lock_arch(atomic_t *val)
|
|||||||
u32_t tmp;
|
u32_t tmp;
|
||||||
|
|
||||||
// preemption_disable();
|
// preemption_disable();
|
||||||
|
|
||||||
asm volatile (
|
asm volatile (
|
||||||
"0:\n"
|
"0:\n"
|
||||||
"pause\n\t" /* Pentium 4's HT love this instruction */
|
"pause\n" /* Pentium 4's HT love this instruction */
|
||||||
"mov %1, [%0]\n\t"
|
"mov %0, %1\n"
|
||||||
"test %1, %1\n\t"
|
"testl %1, %1\n"
|
||||||
"jnz 0b\n\t" /* lightweight looping on locked spinlock */
|
"jnz 0b\n" /* lightweight looping on locked spinlock */
|
||||||
|
|
||||||
"inc %1\n\t" /* now use the atomic operation */
|
"incl %1\n" /* now use the atomic operation */
|
||||||
"xchg [%0], %1\n\t"
|
"xchgl %0, %1\n"
|
||||||
"test %1, %1\n\t"
|
"testl %1, %1\n"
|
||||||
"jnz 0b\n\t"
|
"jnz 0b\n"
|
||||||
: "+m" (val->count), "=r"(tmp)
|
: "+m" (val->count), "=&r"(tmp)
|
||||||
);
|
);
|
||||||
/*
|
|
||||||
* Prevent critical section code from bleeding out this way up.
|
|
||||||
*/
|
|
||||||
// CS_ENTER_BARRIER();
|
// CS_ENTER_BARRIER();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,8 +37,8 @@ static inline eflags_t safe_cli(void)
|
|||||||
{
|
{
|
||||||
eflags_t tmp;
|
eflags_t tmp;
|
||||||
asm volatile (
|
asm volatile (
|
||||||
"pushf\n\t"
|
"pushfl\n\t"
|
||||||
"pop %0\n\t"
|
"popl %0\n\t"
|
||||||
"cli\n"
|
"cli\n"
|
||||||
: "=r" (tmp)
|
: "=r" (tmp)
|
||||||
);
|
);
|
||||||
@ -48,8 +48,8 @@ static inline eflags_t safe_cli(void)
|
|||||||
static inline void safe_sti(eflags_t efl)
|
static inline void safe_sti(eflags_t efl)
|
||||||
{
|
{
|
||||||
asm volatile (
|
asm volatile (
|
||||||
"push %0\n\t"
|
"pushl %0\n\t"
|
||||||
"popf\n"
|
"popfl\n"
|
||||||
: : "r" (efl)
|
: : "r" (efl)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -57,8 +57,8 @@ static inline void safe_sti(eflags_t efl)
|
|||||||
static inline count_t fnzb(u32_t arg)
|
static inline count_t fnzb(u32_t arg)
|
||||||
{
|
{
|
||||||
count_t n;
|
count_t n;
|
||||||
asm volatile ("xor %0, %0 \n\t"
|
asm volatile ("xorl %0, %0 \n\t"
|
||||||
"bsr %0, %1"
|
"bsr %1, %0"
|
||||||
:"=&r" (n)
|
:"=&r" (n)
|
||||||
:"r"(arg)
|
:"r"(arg)
|
||||||
);
|
);
|
||||||
@ -68,8 +68,8 @@ static inline count_t fnzb(u32_t arg)
|
|||||||
static inline count_t _bsf(u32_t arg)
|
static inline count_t _bsf(u32_t arg)
|
||||||
{
|
{
|
||||||
count_t n;
|
count_t n;
|
||||||
asm volatile ("xor %0, %0 \n\t"
|
asm volatile ("xorl %0, %0 \n\t"
|
||||||
"bsf %0, %1"
|
"bsf %1, %0"
|
||||||
:"=&r" (n)
|
:"=&r" (n)
|
||||||
:"r"(arg)
|
:"r"(arg)
|
||||||
);
|
);
|
||||||
|
@ -78,3 +78,5 @@ slab_cache_t * slab_cache_create(
|
|||||||
int flags);
|
int flags);
|
||||||
|
|
||||||
void* __fastcall slab_alloc(slab_cache_t *cache, int flags);
|
void* __fastcall slab_alloc(slab_cache_t *cache, int flags);
|
||||||
|
void __fastcall slab_free(slab_cache_t *cache, void *obj);
|
||||||
|
|
||||||
|
@ -147,9 +147,9 @@ extrn @init_heap@8
|
|||||||
extrn @find_large_md@4
|
extrn @find_large_md@4
|
||||||
extrn @find_small_md@4
|
extrn @find_small_md@4
|
||||||
extrn @phis_alloc@4
|
extrn @phis_alloc@4
|
||||||
extrn @mem_alloc@8
|
|
||||||
|
|
||||||
extrn @heap_alloc@8
|
extrn @mem_alloc@8
|
||||||
|
extrn @mem_free@4
|
||||||
|
|
||||||
extrn _slab_cache_init
|
extrn _slab_cache_init
|
||||||
extrn _alloc_page
|
extrn _alloc_page
|
||||||
@ -159,9 +159,6 @@ extrn _get_free_mem
|
|||||||
extrn _bx_from_load
|
extrn _bx_from_load
|
||||||
|
|
||||||
|
|
||||||
@mem_alloc@8 equ @heap_alloc@8
|
|
||||||
|
|
||||||
|
|
||||||
section '.flat' code readable align 4096
|
section '.flat' code readable align 4096
|
||||||
|
|
||||||
use32
|
use32
|
||||||
|
@ -6,7 +6,7 @@ INCLUDE = include/
|
|||||||
|
|
||||||
DEFS = -DUSE_SMP -DCONFIG_DEBUG
|
DEFS = -DUSE_SMP -DCONFIG_DEBUG
|
||||||
|
|
||||||
CFLAGS = -c -O2 -I $(INCLUDE) -fomit-frame-pointer -fno-builtin-printf -masm=intel
|
CFLAGS = -c -O2 -I $(INCLUDE) -fomit-frame-pointer -fno-builtin-printf
|
||||||
LDFLAGS = -shared -s -Map kernel.map --image-base 0x100000 --file-alignment 32
|
LDFLAGS = -shared -s -Map kernel.map --image-base 0x100000 --file-alignment 32
|
||||||
|
|
||||||
KERNEL_SRC:= \
|
KERNEL_SRC:= \
|
||||||
|
Loading…
Reference in New Issue
Block a user