~ubuntu-branches/ubuntu/breezy/avr-libc/breezy

« back to all changes in this revision

Viewing changes to libc/stdlib/malloc.c

  • Committer: Bazaar Package Importer
  • Author(s): Hakan Ardo
  • Date: 2002-04-15 14:53:38 UTC
  • Revision ID: james.westby@ubuntu.com-20020415145338-c8hi0tn5bx74w7o3
Tags: upstream-20020203
ImportĀ upstreamĀ versionĀ 20020203

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <stdlib.h>
 
2
 
 
3
#define XSIZE(x) ((*x)>>1)
 
4
#define FREE_P(x) (!((*x)&1))
 
5
#define MARK_BUSY(x) ((*x)|=1)
 
6
#define MARK_FREE(x) ((*x)&=0xfffe)
 
7
 
 
8
extern size_t __bss_end;
 
9
#define GET_HEAP_BOTTOM(h) asm volatile ("in %A0, __SP_L__\n\t"            \
 
10
                                         "in %B0, __SP_H__" : "=r" (h) :)
 
11
 
 
12
void *malloc (size_t size)
 
13
{
 
14
  static char once;
 
15
  size_t * heap_bottom;
 
16
  size_t * heap_top = &__bss_end;
 
17
  char f = 0;
 
18
 
 
19
  if (!once) {
 
20
    once = 1;
 
21
    *heap_top = 0xFFFE;
 
22
  }
 
23
  GET_HEAP_BOTTOM (heap_bottom);
 
24
  heap_bottom -= 20;
 
25
  size = (size+1) >> 1; /* round to 2 */
 
26
  do
 
27
    {
 
28
      size_t xsize = XSIZE (heap_top);
 
29
      size_t * heap_next = &heap_top[xsize + 1];
 
30
      if ((xsize<<1)+2 == 0)
 
31
        {
 
32
          f = 1;
 
33
        }
 
34
      if (FREE_P (heap_top))
 
35
        {
 
36
          if (f)
 
37
            {
 
38
              xsize = heap_bottom - heap_top - 1;
 
39
            }
 
40
          else if (FREE_P(heap_next))
 
41
            {
 
42
              *heap_top = ( (XSIZE(heap_next)<<1) + 2 == 0
 
43
                            ? 0xfffe
 
44
                            : (xsize + XSIZE(heap_next) + 1)<<1);
 
45
              continue;
 
46
            }
 
47
          if (xsize >= size)
 
48
            {
 
49
              if (f)
 
50
                heap_top[size + 1] = 0xfffe;
 
51
              else if (xsize != size)
 
52
                heap_top[size + 1] = (xsize - size - 1) << 1;
 
53
              *heap_top = size << 1;
 
54
              MARK_BUSY (heap_top);
 
55
              return heap_top+1;
 
56
            }
 
57
        }
 
58
      heap_top += xsize + 1;
 
59
    } while (!f);
 
60
  return NULL;
 
61
}
 
62
 
 
63
void free (void *p)
 
64
{
 
65
  size_t *t = (size_t*)p - 1;
 
66
  MARK_FREE (t);
 
67
}
 
68