Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. #include <unistd.h>
  2. #include <errno.h>
  3. #include <sys/types.h>
  4.  
  5. static void * ___brk_addr = 0;
  6. extern char end[];
  7. static unsigned long min_brk,max_brk,cur_brk;
  8. extern unsigned long __menuet__memsize;
  9. static void* cur_dynamic_area;
  10. static unsigned cur_total_size;
  11.  
  12. static inline void heap_init(void)
  13. {
  14.         __asm__("int $0x40" :: "a"(68),"b"(11));
  15. }
  16.  
  17. static inline void* heap_alloc(unsigned size)
  18. {
  19.         void* res;
  20.         __asm__("int $0x40" : "=a"(res) : "a"(68),"b"(12),"c"(size));
  21.         return res;
  22. }
  23.  
  24. static inline void heap_free(void* ptr)
  25. {
  26.         __asm__("int $0x40" :: "a"(68),"b"(13),"c"(ptr));
  27. }
  28.  
  29. void init_brk(void)
  30. {
  31.  cur_brk=min_brk=(((unsigned long)&end)+0xfff)&~0xfff;
  32.  max_brk=(__menuet__memsize-32768)&~0xfff;
  33.  ___brk_addr=(void *)min_brk;
  34.  cur_dynamic_area = NULL;
  35.  cur_total_size = max_brk;
  36.  heap_init();
  37. }
  38.  
  39. /*static int sys_brk(unsigned long end_data_seg)
  40. {
  41.  if(!end_data_seg) return cur_brk;
  42.  if (end_data_seg >= min_brk &&
  43.      end_data_seg < max_brk)
  44.   cur_brk = end_data_seg;
  45.  return cur_brk;
  46. }*/
  47.  
  48. /*int brk(void *_heaptop)
  49. {
  50.  return sys_brk((unsigned long)_heaptop);
  51. }
  52.  
  53. static int __init_brk (void)
  54. {
  55.  if (___brk_addr == 0)
  56.  {
  57.   ___brk_addr=(void *)sys_brk(0);
  58.   if (___brk_addr == 0)
  59.   {
  60.    errno = ENOMEM;
  61.    return -1;
  62.   }
  63.  }
  64.  return 0;
  65. }*/
  66.  
  67. void * sbrk(int increment)
  68. {
  69. /* if (__init_brk () == 0)
  70.  {
  71.   void * tmp = ___brk_addr+increment;
  72.   ___brk_addr=(void *)sys_brk((unsigned long)tmp);
  73.   if (___brk_addr == tmp) return tmp-increment;
  74.   errno = ENOMEM;
  75.   return ((void *) -1);
  76.  }
  77.  return ((void *) -1);*/
  78.         void* res;
  79.         unsigned long tmp;
  80.         if (increment <= 0)
  81.         {
  82.                 /* release memory */
  83.                 while (cur_dynamic_area && increment)
  84.                 {
  85.                         tmp = cur_brk - (unsigned long)cur_dynamic_area -
  86.                                 3*sizeof(void*);
  87.                         if (tmp > increment)
  88.                                 tmp = increment;
  89.                         cur_brk -= tmp;
  90.                         increment -= tmp;
  91.                         if (cur_brk == (unsigned long)cur_dynamic_area + 3*sizeof(void*))
  92.                         {
  93.                                 cur_brk = (unsigned long)((void**)cur_dynamic_area)[1];
  94.                                 max_brk = (unsigned long)((void**)cur_dynamic_area)[2];
  95.                                 res = cur_dynamic_area;
  96.                                 cur_dynamic_area = ((void**)cur_dynamic_area)[0];
  97.                                 heap_free(res);
  98.                         }
  99.                 }
  100.                 if (!cur_dynamic_area)
  101.                 {
  102.                         cur_brk += increment;
  103.                         if (cur_brk < min_brk)
  104.                                 cur_brk = min_brk;
  105.                 }
  106.                 return (void*)cur_brk;
  107.         }
  108.         /* allocate memory */
  109.         if (cur_brk + increment <= max_brk)
  110.         {
  111.                 /* We have memory in current block, so use it */
  112.                 res = (void*)cur_brk;
  113.                 cur_brk += increment;
  114.                 return res;
  115.         }
  116.         tmp = 65536;
  117.         /* We do not have memory in current block, so allocate new one */
  118.         if (increment > 65536 - 3*sizeof(void*))
  119.                 tmp = (increment + 3*sizeof(void*) + 0xFFF) & ~0xFFF;
  120.         res = heap_alloc(tmp);
  121.         if (!res)
  122.         {
  123.                 errno = ENOMEM;
  124.                 return (void*)-1;
  125.         }
  126.         ((void**)res)[0] = cur_dynamic_area;
  127.         ((void**)res)[1] = (void*)cur_brk;
  128.         ((void**)res)[2] = (void*)max_brk;
  129.         cur_dynamic_area = res;
  130.         cur_brk = (unsigned long)res + 3*sizeof(void*);
  131.         max_brk = (unsigned long)res + tmp;
  132.         res = (void*)cur_brk;
  133.         cur_brk += increment;
  134.         return (void*)res;
  135. }
  136.