IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 1240


Ignore:
Timestamp:
Jul 19, 2004, 10:45:53 AM (22 years ago)
Author:
desonia
Message:

added recycling of small memory blocks as according to Lupton's suggestions.

Location:
trunk/psLib
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/psLib.kdevses

    r1219 r1240  
    22<!DOCTYPE KDevPrjSession>
    33<KDevPrjSession>
    4  <DocsAndViews NumberOfDocuments="3" >
    5   <Doc0 NumberOfViews="1" URL="file:/home/desonia/psLib/src/dataManip/tst_psImageManip.c" >
    6    <View0 line="13" Type="???" >
    7     <AdditionalSettings Top="2" Width="1196" Attach="1" Height="684" Left="2" MinMaxMode="0" />
     4 <DocsAndViews NumberOfDocuments="5" >
     5  <Doc0 NumberOfViews="1" URL="file:/home/desonia/psLib/src/astronomy/psCCD.h" >
     6   <View0 line="37" Type="???" >
     7    <AdditionalSettings Top="2" Width="1058" Attach="1" Height="629" Left="2" MinMaxMode="0" />
    88   </View0>
    99  </Doc0>
    10   <Doc1 NumberOfViews="1" URL="file:/home/desonia/psLib/test/dataManip/Makefile" >
    11    <View0 line="0" Type="???" >
    12     <AdditionalSettings Top="2" Width="1196" Attach="1" Height="659" Left="2" MinMaxMode="0" />
     10  <Doc1 NumberOfViews="1" URL="file:/home/desonia/psLib/src/collections/psImage.h" >
     11   <View0 line="61" Type="???" >
     12    <AdditionalSettings Top="2" Width="1058" Attach="1" Height="629" Left="2" MinMaxMode="0" />
    1313   </View0>
    1414  </Doc1>
    15   <Doc2 NumberOfViews="1" URL="file:/home/desonia/psLib/test/dataManip/tst_psImageManip.c" >
    16    <View0 line="15" Type="???" >
    17     <AdditionalSettings Top="2" Width="1196" Attach="1" Height="659" Left="2" MinMaxMode="0" />
     15  <Doc2 NumberOfViews="1" URL="file:/home/desonia/psLib/src/astronomy/psCCD.c" >
     16   <View0 line="43" Type="???" >
     17    <AdditionalSettings Top="2" Width="1058" Attach="1" Height="629" Left="2" MinMaxMode="0" />
    1818   </View0>
    1919  </Doc2>
     20  <Doc3 NumberOfViews="1" URL="file:/home/desonia/psLib/src/astronomy/Makefile" >
     21   <View0 line="15" Type="???" >
     22    <AdditionalSettings Top="2" Width="1058" Attach="1" Height="629" Left="2" MinMaxMode="0" />
     23   </View0>
     24  </Doc3>
     25  <Doc4 NumberOfViews="1" URL="file:/home/desonia/psLib/src/collections/Makefile" >
     26   <View0 line="0" Type="???" >
     27    <AdditionalSettings Top="2" Width="1058" Attach="1" Height="629" Left="2" MinMaxMode="0" />
     28   </View0>
     29  </Doc4>
    2030 </DocsAndViews>
    2131 <pluginList>
    2232  <kdevbookmarks>
    23    <bookmarks/>
     33   <bookmarks>
     34    <bookmark url="/home/desonia/psLib/test/dataManip/tst_psImageManip.c" >
     35     <mark line="578" />
     36     <mark line="598" />
     37     <mark line="632" />
     38    </bookmark>
     39   </bookmarks>
    2440  </kdevbookmarks>
    2541  <kdevsubversion>
  • trunk/psLib/src/astronomy/psCCD.d

    r1237 r1240  
    11psCCD.o psCCD.d : psCCD.c psCCD.h ../collections/psType.h ../collections/psImage.h \
    2   ../collections/psList.h ../collections/psCompare.h \
    3   ../collections/psArray.h ../sysUtils/psMemory.h
     2  ../collections/psArray.h ../collections/psCompare.h \
     3  ../collections/psList.h ../sysUtils/psMemory.h
  • trunk/psLib/src/sys/psMemory.c

    r1233 r1240  
    88 *  @author Robert Lupton, Princeton University
    99 *
    10  *  @version $Revision: 1.28 $ $Name: not supported by cvs2svn $
    11  *  @date $Date: 2004-07-15 23:52:34 $
     10 *  @version $Revision: 1.29 $ $Name: not supported by cvs2svn $
     11 *  @date $Date: 2004-07-19 20:45:53 $
    1212 *
    1313 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    2828#define P_PS_MEMMAGIC (void *)0xdeadbeef // Magic number in psMemBlock header
    2929
     30#define P_PS_LARGE_BLOCK_SIZE 65536    // size where under, we try to recycle
     31
    3032static int checkMemBlock(const psMemBlock *m, const char* funcName);
    3133static psMemBlock *lastMemBlockAllocated = NULL;
     
    3335static pthread_mutex_t memIdMutex = PTHREAD_MUTEX_INITIALIZER;
    3436
     37static pthread_mutex_t recycleMemBlockListMutex = PTHREAD_MUTEX_INITIALIZER;
     38
     39static int recycleBins = 13;
     40static int recycleBinSize[14] = {8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,P_PS_LARGE_BLOCK_SIZE};
     41// N.B. recycleBinSize should be terminated by P_PS_LARGE_BLOCK_SIZE (simplifies search loops)
     42static psMemBlock* recycleMemBlockList[13] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
     43
     44#ifdef PS_MEM_DEBUG
     45static psMemBlock* deadBlockList;    // a place to put dead memBlocks in debug mode.
     46#endif
    3547/**
    3648 * Unique ID for allocated blocks
     
    4355static void *memExhaustedCallbackDefault(size_t size)
    4456{
    45     return NULL;
     57    void* ptr = NULL;
     58
     59    pthread_mutex_lock(&recycleMemBlockListMutex);
     60    int level=recycleBins-1;
     61    while (level >= 0 && ptr == NULL) {
     62        while (recycleMemBlockList[level] != NULL && ptr == NULL) {
     63            psMemBlock* old = recycleMemBlockList[level];
     64            recycleMemBlockList[level] = recycleMemBlockList[level]->nextBlock;
     65            free(old);
     66            ptr = malloc(size);
     67        }
     68        level--;
     69    }
     70    pthread_mutex_unlock(&recycleMemBlockListMutex);
     71
     72    return ptr;
    4673}
    4774
     
    243270void *p_psAlloc(size_t size, const char *file, int lineno)
    244271{
    245     psMemBlock *ptr = malloc(sizeof(psMemBlock) + size + sizeof(void*));
     272
     273    psMemBlock *ptr = NULL;
     274
     275    // memory is of the size I want to bother recycling?
     276    if (size < P_PS_LARGE_BLOCK_SIZE) {
     277        // find the bin we need.
     278        int level = 0;
     279        while (size > recycleBinSize[level]) {
     280            level++;
     281        }
     282        // Are we in one of the bins
     283        if (level<recycleBins) {
     284
     285            size = recycleBinSize[level];  // round-up size to next sized bin.
     286
     287            pthread_mutex_lock(&recycleMemBlockListMutex);
     288
     289            if (recycleMemBlockList[level] != NULL) {
     290                ptr = recycleMemBlockList[level];
     291                recycleMemBlockList[level] = ptr->nextBlock;
     292                if (recycleMemBlockList[level] != NULL) {
     293                    recycleMemBlockList[level]->previousBlock = NULL;
     294                }
     295                size = ptr->userMemorySize;
     296            }
     297
     298            pthread_mutex_unlock(&recycleMemBlockListMutex);
     299        }
     300    }
    246301
    247302    if (ptr == NULL) {
    248         ptr = memExhaustedCallback(size);
     303        ptr = malloc(sizeof(psMemBlock) + size + sizeof(void*));
     304
    249305        if (ptr == NULL) {
    250             psAbort(__func__, "Failed to allocate %u bytes at %s:%d",
    251                     size, file, lineno);
    252         }
     306            ptr = memExhaustedCallback(size);
     307            if (ptr == NULL) {
     308                psAbort(__func__, "Failed to allocate %u bytes at %s:%d",
     309                        size, file, lineno);
     310            }
     311        }
     312
     313        ptr->startblock = P_PS_MEMMAGIC;
     314        ptr->endblock = P_PS_MEMMAGIC;
     315        ptr->userMemorySize = size;
     316        pthread_mutex_init(&ptr->refCounterMutex, NULL);
    253317    }
    254318
     
    261325    ptr->freeFcn = NULL;
    262326    *(unsigned int*)&ptr->lineno = lineno;
    263     ptr->startblock = P_PS_MEMMAGIC;
    264     ptr->endblock = P_PS_MEMMAGIC;
    265     ptr->userMemorySize = size;
    266327    *(void**)((int8_t*)(ptr+1)+size) = P_PS_MEMMAGIC;
    267328    ptr->previousBlock = NULL;
    268329
    269     pthread_mutex_init(&ptr->refCounterMutex, NULL);
    270330    ptr->refCounter = 1;                // one user so far
    271331
     
    475535        }
    476536
    477         #ifdef PS_MEM_DEBUG
    478         // for debug mode, we should keep the memBlock around and mark as not referenced.
    479         ptr->refCounter = 0;
    480         (void)p_psRealloc(vptr,0,file,lineno);
    481         #else
    482 
    483537        pthread_mutex_lock(&memBlockListMutex);
    484538
     
    496550        pthread_mutex_unlock(&memBlockListMutex);
    497551
     552
     553        // do we need to recycle?
     554        if (ptr->userMemorySize < P_PS_LARGE_BLOCK_SIZE) {
     555
     556            int level = 1;
     557            while (ptr->userMemorySize >= recycleBinSize[level]) {
     558                level++;
     559            }
     560            level--;
     561
     562            ptr->refCounter = 0;
     563            ptr->previousBlock = NULL;
     564
     565            pthread_mutex_lock(&recycleMemBlockListMutex);
     566            ptr->nextBlock = recycleMemBlockList[level];
     567            if (recycleMemBlockList[level] != NULL) {
     568                recycleMemBlockList[level]->previousBlock = ptr;
     569            }
     570            recycleMemBlockList[level] = ptr;
     571            pthread_mutex_unlock(&recycleMemBlockListMutex);
     572
     573        } else {
     574            // memory is larger than I want to recycle.
     575            #ifdef PS_MEM_DEBUG
     576            (void)p_psRealloc(vptr,0,file,lineno);
     577            ptr->previousBlock = NULL;
     578            ptr->nextBlock = deadBlockList;
     579            if (deadBlockList != NULL) {
     580                deadBlockList->previous = ptr;
     581            }
     582            deadBlockList = ptr;
     583            #else
     584
     585            pthread_mutex_destroy(&ptr->refCounterMutex);
     586            free(ptr);
     587            #endif
     588
     589        }
     590
     591
    498592        pthread_mutex_destroy(&ptr->refCounterMutex);
    499593
    500         free(ptr);
    501         #endif
    502594
    503595        vptr = NULL;    // since we freed it, make sure we return NULL.
  • trunk/psLib/src/sysUtils/psMemory.c

    r1233 r1240  
    88 *  @author Robert Lupton, Princeton University
    99 *
    10  *  @version $Revision: 1.28 $ $Name: not supported by cvs2svn $
    11  *  @date $Date: 2004-07-15 23:52:34 $
     10 *  @version $Revision: 1.29 $ $Name: not supported by cvs2svn $
     11 *  @date $Date: 2004-07-19 20:45:53 $
    1212 *
    1313 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    2828#define P_PS_MEMMAGIC (void *)0xdeadbeef // Magic number in psMemBlock header
    2929
     30#define P_PS_LARGE_BLOCK_SIZE 65536    // size where under, we try to recycle
     31
    3032static int checkMemBlock(const psMemBlock *m, const char* funcName);
    3133static psMemBlock *lastMemBlockAllocated = NULL;
     
    3335static pthread_mutex_t memIdMutex = PTHREAD_MUTEX_INITIALIZER;
    3436
     37static pthread_mutex_t recycleMemBlockListMutex = PTHREAD_MUTEX_INITIALIZER;
     38
     39static int recycleBins = 13;
     40static int recycleBinSize[14] = {8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,P_PS_LARGE_BLOCK_SIZE};
     41// N.B. recycleBinSize should be terminated by P_PS_LARGE_BLOCK_SIZE (simplifies search loops)
     42static psMemBlock* recycleMemBlockList[13] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
     43
     44#ifdef PS_MEM_DEBUG
     45static psMemBlock* deadBlockList;    // a place to put dead memBlocks in debug mode.
     46#endif
    3547/**
    3648 * Unique ID for allocated blocks
     
    4355static void *memExhaustedCallbackDefault(size_t size)
    4456{
    45     return NULL;
     57    void* ptr = NULL;
     58
     59    pthread_mutex_lock(&recycleMemBlockListMutex);
     60    int level=recycleBins-1;
     61    while (level >= 0 && ptr == NULL) {
     62        while (recycleMemBlockList[level] != NULL && ptr == NULL) {
     63            psMemBlock* old = recycleMemBlockList[level];
     64            recycleMemBlockList[level] = recycleMemBlockList[level]->nextBlock;
     65            free(old);
     66            ptr = malloc(size);
     67        }
     68        level--;
     69    }
     70    pthread_mutex_unlock(&recycleMemBlockListMutex);
     71
     72    return ptr;
    4673}
    4774
     
    243270void *p_psAlloc(size_t size, const char *file, int lineno)
    244271{
    245     psMemBlock *ptr = malloc(sizeof(psMemBlock) + size + sizeof(void*));
     272
     273    psMemBlock *ptr = NULL;
     274
     275    // memory is of the size I want to bother recycling?
     276    if (size < P_PS_LARGE_BLOCK_SIZE) {
     277        // find the bin we need.
     278        int level = 0;
     279        while (size > recycleBinSize[level]) {
     280            level++;
     281        }
     282        // Are we in one of the bins
     283        if (level<recycleBins) {
     284
     285            size = recycleBinSize[level];  // round-up size to next sized bin.
     286
     287            pthread_mutex_lock(&recycleMemBlockListMutex);
     288
     289            if (recycleMemBlockList[level] != NULL) {
     290                ptr = recycleMemBlockList[level];
     291                recycleMemBlockList[level] = ptr->nextBlock;
     292                if (recycleMemBlockList[level] != NULL) {
     293                    recycleMemBlockList[level]->previousBlock = NULL;
     294                }
     295                size = ptr->userMemorySize;
     296            }
     297
     298            pthread_mutex_unlock(&recycleMemBlockListMutex);
     299        }
     300    }
    246301
    247302    if (ptr == NULL) {
    248         ptr = memExhaustedCallback(size);
     303        ptr = malloc(sizeof(psMemBlock) + size + sizeof(void*));
     304
    249305        if (ptr == NULL) {
    250             psAbort(__func__, "Failed to allocate %u bytes at %s:%d",
    251                     size, file, lineno);
    252         }
     306            ptr = memExhaustedCallback(size);
     307            if (ptr == NULL) {
     308                psAbort(__func__, "Failed to allocate %u bytes at %s:%d",
     309                        size, file, lineno);
     310            }
     311        }
     312
     313        ptr->startblock = P_PS_MEMMAGIC;
     314        ptr->endblock = P_PS_MEMMAGIC;
     315        ptr->userMemorySize = size;
     316        pthread_mutex_init(&ptr->refCounterMutex, NULL);
    253317    }
    254318
     
    261325    ptr->freeFcn = NULL;
    262326    *(unsigned int*)&ptr->lineno = lineno;
    263     ptr->startblock = P_PS_MEMMAGIC;
    264     ptr->endblock = P_PS_MEMMAGIC;
    265     ptr->userMemorySize = size;
    266327    *(void**)((int8_t*)(ptr+1)+size) = P_PS_MEMMAGIC;
    267328    ptr->previousBlock = NULL;
    268329
    269     pthread_mutex_init(&ptr->refCounterMutex, NULL);
    270330    ptr->refCounter = 1;                // one user so far
    271331
     
    475535        }
    476536
    477         #ifdef PS_MEM_DEBUG
    478         // for debug mode, we should keep the memBlock around and mark as not referenced.
    479         ptr->refCounter = 0;
    480         (void)p_psRealloc(vptr,0,file,lineno);
    481         #else
    482 
    483537        pthread_mutex_lock(&memBlockListMutex);
    484538
     
    496550        pthread_mutex_unlock(&memBlockListMutex);
    497551
     552
     553        // do we need to recycle?
     554        if (ptr->userMemorySize < P_PS_LARGE_BLOCK_SIZE) {
     555
     556            int level = 1;
     557            while (ptr->userMemorySize >= recycleBinSize[level]) {
     558                level++;
     559            }
     560            level--;
     561
     562            ptr->refCounter = 0;
     563            ptr->previousBlock = NULL;
     564
     565            pthread_mutex_lock(&recycleMemBlockListMutex);
     566            ptr->nextBlock = recycleMemBlockList[level];
     567            if (recycleMemBlockList[level] != NULL) {
     568                recycleMemBlockList[level]->previousBlock = ptr;
     569            }
     570            recycleMemBlockList[level] = ptr;
     571            pthread_mutex_unlock(&recycleMemBlockListMutex);
     572
     573        } else {
     574            // memory is larger than I want to recycle.
     575            #ifdef PS_MEM_DEBUG
     576            (void)p_psRealloc(vptr,0,file,lineno);
     577            ptr->previousBlock = NULL;
     578            ptr->nextBlock = deadBlockList;
     579            if (deadBlockList != NULL) {
     580                deadBlockList->previous = ptr;
     581            }
     582            deadBlockList = ptr;
     583            #else
     584
     585            pthread_mutex_destroy(&ptr->refCounterMutex);
     586            free(ptr);
     587            #endif
     588
     589        }
     590
     591
    498592        pthread_mutex_destroy(&ptr->refCounterMutex);
    499593
    500         free(ptr);
    501         #endif
    502594
    503595        vptr = NULL;    // since we freed it, make sure we return NULL.
  • trunk/psLib/test/sysUtils/verified/tst_psMemory.stderr

    r1204 r1240  
    9292 <DATE> <TIME> |<HOST>|I|TPmemCorruption|psMemCheckCorruption should output an error message and memProblemCallback callback should be called.
    9393 <DATE> <TIME> |<HOST>|E|psMemCheckCorru|Memory Corruption: memory block 1 is corrupted (buffer underflow)
    94  <DATE> <TIME> |<HOST>|I|memProblemCallb|memory callback called for id 1 (psMemCheckCorruption:227).
     94 <DATE> <TIME> |<HOST>|I|memProblemCallb|memory callback called for id 1 (psMemCheckCorruption:254).
    9595
    9696---> TESTPOINT PASSED (psMemory{psMemCorruption} | tst_psMemory.c)
Note: See TracChangeset for help on using the changeset viewer.