00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00023 #include "../include/beeos.h"
00024 #include "../include/bbit.h"
00025 #define IN_BMEM
00026 #include "../include/bmalloc.h"
00027 #include "../include/bstring.h"
00028 #include "../include/arch/param.h"
00029
00030 #include <stdarg.h>
00031 #include "../include/bprintf.h"
00032
00033 #ifdef HOSTED_BUILD
00034 #include <malloc.h>
00035 #endif
00036 #ifdef BMEM_DEBUG
00037
00038 #endif
00039
00040
00041 #ifndef HOSTED_BUILD
00042
00043 extern char _end;
00044
00045 #endif
00046
00050 static char *bheap = NULL;
00055 static uchar bheap_bitmap[SRAM_NUMBLOCKS/8 + 1];
00056 static bool lk_bmalloc;
00057 static bool lk_bfree;
00058
00059
00065
00066 void bmallocinit(void)
00067
00068
00069 {
00073 #ifndef HOSTED_BUILD
00074 bheap = (char *) &_end;
00076 #else
00077 bheap = malloc((size_t) SRAM_NUMBLOCKS*SRAM_BLOCKSIZE);
00078 #endif
00079
00080
00081 bmemset(bheap, '\0', (ushort)SRAM_NUMBLOCKS*SRAM_BLOCKSIZE);
00082 bmemset((char *)bheap_bitmap, '\0', (ushort)SRAM_NUMBLOCKS/8);
00083 lk_bfree = false;
00084 lk_bmalloc = false;
00085 #ifdef BMEM_DEBUG
00086
00087 bprintf(20, "bminit: bheap %x, frm %p to %p.\r\n",
00088 (sshort) SRAM_NUMBLOCKS*SRAM_BLOCKSIZE, (sshort) bheap,
00089 (sshort) bheap + SRAM_NUMBLOCKS*SRAM_BLOCKSIZE);
00090
00091 #endif
00092
00093 return;
00094 }
00095
00103
00104
00105 void bfree(char *addr)
00106
00107 {
00121 uchar i = (uchar) SRAM_ADDR2BLOCK(addr);
00122
00123 uchar end_block = 0;
00124
00125 #ifdef BMEM_DEBUG
00126 bprintf(20, "bfr: Free %i blks @%p.\r\n", (sshort)ALLOC_NUMBLOCKS(addr),
00127 (sshort) addr);
00128 #endif
00129
00130 while (lk_bfree);
00131 lk_bfree = true;
00132 end_block = (uchar) i + (uchar) ALLOC_NUMBLOCKS(addr);
00133 for (; i < end_block; i++) SRAM_BITCLR(i);
00134 lk_bfree = false;
00135
00136 return;
00137 }
00138
00148
00149
00150 char *bmalloc(ushort size, char *pExist)
00151
00152
00153
00154 {
00192 char *pMem = NULL;
00193 bool tagged_a_block = false;
00194 bool blockused = false;
00195
00196 uchar reqrd_blocks = (uchar)(size + 1)/(uchar)SRAM_BLOCKSIZE;
00197 uchar i = 0, tagged_block = 0;
00198 uchar exist_block, exist_blocks;
00199
00200 while (lk_bmalloc);
00201 lk_bmalloc = true;
00202
00203
00204 if (((size + 1) % SRAM_BLOCKSIZE) != 0) reqrd_blocks++;
00205
00206 #ifdef BREALLOC
00207
00208 if (NULL != pExist) {
00209 exist_blocks = ALLOC_NUMBLOCKS(pExist);
00210 exist_block = (uchar)SRAM_ADDR2BLOCK(pExist);
00211 if (exist_blocks == reqrd_blocks) return pExist;
00212 else if (exist_blocks < reqrd_blocks) {
00213
00214 i = (exist_blocks - reqrd_blocks);
00215
00216 pMem = (char *) SRAM_BLOCK2ADDR((int)exist_block + (int)i);
00217
00218 *((uchar *)pMem) = i;
00219 bfree(pMem + 1);
00220 ALLOC_NUMBLOCKS(pExist) = reqrd_blocks;
00221 return pExist;
00222 } else {
00223
00224 i = exist_block + exist_blocks;
00225 tagged_block = exist_block;
00226 tagged_a_block = true;
00227 }
00228 # ifdef BMEM_DEBUG
00229 bprintf(20, "bmal: REA: was %i, need %i.\r\n", (sshort)exist_blocks,
00230 (sshort)reqrd_blocks);
00231 # endif
00232 }
00233 #endif
00234
00235 while (i < (uchar)SRAM_NUMBLOCKS) {
00236 blockused = SRAM_BITCHECK(i);
00237 if (tagged_a_block) {
00238 if ((i - tagged_block + 1) >= (ushort) reqrd_blocks) {
00239
00240 for (i = tagged_block; i < ((uchar) reqrd_blocks + tagged_block); i++)
00241 SRAM_BITSET(i);
00242
00243 pMem = (char *) SRAM_BLOCK2ADDR(tagged_block);
00244
00245 *pMem = reqrd_blocks;
00246 pMem++;
00247 break;
00248 } else if (blockused) tagged_a_block = false;
00249 } else if (!blockused) {
00250 tagged_a_block = true;
00251 tagged_block = i;
00252 }
00253 i++;
00254 }
00255
00256 #ifdef BMEM_DEBUG
00257 bprintf(20, "bmal: ONRET: Tag blk %i (%p) for %i blks.\r\n",
00258 (sshort)tagged_block, (sshort) pMem, (sshort) reqrd_blocks);
00259 bprintf(20, "bmal: alc sz @ %p: %i blks = %i.\r\n",
00260 pMem - 1, ALLOC_NUMBLOCKS(pMem), ALLOC_NUMBLOCKS(pMem)*SRAM_BLOCKSIZE);
00261 bprintf(20, "bmal: A2B tst: %i, B2A tst: %p.\r\n",
00262 (sshort) SRAM_ADDR2BLOCK(pMem), (sshort) SRAM_BLOCK2ADDR(tagged_block));
00263 for (i = 0; (i < 10) && (i < SRAM_NUMBLOCKS); i++) {
00264
00265 bprintf(20, "\tbmp: 0x%x.\r\n", (sshort) ((char) bheap_bitmap[i]));
00266
00267 }
00268 #endif
00269 lk_bmalloc = false;
00270
00271 return pMem;
00272 }
00273
00274 #ifdef BREMALLOC
00275
00281
00282
00283 char *bremalloc(ushort size, char *pExist)
00284
00285
00286
00287 {
00302 char *pMem;
00303 uchar oldsize, newsize;
00304
00305 # ifdef BMEM_DEBUG
00306 oldsize = 0;
00307 newsize = 0;
00308 # endif
00309
00310 pMem = bmalloc(size, pExist);
00311 if (NULL != pMem) {
00312
00313 newsize = (uchar) ALLOC_NUMBLOCKS(( (uchar *)pMem ))*SRAM_BLOCKSIZE;
00314 if (NULL != pExist) {
00315
00316 oldsize = (uchar) (ALLOC_NUMBLOCKS(( (uchar *)pExist ))*(uchar)SRAM_BLOCKSIZE);
00317 if (newsize > oldsize)
00318 bmemset(pMem + oldsize, '\0', newsize - oldsize);
00319 if (pMem != pExist) {
00320 bmemcpy(pMem, pExist, oldsize);
00321 }
00322 bfree(pExist);
00323 } else {
00324 bmemset(pMem, '\0', newsize);
00325 }
00326 }
00327
00328 # ifdef BMEM_DEBUG
00329
00330 bprintf(20, "brem: ONRET: oldsz %i, newsz %i, pMem %p, pExist %p.\r\n"
00331 , (sshort) oldsize, (sshort) newsize, (sshort) pMem, (sshort) pExist);
00332
00333 # endif
00334
00335 return pMem;
00336
00337 }
00338
00339 #endif