* src/pic16/device.c (Pics16[]): added devices 18F2550, 18F4331,
[fw/sdcc] / 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$
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     
37     while(hsize < heapsize-1) {
38
39       /* a guess of the next block size */
40       bsize = (heapsize - hsize);
41       if(bsize > MAX_BLOCK_SIZE)bsize = MAX_BLOCK_SIZE;
42       else bsize--;
43       
44       if(bsize < 0)return;
45       
46       /* now we can create the block */
47       pHeap->datum = bsize;
48       pHeap = (_malloc_rec _MALLOC_SPEC *)((unsigned int)pHeap + bsize);
49
50       hsize += bsize;
51       if(!bsize)break;
52     }
53 }
54
55 /* search heap starting from sBlock for a block of size bSize, merging
56  * adjacent blocks if ne necessery */
57 _malloc_rec _MALLOC_SPEC *_mergeHeapBlock(_malloc_rec _MALLOC_SPEC *sBlock, unsigned char bSize)
58 {
59   _malloc_rec _MALLOC_SPEC *temp;
60   unsigned char bLen;
61   unsigned char eLen;
62   unsigned char dat;
63   
64     bLen = sBlock->bits.count;
65   
66     /* current block is not enough, see if we can merge some adjacent memory
67      * blocks to make it fit */
68     temp = (_malloc_rec _MALLOC_SPEC *)((unsigned int)sBlock + bLen);   //sBlock->bits.count);
69     eLen = bLen;
70     while((temp->datum) && (!temp->bits.alloc) && (eLen < bSize)) {
71       eLen += (dat=temp->bits.count);
72       temp = (_malloc_rec _MALLOC_SPEC *)((unsigned int)temp + dat);
73     }
74
75     if(eLen > bSize) {
76       unsigned char i;
77             
78         /* yes, there are some free blocks that can be merged, so merge them... */
79         temp = sBlock;
80         while(eLen > 0) {
81           if(eLen > MAX_BLOCK_SIZE)i = MAX_BLOCK_SIZE;
82             else i = eLen;
83           temp->datum = i;
84           temp = (_malloc_rec _MALLOC_SPEC *)((unsigned int)temp + i);
85           eLen -= i;
86         }
87
88         /* return block starts at the old block start address */
89         return (sBlock);
90     } else {
91       
92       /* no, there are no free blocks after sBlock, so return NULL */
93       return ((_malloc_rec _MALLOC_SPEC *)0);
94     }
95 }