diff --git a/src/lib/libc_old/stdlib/malloc.c b/src/lib/libc_old/stdlib/malloc.c index ca564d9..51c12c3 100644 --- a/src/lib/libc_old/stdlib/malloc.c +++ b/src/lib/libc_old/stdlib/malloc.c @@ -1,25 +1,49 @@ -/************************************************************************************** +/***************************************************************************************** Copyright (c) 2002 The UbixOS Project All rights reserved. -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: -Redistributions of source code must retain the above copyright notice, this list of conditions, the following disclaimer and the list of authors. -Redistributions in binary form must reproduce the above copyright notice, this list of conditions, the following disclaimer and the list of authors -in the documentation and/or other materials provided with the distribution. Neither the name of the UbixOS Project nor the names of its -contributors may be used to endorse or promote products derived from this software without specific prior written permission. +Redistributions of source code must retain the above copyright notice, this list of +conditions, the following disclaimer and the list of authors. Redistributions in binary +form must reproduce the above copyright notice, this list of conditions, the following +disclaimer and the list of authors in the documentation and/or other materials provided +with the distribution. Neither the name of the UbixOS Project nor the names of its +contributors may be used to endorse or promote products derived from this software +without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE -GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + $Log$ + Revision 1.4 2004/05/20 22:54:02 reddawg + Cleaned Up Warrnings + + Revision 1.3 2004/05/19 04:07:43 reddawg + kmalloc(size,pid) no more it is no kmalloc(size); the way it should of been + + Revision 1.2 2004/04/20 00:53:16 reddawg + Works + + Revision 1.1.1.1 2004/04/15 12:07:10 reddawg + UbixOS v1.0 + + Revision 1.21 2004/04/13 16:36:33 reddawg + Changed our copyright, it is all now under a BSD-Style license + + $Id$ -**************************************************************************************/ +*****************************************************************************************/ #include #include @@ -29,28 +53,34 @@ struct memDescriptor *prev; //4 struct memDescriptor *next; //4 void *baseAddr; //4 - unsigned long limit; //4 - unsigned char status; //1 - char reserved[15]; //15 + uInt32 limit; //4 + uInt8 status; //1 + char reserved[11]; //11 }; +static void insertFreeDesc(struct memDescriptor *freeDesc); + struct memDescriptor *kernDesc = 0x0; struct memDescriptor *freeKernDesc = 0x0; struct memDescriptor *emptyKernDesc = 0x0; -void insertFreeDesc(struct memDescriptor *freeDesc); +int mallocLock = 0x0; void initMalloc() { int i=0; struct memDescriptor *tmpDesc1 = 0x0; struct memDescriptor *tmpDesc2 = 0x0; - emptyKernDesc = (struct memDescriptor *)getPage(1); + emptyKernDesc = (struct memDescriptor *)getPage(4); tmpDesc1 = emptyKernDesc; tmpDesc1->prev = 0x0; - for (i=1;i<((4096/sizeof(struct memDescriptor)));i++) { + tmpDesc1->status = 0x0; + tmpDesc1->limit = 0x0; + for (i=1;i<((4096/sizeof(struct memDescriptor))*4);i++) { tmpDesc2 = &emptyKernDesc[i]; tmpDesc2->prev = tmpDesc1; tmpDesc1->next = tmpDesc2; + tmpDesc2->status = 0x0; + tmpDesc2->limit = 0x0; tmpDesc1 = tmpDesc2; } tmpDesc1->next = 0x0; @@ -58,6 +88,16 @@ return; } +/************************************************************************ + +Function: void *getEmptyDesc() +Description: Find An Empty Descriptor + +Notes: + +02/17/03 - Is This Efficient? + +************************************************************************/ void *getEmptyDesc() { struct memDescriptor *tmpDesc = emptyKernDesc; if (tmpDesc != 0x0) { @@ -67,18 +107,37 @@ tmpDesc->prev = 0x0; return(tmpDesc); } - printf("Error Finding Empty Descriptor!\n"); return(0x0); } -void *malloc(uInt len) { +/************************************************************************ + +Function: void *malloc(uInt32 len) +Description: Allocate Kernel Memory + +Notes: + +02/17/03 - Do I Still Need To Pass In The Pid? + +************************************************************************/ +void *malloc(uInt32 len) { struct memDescriptor *tmpDesc1 = 0x0; struct memDescriptor *tmpDesc2 = 0x0; + char *buf = 0x0; + int i = 0x0; + + if (mallocLock != 0x0) + while (1) asm("nop"); + + mallocLock = 1; //If Kernel Descriptor Is NULL Initialize Malloc if (emptyKernDesc == 0x0) { initMalloc(); } len = (len + 15) & 0xFFFFFFF0; + if (len == 0x0) { + return(0x0); + } for (tmpDesc1 = freeKernDesc;tmpDesc1;tmpDesc1=tmpDesc1->next) { if (tmpDesc1->limit >= len) { tmpDesc1->status = 0x1; @@ -100,81 +159,110 @@ tmpDesc1->limit = len; tmpDesc2->baseAddr = tmpDesc1->baseAddr + len; tmpDesc2->status = 0x0; + tmpDesc2->next = 0x0; + tmpDesc2->prev = 0x0; insertFreeDesc(tmpDesc2); } + mallocLock = 0x0; + buf = (char *)tmpDesc1->baseAddr; + for (i=0;ilimit;i++) { + (char)buf[i] = (char)0x0; + } return(tmpDesc1->baseAddr); } } tmpDesc1 = getEmptyDesc(); if (tmpDesc1 != 0x0) { - tmpDesc1->baseAddr = (struct memDescriptor *)getPage((len+4095)/4096); + tmpDesc1->baseAddr = (struct memDescriptor *)getPage(((len + 4095)/4096)); tmpDesc1->limit = len; tmpDesc1->status = 0x1; tmpDesc1->next = kernDesc; tmpDesc1->prev = 0x0; - if (kernDesc != 0x0) { - kernDesc->prev = tmpDesc1; - } - kernDesc = tmpDesc1; - if ((len/4096) > 0) { + kernDesc = tmpDesc1; + kernDesc->next->prev = tmpDesc1; + if ((len-4096) > 0) { tmpDesc2 = getEmptyDesc(); tmpDesc2->status = 0x0; tmpDesc2->baseAddr = tmpDesc1->baseAddr + tmpDesc1->limit; tmpDesc2->limit = ((len + 4095)/4096)*4096 - tmpDesc1->limit; + tmpDesc2->prev = 0x0; + tmpDesc2->next = 0x0; insertFreeDesc(tmpDesc2); } - /* - printf("[0x"); - printf("%X",tmpDesc1->baseAddr); - printf("]\n"); - */ + mallocLock = 0x0; + buf = (char *)tmpDesc1->baseAddr; + for (i=0;ilimit;i++) { + (char)buf[i] = (char)0x0; + } return(tmpDesc1->baseAddr); } //Return Null If Unable To Malloc + mallocLock = 0x0; return(0x0); } + +/************************************************************************ -void free(void *baseAddr) { - long *data = 0x0; +Function: void kfree(void *baseAddr) +Description: This Will Find The Descriptor And Free It + +Notes: + +02/17/03 - I need To Make It Join Descriptors + +************************************************************************/ +void kfree(void *baseAddr) { + uInt32 *data = 0x0; long i = 0x0; struct memDescriptor *tmpDesc1 = 0x0; struct memDescriptor *tmpDesc2 = 0x0; - if (baseAddr == 0x0) { - return; - } + while (mallocLock != 0x0) asm("nop"); + + mallocLock = 1; for (tmpDesc1=kernDesc;tmpDesc1;tmpDesc1=tmpDesc1->next) { if (tmpDesc1->baseAddr == baseAddr) { tmpDesc1->status = 0x0; - if (tmpDesc1->prev) { + if (tmpDesc1->prev != 0x0) { tmpDesc2 = tmpDesc1->prev; tmpDesc2->next = tmpDesc1->next; } - if (tmpDesc1->next) { + if (tmpDesc1->next != 0x0) { tmpDesc2 = tmpDesc1->next; - if (tmpDesc2) { - tmpDesc2->prev = tmpDesc1->prev; - } + tmpDesc2->prev = tmpDesc1->prev; } - if ((kernDesc == tmpDesc1) && (tmpDesc1->prev)) { - kernDesc = tmpDesc1->prev; - } - else { + if (kernDesc == tmpDesc1) { kernDesc = tmpDesc1->next; } + tmpDesc1->next = 0x0; + tmpDesc1->prev = 0x0; insertFreeDesc(tmpDesc1); - data = baseAddr; + data = (uInt32 *)baseAddr; for (i=0;i < (tmpDesc1->limit/4);i++) { data[i] = 0x0; } + //mergeMemBlocks(); + mallocLock = 0x0; return; } } - printf("Error Freeing User Descriptor! [0x%X]\n",(unsigned int) baseAddr); + mallocLock = 0x0; return; } -void insertFreeDesc(struct memDescriptor *freeDesc) { +/************************************************************************ + +Function: static void insertFreeDesc(struct memDescriptor *freeDesc) +Description: This Function Inserts A Free Descriptor On The List Which Is + Kept In Size Order + +Notes: + +02/17/03 - This Was Inspired By TCA's Great Wisdom - + "[20:20:59] You should just insert it in order" + +************************************************************************/ +static void insertFreeDesc(struct memDescriptor *freeDesc) { struct memDescriptor *tmpDesc; freeDesc->status = 0x0; if (freeKernDesc != 0x0) { @@ -198,6 +286,72 @@ freeDesc->prev = 0x0; freeDesc->next = 0x0; freeKernDesc = freeDesc; + return; + } + //sysErr("Error With Freeing Blocks"); + return; + } + +/************************************************************************ + +Function: void mergeMemBlocks() +Description: This Function Will Merge Free Blocks And Free Pages + +Notes: + +03/05/03 - We Have A Problem It Seems The First Block Is Limit 0x0 + +************************************************************************/ +void mergeMemBlocks() { + struct memDescriptor *tmpDesc1 = 0x0; + struct memDescriptor *tmpDesc2 = 0x0; + uInt32 baseAddr = 0x0; + + return; + + //Loop The Free Descriptors See If We Can Merge Them + for (tmpDesc1=freeKernDesc;tmpDesc1;tmpDesc1=tmpDesc1->next) { + /* + Compare The Base Addr With The Other Descriptors If You Find The One + That You Are Looking For Lets Merge Them + */ + if (tmpDesc1->limit != 0x0) { + baseAddr = (uInt32)tmpDesc1->baseAddr + (uInt32)tmpDesc1->limit; + for (tmpDesc2=freeKernDesc;tmpDesc2;tmpDesc2=tmpDesc2->next) { + if ((uInt32)tmpDesc2->baseAddr == baseAddr) { + tmpDesc1->limit += tmpDesc2->limit; + tmpDesc2->baseAddr = 0x0; + tmpDesc2->limit = 0x0; + tmpDesc2->status = 0x0; + if (tmpDesc2->prev) { + tmpDesc2->prev->next = tmpDesc2->next; + } + if (tmpDesc2->next) { + tmpDesc2->next->prev = tmpDesc2->prev; + } + tmpDesc2->prev = 0x0; + tmpDesc2->next = emptyKernDesc; + emptyKernDesc->prev = tmpDesc2; + emptyKernDesc = tmpDesc2; + if (tmpDesc1->prev) { + tmpDesc1->prev->next = tmpDesc1->next; + } + if (tmpDesc1->next) { + tmpDesc1->next->prev = tmpDesc1->prev; + } + tmpDesc1->prev = 0x0; + tmpDesc1->next = 0x0; + insertFreeDesc(tmpDesc1); + tmpDesc1 = freeKernDesc; + break; + } + } + } } return; - } \ No newline at end of file + } + +/*** + END + ***/ +