IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 8438


Ignore:
Timestamp:
Aug 21, 2006, 11:22:56 AM (20 years ago)
Author:
rhl
Message:

1/ Don't let psRealloc realloc blocks that psAlloc knows to be
powers of 2 (bug 803)
2/ Largest block on specially-handled list is handled incorrectly (bug 804)
3/ Added psMemStats() to report state of memory system

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/src/sys/psMemory.c

    r8232 r8438  
    88*  @author Robert Lupton, Princeton University
    99*
    10 *  @version $Revision: 1.75 $ $Name: not supported by cvs2svn $
    11 *  @date $Date: 2006-08-08 23:32:23 $
     10*  @version $Revision: 1.76 $ $Name: not supported by cvs2svn $
     11*  @date $Date: 2006-08-21 21:22:56 $
    1212*
    1313*  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
     
    1919#include <stdio.h>
    2020#include <stdint.h>
     21#include <string.h>
     22#include <assert.h>
    2123
    2224#include "psMemory.h"
     
    5254static bool memory_is_persistent = false;
    5355
    54 static psS32 recycleBins = 13;
    55 static psS32 recycleBinSize[14] = {
    56                                       8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, P_PS_LARGE_BLOCK_SIZE
    57                                   };
     56#define N_RECYCLE_BINS 14  // number of recycle bins
     57static const psS32 recycleBins = N_RECYCLE_BINS;
     58static const psS32 recycleBinSize[N_RECYCLE_BINS] =
     59    {
     60        8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, P_PS_LARGE_BLOCK_SIZE
     61    };
    5862
    5963// N.B. recycleBinSize should be terminated by P_PS_LARGE_BLOCK_SIZE (simplifies search loops)
    60 static psMemBlock* recycleMemBlockList[13] = {
    61             NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
     64static psMemBlock* recycleMemBlockList[N_RECYCLE_BINS] = {
     65            NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
    6266        };
    6367
     
    453457        }
    454458
    455         if (safeThreads) {
    456             pthread_mutex_lock(&memBlockListMutex);
    457         }
    458 
    459         isBlockLast = (ptr == lastMemBlockAllocated);
    460 
    461         ptr = (psMemBlock* ) realloc(ptr, sizeof(psMemBlock) + size + sizeof(psPtr ));
    462 
    463         if (ptr == NULL) {
    464             ptr = memExhaustedCallback(size);
    465             if(ptr == NULL) {
    466                 psAbort(__func__, "Failed to reallocate %ld bytes at %s:%d", size, file, lineno);
    467             }
    468         }
    469 
    470         ptr->userMemorySize = size;
    471         *(psPtr *)((int8_t *) (ptr + 1) + size) = P_PS_MEMMAGIC;
    472 
    473         if (isBlockLast) {
    474             lastMemBlockAllocated = ptr;
    475         }
    476         // the block location may have changed, so fix the linked list addresses.
    477         if (ptr->nextBlock != NULL) {
    478             ptr->nextBlock->previousBlock = ptr;
    479         }
    480         if (ptr->previousBlock != NULL) {
    481             ptr->previousBlock->nextBlock = ptr;
    482         }
    483 
    484         if (safeThreads) {
    485             pthread_mutex_unlock(&memBlockListMutex);
     459        if (size < ptr->userMemorySize) {
     460            ;    // nothing to do
     461        } else {
     462            isBlockLast = (ptr == lastMemBlockAllocated);
     463
     464            psPtr *nvptr = p_psAlloc(size, file, lineno);
     465            psMemBlock *nptr = ((psMemBlock *)nvptr) - 1;
     466            memcpy(nvptr, vptr, ptr->userMemorySize < size ? ptr->userMemorySize : size);
     467            *(psMemId *)&nptr->id = ptr->id;
     468            nptr->persistent = ptr->persistent;
     469
     470            psFree(vptr);
     471            ptr = nptr;
    486472        }
    487473
     
    11511137    ptr->persistent = value;
    11521138}
     1139
     1140/************************************************************************************************************/
     1141/*
     1142 * Return the total amount of memory owned by psLib; if non-NULL also provide a breakdown
     1143 * into recyclable, allocated, and allocated-and-persistent
     1144 *
     1145 * It would be simple enough to fix this code to return an array of structs to describe
     1146 * the insides of the allocator rather than the printf used here.
     1147 */
     1148size_t psMemStats(const bool print, // print details as they're found?
     1149                  size_t *allocated, // memory that's currently allocated (but not persistent)
     1150                  size_t *persistent, // persistent memory that's currently allocated
     1151                  size_t *freelist) // memory that's waiting to be recycled
     1152{
     1153    const size_t overhead = sizeof(psMemBlock) + sizeof(psPtr); // overhead on each allocation
     1154
     1155    if (print) {
     1156        printf("Type       %6s  %10s %8s\n", "size", "nByte", "nBlock");
     1157    }
     1158
     1159    if (safeThreads) {
     1160        pthread_mutex_lock(&memBlockListMutex);
     1161    }
     1162    /*
     1163     * All memory that's currently allocated, whether persistent or not
     1164     */
     1165    size_t allocated_s, persistent_s;
     1166    if (allocated == NULL) {
     1167        allocated = &allocated_s;
     1168    }
     1169    if (persistent == NULL) {
     1170        persistent = &persistent_s;
     1171    }
     1172
     1173    size_t alloc = 0, persist = 0;
     1174    size_t nalloc = 0, npersist = 0;
     1175    for (psMemBlock* ptr = lastMemBlockAllocated; ptr != NULL; ptr = ptr->nextBlock) {
     1176        assert (ptr->refCounter > 0);
     1177
     1178        if (ptr->persistent) {
     1179            npersist++;
     1180            persist += ptr->userMemorySize + overhead;
     1181        } else {
     1182            nalloc++;
     1183            alloc += ptr->userMemorySize + overhead;
     1184        }
     1185    }
     1186    *allocated = alloc;
     1187    *persistent = persist;
     1188
     1189    if (print) {
     1190        printf("Allocated  %6s  %10d %8d\n", "", alloc, nalloc);
     1191        printf("Persistent %6s  %10d %8d\n", "", persist, npersist);
     1192    }
     1193    /*
     1194     * Count the memory on the free list
     1195     */
     1196    size_t freelist_s;
     1197    if (freelist == NULL) {
     1198        freelist = &freelist_s;
     1199    }
     1200
     1201    *freelist = 0;
     1202    int nblock_tot = 0;
     1203    for (int i = 0; ; i++) {
     1204        if (recycleBinSize[i] == P_PS_LARGE_BLOCK_SIZE) {
     1205            break;
     1206        }
     1207        size_t bin_contents = 0;
     1208        size_t nblock = 0;
     1209        for (const psMemBlock *ptr = recycleMemBlockList[i]; ptr != NULL; ptr = ptr->nextBlock) {
     1210            nblock++;
     1211            bin_contents += ptr->userMemorySize + overhead;
     1212        }
     1213        *freelist += bin_contents;
     1214        nblock_tot += nblock;
     1215
     1216        if (print) {
     1217            printf("Freelist   %6d  %10d %8d\n", recycleBinSize[i], bin_contents, nblock);
     1218        }
     1219    }
     1220    if (print) {
     1221        printf("Freelist   %6s  %10d %8d\n", "", *freelist, nblock_tot);
     1222    }
     1223
     1224    if (safeThreads) {
     1225        pthread_mutex_unlock(&memBlockListMutex);
     1226    }
     1227
     1228    return *freelist + *allocated + *persistent;
     1229}
Note: See TracChangeset for help on using the changeset viewer.