1) slab allocator

2) new kernel heap

git-svn-id: svn://kolibrios.org@859 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Sergey Semyonov (Serge) 2008-09-10 13:04:24 +00:00
parent 67aca9ac45
commit 2b91637d4d
18 changed files with 1148 additions and 758 deletions

View File

@ -69,7 +69,7 @@ __start:
; ENABLE PAGING ; ENABLE PAGING
mov ecx, 32 mov ecx, 64
mov edi, _sys_pdbr+(OS_BASE shr 20)+(0x100000000-OS_BASE) mov edi, _sys_pdbr+(OS_BASE shr 20)+(0x100000000-OS_BASE)
mov eax, PG_LARGE+PG_SW mov eax, PG_LARGE+PG_SW
@@: @@:

View File

@ -544,8 +544,6 @@ struc MEM_STATE
struc PG_DATA struc PG_DATA
{ .mem_amount dd ? { .mem_amount dd ?
.vesa_mem dd ? .vesa_mem dd ?
.pages_count dd ?
.pages_free dd ?
.pages_faults dd ? .pages_faults dd ?
.pagemap_size dd ? .pagemap_size dd ?
.kernel_pages dd ? .kernel_pages dd ?

View File

@ -0,0 +1,295 @@
#include <types.h>
#include <core.h>
#include <spinlock.h>
#include <link.h>
#include <mm.h>
#include <slab.h>
typedef struct
{
link_t link;
link_t adj;
addr_t base;
size_t size;
void* parent;
u32_t reserved;
}md_t;
typedef struct {
SPINLOCK_DECLARE(lock); /**< this lock protects everything below */
u32_t availmask;
link_t list[32];
}heap_t;
slab_cache_t *md_slab;
slab_cache_t *phm_slab;
heap_t lheap;
heap_t sheap;
static inline void _set_lmask(count_t idx)
{ asm volatile ("bts DWORD PTR [_lheap], %0"::"r"(idx):"cc"); }
static inline void _reset_lmask(count_t idx)
{ asm volatile ("btr DWORD PTR [_lheap], %0"::"r"(idx):"cc"); }
static inline void _set_smask(count_t idx)
{ asm volatile ("bts DWORD PTR [_sheap], %0"::"r"(idx):"cc"); }
static inline void _reset_smask(count_t idx)
{ asm volatile ("btr DWORD PTR [_sheap], %0"::"r"(idx):"cc"); }
int __fastcall init_heap(addr_t base, size_t size)
{
md_t *md;
u32_t i;
ASSERT(base != 0);
ASSERT(size != 0)
ASSERT(base & 0x3FFFFF == 0);
ASSERT(size & 0x3FFFFF == 0);
for (i = 0; i < 32; i++)
{
list_initialize(&lheap.list[i]);
list_initialize(&sheap.list[i]);
};
md_slab = slab_cache_create(sizeof(md_t), 32,NULL,NULL,SLAB_CACHE_MAGDEFERRED);
md = (md_t*)slab_alloc(md_slab,0);
list_initialize(&md->adj);
md->base = base;
md->size = size;
md->parent = NULL;
md->reserved = 0;
list_prepend(&md->link, &lheap.list[31]);
lheap.availmask = 0x80000000;
sheap.availmask = 0x00000000;
// phm_slab = slab_cache_create(sizeof(phismem_t), 32,NULL,NULL,SLAB_CACHE_MAGDEFERRED);
return 1;
};
md_t* __fastcall find_large_md(size_t size)
{
md_t *md = NULL;
count_t idx0;
u32_t mask;
ASSERT(size & 0x3FFFFF == 0);
idx0 = (size>>22) - 1 < 32 ? (size>>22) - 1 : 31;
mask = lheap.availmask & ( -1<<idx0 );
if(mask)
{
idx0 = _bsf(mask);
ASSERT( !list_empty(&lheap.list[idx0]))
md = (md_t*)lheap.list[idx0].next;
}
else
return NULL;
list_remove((link_t*)md);
if(list_empty(&lheap.list[idx0]))
_reset_lmask(idx0);
if(md->size > size)
{
count_t idx1;
md_t *new_md = (md_t*)slab_alloc(md_slab,0);
link_initialize(&new_md->link);
list_insert(&md->adj, &new_md->adj);
new_md->base = md->base;
new_md->size = size;
md->base+= size;
md->size-= size;
idx1 = (md->size>>22) - 1 < 32 ? (md->size>>22) - 1 : 31;
list_prepend(&md->link, &lheap.list[idx1]);
_set_lmask(idx1);
return new_md;
}
return md;
}
md_t* __fastcall find_small_md(size_t size)
{
eflags_t efl;
md_t *md = NULL;
count_t idx0;
u32_t mask;
ASSERT(size & 0xFFF == 0);
efl = safe_cli();
idx0 = (size>>12) - 1 < 32 ? (size>>12) - 1 : 31;
mask = sheap.availmask & ( -1<<idx0 );
if(mask)
{
idx0 = _bsf(mask);
ASSERT( !list_empty(&sheap.list[idx0]))
md = (md_t*)sheap.list[idx0].next;
list_remove((link_t*)md);
if(list_empty(&sheap.list[idx0]))
_reset_smask(idx0);
}
else
{
md_t *lmd;
lmd = find_large_md((size+0x3FFFFF)&~0x3FFFFF);
if( !lmd)
{
safe_sti(efl);
return NULL;
};
md = (md_t*)slab_alloc(md_slab,0);
link_initialize(&md->link);
list_initialize(&md->adj);
md->base = lmd->base;
md->size = lmd->size;
md->parent = lmd;
md->reserved = 0;
};
if(md->size > size)
{
count_t idx1;
md_t *new_md = (md_t*)slab_alloc(md_slab,0);
link_initialize(&new_md->link);
list_insert(&md->adj, &new_md->adj);
new_md->base = md->base;
new_md->size = size;
new_md->parent = md->parent;
new_md->reserved = 0;
md->base+= size;
md->size-= size;
idx1 = (md->size>>22) - 1 < 32 ? (md->size>>22) - 1 : 31;
list_prepend(&md->link, &sheap.list[idx1]);
_set_smask(idx1);
safe_sti(efl);
return new_md;
}
safe_sti(efl);
return md;
}
phismem_t* __fastcall phis_alloc(count_t count)
{
phismem_t *phm;
count_t tmp;
phm = (phismem_t*)slab_alloc(phm_slab, 0);
phm->count = count;
tmp = count;
while(tmp)
{
u32_t order;
asm volatile ("bsr %0, %1":"=&r"(order):"r"(tmp):"cc");
asm volatile ("btr %0, %1" :"=r"(tmp):"r"(order):"cc");
phm->frames[order] = core_alloc(order);
};
return phm;
}
#define page_tabs 0xDF800000
void map_phm(addr_t base, phismem_t *phm, u32_t mapflags)
{
count_t count;
addr_t *pte;
count = phm->count;
pte = &((addr_t*)page_tabs)[base>>12];
while(count)
{
u32_t order;
addr_t frame;
count_t size;
asm volatile ("bsr %0, %1":"=&r"(order):"r"(count):"cc");
asm volatile ("btr %0, %1" :"=r"(count):"r"(order):"cc");
frame = phm->frames[order] | mapflags;
size = (1 << order);
while(size--)
{
*pte++ = frame;
frame+= 4096;
}
}
};
void* __fastcall mem_alloc(size_t size, u32_t flags)
{
md_t *md;
phismem_t *phm;
size = (size+4095)&~4095;
md = find_small_md(size);
if( md )
{
phm = phis_alloc(size>>12);
map_phm(md->base, phm, flags);
return (void*)md->base;
}
return NULL;
};
void* __stdcall alloc_kernel_space(size_t size); //__asm__("alloc_kernel_space");
void* __stdcall alloc_kernel_space(size_t size)
{
md_t *md;
size = (size+4095)&~4095;
md = find_small_md(size);
if( md )
return (void*)md->base;
return NULL;
}
//void* __stdcall kernel_alloc(size_t size)
//{
//
// return NULL;
//}
//*/

View File

@ -38,506 +38,10 @@ block_base equ MEM_BLOCK.base
block_size equ MEM_BLOCK.size block_size equ MEM_BLOCK.size
block_flags equ MEM_BLOCK.flags 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 align 4
proc free_kernel_space stdcall uses ebx ecx edx esi edi, base:dword 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 ret
endp endp
@ -555,8 +59,9 @@ proc kernel_alloc stdcall, size:dword
add eax, 4095 add eax, 4095
and eax, not 4095; and eax, not 4095;
mov [size], eax mov [size], eax
and eax, eax test eax, eax
jz .err jz .err
mov ebx, eax mov ebx, eax
shr ebx, 12 shr ebx, 12
mov [pages_count], ebx mov [pages_count], ebx
@ -617,172 +122,11 @@ endp
align 4 align 4
proc kernel_free stdcall, base:dword 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 ret
endp 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_next
restore block_prev restore block_prev

View File

@ -174,7 +174,7 @@ release_pages:
add esi, 4 add esi, 4
dec ecx dec ecx
jnz @B jnz @B
mov [pg_data.pages_free], ebp ; mov [pg_data.pages_free], ebp
and [pg_data.pg_mutex],0 and [pg_data.pg_mutex],0
popad popad
ret ret
@ -901,12 +901,13 @@ sysfn_meminfo:
cmp ebx, OS_BASE cmp ebx, OS_BASE
jae .fail jae .fail
mov eax, [pg_data.pages_count] mov eax, [_mem_amount]
shr eax, 12
mov [ebx], eax mov [ebx], eax
shl eax, 12 shl eax, 12
mov [esp+36], eax mov [esp+36], eax
mov ecx, [pg_data.pages_free] call _get_free_mem
mov [ebx+4], ecx mov [ebx+4], eax
mov edx, [pg_data.pages_faults] mov edx, [pg_data.pages_faults]
mov [ebx+8], edx mov [ebx+8], edx
mov esi, [heap_size] mov esi, [heap_size]

View File

@ -30,13 +30,12 @@ static void __fastcall buddy_system_free(zone_t *z, link_t *block);
static void zone_mark_unavailable(zone_t *zone, index_t frame_idx); static void zone_mark_unavailable(zone_t *zone, index_t frame_idx);
static addr_t __fastcall zone_alloc(zone_t *zone, u32_t order); static addr_t __fastcall zone_alloc(zone_t *zone, u32_t order);
void __fastcall zone_free(zone_t *zone, pfn_t frame_idx);
size_t buddy_conf_size(int max_order); size_t buddy_conf_size(int max_order);
static inline void frame_initialize(frame_t *frame); static inline void frame_initialize(frame_t *frame);
static inline u32_t fnzb(u32_t arg);
void init_mm(); void init_mm();
@ -211,16 +210,6 @@ static inline void frame_initialize(frame_t *frame)
frame->buddy_order = 0; frame->buddy_order = 0;
} }
static inline count_t fnzb(u32_t arg)
{
int n;
asm volatile ("xor %0, %0 \n\t"
"bsr %0, %1"
:"=r" (n)
:"r"(arg)
);
return n;
}
static link_t *buddy_find_block(zone_t *zone, link_t *child, static link_t *buddy_find_block(zone_t *zone, link_t *child,
u32_t order) u32_t order)
@ -502,6 +491,7 @@ static __fastcall pfn_t zone_frame_alloc(zone_t *zone, u32_t order)
/* get frame address */ /* get frame address */
v = make_frame_index(zone, frame); v = make_frame_index(zone, frame);
return v; return v;
} }
@ -518,6 +508,17 @@ void __fastcall frame_set_parent(pfn_t pfn, void *data)
spinlock_unlock(&z_core.lock); spinlock_unlock(&z_core.lock);
} }
void* __fastcall frame_get_parent(pfn_t pfn)
{
// zone_t *zone = find_zone_and_lock(pfn, &hint);
void *res;
spinlock_lock(&z_core.lock);
res = zone_get_frame(&z_core, pfn)->parent;
spinlock_unlock(&z_core.lock);
return res;
}
static inline int to_order(count_t arg) static inline int to_order(count_t arg)
{ {
@ -548,7 +549,7 @@ addr_t __fastcall zone_alloc(zone_t *zone, u32_t order)
return (v << FRAME_WIDTH); return (v << FRAME_WIDTH);
} }
addr_t core_alloc(u32_t order) //__cdecl __dllexport addr_t __fastcall core_alloc(u32_t order) //export
{ {
eflags_t efl; eflags_t efl;
pfn_t v; pfn_t v;
@ -562,6 +563,17 @@ addr_t core_alloc(u32_t order) //__cdecl __dllexport
return (v << FRAME_WIDTH); return (v << FRAME_WIDTH);
}; };
void __fastcall core_free(addr_t frame) //export
{
eflags_t efl;
efl = safe_cli();
spinlock_lock(&z_core.lock);
zone_free(&z_core, frame>>12);
spinlock_unlock(&z_core.lock);
safe_sti(efl);
}
addr_t alloc_page() //obsolete addr_t alloc_page() //obsolete
{ {
eflags_t efl; eflags_t efl;
@ -619,17 +631,6 @@ void __fastcall zone_free(zone_t *zone, pfn_t frame_idx)
} }
} }
void core_free(addr_t frame) //export
{
eflags_t efl;
efl = safe_cli();
spinlock_lock(&z_core.lock);
zone_free(&z_core, frame>>12);
spinlock_unlock(&z_core.lock);
safe_sti(efl);
}
void frame_free(addr_t frame) //export void frame_free(addr_t frame) //export
{ {
eflags_t efl; eflags_t efl;
@ -642,3 +643,8 @@ void frame_free(addr_t frame) //export
safe_sti(efl); safe_sti(efl);
} }
count_t get_free_mem()
{
return z_core.free_count;
}

View File

@ -213,10 +213,10 @@ do_change_task:
; set thread io map ; set thread io map
mov ecx, [ebx+APPDATA.io_map] ; mov ecx, [ebx+APPDATA.io_map]
mov edx, [ebx+APPDATA.io_map+4] ; mov edx, [ebx+APPDATA.io_map+4]
mov dword [page_tabs+((tss._io_map_0 and -4096) shr 10)], ecx ; mov dword [page_tabs+((tss._io_map_0 and -4096) shr 10)], ecx
mov dword [page_tabs+((tss._io_map_1 and -4096) shr 10)], edx ; mov dword [page_tabs+((tss._io_map_1 and -4096) shr 10)], edx
mov eax, [ebx+APPDATA.dir_table] mov eax, [ebx+APPDATA.dir_table]
cmp eax, [esi+APPDATA.dir_table] cmp eax, [esi+APPDATA.dir_table]

View File

@ -0,0 +1,471 @@
#include <types.h>
#include <core.h>
#include <spinlock.h>
#include <link.h>
#include <mm.h>
#include <slab.h>
extern zone_t z_core;
static LIST_INITIALIZE(slab_cache_list);
static slab_cache_t *slab_cache;
static slab_cache_t slab_cache_cache;
static slab_t *slab_create();
static slab_cache_t * slab_cache_alloc();
void slab_free(slab_cache_t *cache, void *obj);
/**
* Allocate frames for slab space and initialize
*
*/
static slab_t * slab_space_alloc(slab_cache_t *cache, int flags)
{
void *data;
slab_t *slab;
size_t fsize;
unsigned int i;
u32_t p;
data = (void*)PA2KA(core_alloc(cache->order));
if (!data) {
return NULL;
}
slab = (slab_t*)slab_create();
if (!slab) {
core_free(KA2PA(data));
return NULL;
}
/* Fill in slab structures */
for (i = 0; i < ((u32_t) 1 << cache->order); i++)
frame_set_parent(ADDR2PFN(KA2PA(data)) + i, slab);
slab->start = data;
slab->available = cache->objects;
slab->nextavail = (void*)data;
slab->cache = cache;
for (i = 0, p = (u32_t)slab->start; i < cache->objects; i++)
{
*(addr_t *)p = p+cache->size;
p = p+cache->size;
};
atomic_inc(&cache->allocated_slabs);
return slab;
}
/**
* Take new object from slab or create new if needed
*
* @return Object address or null
*/
static void * slab_obj_create(slab_cache_t *cache, int flags)
{
slab_t *slab;
void *obj;
spinlock_lock(&cache->slablock);
if (list_empty(&cache->partial_slabs)) {
/* Allow recursion and reclaiming
* - this should work, as the slab control structures
* are small and do not need to allocate with anything
* other than frame_alloc when they are allocating,
* that's why we should get recursion at most 1-level deep
*/
slab = slab_space_alloc(cache, flags);
if (!slab)
{
spinlock_unlock(&cache->slablock);
return NULL;
}
} else {
slab = list_get_instance(cache->partial_slabs.next, slab_t, link);
list_remove(&slab->link);
}
obj = slab->nextavail;
slab->nextavail = *(void**)obj;
slab->available--;
if (!slab->available)
list_prepend(&slab->link, &cache->full_slabs);
else
list_prepend(&slab->link, &cache->partial_slabs);
spinlock_unlock(&cache->slablock);
// if (cache->constructor && cache->constructor(obj, flags)) {
/* Bad, bad, construction failed */
// slab_obj_destroy(cache, obj, slab);
// return NULL;
// }
return obj;
}
/** Map object to slab structure */
static slab_t * obj2slab(void *obj)
{
return (slab_t *) frame_get_parent(ADDR2PFN(KA2PA(obj)));
}
/** Allocate new object from cache - if no flags given, always returns
memory */
void* __fastcall slab_alloc(slab_cache_t *cache, int flags)
{
eflags_t efl;
void *result = NULL;
/* Disable interrupts to avoid deadlocks with interrupt handlers */
efl = safe_cli();
// if (!(cache->flags & SLAB_CACHE_NOMAGAZINE)) {
// result = magazine_obj_get(cache);
// }
// if (!result)
result = slab_obj_create(cache, flags);
safe_sti(efl);
// if (result)
// atomic_inc(&cache->allocated_objs);
return result;
}
/**************************************/
/* Slab cache functions */
/** Return number of objects that fit in certain cache size */
static unsigned int comp_objects(slab_cache_t *cache)
{
if (cache->flags & SLAB_CACHE_SLINSIDE)
return ((PAGE_SIZE << cache->order) - sizeof(slab_t)) / cache->size;
else
return (PAGE_SIZE << cache->order) / cache->size;
}
/** Return wasted space in slab */
static unsigned int badness(slab_cache_t *cache)
{
unsigned int objects;
unsigned int ssize;
size_t val;
objects = comp_objects(cache);
ssize = PAGE_SIZE << cache->order;
if (cache->flags & SLAB_CACHE_SLINSIDE)
ssize -= sizeof(slab_t);
val = ssize - objects * cache->size;
return val;
}
/** Initialize allocated memory as a slab cache */
static void
_slab_cache_create(slab_cache_t *cache,
size_t size,
size_t align,
int (*constructor)(void *obj, int kmflag),
int (*destructor)(void *obj),
int flags)
{
int pages;
// ipl_t ipl;
// memsetb((uintptr_t)cache, sizeof(*cache), 0);
// cache->name = name;
//if (align < sizeof(unative_t))
// align = sizeof(unative_t);
// size = ALIGN_UP(size, align);
cache->size = size;
// cache->constructor = constructor;
// cache->destructor = destructor;
cache->flags = flags;
list_initialize(&cache->full_slabs);
list_initialize(&cache->partial_slabs);
list_initialize(&cache->magazines);
// spinlock_initialize(&cache->slablock, "slab_lock");
// spinlock_initialize(&cache->maglock, "slab_maglock");
// if (! (cache->flags & SLAB_CACHE_NOMAGAZINE))
// make_magcache(cache);
/* Compute slab sizes, object counts in slabs etc. */
/* Minimum slab order */
pages = SIZE2FRAMES(cache->size);
/* We need the 2^order >= pages */
if (pages == 1)
cache->order = 0;
else
cache->order = fnzb(pages-1)+1;
while (badness(cache) > SLAB_MAX_BADNESS(cache)) {
cache->order += 1;
}
cache->objects = comp_objects(cache);
/* Add cache to cache list */
// ipl = interrupts_disable();
// spinlock_lock(&slab_cache_lock);
list_append(&cache->link, &slab_cache_list);
// spinlock_unlock(&slab_cache_lock);
// interrupts_restore(ipl);
}
/** Create slab cache */
slab_cache_t * slab_cache_create(
size_t size,
size_t align,
int (*constructor)(void *obj, int kmflag),
int (*destructor)(void *obj),
int flags)
{
slab_cache_t *cache;
cache = (slab_cache_t*)slab_cache_alloc();
_slab_cache_create(cache, size, align, constructor, destructor, flags);
return cache;
}
/**
* Deallocate space associated with slab
*
* @return number of freed frames
*/
static count_t slab_space_free(slab_cache_t *cache, slab_t *slab)
{
frame_free(KA2PA(slab->start));
if (! (cache->flags & SLAB_CACHE_SLINSIDE))
slab_free(slab_cache, slab);
// atomic_dec(&cache->allocated_slabs);
return 1 << cache->order;
}
/**
* Return object to slab and call a destructor
*
* @param slab If the caller knows directly slab of the object, otherwise NULL
*
* @return Number of freed pages
*/
static count_t slab_obj_destroy(slab_cache_t *cache, void *obj,
slab_t *slab)
{
int freed = 0;
if (!slab)
slab = obj2slab(obj);
// ASSERT(slab->cache == cache);
// if (cache->destructor)
// freed = cache->destructor(obj);
// spinlock_lock(&cache->slablock);
// ASSERT(slab->available < cache->objects);
*(void**)obj = slab->nextavail;
slab->nextavail = obj;
slab->available++;
/* Move it to correct list */
if (slab->available == cache->objects) {
/* Free associated memory */
list_remove(&slab->link);
// spinlock_unlock(&cache->slablock);
return freed + slab_space_free(cache, slab);
} else if (slab->available == 1) {
/* It was in full, move to partial */
list_remove(&slab->link);
list_prepend(&slab->link, &cache->partial_slabs);
}
// spinlock_unlock(&cache->slablock);
return freed;
}
/** Return object to cache, use slab if known */
static void _slab_free(slab_cache_t *cache, void *obj, slab_t *slab)
{
// ipl_t ipl;
// ipl = interrupts_disable();
// if ((cache->flags & SLAB_CACHE_NOMAGAZINE) \
|| magazine_obj_put(cache, obj)) {
slab_obj_destroy(cache, obj, slab);
// }
// interrupts_restore(ipl);
// atomic_dec(&cache->allocated_objs);
}
/** Return slab object to cache */
void slab_free(slab_cache_t *cache, void *obj)
{
_slab_free(cache, obj, NULL);
}
static slab_t *slab_create()
{
slab_t *slab;
void *obj;
u32_t p;
// spinlock_lock(&cache->slablock);
if (list_empty(&slab_cache->partial_slabs)) {
/* Allow recursion and reclaiming
* - this should work, as the slab control structures
* are small and do not need to allocate with anything
* other than frame_alloc when they are allocating,
* that's why we should get recursion at most 1-level deep
*/
// spinlock_unlock(&cache->slablock);
// slab = slab_create();
void *data;
unsigned int i;
data = (void*)PA2KA(core_alloc(0));
if (!data) {
return NULL;
}
slab = (slab_t*)((u32_t)data + PAGE_SIZE - sizeof(slab_t));
/* Fill in slab structures */
frame_set_parent(ADDR2PFN(KA2PA(data)), slab);
slab->start = data;
slab->available = slab_cache->objects;
slab->nextavail = (void*)data;
slab->cache = slab_cache;
for (i = 0,p = (u32_t)slab->start;i < slab_cache->objects; i++)
{
*(int *)p = p+slab_cache->size;
p = p+slab_cache->size;
};
atomic_inc(&slab_cache->allocated_slabs);
// spinlock_lock(&cache->slablock);
} else {
slab = list_get_instance(slab_cache->partial_slabs.next, slab_t, link);
list_remove(&slab->link);
}
obj = slab->nextavail;
slab->nextavail = *((void**)obj);
slab->available--;
if (!slab->available)
list_prepend(&slab->link, &slab_cache->full_slabs);
else
list_prepend(&slab->link, &slab_cache->partial_slabs);
// spinlock_unlock(&cache->slablock);
return (slab_t*)obj;
}
static slab_cache_t * slab_cache_alloc()
{
slab_t *slab;
void *obj;
u32_t *p;
if (list_empty(&slab_cache_cache.partial_slabs)) {
/* Allow recursion and reclaiming
* - this should work, as the slab control structures
* are small and do not need to allocate with anything
* other than frame_alloc when they are allocating,
* that's why we should get recursion at most 1-level deep
*/
// spinlock_unlock(&cache->slablock);
// slab = slab_create();
void *data;
unsigned int i;
data = (void*)(PA2KA(core_alloc(0)));
if (!data) {
return NULL;
}
slab = (slab_t*)((u32_t)data + PAGE_SIZE - sizeof(slab_t));
/* Fill in slab structures */
frame_set_parent(ADDR2PFN(KA2PA(data)), slab);
slab->start = data;
slab->available = slab_cache_cache.objects;
slab->nextavail = (void*)data;
slab->cache = &slab_cache_cache;
for (i = 0,p = (u32_t*)slab->start;i < slab_cache_cache.objects; i++)
{
*p = (u32_t)p+slab_cache_cache.size;
p = (u32_t*)((u32_t)p+slab_cache_cache.size);
};
atomic_inc(&slab_cache_cache.allocated_slabs);
// spinlock_lock(&cache->slablock);
} else {
slab = list_get_instance(slab_cache_cache.partial_slabs.next, slab_t, link);
list_remove(&slab->link);
}
obj = slab->nextavail;
slab->nextavail = *((void**)obj);
slab->available--;
if (!slab->available)
list_prepend(&slab->link, &slab_cache_cache.full_slabs);
else
list_prepend(&slab->link, &slab_cache_cache.partial_slabs);
// spinlock_unlock(&cache->slablock);
return (slab_cache_t*)obj;
}
void slab_cache_init(void)
{
_slab_cache_create(&slab_cache_cache, sizeof(slab_cache_t),
sizeof(void *), NULL, NULL,
SLAB_CACHE_NOMAGAZINE | SLAB_CACHE_SLINSIDE);
/* Initialize external slab cache */
slab_cache = slab_cache_create(sizeof(slab_t),
0, NULL, NULL,SLAB_CACHE_MAGDEFERRED);
};

View File

@ -468,7 +468,7 @@ term9:
mov eax, [.slot] mov eax, [.slot]
shl eax, 8 shl eax, 8
mov eax,[SLOT_BASE+eax+APPDATA.dir_table] mov eax,[SLOT_BASE+eax+APPDATA.dir_table]
stdcall destroy_app_space, eax ; stdcall destroy_app_space, eax
mov esi, [.slot] mov esi, [.slot]
cmp [fpu_owner],esi ; if user fpu last -> fpu user = 1 cmp [fpu_owner],esi ; if user fpu last -> fpu user = 1

View File

@ -1074,7 +1074,7 @@ proc set_app_params stdcall,slot:dword, params:dword,\
mov eax, [esi+0x08] ;app_eip mov eax, [esi+0x08] ;app_eip
mov [ebx+REG_EIP], eax ;app_entry mov [ebx+REG_EIP], eax ;app_entry
mov [ebx+REG_CS], dword app_code mov [ebx+REG_CS], dword app_code
mov [ebx+REG_EFLAGS], dword EFL_IOPL1+EFL_IF mov [ebx+REG_EFLAGS], dword EFL_IOPL3+EFL_IF
mov eax, [esi+0x0C] ;app_esp mov eax, [esi+0x0C] ;app_esp
mov [ebx+REG_APP_ESP], eax ;app_stack mov [ebx+REG_APP_ESP], eax ;app_stack

View File

@ -0,0 +1,123 @@
typedef unsigned char u8_t;
typedef unsigned short int u16_t;
typedef unsigned int u32_t;
typedef unsigned long long u64_t;
static inline u8_t inb(u16_t port)
{
u8_t val;
if(port < 0x100)
asm volatile ("in %b0, %w1 \n" : "=a" (val) : "dN" (port) );
else
asm volatile ("in %b0, %w1 \n" : "=a" (val) : "d" (port) );
return val;
}
static inline outb(u16_t port, u8_t val)
{
if (port < 0x100) /* GCC can optimize this if constant */
asm volatile ("out %w0, %b1" : :"dN"(port), "a"(val));
else
asm volatile ("out %w0, %b1" : :"d"(port), "a"(val));
}
/* Convert the integer D to a string and save the string in BUF. If
BASE is equal to 'd', interpret that D is decimal, and if BASE is
equal to 'x', interpret that D is hexadecimal. */
static void itoa (char *buf, int base, int d)
{
char *p = buf;
char *p1, *p2;
unsigned long ud = d;
int divisor = 10;
/* If %d is specified and D is minus, put `-' in the head. */
if (base == 'd' && d < 0)
{
*p++ = '-';
buf++;
ud = -d;
}
else if (base == 'x')
divisor = 16;
/* Divide UD by DIVISOR until UD == 0. */
do
{
int remainder = ud % divisor;
*p++ = (remainder < 10) ? remainder + '0' : remainder + 'a' - 10;
}
while (ud /= divisor);
/* Terminate BUF. */
*p = 0;
/* Reverse BUF. */
p1 = buf;
p2 = p - 1;
while (p1 < p2)
{
char tmp = *p1;
*p1 = *p2;
*p2 = tmp;
p1++;
p2--;
}
}
void putc(int c)
{
while (!(inb(0x3f8+5) & 0x60));
outb(0x3f8,c);
if (c == '\n')
putc('\r');
}
void _printf (const char *format, ...)
{
char **arg = (char **) &format;
int c;
char buf[20];
arg++;
while ((c = *format++) != 0)
{
if (c != '%')
putc(c);
else
{
char *p;
c = *format++;
switch (c)
{
case 'd':
case 'u':
case 'x':
itoa (buf, c, *((int *) arg++));
p = buf;
goto string;
break;
case 's':
p = *arg++;
if (! p)
p = "(null)";
string:
while (*p)
putc(*p++);
break;
default:
putc(*((int *) arg++));
break;
}
}
}
}

View File

@ -9,7 +9,8 @@ $Revision$
pusha pusha
mov eax,[pg_data.pages_free] call _get_free_mem
; 1/32 ; 1/32
shr eax,5 shr eax,5
; round off up to 8 pages ; round off up to 8 pages

View File

@ -46,3 +46,43 @@ static inline void safe_sti(eflags_t efl)
: : "r" (efl) : : "r" (efl)
); );
} }
static inline count_t fnzb(u32_t arg)
{
count_t n;
asm volatile ("xor %0, %0 \n\t"
"bsr %0, %1"
:"=&r" (n)
:"r"(arg)
);
return n;
}
static inline count_t _bsf(u32_t arg)
{
count_t n;
asm volatile ("xor %0, %0 \n\t"
"bsf %0, %1"
:"=&r" (n)
:"r"(arg)
);
return n;
}
static inline void _bts(u32_t *data, count_t val)
{
asm volatile ("bts %0, %1 \n\t"
:
:"g"(data), "r"(val)
:"cc"
);
}
static inline void _btr(u32_t *data, count_t val)
{
asm volatile ("btr %0, %1 \n\t"
:
:"g"(data), "r"(val)
:"cc"
);
}

View File

@ -5,6 +5,9 @@ typedef struct link
struct link *next; struct link *next;
}link_t; }link_t;
#define LIST_INITIALIZE(name) \
link_t name = { .prev = &name, .next = &name }
#define list_get_instance(link, type, member) \ #define list_get_instance(link, type, member) \
((type *)(((u8_t *)(link)) - ((u8_t *)&(((type *)NULL)->member)))) ((type *)(((u8_t *)(link)) - ((u8_t *)&(((type *)NULL)->member))))
@ -48,3 +51,10 @@ static inline void list_prepend(link_t *link, link_t *head)
head->next = link; head->next = link;
} }
static inline list_insert(link_t *old, link_t *new)
{
new->prev = old->prev;
new->next = old;
new->prev->next = new;
old->prev = new;
}

View File

@ -22,9 +22,15 @@ typedef struct {
int flags; int flags;
} zone_t; } zone_t;
typedef struct
{
count_t count;
addr_t frames[18];
}phismem_t;
# define PA2KA(x) (((u32_t) (x)) + OS_BASE)
# define KA2PA(x) (((u32_t) (x)) - OS_BASE) # define PA2KA(x) (((addr_t) (x)) + OS_BASE)
# define KA2PA(x) (((addr_t) (x)) - OS_BASE)
#define PAGE_SIZE 4096 #define PAGE_SIZE 4096
#define FRAME_WIDTH 12 #define FRAME_WIDTH 12
@ -50,10 +56,13 @@ static inline pfn_t ADDR2PFN(addr_t addr)
void init_mm(); void init_mm();
pfn_t core_alloc(u32_t order); addr_t __fastcall core_alloc(u32_t order);
void __fastcall core_free(addr_t frame);
pfn_t alloc_page() __attribute__ ((deprecated)); pfn_t alloc_page() __attribute__ ((deprecated));
pfn_t __stdcall alloc_pages(count_t count) __asm__ ("_alloc_pages") __attribute__ ((deprecated)); pfn_t __stdcall alloc_pages(count_t count) __asm__ ("_alloc_pages") __attribute__ ((deprecated));
void core_free(pfn_t frame);
void frame_free(pfn_t frame); void frame_free(pfn_t frame);
void __fastcall frame_set_parent(pfn_t pfn, void *data);
void* __fastcall frame_get_parent(pfn_t pfn);

View File

@ -0,0 +1,80 @@
typedef struct {
link_t link;
count_t busy; /**< Count of full slots in magazine */
count_t size; /**< Number of slots in magazine */
void *objs[]; /**< Slots in magazine */
} slab_magazine_t;
typedef struct {
slab_magazine_t *current;
slab_magazine_t *last;
SPINLOCK_DECLARE(lock);
} slab_mag_cache_t;
typedef struct {
link_t link;
/* Configuration */
/** Size of slab position - align_up(sizeof(obj)) */
size_t size;
// int (*constructor)(void *obj, int kmflag);
// int (*destructor)(void *obj);
/** Flags changing behaviour of cache */
int flags;
/* Computed values */
u32_t order; /**< Order of frames to be allocated */
unsigned int objects; /**< Number of objects that fit in */
/* Statistics */
atomic_t allocated_slabs;
atomic_t allocated_objs;
atomic_t cached_objs;
/** How many magazines in magazines list */
atomic_t magazine_counter;
/* Slabs */
link_t full_slabs; /**< List of full slabs */
link_t partial_slabs; /**< List of partial slabs */
SPINLOCK_DECLARE(slablock);
/* Magazines */
link_t magazines; /**< List o full magazines */
SPINLOCK_DECLARE(maglock);
/** CPU cache */
slab_mag_cache_t *mag_cache;
} slab_cache_t;
typedef struct {
link_t link; /**< List of full/partial slabs. */
slab_cache_t *cache; /**< Pointer to parent cache. */
count_t available; /**< Count of available items in this slab. */
void *start; /**< Start address of first item. */
void *nextavail; /**< The index of next available item. */
} slab_t;
#define SLAB_INSIDE_SIZE (4096 >> 3)
/** Maximum wasted space we allow for cache */
#define SLAB_MAX_BADNESS(cache) (((size_t) PAGE_SIZE << (cache)->order) >> 2)
/** Do not use per-cpu cache */
#define SLAB_CACHE_NOMAGAZINE 0x1
/** Have control structure inside SLAB */
#define SLAB_CACHE_SLINSIDE 0x2
/** We add magazine cache later, if we have this flag */
#define SLAB_CACHE_MAGDEFERRED (0x4 | SLAB_CACHE_NOMAGAZINE)
slab_cache_t * slab_cache_create(
size_t size,
size_t align,
int (*constructor)(void *obj, int kmflag),
int (*destructor)(void *obj),
int flags);
void* __fastcall slab_alloc(slab_cache_t *cache, int flags);

View File

@ -123,6 +123,12 @@ public @balloc@4
public __setvars public __setvars
public _rd_base
public _rd_fat
public _rd_fat_end
public _rd_root
public _rd_root_end
extrn _16bit_start extrn _16bit_start
extrn _16bit_end extrn _16bit_end
@ -131,15 +137,22 @@ extrn _enter_bootscreen
extrn _init extrn _init
extrn _init_mm extrn _init_mm
public _rd_base extrn @init_heap@8
public _rd_fat extrn @find_large_md@4
public _rd_fat_end extrn @find_small_md@4
public _rd_root extrn @phis_alloc@4
public _rd_root_end extrn @mem_alloc@8
extrn _alloc_kernel_space@4
extrn _slab_cache_init
extrn _alloc_pages extrn _alloc_pages
extrn _alloc_page extrn _alloc_page
extrn _get_free_mem
alloc_kernel_space equ _alloc_kernel_space@4
extrn _bx_from_load extrn _bx_from_load
section '.flat' code readable align 4096 section '.flat' code readable align 4096
@ -349,11 +362,15 @@ _high_code:
; MEMORY MODEL ; MEMORY MODEL
call init_kernel_heap ; FIXME initialize heap after pager
call _init_mm call _init_mm
mov [pg_data.pg_mutex], 0 mov [pg_data.pg_mutex], 0
call _slab_cache_init
mov ecx, 0x80000000
mov edx, 0x40000000
call @init_heap@8
mov esi, _16bit_start mov esi, _16bit_start
mov ecx, _16bit_end mov ecx, _16bit_end
shr ecx, 2 shr ecx, 2
@ -361,8 +378,6 @@ _high_code:
cld cld
rep movsd rep movsd
xchg bx, bx
jmp far 0x60:_enter_bootscreen; jmp far 0x60:_enter_bootscreen;
align 4 align 4
@ -379,8 +394,9 @@ __setvars:
; SAVE & CLEAR 0-0xffff ; SAVE & CLEAR 0-0xffff
cld
xor esi, esi xor esi, esi
mov edi,0x1F0000 mov edi,BOOT_VAR
mov ecx,0x10000 / 4 mov ecx,0x10000 / 4
rep movsd rep movsd
xor edi, edi xor edi, edi
@ -388,6 +404,15 @@ __setvars:
mov ecx,0x10000 / 4 mov ecx,0x10000 / 4
rep stosd rep stosd
mov edi, SLOT_BASE
mov ecx,0x10000 / 4
rep stosd
mov dword [_sys_pdbr], eax
mov dword [_sys_pdbr+4], eax
mov eax, cr3
mov cr3, eax
; SAVE REAL MODE VARIABLES ; SAVE REAL MODE VARIABLES
mov ax, [BOOT_VAR + 0x9031] mov ax, [BOOT_VAR + 0x9031]
mov [IDEContrRegsBaseAddr], ax mov [IDEContrRegsBaseAddr], ax
@ -788,7 +813,6 @@ include 'detect/disks.inc'
; SET MOUSE ; SET MOUSE
;call detect_devices
stdcall load_driver, szPS2MDriver stdcall load_driver, szPS2MDriver
; stdcall load_driver, szCOM_MDriver ; stdcall load_driver, szCOM_MDriver
@ -829,10 +853,10 @@ include 'detect/disks.inc'
add esi, 0x1000 add esi, 0x1000
stdcall map_page,esi,(tss._io_map_1-OS_BASE), PG_MAP stdcall map_page,esi,(tss._io_map_1-OS_BASE), PG_MAP
stdcall map_page,tss._io_map_0,\ ; stdcall map_page,tss._io_map_0,\
(tss._io_map_0-OS_BASE), PG_MAP ; (tss._io_map_0-OS_BASE), PG_MAP
stdcall map_page,tss._io_map_1,\ ; stdcall map_page,tss._io_map_1,\
(tss._io_map_1-OS_BASE), PG_MAP ; (tss._io_map_1-OS_BASE), PG_MAP
; mov ax,[OS_BASE+0x10000+bx_from_load] ; mov ax,[OS_BASE+0x10000+bx_from_load]
; cmp ax,'r1' ; if not rused ram disk - load network configuration from files {SPraid.simba} ; cmp ax,'r1' ; if not rused ram disk - load network configuration from files {SPraid.simba}
@ -842,17 +866,6 @@ include 'detect/disks.inc'
; LOAD FIRST APPLICATION ; LOAD FIRST APPLICATION
cmp byte [BOOT_VAR+0x9030],1
jne no_load_vrr_m
mov ebp, vrr_m
call fs_execute_from_sysdir
cmp eax,2 ; if vrr_m app found (PID=2)
je first_app_found
no_load_vrr_m:
mov ebp, firstapp mov ebp, firstapp
call fs_execute_from_sysdir call fs_execute_from_sysdir
@ -1893,18 +1906,6 @@ sys_midi:
ret ret
detect_devices:
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
;include 'detect/commouse.inc'
;include 'detect/ps2mouse.inc'
;include 'detect/dev_fd.inc'
;include 'detect/dev_hdcd.inc'
;include 'detect/sear_par.inc'
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ret
sys_end: sys_end:
mov eax,[TASK_BASE] mov eax,[TASK_BASE]
@ -2170,7 +2171,7 @@ sysfn_mouse_acceleration: ; 18.19 = set/get mouse features
ret ret
sysfn_getfreemem: sysfn_getfreemem:
mov eax, [pg_data.pages_free] call _get_free_mem
shl eax, 2 shl eax, 2
mov [esp+32],eax mov [esp+32],eax
ret ret

View File

@ -4,23 +4,31 @@ FASM = fasm.exe
INCLUDE = include/ INCLUDE = include/
DEFS = -DUSE_SMP DEFS = -DUSE_SMP -DCONFIG_DEBUG
CFLAGS = -c -O2 -DCONFIG_DEBUG -I $(INCLUDE) -fomit-frame-pointer -fno-builtin-printf -masm=intel CFLAGS = -c -O2 -I $(INCLUDE) -fomit-frame-pointer -fno-builtin-printf -masm=intel
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:= \
kernel.asm \ kernel.asm \
core/memory.inc \
core/heap.inc \
core/taskman.inc \
core/sys32.inc \
core/dll.inc
PE_SRC:= \
init.c \ init.c \
mm.c \ mm.c \
slab.c \
heap.c \
spinlock.c \ spinlock.c \
boot/boot.asm \ boot/boot.asm \
boot/start.asm boot/start.asm
KERNEL_OBJS = $(patsubst %.s, bin/%.obj, $(patsubst %.asm, bin/%.obj,\ PE_OBJS = $(patsubst %.s, bin/%.obj, $(patsubst %.asm, bin/%.obj,\
$(patsubst %.c, bin/%.obj, $(KERNEL_SRC)))) $(patsubst %.c, bin/%.obj, $(PE_SRC))))
all: kernel.gz all: kernel.gz
@ -28,8 +36,8 @@ all: kernel.gz
kernel.gz :kernel.mnt kernel.gz :kernel.mnt
7z a -tgzip kernel.gz kernel.mnt 7z a -tgzip kernel.gz kernel.mnt
kernel.mnt: $(KERNEL_OBJS) Makefile ld.x kernel.mnt: kernel.obj $(PE_OBJS) Makefile ld.x
ld $(LDFLAGS) -T ld.x -o $@ $(KERNEL_OBJS) ld $(LDFLAGS) -T ld.x -o $@ kernel.obj $(PE_OBJS)
bin/%.obj : core/%.c Makefile bin/%.obj : core/%.c Makefile
$(CC) $(CFLAGS) -o $@ $< $(CC) $(CFLAGS) -o $@ $<
@ -37,6 +45,9 @@ bin/%.obj : core/%.c Makefile
bin/%.obj: %.asm bin/%.obj: %.asm
$(FASM) $< $@ $(FASM) $< $@
kernel.obj: $(KERNEL_SRC)
$(FASM) kernel.asm
all: $(SUBDIRS) all: $(SUBDIRS)
.PHONY: all .PHONY: all