Large cummulative patch for pic16 port.
[fw/sdcc] / device / lib / pic16 / libc / stdlib / realloc.c
1 /*
2  * malloc.c - dynamic memory allocation
3  *
4  * written by Vangelis Rokas, 2004 (vrokas@otenet.gr)
5  *
6  */
7
8 #include "malloc.h"
9
10 extern unsigned char *_dynamicHeap;                     /* pointer to heap */
11
12 unsigned char *realloc(unsigned char *mblock, unsigned char len)
13 {
14   _malloc_rec *pHeap;                   /* pointer to block header */
15   _malloc_rec *temp;
16   unsigned char bLen;                   /* size of block  */
17   unsigned char eLen;
18
19         if(len > MAX_BLOCK_SIZE)
20                 return ((unsigned char *)0);
21
22         len++;          /* increase to count header too */
23
24         pHeap = (_malloc_rec *)(mblock-1);
25         bLen = pHeap->bits.count;
26
27         /* new size is same as old, return pointer */
28         if(bLen == len)return (mblock);
29
30         if(bLen > len) {
31                 /* new segment is smaller than the old one, that's easy! */
32                 pHeap->bits.count = len;
33                 temp = pHeap + len;
34                 temp->bits.alloc = 0;
35                 temp->bits.count = bLen - len;
36
37                 return (((unsigned char *)pHeap) + 1);
38         }
39
40         /* so, new segment has size bigger than the old one
41          * we can only return a valid pointer only when after
42          * the block there is an empty block that can be merged
43          * to produce a new block of the requested size, otherwise
44          * we return NULL */
45
46         temp = pHeap + pHeap->bits.count;
47         eLen = bLen;
48         while((temp->datum) && (!temp->bits.alloc) && (eLen < len)) {
49                 eLen += temp->bits.count;
50                 temp += temp->bits.count;
51         }
52
53         if(eLen >= len) {
54                 int i;
55                 /* so we found one, adjust memory blocks */
56                 temp = pHeap;
57
58                 temp->bits.count = len;
59                 eLen -= len;
60                 temp += len;
61
62                 while(eLen>0) {
63                         if(eLen > MAX_BLOCK_SIZE)i = MAX_BLOCK_SIZE;
64                         else i = eLen;
65
66                         temp->bits.count = i;
67                         temp->bits.alloc = 0;
68                         temp += i;
69                         eLen -= i;
70                 }
71
72                 return (((unsigned char *)pHeap) + 1);
73         }
74
75
76         /* no could not find a valid block, return NULL */
77
78   return ((unsigned char *)0);
79 }