kmalloc.c
lib/kmalloc.h
lib/kprintf.h
ubixos/kpanic.h
ubixos/sched.h
ubixos/spinlock.h
vmm/vmm.h
string.h
assert.h
sys/thread.h
ubixos/kpanic.h
ubixos/sched.h
ubixos/spinlock.h
src/sys/lib/kmalloc.c
ubixos/types.h
sys/_types.h
vmm/paging.h
string.h
vfs/file.h
sys/tss.h
lib/kmalloc.h
vmm/vmm.h
vfs/mount.h
lib/kprintf.h
assert.h
ubixfs/dirCache.h
sys/sysproto.h
sys/signal.h
ubixos/tty.h
void * static void* getEmptyDesc () getEmptyDesc emptyDescSpinLock emptyKernDesc kpanic memset memDescriptor::next memDescriptor::prev spinLock spinUnlock vmm_getFreeMallocPage x1 kmalloc
int static int insertFreeDesc (struct memDescriptor *freeDesc) insertFreeDesc struct memDescriptor * freeDesc assert freeKernDesc kpanic memDescriptor::limit memDescriptor::next memDescriptor::prev kfree kmalloc
void void kfree (void *baseAddr) kfree void * baseAddr assert memDescriptor::baseAddr insertFreeDesc kprintf memDescriptor::limit mallocSpinLock memset memDescriptor::next memDescriptor::prev spinLock spinUnlock usedKernDesc close device_remove elf_loadfile execFile fclose fopen kmod_load ldEnable mpi_destroyMbox mpi_fetchMessage ne2kFreeBuffer operator delete operator delete[] sys_exec sys_write sysExec systemTask ubixfs_cacheDelete ubixFSmkDir ubthread_cond_destroy ubthread_mutex_destroy vfs_mount writeUbixFS
void * void* kmalloc (uInt32 len) kmalloc uInt32 len assert memDescriptor::baseAddr freeKernDesc getEmptyDesc insertFreeDesc kprintf memDescriptor::limit MALLOC_ALIGN mallocSpinLock memDescriptor::next memDescriptor::prev spinLock spinUnlock usedKernDesc addDirEntry biosCall devfs_initialize devfs_makeNode device_add elf_loadfile execFile falloc fdc_init fopen initHardDisk initLNC kmain kmod_add kmod_load ldEnable lncAttach mpi_createMbox mpi_postMessage mpi_spam ne2k_init ne2kAllocBuffer openFileUbixFS operator new operator new[] sched_init schedNewTask sys_exec sys_write sysctl_add sysctl_init sysExec tty_init ubixfs_cacheNew ubixfs_initialize ubixFSLoadDir ubixFSmkDir ubixFSUnlink ubthread_cond_init ubthread_create ubthread_mutex_init ufs_openFile vfs_mount vfsRegisterFS vitals_init writeUbixFS
void static void mergeMemBlocks () mergeMemBlocks memDescriptor::baseAddr emptyKernDesc freeKernDesc memDescriptor::limit memDescriptor::next memDescriptor::prev
spinLock_t spinLock_t emptyDescSpinLock emptyDescSpinLock SPIN_LOCK_INITIALIZER getEmptyDesc
struct memDescriptor * struct memDescriptor* emptyKernDesc emptyKernDesc 0x0 getEmptyDesc mergeMemBlocks
struct memDescriptor * struct memDescriptor* freeKernDesc freeKernDesc 0x0 insertFreeDesc kmalloc mergeMemBlocks
spinLock_t spinLock_t mallocSpinLock mallocSpinLock SPIN_LOCK_INITIALIZER kfree kmalloc
struct memDescriptor * struct memDescriptor* usedKernDesc usedKernDesc 0x0 kfree kmalloc

    /*****************************************************************************************
    Copyright(c)2002-2004TheUbixOSProject
    Allrightsreserved.

    Redistributionanduseinsourceandbinaryforms,withorwithoutmodification,are
    permittedprovidedthatthefollowingconditionsaremet:

    Redistributionsofsourcecodemustretaintheabovecopyrightnotice,thislistof
    conditions,thefollowingdisclaimerandthelistofauthors.Redistributionsinbinary
    formmustreproducetheabovecopyrightnotice,thislistofconditions,thefollowing
    disclaimerandthelistofauthorsinthedocumentationand/orothermaterialsprovided
    withthedistribution.NeitherthenameoftheUbixOSProjectnorthenamesofits
    contributorsmaybeusedtoendorseorpromoteproductsderivedfromthissoftware
    withoutspecificpriorwrittenpermission.

    THISSOFTWAREISPROVIDEDBYTHECOPYRIGHTHOLDERSANDCONTRIBUTORS"ASIS"ANDANY
    EXPRESSORIMPLIEDWARRANTIES,INCLUDING,BUTNOTLIMITEDTO,THEIMPLIEDWARRANTIESOF
    MERCHANTABILITYANDFITNESSFORAPARTICULARPURPOSEAREDISCLAIMED.INNOEVENTSHALL
    THECOPYRIGHTOWNERORCONTRIBUTORSBELIABLEFORANYDIRECT,INDIRECT,INCIDENTAL,
    SPECIAL,EXEMPLARY,ORCONSEQUENTIALDAMAGES(INCLUDING,BUTNOTLIMITEDTO,PROCUREMENT
    OFSUBSTITUTEGOODSORSERVICES;LOSSOFUSE,DATA,ORPROFITS;ORBUSINESSINTERRUPTION)
    HOWEVERCAUSEDANDONANYTHEORYOFLIABILITY,WHETHERINCONTRACT,STRICTLIABILITY,OR
    TORT(INCLUDINGNEGLIGENCEOROTHERWISE)ARISINGINANYWAYOUTOFTHEUSEOFTHIS
    SOFTWARE,EVENIFADVISEDOFTHEPOSSIBILITYOFSUCHDAMAGE.

    $Id: kmalloc_8c.xml 88 2016-01-12 00:11:29Z reddawg $

    *****************************************************************************************/

    #include<lib/kmalloc.h>
    #include<lib/kprintf.h>
    #include<ubixos/kpanic.h>
    #include<ubixos/sched.h>
    #include<ubixos/spinlock.h>
    #include<vmm/vmm.h>
    #include<string.h>
    #include<assert.h>

    /*
    Setupthreedescriptortables:

    kernDesc-Theinusedescriptortable
    freeKernDesc-Thefreedescriptortable(descriptorswithmemorybackingjustnotinuse)
    emptyKernDesc-Theemptydescriptortable(descriptorswithoutamemorybacking)

    */
    staticstructmemDescriptor*usedKernDesc=0x0;
    staticstructmemDescriptor*freeKernDesc=0x0;
    staticstructmemDescriptor*emptyKernDesc=0x0;

    /*
    Setupourspinlockssowedonotcorruptlinkedlistsifwehavere-entrancy
    */
    staticspinLock_tmallocSpinLock=SPIN_LOCK_INITIALIZER;
    staticspinLock_temptyDescSpinLock=SPIN_LOCK_INITIALIZER;

    /************************************************************************

    Function:void*getEmptyDesc()
    Description:FindAnEmptyDescriptor

    Notes:

    02/17/03-IsThisEfficient?

    ************************************************************************/
    staticvoid*getEmptyDesc(){
    inti=0x0;
    structmemDescriptor*tmpDesc=0x0;

    spinLock(&emptyDescSpinLock);

    tmpDesc=emptyKernDesc;

    if(tmpDesc!=0x0){
    emptyKernDesc=tmpDesc->next;
    if(emptyKernDesc!=0x0)
    emptyKernDesc->prev=0x0;

    tmpDesc->next=0x0;
    tmpDesc->prev=0x0;
    spinUnlock(&emptyDescSpinLock);
    return(tmpDesc);
    }
    if((emptyKernDesc=(structmemDescriptor*)vmm_getFreeMallocPage(4))==0x0)
    kpanic("Error:vmmGetFreeKernelPagereturnedNULL\n");

    /*zerooutthememorysoweknowthereisnogarbage*/
    memset(emptyKernDesc,0x0,0x4000);

    emptyKernDesc[0].next=&emptyKernDesc[1];

    for(i=0x1;i<((0x4000/sizeof(structmemDescriptor)));i++){
    if(i+1<(0x4000/sizeof(structmemDescriptor)))
    emptyKernDesc[i].next=&emptyKernDesc[i+1];
    else
    emptyKernDesc[i].next=0x0;
    emptyKernDesc[i].prev=&emptyKernDesc[i-1];
    }

    tmpDesc=&emptyKernDesc[0];

    emptyKernDesc=tmpDesc->next;
    emptyKernDesc->prev=0x0;
    tmpDesc->next=0x0;
    tmpDesc->prev=0x0;
    spinUnlock(&emptyDescSpinLock);
    return(tmpDesc);
    }

    /************************************************************************

    Function:voidinsertFreeDesc(structmemDescriptor*freeDesc)
    Description:ThisFunctionInsertsAFreeDescriptorOnTheListWhichIs
    KeptInSizeOrder

    Notes:

    02/17/03-ThisWasInspiredByTCA'sGreatWisdom-
    "[20:20:59]<TCA>Youshouldjustinsertitinorder"

    ************************************************************************/
    staticintinsertFreeDesc(structmemDescriptor*freeDesc){
    structmemDescriptor*tmpDesc=0x0;
    assert(freeDesc);

    if(freeDesc->limit<=0x0)
    kpanic("InsertingDescriptorwithnolimit\n");

    if(freeKernDesc!=0x0){

    #if0
    freeDesc->next=freeKernDesc;
    freeDesc->prev=0x0;
    freeKernDesc->prev=freeDesc;
    freeKernDesc=freeDesc;
    #endif

    for(tmpDesc=freeKernDesc;tmpDesc!=0x0;tmpDesc=tmpDesc->next){
    if(freeDesc->limit<=tmpDesc->limit){

    freeDesc->prev=tmpDesc->prev;
    if(tmpDesc->prev!=0x0)
    tmpDesc->prev->next=freeDesc;

    tmpDesc->prev=freeDesc;
    freeDesc->next=tmpDesc;

    if(tmpDesc==freeKernDesc)
    freeKernDesc=freeDesc;
    return(0x0);
    }
    if(tmpDesc->next==0x0){
    tmpDesc->next=freeDesc;
    freeDesc->prev=tmpDesc;
    freeDesc->next=0x0;
    return(0x0);
    }
    }
    kpanic("didntInsert\n");
    return(0x0);
    }
    else{
    freeDesc->prev=0x0;
    freeDesc->next=0x0;
    freeKernDesc=freeDesc;
    return(0x0);
    }

    return(0x1);
    }

    /************************************************************************

    Function:voidmergeMemBlocks()
    Description:ThisFunctionWillMergeFreeBlocksAndFreePages

    Notes:

    03/05/03-WeHaveAProblemItSeemsTheFirstBlockIsLimit0x0

    ************************************************************************/
    staticvoidmergeMemBlocks(){
    structmemDescriptor*tmpDesc1=0x0;
    structmemDescriptor*tmpDesc2=0x0;
    uInt32baseAddr=0x0;

    return;

    //LoopTheFreeDescriptorsSeeIfWeCanMergeThem
    mergeStart:
    for(tmpDesc1=freeKernDesc;tmpDesc1!=0x0;tmpDesc1=tmpDesc1->next){
    /*
    CompareTheBaseAddrWithTheOtherDescriptorsIfYouFindTheOne
    ThatYouAreLookingForLetsMergeThem
    */
    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;
    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;
    kprintf("mergememBlocks:[%i]\n",tmpDesc1->limit);
    insertFreeDesc(tmpDesc1);
    //tmpDesc1=freeKernDesc;
    gotomergeStart;
    break;
    }
    }
    }
    }
    return;
    }

    /************************************************************************

    Function:void*kmalloc(uInt32len)
    Description:AllocateKernelMemory

    Notes:

    02/17/03-DoIStillNeedToPassInThePid?

    ************************************************************************/
    void*kmalloc(uInt32len){
    structmemDescriptor*tmpDesc1=0x0;
    structmemDescriptor*tmpDesc2=0x0;
    char*buf=0x0;
    inti=0x0;
    uInt16pages=0x0;

    spinLock(&mallocSpinLock);

    len=MALLOC_ALIGN(len);

    if(len==0x0){
    spinUnlock(&mallocSpinLock);
    kprintf("kmalloc:len=0!\n");
    return(0x0);
    }
    for(tmpDesc1=freeKernDesc;tmpDesc1!=0x0;tmpDesc1=tmpDesc1->next){
    assert(tmpDesc1);
    if(tmpDesc1->limit>=len){
    if(tmpDesc1->prev!=0x0)
    tmpDesc1->prev->next=tmpDesc1->next;
    if(tmpDesc1->next!=0x0)
    tmpDesc1->next->prev=tmpDesc1->prev;

    if(tmpDesc1==freeKernDesc)
    freeKernDesc=tmpDesc1->next;

    tmpDesc1->prev=0x0;
    tmpDesc1->next=usedKernDesc;
    if(usedKernDesc!=0x0)
    usedKernDesc->prev=tmpDesc1;
    usedKernDesc=tmpDesc1;
    if(tmpDesc1->limit>len){
    tmpDesc2=getEmptyDesc();
    assert(tmpDesc2);
    tmpDesc2->limit=tmpDesc1->limit-len;
    tmpDesc1->limit=len;
    tmpDesc2->baseAddr=tmpDesc1->baseAddr+len;
    tmpDesc2->next=0x0;
    tmpDesc2->prev=0x0;
    insertFreeDesc(tmpDesc2);
    }
    buf=(char*)tmpDesc1->baseAddr;
    for(i=0;i<tmpDesc1->limit;i++){
    (char)buf[i]=(char)0x0;
    }
    spinUnlock(&mallocSpinLock);
    //kprintf("m1[%i:%i:0x%X]",tmpDesc1->limit,len,tmpDesc1->baseAddr);
    assert(tmpDesc1->baseAddr);
    return(tmpDesc1->baseAddr);
    }
    }
    tmpDesc1=getEmptyDesc();
    //kprintf("noemptydesc\n");
    if(tmpDesc1!=0x0){
    pages=((len+4095)/4096);
    tmpDesc1->baseAddr=(structmemDescriptor*)vmm_getFreeMallocPage(pages);
    tmpDesc1->limit=len;
    tmpDesc1->next=usedKernDesc;
    tmpDesc1->prev=0x0;
    if(usedKernDesc!=0x0)
    usedKernDesc->prev=tmpDesc1;
    usedKernDesc=tmpDesc1;

    if(((pages*4096)-len)>0x0){
    tmpDesc2=getEmptyDesc();
    assert(tmpDesc2);
    tmpDesc2->baseAddr=tmpDesc1->baseAddr+tmpDesc1->limit;
    tmpDesc2->limit=((pages*4096)-len);
    tmpDesc2->prev=0x0;
    tmpDesc2->next=0x0;
    if(tmpDesc2->limit<=0x0)
    kprintf("kmalloc-2tmpDesc2:[%i]\n",tmpDesc2->limit);
    insertFreeDesc(tmpDesc2);
    }

    buf=(char*)tmpDesc1->baseAddr;
    for(i=0;i<tmpDesc1->limit;i++){
    (char)buf[i]=(char)0x0;
    }
    spinUnlock(&mallocSpinLock);
    //kprintf("baseAddr2[0x%X:0x%X]",tmpDesc1,tmpDesc1->baseAddr);
    //kprintf("m2[%i:%i:0x%X]",tmpDesc1->limit,len,tmpDesc1->baseAddr);
    assert(tmpDesc1->baseAddr);
    return(tmpDesc1->baseAddr);
    }
    //ReturnNullIfUnableToMalloc
    spinUnlock(&mallocSpinLock);
    //kprintf("baseAddr3[0x0]");
    return(0x0);
    }

    /************************************************************************

    Function:voidkfree(void*baseAddr)
    Description:ThisWillFindTheDescriptorAndFreeIt

    Notes:

    02/17/03-IneedToMakeItJoinDescriptors

    ************************************************************************/
    voidkfree(void*baseAddr){
    structmemDescriptor*tmpDesc=0x0;

    if(baseAddr==0x0)return;
    assert(baseAddr);

    assert(usedKernDesc);
    spinLock(&mallocSpinLock);

    for(tmpDesc=usedKernDesc;tmpDesc!=0x0;tmpDesc=tmpDesc->next){

    if(tmpDesc->baseAddr==baseAddr){
    memset(tmpDesc->baseAddr,0xBE,tmpDesc->limit);

    if(usedKernDesc==tmpDesc)
    usedKernDesc=tmpDesc->next;

    if(tmpDesc->prev!=0x0)
    tmpDesc->prev->next=tmpDesc->next;

    if(tmpDesc->next!=0x0)
    tmpDesc->next->prev=tmpDesc->prev;

    tmpDesc->next=0x0;
    tmpDesc->prev=0x0;

    if(tmpDesc->limit<=0x0)
    kprintf("kfreetmpDesc1:[%i]\n",tmpDesc->limit);
    //kprintf("{0x%X}",tmpDesc->baseAddr);
    insertFreeDesc(tmpDesc);

    //mergeMemBlocks();
    spinUnlock(&mallocSpinLock);
    return;
    }
    }
    spinUnlock(&mallocSpinLock);
    kprintf("Kernel:ErrorFreeingDescriptor![0x%X]\n",(uInt32)baseAddr);
    return;
    }

    /***
    $Log: kmalloc_8c.xml,v $
    Revision 1.6  2006/12/19 14:12:51  reddawg
    rtld-elf almost workign

    Revision1.32006/12/0514:10:21reddawg
    WorkignDistro

    Revision1.22006/10/0615:48:01reddawg
    StartingtomakeubixosworkwithUFS2

    Revision1.1.1.12006/06/0112:46:16reddawg
    ubix2

    Revision1.42006/06/0112:42:09reddawg
    Gettingbacktothebasics

    Revision1.32006/06/0103:58:33reddawg
    wonderingaboutthisstuffhere

    Revision1.22005/10/1200:13:37reddawg
    Removed

    Revision1.1.1.12005/09/2617:24:11reddawg
    nomessage

    Revision1.352005/08/0418:32:59fsdfs

    addederrorreporting

    Revision1.342005/08/0418:23:41reddawg
    BUG:Asserthasissuesthatmustbelookedinto

    Revision1.332005/08/0417:11:11fsdfs

    ----------------------------------------

    -------------------

    Revision1.322004/09/2821:50:04reddawg
    kmalloc:nowwhenwekfreememoryisfilledwith0xBEsoitiseasytodebugifwecontinuetousefree'dmemory

    Revision1.312004/09/1916:17:25reddawg
    fixedmemoryleakwenowlosenomemory....

    Revision1.302004/09/1421:51:24reddawg
    Debuginfo

    Revision1.292004/09/1123:39:31reddawg
    oktimeforbed

    Revision1.282004/09/1123:21:26reddawg
    runnowdoyougetfegfaultswithBB?

    Revision1.272004/09/1122:49:28reddawg
    patlookatlines276-285doesthemathseemright?

    Revision1.262004/09/1122:33:13reddawg
    minorchanges

    Revision1.252004/09/1112:11:11reddawg
    CleaninguptheVFSmorechangestofollow...

    Revision1.242004/09/0823:19:58reddawg
    hmm

    Revision1.232004/09/0615:13:25reddawg
    LastcommitbeforeFreeBSD6.0

    Revision1.222004/08/2622:51:18reddawg
    TCAtouchedme:(ithinkhelikesmen....

    sched.h:kTask_taddedparentPid
    endtask.c:fixedtermbacktoparentPid
    exec.c:cleanedwarnings
    fork.c:fixedtermtochildPid
    sched.c:cleanupfordeadtasks
    systemtask.c:cleanupdeadtasks
    kmalloc.c:cleanedupwarnings
    udp.c:cleanedupwarnings
    bot.c:cleanedupwarnings
    shell.c:cleanedupwarnings
    tcpdump.c:tookadump
    hd.c:cleanedupwarnings
    ubixfs.c:stoppedprningdebuginfo

    Revision1.212004/07/2815:05:43reddawg
    Major:
    Pagesnowhavestrictsecurityenforcement.
    Manynulldereferenceshavebeenresolved.
    Whenappsloadedpermissionssetforpagesrwandro

    Revision1.202004/07/2800:17:05reddawg
    Major:
    Disconnectedpage0x0fromthesystem...Unfortunatelythisbrokemanythings
    allofwhichhavebeenfixed.ThiswasgoodbecausenothingdeferencesNULL
    anymore.

    Thingsaffected:
    malloc,kmalloc,getfreepage,getfreevirtualpage,pagefault,fork,exec,ld,ld.so,exec,file

    Revision1.192004/07/2619:15:49reddawg
    testcode,fixesandthelike

    Revision1.182004/07/2616:52:45reddawg
    herewego

    Revision1.172004/07/2423:04:44reddawg
    Changes...markletmeknowifyoufaultatpid185whenyoutypestress

    Revision1.162004/07/2110:02:09reddawg
    devfs:renamedfunctions
    devicesystem:renamedfunctions
    fdc:fixedafewpotentialbugsandcleanedupsomeunusedvariables
    strol:fixeddefinition
    endtask:madeitprintoutfreepagedebuginfo
    kmalloc:fixedahugememoryleakwehadsomeunhandleddescriptorinsertionsosomedescriptorswerelost
    ld:fixedapointerconversion
    file:cleanedupafewunusedvariables
    sched:broketaskdeletion
    kprintf:fixedogPrintfdefinition

    Revision1.152004/07/2023:20:50reddawg
    kmalloc:forgottoremoveanassert

    Revision1.142004/07/2023:18:11reddawg
    Mademallocalittlemorerobustbutwehaveaseriousmemoryleaksomewhere

    Revision1.132004/07/2022:29:55reddawg
    assert:remadeassert

    Revision1.122004/07/2018:58:24reddawg
    Fewfixes

    Revision1.112004/07/1805:24:15reddawg
    Fixens

    Revision1.102004/07/1718:00:47reddawg
    kmalloc:addedassert()

    Revision1.92004/07/1715:54:52reddawg
    kmalloc:addedassert()
    bioscall:fixedsomepotentialproblembynotmaking16bitcode
    paging:addedassert()

    Revision1.82004/06/1714:50:32reddawg
    kmalloc:convertedsomevariablestostatic

    Revision1.72004/06/1702:54:54flameshadow
    chg:fixedcast

    Revision1.62004/05/2611:56:51reddawg
    kmalloc:fixedmemrgeMemBlockshopefullyitwillpreventfuturesegfaultissues
    bynothavinganymoreoverlappingblocks

    Revision1.52004/05/2514:01:14reddawg
    ImplimentedBetterSpinlockingNoMoreIssuesWithKMALLOCwhichactually
    wascausingbizzareproblems

    END
    ***/