Imported Upstream version 2.9.0
[debian/cc1111] / device / lib / pic16 / libc / stdlib / memmisc.c
1 /*
2  * memmisc.c - heap handling functions
3  *
4  * written by Vangelis Rokas, 2005 <vrokas AT otenet.gr>
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the
8  * Free Software Foundation; either version 2, or (at your option) any
9  * later version.
10  *  
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  * 
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19  * 
20  * In other words, you are welcome to use, share and improve this program.
21  * You are forbidden to forbid anyone else to use, share and improve
22  * what you give them.   Help stamp out software-hoarding!  
23  *
24  * $Id: memmisc.c 3835 2005-08-07 20:09:11Z tecodev $
25  */
26
27 #include <malloc.h>
28
29 void _initHeap(unsigned char _MALLOC_SPEC *dheap, unsigned int heapsize)
30 {
31   _malloc_rec _MALLOC_SPEC *pHeap;
32   unsigned int hsize=0;
33   int bsize;
34   
35     pHeap = (_malloc_rec _MALLOC_SPEC *)dheap;
36     if (heapsize == 0) return;
37     /* we need one byte as the end of block list marker */
38     heapsize--;
39     
40     while (hsize < heapsize) {
41       /* a guess of the next block size */
42       bsize = (heapsize - hsize); /* thus: bsize > 0 */
43       if(bsize > MAX_BLOCK_SIZE) bsize = MAX_BLOCK_SIZE;
44       
45       /* now we can create the block */
46       pHeap->datum = bsize;
47       pHeap = (_malloc_rec _MALLOC_SPEC *)((unsigned int)pHeap + bsize);
48
49       hsize += bsize;
50     }
51
52     /* mark end of block list */
53     pHeap->datum = 0;
54 }
55
56 /* search heap starting from sBlock for a block of size bSize, merging
57  * adjacent blocks if necessery */
58 _malloc_rec _MALLOC_SPEC *_mergeHeapBlock(_malloc_rec _MALLOC_SPEC *sBlock, unsigned char bSize)
59 {
60   _malloc_rec _MALLOC_SPEC *temp;
61   unsigned char bLen;
62   unsigned char eLen;
63   unsigned char dat;
64   
65     bLen = sBlock->bits.count;
66   
67     /* current block is not enough, see if we can merge some adjacent memory
68      * blocks to make it fit */
69     temp = (_malloc_rec _MALLOC_SPEC *)((unsigned int)sBlock + bLen);   //sBlock->bits.count);
70     eLen = bLen;
71     while((temp->datum) && (!temp->bits.alloc) && (eLen <= bSize)) {
72       eLen += (dat=temp->bits.count);
73       temp = (_malloc_rec _MALLOC_SPEC *)((unsigned int)temp + dat);
74     }
75
76     if(eLen > bSize) {
77       unsigned char i;
78             
79         /* yes, there are some free blocks that can be merged, so merge them... */
80         temp = sBlock;
81         while(eLen > 0) {
82           if(eLen > MAX_BLOCK_SIZE)i = MAX_BLOCK_SIZE;
83             else i = eLen;
84           temp->datum = i;
85           temp = (_malloc_rec _MALLOC_SPEC *)((unsigned int)temp + i);
86           eLen -= i;
87         }
88
89         /* return block starts at the old block start address */
90         return (sBlock);
91     } else {
92       
93       /* no, there are no free blocks after sBlock, so return NULL */
94       return ((_malloc_rec _MALLOC_SPEC *)0);
95     }
96 }