Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 4972 → Rev 4973

/programs/develop/libraries/menuetlibc/src/libc/crt0/brk.c
0,0 → 1,135
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
 
static void * ___brk_addr = 0;
extern char end[];
static unsigned long min_brk,max_brk,cur_brk;
extern unsigned long __menuet__memsize;
static void* cur_dynamic_area;
static unsigned cur_total_size;
 
static inline void heap_init(void)
{
__asm__("int $0x40" :: "a"(68),"b"(11));
}
 
static inline void* heap_alloc(unsigned size)
{
void* res;
__asm__("int $0x40" : "=a"(res) : "a"(68),"b"(12),"c"(size));
return res;
}
 
static inline void heap_free(void* ptr)
{
__asm__("int $0x40" :: "a"(68),"b"(13),"c"(ptr));
}
 
void init_brk(void)
{
cur_brk=min_brk=(((unsigned long)&end)+0xfff)&~0xfff;
max_brk=(__menuet__memsize-32768)&~0xfff;
___brk_addr=(void *)min_brk;
cur_dynamic_area = NULL;
cur_total_size = max_brk;
heap_init();
}
 
/*static int sys_brk(unsigned long end_data_seg)
{
if(!end_data_seg) return cur_brk;
if (end_data_seg >= min_brk &&
end_data_seg < max_brk)
cur_brk = end_data_seg;
return cur_brk;
}*/
 
/*int brk(void *_heaptop)
{
return sys_brk((unsigned long)_heaptop);
}
 
static int __init_brk (void)
{
if (___brk_addr == 0)
{
___brk_addr=(void *)sys_brk(0);
if (___brk_addr == 0)
{
errno = ENOMEM;
return -1;
}
}
return 0;
}*/
 
void * sbrk(int increment)
{
/* if (__init_brk () == 0)
{
void * tmp = ___brk_addr+increment;
___brk_addr=(void *)sys_brk((unsigned long)tmp);
if (___brk_addr == tmp) return tmp-increment;
errno = ENOMEM;
return ((void *) -1);
}
return ((void *) -1);*/
void* res;
unsigned long tmp;
if (increment <= 0)
{
/* release memory */
while (cur_dynamic_area && increment)
{
tmp = cur_brk - (unsigned long)cur_dynamic_area -
3*sizeof(void*);
if (tmp > increment)
tmp = increment;
cur_brk -= tmp;
increment -= tmp;
if (cur_brk == (unsigned long)cur_dynamic_area + 3*sizeof(void*))
{
cur_brk = (unsigned long)((void**)cur_dynamic_area)[1];
max_brk = (unsigned long)((void**)cur_dynamic_area)[2];
res = cur_dynamic_area;
cur_dynamic_area = ((void**)cur_dynamic_area)[0];
heap_free(res);
}
}
if (!cur_dynamic_area)
{
cur_brk += increment;
if (cur_brk < min_brk)
cur_brk = min_brk;
}
return (void*)cur_brk;
}
/* allocate memory */
if (cur_brk + increment <= max_brk)
{
/* We have memory in current block, so use it */
res = (void*)cur_brk;
cur_brk += increment;
return res;
}
tmp = 65536;
/* We do not have memory in current block, so allocate new one */
if (increment > 65536 - 3*sizeof(void*))
tmp = (increment + 3*sizeof(void*) + 0xFFF) & ~0xFFF;
res = heap_alloc(tmp);
if (!res)
{
errno = ENOMEM;
return (void*)-1;
}
((void**)res)[0] = cur_dynamic_area;
((void**)res)[1] = (void*)cur_brk;
((void**)res)[2] = (void*)max_brk;
cur_dynamic_area = res;
cur_brk = (unsigned long)res + 3*sizeof(void*);
max_brk = (unsigned long)res + tmp;
res = (void*)cur_brk;
cur_brk += increment;
return (void*)res;
}