IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 1360


Ignore:
Timestamp:
Jul 30, 2004, 4:28:29 PM (22 years ago)
Author:
desonia
Message:

* empty log message *

Location:
trunk/psLib
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/src/collections/psVector.c

    r1305 r1360  
    11/** @file  psVector.c
    2  *
    3  *  @brief Contains support for basic vector types
    4  *
    5  *  This file defines the basic type for a vector struct and functions useful
    6  *  in manupulating vectors.
    7  *
    8  *  @author Ross Harman, MHPCC
    9  *
    10  *  @version $Revision: 1.16 $ $Name: not supported by cvs2svn $
    11  *  @date $Date: 2004-07-28 00:06:13 $
    12  *
    13  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
    14  */
     2*
     3*  @brief Contains support for basic vector types
     4*
     5*  This file defines the basic type for a vector struct and functions useful
     6*  in manupulating vectors.
     7*
     8*  @author Ross Harman, MHPCC
     9*
     10*  @version $Revision: 1.17 $ $Name: not supported by cvs2svn $
     11*  @date $Date: 2004-07-31 02:28:10 $
     12*
     13*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     14*/
    1515
    1616/******************************************************************************/
     
    5454/*  FUNCTION IMPLEMENTATION - LOCAL                                          */
    5555/*****************************************************************************/
    56 static void vectorFree(psVector *restrict psVec);
     56static void vectorFree( psVector *restrict psVec );
    5757
    5858/*****************************************************************************/
    5959/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
    6060/*****************************************************************************/
    61 psVector* psVectorAlloc(unsigned int nalloc, psElemType elemType)
    62 {
    63     psVector *psVec = NULL;
     61psVector* psVectorAlloc( unsigned int nalloc, psElemType elemType )
     62{
     63    psVector * psVec = NULL;
    6464    int elementSize = 0;
    65 
     65   
    6666    // Invalid nalloc
    67     if(nalloc < 1) {
    68         psError(__func__, "Invalid value for nalloc. nalloc: %d\n", nalloc);
    69         return NULL;
    70     }
    71 
    72     elementSize = PSELEMTYPE_SIZEOF(elemType);
    73 
     67    if ( nalloc < 1 ) {
     68            psError( __func__, "Invalid value for nalloc. nalloc: %d\n", nalloc );
     69            return NULL;
     70        }
     71       
     72    elementSize = PSELEMTYPE_SIZEOF( elemType );
     73   
    7474    // Create vector struct
    75     psVec = (psVector *)psAlloc(sizeof(psVector));
    76     p_psMemSetDeallocator(psVec,(psFreeFcn)vectorFree);
    77 
     75    psVec = ( psVector * ) psAlloc( sizeof( psVector ) );
     76    p_psMemSetDeallocator( psVec, ( psFreeFcn ) vectorFree );
     77   
    7878    psVec->type.dimen = PS_DIMEN_VECTOR;
    7979    psVec->type.type = elemType;
    8080    psVec->nalloc = nalloc;
    8181    psVec->n = nalloc;
    82 
     82   
    8383    // Create vector data array
    84     psVec->data.V = psAlloc(nalloc*elementSize);
    85 
     84    psVec->data.V = psAlloc( nalloc * elementSize );
     85   
    8686    return psVec;
    8787}
    8888
    89 psVector *psVectorRealloc(unsigned int nalloc, psVector *restrict in)
     89psVector *psVectorRealloc( unsigned int nalloc, psVector *restrict in )
    9090{
    9191    int elementSize = 0;
    9292    psElemType elemType;
    93 
     93   
    9494    // Invalid nalloc
    95     if(nalloc < 1) {
    96         psError(__func__, "Invalid value for realloc (%d)\n", nalloc);
    97         return NULL;
    98     }
    99 
    100     if(in == NULL) {
    101         psError(__func__, "Null input vector\n");
    102         return NULL;
    103     } else if(in->nalloc != nalloc) {                    // No need to realloc to same size
    104         elemType = in->type.type;
    105         elementSize = PSELEMTYPE_SIZEOF(elemType);
    106         if(nalloc < in->n) {
    107             in->n = nalloc;
    108         }
    109 
    110         // Realloc after decrementation to avoid accessing freed array elements
    111         in->data.V = psRealloc(in->data.V,nalloc*elementSize);
    112         in->nalloc = nalloc;
    113     }
    114 
     95    if ( nalloc < 1 ) {
     96            psError( __func__, "Invalid value for realloc (%d)\n", nalloc );
     97            return NULL;
     98        }
     99       
     100    if ( in == NULL ) {
     101            psError( __func__, "Null input vector\n" );
     102            return NULL;
     103        } else if ( in->nalloc != nalloc ) {                    // No need to realloc to same size
     104            elemType = in->type.type;
     105            elementSize = PSELEMTYPE_SIZEOF( elemType );
     106            if ( nalloc < in->n ) {
     107                    in->n = nalloc;
     108                }
     109               
     110            // Realloc after decrementation to avoid accessing freed array elements
     111            in->data.V = psRealloc( in->data.V, nalloc * elementSize );
     112            in->nalloc = nalloc;
     113        }
     114       
    115115    return in;
    116116}
    117117
    118 psVector *psVectorRecycle(psVector *restrict in, psElemType type, unsigned int nalloc)
     118psVector *psVectorRecycle( psVector *restrict in, psElemType type, unsigned int nalloc )
    119119{
    120120    psElemType elemType;
    121 
    122     if (in == NULL) {
    123         return psVectorAlloc(nalloc, type);
    124     }
    125 
     121   
     122    if ( in == NULL ) {
     123            return psVectorAlloc( nalloc, type );
     124        }
     125       
    126126    elemType = in->type.type;
    127 
    128     if (in->nalloc == nalloc && elemType == type) {
    129         // it is proper size/type already
    130         return in;
    131     }
    132 
     127   
     128    if ( in->nalloc == nalloc && elemType == type ) {
     129            // it is proper size/type already
     130            return in;
     131        }
     132       
    133133    // Invalid nalloc
    134     if(nalloc < 1) {
    135         psError(__func__, "Invalid value for nalloc (%d)\n", nalloc);
    136         psFree(in);
    137         return NULL;
    138     }
    139 
    140 
    141     in->data.V = psRealloc(in->data.V,nalloc*PSELEMTYPE_SIZEOF(type));
    142 
    143     in->n = 0;
     134    if ( nalloc < 1 ) {
     135            psError( __func__, "Invalid value for nalloc (%d)\n", nalloc );
     136            psFree( in );
     137            return NULL;
     138        }
     139       
     140       
     141    in->data.V = psRealloc( in->data.V, nalloc * PSELEMTYPE_SIZEOF( type ) );
     142   
    144143    in->type.type = type;
    145144    in->nalloc = nalloc;
    146 
     145    in->n = nalloc;
     146   
    147147    return in;
    148148}
    149149
    150 psVector *psVectorSort(psVector *restrict outVector, const psVector *restrict inVector)
     150psVector *psVectorSort( psVector *restrict outVector, const psVector *restrict inVector )
    151151{
    152152    int inN = 0;
     
    156156    void *outVec = NULL;
    157157    psElemType inType = 0;
    158 
    159     if(inVector == NULL) {
    160         psError(__func__, " : Line %d - Null input vector\n", __LINE__);
    161         return outVector;
    162     }
    163 
     158   
     159    if ( inVector == NULL ) {
     160            psError( __func__, " : Line %d - Null input vector\n", __LINE__ );
     161            return outVector;
     162        }
     163       
    164164    inType = inVector->type.type;
    165165    inN = inVector->n;
    166166    inVec = inVector->data.V;
    167     elSize = PSELEMTYPE_SIZEOF(inType);
    168 
    169     if(outVector == NULL) {
    170         outVector = psVectorAlloc(inN, inType);
    171         outVector->n = inVector->n;
    172     }
    173 
     167    elSize = PSELEMTYPE_SIZEOF( inType );
     168   
     169    if ( outVector == NULL ) {
     170            outVector = psVectorAlloc( inN, inType );
     171            outVector->n = inVector->n;
     172        }
     173       
    174174    outN = outVector->n;
    175175    outVec = outVector->data.V;
    176 
    177     if(inN != outN) {
    178         psError(__func__, " : Line %d - Input and output vector sizes are not equal: in=%d out=%d\n", __LINE__,
    179                 inN, outN);
    180         return outVector;
    181     }
    182 
    183     if(inType != outVector->type.type) {
    184         psError(__func__, " : Line %d - Input and output vectors are not same type: in=%d out=%d\n", __LINE__,
    185                 inType, outVector->type.type);
    186         return outVector;
    187     }
    188 
    189     if(inN == 0) {
    190         psError(__func__, " : Line %d - No elements in use for input vector\n", __LINE__);
    191         return outVector;
    192     }
    193 
    194     if(outN == 0) {
    195         psError(__func__, " : Line %d - No elements in use for output vector\n", __LINE__);
    196         return outVector;
    197     }
    198 
     176   
     177    if ( inN != outN ) {
     178            psError( __func__, " : Line %d - Input and output vector sizes are not equal: in=%d out=%d\n", __LINE__,
     179                     inN, outN );
     180            return outVector;
     181        }
     182       
     183    if ( inType != outVector->type.type ) {
     184            psError( __func__, " : Line %d - Input and output vectors are not same type: in=%d out=%d\n", __LINE__,
     185                     inType, outVector->type.type );
     186            return outVector;
     187        }
     188       
     189    if ( inN == 0 ) {
     190            psError( __func__, " : Line %d - No elements in use for input vector\n", __LINE__ );
     191            return outVector;
     192        }
     193       
     194    if ( outN == 0 ) {
     195            psError( __func__, " : Line %d - No elements in use for output vector\n", __LINE__ );
     196            return outVector;
     197        }
     198       
    199199    // Copy input vector values into output vector
    200     memcpy(outVec, inVec, elSize*outN);
    201 
     200    memcpy( outVec, inVec, elSize * outN );
     201   
    202202    // Sort output vector
    203     switch(inType) {
    204     case PS_TYPE_U8:
    205         qsort(outVec, inN, elSize, psCompareU8);
    206         break;
    207     case PS_TYPE_U16:
    208         qsort(outVec, inN, elSize, psCompareU16);
    209         break;
    210     case PS_TYPE_U32:
    211         qsort(outVec, inN, elSize, psCompareU32);
    212         break;
    213     case PS_TYPE_U64:
    214         qsort(outVec, inN, elSize, psCompareU64);
    215         break;
    216     case PS_TYPE_S8:
    217         qsort(outVec, inN, elSize, psCompareS8);
    218         break;
    219     case PS_TYPE_S16:
    220         qsort(outVec, inN, elSize, psCompareS16);
    221         break;
    222     case PS_TYPE_S32:
    223         qsort(outVec, inN, elSize, psCompareS32);
    224         break;
    225     case PS_TYPE_S64:
    226         qsort(outVec, inN, elSize, psCompareS64);
    227         break;
    228     case PS_TYPE_F32:
    229         qsort(outVec, inN, elSize, psCompareF32);
    230         break;
    231     case PS_TYPE_F64:
    232         qsort(outVec, inN, elSize, psCompareF64);
    233         break;
    234     default:
    235         psError(__func__, " : Line %d - Invalid psType\n", __LINE__);
    236     }
    237 
     203    switch ( inType ) {
     204            case PS_TYPE_U8:
     205            qsort( outVec, inN, elSize, psCompareU8 );
     206            break;
     207            case PS_TYPE_U16:
     208            qsort( outVec, inN, elSize, psCompareU16 );
     209            break;
     210            case PS_TYPE_U32:
     211            qsort( outVec, inN, elSize, psCompareU32 );
     212            break;
     213            case PS_TYPE_U64:
     214            qsort( outVec, inN, elSize, psCompareU64 );
     215            break;
     216            case PS_TYPE_S8:
     217            qsort( outVec, inN, elSize, psCompareS8 );
     218            break;
     219            case PS_TYPE_S16:
     220            qsort( outVec, inN, elSize, psCompareS16 );
     221            break;
     222            case PS_TYPE_S32:
     223            qsort( outVec, inN, elSize, psCompareS32 );
     224            break;
     225            case PS_TYPE_S64:
     226            qsort( outVec, inN, elSize, psCompareS64 );
     227            break;
     228            case PS_TYPE_F32:
     229            qsort( outVec, inN, elSize, psCompareF32 );
     230            break;
     231            case PS_TYPE_F64:
     232            qsort( outVec, inN, elSize, psCompareF64 );
     233            break;
     234            default:
     235            psError( __func__, " : Line %d - Invalid psType\n", __LINE__ );
     236        }
     237       
    238238    return outVector;
    239239}
     
    241241#define SORT_INDICES(TYPE)                                                                                   \
    242242for(i=0; i<inN; i++) {                                                                                       \
    243     for(j=0; j<inN; j++) {                                                                                   \
    244         diff = fabs((double)tmpVector->data.TYPE[i] - inVec[j]);                                             \
    245         if(diff < FLT_EPSILON) {                                                                             \
    246             outVec[i] = j;                                                                                   \
    247             break;                                                                                           \
    248         }                                                                                                    \
    249     }                                                                                                        \
    250 }
    251 
    252 psVector *psVectorSortIndex(psVector *restrict outVector, const psVector *restrict inVector)
     243        for(j=0; j<inN; j++) {                                                                                   \
     244                diff = fabs((double)tmpVector->data.TYPE[i] - inVec[j]);                                             \
     245                if(diff < FLT_EPSILON) {                                                                             \
     246                        outVec[i] = j;                                                                                   \
     247                        break;                                                                                           \
     248                    }                                                                                                    \
     249            }                                                                                                        \
     250    }
     251   
     252psVector *psVectorSortIndex( psVector *restrict outVector, const psVector *restrict inVector )
    253253{
    254254    int inN = 0;
     
    261261    psVector *tmpVector = NULL;
    262262    psElemType inType = 0;
    263 
    264     if(inVector == NULL) {
    265         psError(__func__, " : Line %d - Null input vector\n", __LINE__);
    266         return outVector;
    267     }
    268 
     263   
     264    if ( inVector == NULL ) {
     265            psError( __func__, " : Line %d - Null input vector\n", __LINE__ );
     266            return outVector;
     267        }
     268       
    269269    inN = inVector->n;
    270270    inVec = inVector->data.V;
    271271    inType = inVector->type.type;
    272 
    273     if(outVector == NULL) {
    274         outVector = psVectorAlloc(inN, PS_TYPE_U32);
    275         outVector->n = inN;
    276     }
    277 
     272   
     273    if ( outVector == NULL ) {
     274            outVector = psVectorAlloc( inN, PS_TYPE_U32 );
     275            outVector->n = inN;
     276        }
     277       
    278278    outN = outVector->n;
    279279    outVec = outVector->data.V;
    280 
    281     if(inN != outN) {
    282         psError(__func__, " : Line %d - Input and output vector sizes are not equal: in=%d out=%d\n",
    283                 __LINE__, inN, outN);
    284         return outVector;
    285     }
    286 
    287     if(outVector->type.type != PS_TYPE_U32) {
    288         psError(__func__, " : Line %d - Output vector is not of type U32: out=%d\n",
    289                 __LINE__, outVector->type.type);
    290         return outVector;
    291     }
    292 
    293     tmpVector = psVectorAlloc(inN, inType);
     280   
     281    if ( inN != outN ) {
     282            psError( __func__, " : Line %d - Input and output vector sizes are not equal: in=%d out=%d\n",
     283                     __LINE__, inN, outN );
     284            return outVector;
     285        }
     286       
     287    if ( outVector->type.type != PS_TYPE_U32 ) {
     288            psError( __func__, " : Line %d - Output vector is not of type U32: out=%d\n",
     289                     __LINE__, outVector->type.type );
     290            return outVector;
     291        }
     292       
     293    tmpVector = psVectorAlloc( inN, inType );
    294294    tmpVector->n = inN;
    295     tmpVector = psVectorSort(tmpVector, inVector);
    296 
     295    tmpVector = psVectorSort( tmpVector, inVector );
     296   
    297297    // Sort output vector
    298     switch(inType) {
    299     case PS_TYPE_U8:
    300         SORT_INDICES(U8);
    301         break;
    302     case PS_TYPE_U16:
    303         SORT_INDICES(U16);
    304         break;
    305     case PS_TYPE_U32:
    306         SORT_INDICES(U32);
    307         break;
    308     case PS_TYPE_U64:
    309         SORT_INDICES(U64);
    310         break;
    311     case PS_TYPE_S8:
    312         SORT_INDICES(S8);
    313         break;
    314     case PS_TYPE_S16:
    315         SORT_INDICES(S16);
    316         break;
    317     case PS_TYPE_S32:
    318         SORT_INDICES(S32);
    319         break;
    320     case PS_TYPE_S64:
    321         SORT_INDICES(S64);
    322         break;
    323     case PS_TYPE_F32:
    324         SORT_INDICES(F32);
    325         break;
    326     case PS_TYPE_F64:
    327         SORT_INDICES(F64);
    328         break;
    329     default:
    330         psError(__func__, " : Line %d - Invalid psType\n", __LINE__);
    331     }
    332 
     298    switch ( inType ) {
     299            case PS_TYPE_U8:
     300            SORT_INDICES( U8 );
     301            break;
     302            case PS_TYPE_U16:
     303            SORT_INDICES( U16 );
     304            break;
     305            case PS_TYPE_U32:
     306            SORT_INDICES( U32 );
     307            break;
     308            case PS_TYPE_U64:
     309            SORT_INDICES( U64 );
     310            break;
     311            case PS_TYPE_S8:
     312            SORT_INDICES( S8 );
     313            break;
     314            case PS_TYPE_S16:
     315            SORT_INDICES( S16 );
     316            break;
     317            case PS_TYPE_S32:
     318            SORT_INDICES( S32 );
     319            break;
     320            case PS_TYPE_S64:
     321            SORT_INDICES( S64 );
     322            break;
     323            case PS_TYPE_F32:
     324            SORT_INDICES( F32 );
     325            break;
     326            case PS_TYPE_F64:
     327            SORT_INDICES( F64 );
     328            break;
     329            default:
     330            psError( __func__, " : Line %d - Invalid psType\n", __LINE__ );
     331        }
     332       
    333333    // Free temp memory
    334     psFree(tmpVector);
    335 
     334    psFree( tmpVector );
     335   
    336336    return outVector;
    337337}
    338338
    339 static void vectorFree(psVector *restrict psVec)
    340 {
    341     if (psVec == NULL) {
    342         return;
    343     }
    344 
    345     psFree(psVec->data.V);
    346 }
     339static void vectorFree( psVector *restrict psVec )
     340{
     341    if ( psVec == NULL ) {
     342            return ;
     343        }
     344       
     345    psFree( psVec->data.V );
     346}
  • trunk/psLib/src/mathtypes/psVector.c

    r1305 r1360  
    11/** @file  psVector.c
    2  *
    3  *  @brief Contains support for basic vector types
    4  *
    5  *  This file defines the basic type for a vector struct and functions useful
    6  *  in manupulating vectors.
    7  *
    8  *  @author Ross Harman, MHPCC
    9  *
    10  *  @version $Revision: 1.16 $ $Name: not supported by cvs2svn $
    11  *  @date $Date: 2004-07-28 00:06:13 $
    12  *
    13  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
    14  */
     2*
     3*  @brief Contains support for basic vector types
     4*
     5*  This file defines the basic type for a vector struct and functions useful
     6*  in manupulating vectors.
     7*
     8*  @author Ross Harman, MHPCC
     9*
     10*  @version $Revision: 1.17 $ $Name: not supported by cvs2svn $
     11*  @date $Date: 2004-07-31 02:28:10 $
     12*
     13*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     14*/
    1515
    1616/******************************************************************************/
     
    5454/*  FUNCTION IMPLEMENTATION - LOCAL                                          */
    5555/*****************************************************************************/
    56 static void vectorFree(psVector *restrict psVec);
     56static void vectorFree( psVector *restrict psVec );
    5757
    5858/*****************************************************************************/
    5959/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
    6060/*****************************************************************************/
    61 psVector* psVectorAlloc(unsigned int nalloc, psElemType elemType)
    62 {
    63     psVector *psVec = NULL;
     61psVector* psVectorAlloc( unsigned int nalloc, psElemType elemType )
     62{
     63    psVector * psVec = NULL;
    6464    int elementSize = 0;
    65 
     65   
    6666    // Invalid nalloc
    67     if(nalloc < 1) {
    68         psError(__func__, "Invalid value for nalloc. nalloc: %d\n", nalloc);
    69         return NULL;
    70     }
    71 
    72     elementSize = PSELEMTYPE_SIZEOF(elemType);
    73 
     67    if ( nalloc < 1 ) {
     68            psError( __func__, "Invalid value for nalloc. nalloc: %d\n", nalloc );
     69            return NULL;
     70        }
     71       
     72    elementSize = PSELEMTYPE_SIZEOF( elemType );
     73   
    7474    // Create vector struct
    75     psVec = (psVector *)psAlloc(sizeof(psVector));
    76     p_psMemSetDeallocator(psVec,(psFreeFcn)vectorFree);
    77 
     75    psVec = ( psVector * ) psAlloc( sizeof( psVector ) );
     76    p_psMemSetDeallocator( psVec, ( psFreeFcn ) vectorFree );
     77   
    7878    psVec->type.dimen = PS_DIMEN_VECTOR;
    7979    psVec->type.type = elemType;
    8080    psVec->nalloc = nalloc;
    8181    psVec->n = nalloc;
    82 
     82   
    8383    // Create vector data array
    84     psVec->data.V = psAlloc(nalloc*elementSize);
    85 
     84    psVec->data.V = psAlloc( nalloc * elementSize );
     85   
    8686    return psVec;
    8787}
    8888
    89 psVector *psVectorRealloc(unsigned int nalloc, psVector *restrict in)
     89psVector *psVectorRealloc( unsigned int nalloc, psVector *restrict in )
    9090{
    9191    int elementSize = 0;
    9292    psElemType elemType;
    93 
     93   
    9494    // Invalid nalloc
    95     if(nalloc < 1) {
    96         psError(__func__, "Invalid value for realloc (%d)\n", nalloc);
    97         return NULL;
    98     }
    99 
    100     if(in == NULL) {
    101         psError(__func__, "Null input vector\n");
    102         return NULL;
    103     } else if(in->nalloc != nalloc) {                    // No need to realloc to same size
    104         elemType = in->type.type;
    105         elementSize = PSELEMTYPE_SIZEOF(elemType);
    106         if(nalloc < in->n) {
    107             in->n = nalloc;
    108         }
    109 
    110         // Realloc after decrementation to avoid accessing freed array elements
    111         in->data.V = psRealloc(in->data.V,nalloc*elementSize);
    112         in->nalloc = nalloc;
    113     }
    114 
     95    if ( nalloc < 1 ) {
     96            psError( __func__, "Invalid value for realloc (%d)\n", nalloc );
     97            return NULL;
     98        }
     99       
     100    if ( in == NULL ) {
     101            psError( __func__, "Null input vector\n" );
     102            return NULL;
     103        } else if ( in->nalloc != nalloc ) {                    // No need to realloc to same size
     104            elemType = in->type.type;
     105            elementSize = PSELEMTYPE_SIZEOF( elemType );
     106            if ( nalloc < in->n ) {
     107                    in->n = nalloc;
     108                }
     109               
     110            // Realloc after decrementation to avoid accessing freed array elements
     111            in->data.V = psRealloc( in->data.V, nalloc * elementSize );
     112            in->nalloc = nalloc;
     113        }
     114       
    115115    return in;
    116116}
    117117
    118 psVector *psVectorRecycle(psVector *restrict in, psElemType type, unsigned int nalloc)
     118psVector *psVectorRecycle( psVector *restrict in, psElemType type, unsigned int nalloc )
    119119{
    120120    psElemType elemType;
    121 
    122     if (in == NULL) {
    123         return psVectorAlloc(nalloc, type);
    124     }
    125 
     121   
     122    if ( in == NULL ) {
     123            return psVectorAlloc( nalloc, type );
     124        }
     125       
    126126    elemType = in->type.type;
    127 
    128     if (in->nalloc == nalloc && elemType == type) {
    129         // it is proper size/type already
    130         return in;
    131     }
    132 
     127   
     128    if ( in->nalloc == nalloc && elemType == type ) {
     129            // it is proper size/type already
     130            return in;
     131        }
     132       
    133133    // Invalid nalloc
    134     if(nalloc < 1) {
    135         psError(__func__, "Invalid value for nalloc (%d)\n", nalloc);
    136         psFree(in);
    137         return NULL;
    138     }
    139 
    140 
    141     in->data.V = psRealloc(in->data.V,nalloc*PSELEMTYPE_SIZEOF(type));
    142 
    143     in->n = 0;
     134    if ( nalloc < 1 ) {
     135            psError( __func__, "Invalid value for nalloc (%d)\n", nalloc );
     136            psFree( in );
     137            return NULL;
     138        }
     139       
     140       
     141    in->data.V = psRealloc( in->data.V, nalloc * PSELEMTYPE_SIZEOF( type ) );
     142   
    144143    in->type.type = type;
    145144    in->nalloc = nalloc;
    146 
     145    in->n = nalloc;
     146   
    147147    return in;
    148148}
    149149
    150 psVector *psVectorSort(psVector *restrict outVector, const psVector *restrict inVector)
     150psVector *psVectorSort( psVector *restrict outVector, const psVector *restrict inVector )
    151151{
    152152    int inN = 0;
     
    156156    void *outVec = NULL;
    157157    psElemType inType = 0;
    158 
    159     if(inVector == NULL) {
    160         psError(__func__, " : Line %d - Null input vector\n", __LINE__);
    161         return outVector;
    162     }
    163 
     158   
     159    if ( inVector == NULL ) {
     160            psError( __func__, " : Line %d - Null input vector\n", __LINE__ );
     161            return outVector;
     162        }
     163       
    164164    inType = inVector->type.type;
    165165    inN = inVector->n;
    166166    inVec = inVector->data.V;
    167     elSize = PSELEMTYPE_SIZEOF(inType);
    168 
    169     if(outVector == NULL) {
    170         outVector = psVectorAlloc(inN, inType);
    171         outVector->n = inVector->n;
    172     }
    173 
     167    elSize = PSELEMTYPE_SIZEOF( inType );
     168   
     169    if ( outVector == NULL ) {
     170            outVector = psVectorAlloc( inN, inType );
     171            outVector->n = inVector->n;
     172        }
     173       
    174174    outN = outVector->n;
    175175    outVec = outVector->data.V;
    176 
    177     if(inN != outN) {
    178         psError(__func__, " : Line %d - Input and output vector sizes are not equal: in=%d out=%d\n", __LINE__,
    179                 inN, outN);
    180         return outVector;
    181     }
    182 
    183     if(inType != outVector->type.type) {
    184         psError(__func__, " : Line %d - Input and output vectors are not same type: in=%d out=%d\n", __LINE__,
    185                 inType, outVector->type.type);
    186         return outVector;
    187     }
    188 
    189     if(inN == 0) {
    190         psError(__func__, " : Line %d - No elements in use for input vector\n", __LINE__);
    191         return outVector;
    192     }
    193 
    194     if(outN == 0) {
    195         psError(__func__, " : Line %d - No elements in use for output vector\n", __LINE__);
    196         return outVector;
    197     }
    198 
     176   
     177    if ( inN != outN ) {
     178            psError( __func__, " : Line %d - Input and output vector sizes are not equal: in=%d out=%d\n", __LINE__,
     179                     inN, outN );
     180            return outVector;
     181        }
     182       
     183    if ( inType != outVector->type.type ) {
     184            psError( __func__, " : Line %d - Input and output vectors are not same type: in=%d out=%d\n", __LINE__,
     185                     inType, outVector->type.type );
     186            return outVector;
     187        }
     188       
     189    if ( inN == 0 ) {
     190            psError( __func__, " : Line %d - No elements in use for input vector\n", __LINE__ );
     191            return outVector;
     192        }
     193       
     194    if ( outN == 0 ) {
     195            psError( __func__, " : Line %d - No elements in use for output vector\n", __LINE__ );
     196            return outVector;
     197        }
     198       
    199199    // Copy input vector values into output vector
    200     memcpy(outVec, inVec, elSize*outN);
    201 
     200    memcpy( outVec, inVec, elSize * outN );
     201   
    202202    // Sort output vector
    203     switch(inType) {
    204     case PS_TYPE_U8:
    205         qsort(outVec, inN, elSize, psCompareU8);
    206         break;
    207     case PS_TYPE_U16:
    208         qsort(outVec, inN, elSize, psCompareU16);
    209         break;
    210     case PS_TYPE_U32:
    211         qsort(outVec, inN, elSize, psCompareU32);
    212         break;
    213     case PS_TYPE_U64:
    214         qsort(outVec, inN, elSize, psCompareU64);
    215         break;
    216     case PS_TYPE_S8:
    217         qsort(outVec, inN, elSize, psCompareS8);
    218         break;
    219     case PS_TYPE_S16:
    220         qsort(outVec, inN, elSize, psCompareS16);
    221         break;
    222     case PS_TYPE_S32:
    223         qsort(outVec, inN, elSize, psCompareS32);
    224         break;
    225     case PS_TYPE_S64:
    226         qsort(outVec, inN, elSize, psCompareS64);
    227         break;
    228     case PS_TYPE_F32:
    229         qsort(outVec, inN, elSize, psCompareF32);
    230         break;
    231     case PS_TYPE_F64:
    232         qsort(outVec, inN, elSize, psCompareF64);
    233         break;
    234     default:
    235         psError(__func__, " : Line %d - Invalid psType\n", __LINE__);
    236     }
    237 
     203    switch ( inType ) {
     204            case PS_TYPE_U8:
     205            qsort( outVec, inN, elSize, psCompareU8 );
     206            break;
     207            case PS_TYPE_U16:
     208            qsort( outVec, inN, elSize, psCompareU16 );
     209            break;
     210            case PS_TYPE_U32:
     211            qsort( outVec, inN, elSize, psCompareU32 );
     212            break;
     213            case PS_TYPE_U64:
     214            qsort( outVec, inN, elSize, psCompareU64 );
     215            break;
     216            case PS_TYPE_S8:
     217            qsort( outVec, inN, elSize, psCompareS8 );
     218            break;
     219            case PS_TYPE_S16:
     220            qsort( outVec, inN, elSize, psCompareS16 );
     221            break;
     222            case PS_TYPE_S32:
     223            qsort( outVec, inN, elSize, psCompareS32 );
     224            break;
     225            case PS_TYPE_S64:
     226            qsort( outVec, inN, elSize, psCompareS64 );
     227            break;
     228            case PS_TYPE_F32:
     229            qsort( outVec, inN, elSize, psCompareF32 );
     230            break;
     231            case PS_TYPE_F64:
     232            qsort( outVec, inN, elSize, psCompareF64 );
     233            break;
     234            default:
     235            psError( __func__, " : Line %d - Invalid psType\n", __LINE__ );
     236        }
     237       
    238238    return outVector;
    239239}
     
    241241#define SORT_INDICES(TYPE)                                                                                   \
    242242for(i=0; i<inN; i++) {                                                                                       \
    243     for(j=0; j<inN; j++) {                                                                                   \
    244         diff = fabs((double)tmpVector->data.TYPE[i] - inVec[j]);                                             \
    245         if(diff < FLT_EPSILON) {                                                                             \
    246             outVec[i] = j;                                                                                   \
    247             break;                                                                                           \
    248         }                                                                                                    \
    249     }                                                                                                        \
    250 }
    251 
    252 psVector *psVectorSortIndex(psVector *restrict outVector, const psVector *restrict inVector)
     243        for(j=0; j<inN; j++) {                                                                                   \
     244                diff = fabs((double)tmpVector->data.TYPE[i] - inVec[j]);                                             \
     245                if(diff < FLT_EPSILON) {                                                                             \
     246                        outVec[i] = j;                                                                                   \
     247                        break;                                                                                           \
     248                    }                                                                                                    \
     249            }                                                                                                        \
     250    }
     251   
     252psVector *psVectorSortIndex( psVector *restrict outVector, const psVector *restrict inVector )
    253253{
    254254    int inN = 0;
     
    261261    psVector *tmpVector = NULL;
    262262    psElemType inType = 0;
    263 
    264     if(inVector == NULL) {
    265         psError(__func__, " : Line %d - Null input vector\n", __LINE__);
    266         return outVector;
    267     }
    268 
     263   
     264    if ( inVector == NULL ) {
     265            psError( __func__, " : Line %d - Null input vector\n", __LINE__ );
     266            return outVector;
     267        }
     268       
    269269    inN = inVector->n;
    270270    inVec = inVector->data.V;
    271271    inType = inVector->type.type;
    272 
    273     if(outVector == NULL) {
    274         outVector = psVectorAlloc(inN, PS_TYPE_U32);
    275         outVector->n = inN;
    276     }
    277 
     272   
     273    if ( outVector == NULL ) {
     274            outVector = psVectorAlloc( inN, PS_TYPE_U32 );
     275            outVector->n = inN;
     276        }
     277       
    278278    outN = outVector->n;
    279279    outVec = outVector->data.V;
    280 
    281     if(inN != outN) {
    282         psError(__func__, " : Line %d - Input and output vector sizes are not equal: in=%d out=%d\n",
    283                 __LINE__, inN, outN);
    284         return outVector;
    285     }
    286 
    287     if(outVector->type.type != PS_TYPE_U32) {
    288         psError(__func__, " : Line %d - Output vector is not of type U32: out=%d\n",
    289                 __LINE__, outVector->type.type);
    290         return outVector;
    291     }
    292 
    293     tmpVector = psVectorAlloc(inN, inType);
     280   
     281    if ( inN != outN ) {
     282            psError( __func__, " : Line %d - Input and output vector sizes are not equal: in=%d out=%d\n",
     283                     __LINE__, inN, outN );
     284            return outVector;
     285        }
     286       
     287    if ( outVector->type.type != PS_TYPE_U32 ) {
     288            psError( __func__, " : Line %d - Output vector is not of type U32: out=%d\n",
     289                     __LINE__, outVector->type.type );
     290            return outVector;
     291        }
     292       
     293    tmpVector = psVectorAlloc( inN, inType );
    294294    tmpVector->n = inN;
    295     tmpVector = psVectorSort(tmpVector, inVector);
    296 
     295    tmpVector = psVectorSort( tmpVector, inVector );
     296   
    297297    // Sort output vector
    298     switch(inType) {
    299     case PS_TYPE_U8:
    300         SORT_INDICES(U8);
    301         break;
    302     case PS_TYPE_U16:
    303         SORT_INDICES(U16);
    304         break;
    305     case PS_TYPE_U32:
    306         SORT_INDICES(U32);
    307         break;
    308     case PS_TYPE_U64:
    309         SORT_INDICES(U64);
    310         break;
    311     case PS_TYPE_S8:
    312         SORT_INDICES(S8);
    313         break;
    314     case PS_TYPE_S16:
    315         SORT_INDICES(S16);
    316         break;
    317     case PS_TYPE_S32:
    318         SORT_INDICES(S32);
    319         break;
    320     case PS_TYPE_S64:
    321         SORT_INDICES(S64);
    322         break;
    323     case PS_TYPE_F32:
    324         SORT_INDICES(F32);
    325         break;
    326     case PS_TYPE_F64:
    327         SORT_INDICES(F64);
    328         break;
    329     default:
    330         psError(__func__, " : Line %d - Invalid psType\n", __LINE__);
    331     }
    332 
     298    switch ( inType ) {
     299            case PS_TYPE_U8:
     300            SORT_INDICES( U8 );
     301            break;
     302            case PS_TYPE_U16:
     303            SORT_INDICES( U16 );
     304            break;
     305            case PS_TYPE_U32:
     306            SORT_INDICES( U32 );
     307            break;
     308            case PS_TYPE_U64:
     309            SORT_INDICES( U64 );
     310            break;
     311            case PS_TYPE_S8:
     312            SORT_INDICES( S8 );
     313            break;
     314            case PS_TYPE_S16:
     315            SORT_INDICES( S16 );
     316            break;
     317            case PS_TYPE_S32:
     318            SORT_INDICES( S32 );
     319            break;
     320            case PS_TYPE_S64:
     321            SORT_INDICES( S64 );
     322            break;
     323            case PS_TYPE_F32:
     324            SORT_INDICES( F32 );
     325            break;
     326            case PS_TYPE_F64:
     327            SORT_INDICES( F64 );
     328            break;
     329            default:
     330            psError( __func__, " : Line %d - Invalid psType\n", __LINE__ );
     331        }
     332       
    333333    // Free temp memory
    334     psFree(tmpVector);
    335 
     334    psFree( tmpVector );
     335   
    336336    return outVector;
    337337}
    338338
    339 static void vectorFree(psVector *restrict psVec)
    340 {
    341     if (psVec == NULL) {
    342         return;
    343     }
    344 
    345     psFree(psVec->data.V);
    346 }
     339static void vectorFree( psVector *restrict psVec )
     340{
     341    if ( psVec == NULL ) {
     342            return ;
     343        }
     344       
     345    psFree( psVec->data.V );
     346}
  • trunk/psLib/src/sys/psMemory.c

    r1240 r1360  
    11/** @file  psMemory.c
    2  *
    3  *  @brief Contains the definitions for the memory management system
    4  *
    5  *  psMemory.h has additional information and documentation of the routines found in this file.
    6  *
    7  *  @author Robert DeSonia, MHPCC
    8  *  @author Robert Lupton, Princeton University
    9  *
    10  *  @version $Revision: 1.29 $ $Name: not supported by cvs2svn $
    11  *  @date $Date: 2004-07-19 20:45:53 $
    12  *
    13  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
    14  */
     2*
     3*  @brief Contains the definitions for the memory management system
     4*
     5*  psMemory.h has additional information and documentation of the routines found in this file.
     6*
     7*  @author Robert DeSonia, MHPCC
     8*  @author Robert Lupton, Princeton University
     9*
     10*  @version $Revision: 1.30 $ $Name: not supported by cvs2svn $
     11*  @date $Date: 2004-07-31 02:28:10 $
     12*
     13*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     14*/
    1515
    1616#define PS_ALLOW_MALLOC                 // we're allowed to call malloc()
     
    3030#define P_PS_LARGE_BLOCK_SIZE 65536    // size where under, we try to recycle
    3131
    32 static int checkMemBlock(const psMemBlock *m, const char* funcName);
     32static int checkMemBlock( const psMemBlock *m, const char* funcName );
    3333static psMemBlock *lastMemBlockAllocated = NULL;
    3434static pthread_mutex_t memBlockListMutex = PTHREAD_MUTEX_INITIALIZER;
     
    3838
    3939static int recycleBins = 13;
    40 static int recycleBinSize[14] = {8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,P_PS_LARGE_BLOCK_SIZE};
     40static int recycleBinSize[ 14 ] =
     41    {
     42        8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, P_PS_LARGE_BLOCK_SIZE
     43    };
    4144// N.B. recycleBinSize should be terminated by P_PS_LARGE_BLOCK_SIZE (simplifies search loops)
    42 static psMemBlock* recycleMemBlockList[13] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
    43 
     45static psMemBlock* recycleMemBlockList[ 13 ] =
     46    {
     47        NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
     48    };
     49   
    4450#ifdef PS_MEM_DEBUG
    4551static psMemBlock* deadBlockList;    // a place to put dead memBlocks in debug mode.
     
    5359 *  Default memExhausted callback.
    5460 */
    55 static void *memExhaustedCallbackDefault(size_t size)
    56 {
    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 
     61static void *memExhaustedCallbackDefault( size_t size )
     62{
     63    void * ptr = NULL;
     64   
     65    pthread_mutex_lock( &recycleMemBlockListMutex );
     66    int level = recycleBins - 1;
     67    while ( level >= 0 && ptr == NULL ) {
     68            while ( recycleMemBlockList[ level ] != NULL && ptr == NULL ) {
     69                    psMemBlock * old = recycleMemBlockList[ level ];
     70                    recycleMemBlockList[ level ] = recycleMemBlockList[ level ] ->nextBlock;
     71                    free( old );
     72                    ptr = malloc( size );
     73                }
     74            level--;
     75        }
     76    pthread_mutex_unlock( &recycleMemBlockListMutex );
     77   
    7278    return ptr;
    7379}
     
    7581static psMemExhaustedCallback memExhaustedCallback = memExhaustedCallbackDefault;
    7682
    77 psMemExhaustedCallback psMemExhaustedCallbackSet(psMemExhaustedCallback func)
     83psMemExhaustedCallback psMemExhaustedCallbackSet( psMemExhaustedCallback func )
    7884{
    7985    psMemExhaustedCallback old = memExhaustedCallback;
    80 
    81     if (func != NULL) {
    82         memExhaustedCallback = func;
    83     } else {
    84         memExhaustedCallback = memExhaustedCallbackDefault;
    85     }
    86 
     86   
     87    if ( func != NULL ) {
     88            memExhaustedCallback = func;
     89        } else {
     90            memExhaustedCallback = memExhaustedCallbackDefault;
     91        }
     92       
    8793    return old;
    8894}
    8995
    90 static void memProblemCallbackDefault(const psMemBlock *ptr,
    91                                       const char *file, int lineno)
    92 {
    93     if (ptr->refCounter < 1) {
    94         psError(__func__,
    95                 "Block %ld allocated at %s:%d freed more than once at %s:%d\n",
    96                 ptr->id, ptr->file, ptr->lineno, file, lineno);
    97     }
    98 
    99     if (lineno > 0) {
    100         psAbort(__func__, "Detected a problem in the memory system at %s:%d", file, lineno);
    101     }
     96static void memProblemCallbackDefault( const psMemBlock *ptr,
     97                                       const char *file, int lineno )
     98{
     99    if ( ptr->refCounter < 1 ) {
     100            psError( __func__,
     101                     "Block %ld allocated at %s:%d freed more than once at %s:%d\n",
     102                     ptr->id, ptr->file, ptr->lineno, file, lineno );
     103        }
     104       
     105    if ( lineno > 0 ) {
     106            psAbort( __func__, "Detected a problem in the memory system at %s:%d", file, lineno );
     107        }
    102108}
    103109static psMemProblemCallback memProblemCallback = memProblemCallbackDefault;
    104110
    105 psMemProblemCallback psMemProblemCallbackSet(psMemProblemCallback func)
     111psMemProblemCallback psMemProblemCallbackSet( psMemProblemCallback func )
    106112{
    107113    psMemProblemCallback old = memProblemCallback;
    108 
    109     if (func != NULL) {
    110         memProblemCallback = func;
    111     } else {
    112         memProblemCallback = memProblemCallbackDefault;
    113     }
    114 
     114   
     115    if ( func != NULL ) {
     116            memProblemCallback = func;
     117        } else {
     118            memProblemCallback = memProblemCallbackDefault;
     119        }
     120       
    115121    return old;
    116122}
     
    123129psMemoryId p_psMemFreeID = 0;   // notify user this block is freed
    124130
    125 psMemoryId psMemAllocateCallbackSetID(psMemoryId id)
     131psMemoryId psMemAllocateCallbackSetID( psMemoryId id )
    126132{
    127133    psMemoryId old = p_psMemAllocateID;
    128134    p_psMemAllocateID = id;
    129 
     135   
    130136    return old;
    131137}
    132138
    133 psMemoryId psMemFreeCallbackSetID(psMemoryId id)
     139psMemoryId psMemFreeCallbackSetID( psMemoryId id )
    134140{
    135141    psMemoryId old = p_psMemFreeID;
    136142    p_psMemFreeID = id;
    137 
     143   
    138144    return old;
    139145}
     
    145151 * isn't resignalled)
    146152 */
    147 static psMemoryId memAllocateCallbackDefault(const psMemBlock *ptr)
     153static psMemoryId memAllocateCallbackDefault( const psMemBlock *ptr )
    148154{
    149155    static psMemoryId incr = 0;  // "p_psMemAllocateID += incr"
    150 
     156   
    151157    return incr;
    152158}
    153159
    154 static psMemoryId memFreeCallbackDefault(const psMemBlock *ptr)
     160static psMemoryId memFreeCallbackDefault( const psMemBlock *ptr )
    155161{
    156162    static psMemoryId incr = 0;  // "p_psMemFreeID += incr"
    157 
     163   
    158164    return incr;
    159165}
     
    165171static psMemFreeCallback memFreeCallback = memFreeCallbackDefault;
    166172
    167 psMemAllocateCallback psMemAllocateCallbackSet(psMemAllocateCallback func)
     173psMemAllocateCallback psMemAllocateCallbackSet( psMemAllocateCallback func )
    168174{
    169175    psMemFreeCallback old = memAllocateCallback;
    170 
    171     if (func != NULL) {
    172         memAllocateCallback = func;
    173     } else {
    174         memAllocateCallback = memAllocateCallbackDefault;
    175     }
    176 
     176   
     177    if ( func != NULL ) {
     178            memAllocateCallback = func;
     179        } else {
     180            memAllocateCallback = memAllocateCallbackDefault;
     181        }
     182       
    177183    return old;
    178184}
    179185
    180 psMemFreeCallback psMemFreeCallbackSet(psMemFreeCallback func)
     186psMemFreeCallback psMemFreeCallbackSet( psMemFreeCallback func )
    181187{
    182188    psMemFreeCallback old = memFreeCallback;
    183 
    184     if (func != NULL) {
    185         memFreeCallback = func;
    186     } else {
    187         memFreeCallback = memFreeCallbackDefault;
    188     }
    189 
     189   
     190    if ( func != NULL ) {
     191            memFreeCallback = func;
     192        } else {
     193            memFreeCallback = memFreeCallbackDefault;
     194        }
     195       
    190196    return old;
    191197}
     
    194200 * Return memory ID counter for next block to be allocated
    195201 */
    196 psMemoryId psMemGetId(void)
     202psMemoryId psMemGetId( void )
    197203{
    198204    psMemoryId id;
    199     pthread_mutex_lock(&memIdMutex);
     205    pthread_mutex_lock( &memIdMutex );
    200206    id = memid + 1;
    201     pthread_mutex_unlock(&memIdMutex);
    202 
     207    pthread_mutex_unlock( &memIdMutex );
     208   
    203209    return id;
    204210}
     
    210216 */
    211217
    212 static int checkMemBlock(const psMemBlock *m, const char* funcName)
     218static int checkMemBlock( const psMemBlock *m, const char* funcName )
    213219{
    214220    // n.b. since this is called by psMemCheckCorruption while the memblock list is mutex locked,
    215221    // we shouldn't call such things as p_psAlloc/p_psFree here.
    216 
    217     if (m == NULL) {
    218         psError(funcName,"Memory Corruption: NULL memory block found.");
    219         return 1;
    220     }
    221 
    222     if (m->refCounter == 0) {
    223         // using an unreferenced block of memory, are you?
    224         psError(__func__,"Memory Corruption: memory block %ld was freed but still used.",
    225                 m->id);
    226         return 1;
    227     }
    228 
    229     if (m->startblock != P_PS_MEMMAGIC || m->endblock != P_PS_MEMMAGIC) {
    230         psError(funcName, "Memory Corruption: memory block %ld is corrupted (buffer underflow)",
    231                 m->id);
    232         return 1;
    233     }
    234     if (*(void**)((int8_t*)(m+1)+m->userMemorySize) != P_PS_MEMMAGIC) {
    235         psError(funcName, "Memory Corruption: memory block %ld is corrupted (buffer overflow)",
    236                 m->id);
    237         return 1;
    238     }
    239 
     222   
     223    if ( m == NULL ) {
     224            psError( funcName, "Memory Corruption: NULL memory block found." );
     225            return 1;
     226        }
     227       
     228    if ( m->refCounter == 0 ) {
     229            // using an unreferenced block of memory, are you?
     230            psError( __func__, "Memory Corruption: memory block %ld was freed but still used.",
     231                     m->id );
     232            return 1;
     233        }
     234       
     235    if ( m->startblock != P_PS_MEMMAGIC || m->endblock != P_PS_MEMMAGIC ) {
     236            psError( funcName, "Memory Corruption: memory block %ld is corrupted (buffer underflow)",
     237                     m->id );
     238            return 1;
     239        }
     240    if ( *( void** ) ( ( int8_t* ) ( m + 1 ) + m->userMemorySize ) != P_PS_MEMMAGIC ) {
     241            psError( funcName, "Memory Corruption: memory block %ld is corrupted (buffer overflow)",
     242                     m->id );
     243            return 1;
     244        }
     245       
    240246    return 0;
    241247}
    242248
    243 int psMemCheckCorruption(bool abort_on_error)
     249int psMemCheckCorruption( bool abort_on_error )
    244250{
    245251    int nbad = 0;                       // number of bad blocks
    246 
     252   
    247253    // get exclusive access to the memBlock list to avoid it changing on us while we use it.
    248     pthread_mutex_lock(&memBlockListMutex);
    249 
    250     for (psMemBlock* iter=lastMemBlockAllocated; iter != NULL; iter=iter->nextBlock) {
    251         if (checkMemBlock(iter, __func__)) {
    252             nbad++;
    253 
    254             memProblemCallback(iter, __func__, __LINE__);
    255 
    256             if (abort_on_error) {
    257                 // release the lock on the memblock list
    258                 pthread_mutex_unlock(&memBlockListMutex);
    259                 psAbort(__func__, "Detected memory corruption");
    260                 return nbad;
    261             }
    262         }
    263     }
    264 
     254    pthread_mutex_lock( &memBlockListMutex );
     255   
     256    for ( psMemBlock * iter = lastMemBlockAllocated; iter != NULL; iter = iter->nextBlock ) {
     257            if ( checkMemBlock( iter, __func__ ) ) {
     258                    nbad++;
     259                   
     260                    memProblemCallback( iter, __func__, __LINE__ );
     261                   
     262                    if ( abort_on_error ) {
     263                            // release the lock on the memblock list
     264                            pthread_mutex_unlock( &memBlockListMutex );
     265                            psAbort( __func__, "Detected memory corruption" );
     266                            return nbad;
     267                        }
     268                }
     269        }
     270       
    265271    // release the lock on the memblock list
    266     pthread_mutex_unlock(&memBlockListMutex);
     272    pthread_mutex_unlock( &memBlockListMutex );
    267273    return nbad;
    268274}
    269275
    270 void *p_psAlloc(size_t size, const char *file, int lineno)
    271 {
    272 
    273     psMemBlock *ptr = NULL;
    274 
     276void *p_psAlloc( size_t size, const char *file, int lineno )
     277{
     278
     279    psMemBlock * ptr = NULL;
     280   
    275281    // 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     }
    301 
    302     if (ptr == NULL) {
    303         ptr = malloc(sizeof(psMemBlock) + size + sizeof(void*));
    304 
    305         if (ptr == NULL) {
    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);
    317     }
    318 
     282    if ( size < P_PS_LARGE_BLOCK_SIZE ) {
     283            // find the bin we need.
     284            int level = 0;
     285            while ( size > recycleBinSize[ level ] ) {
     286                    level++;
     287                }
     288            // Are we in one of the bins
     289            if ( level < recycleBins ) {
     290           
     291                    size = recycleBinSize[ level ];  // round-up size to next sized bin.
     292                   
     293                    pthread_mutex_lock( &recycleMemBlockListMutex );
     294                   
     295                    if ( recycleMemBlockList[ level ] != NULL ) {
     296                            ptr = recycleMemBlockList[ level ];
     297                            recycleMemBlockList[ level ] = ptr->nextBlock;
     298                            if ( recycleMemBlockList[ level ] != NULL ) {
     299                                    recycleMemBlockList[ level ] ->previousBlock = NULL;
     300                                }
     301                            size = ptr->userMemorySize;
     302                        }
     303                       
     304                    pthread_mutex_unlock( &recycleMemBlockListMutex );
     305                }
     306        }
     307       
     308    if ( ptr == NULL ) {
     309            ptr = malloc( sizeof( psMemBlock ) + size + sizeof( void* ) );
     310           
     311            if ( ptr == NULL ) {
     312                    ptr = memExhaustedCallback( size );
     313                    if ( ptr == NULL ) {
     314                            psAbort( __func__, "Failed to allocate %u bytes at %s:%d",
     315                                     size, file, lineno );
     316                        }
     317                }
     318               
     319            ptr->startblock = P_PS_MEMMAGIC;
     320            ptr->endblock = P_PS_MEMMAGIC;
     321            ptr->userMemorySize = size;
     322            pthread_mutex_init( &ptr->refCounterMutex, NULL );
     323        }
     324       
    319325    // increment the memory id safely.
    320     pthread_mutex_lock(&memBlockListMutex);
    321     *(psMemoryId*)&ptr->id = ++memid;
    322     pthread_mutex_unlock(&memBlockListMutex);
    323 
     326    pthread_mutex_lock( &memBlockListMutex );
     327    *( psMemoryId* ) & ptr->id = ++memid;
     328    pthread_mutex_unlock( &memBlockListMutex );
     329   
    324330    ptr->file = file;
    325331    ptr->freeFcn = NULL;
    326     *(unsigned int*)&ptr->lineno = lineno;
    327     *(void**)((int8_t*)(ptr+1)+size) = P_PS_MEMMAGIC;
     332    *( unsigned int* ) & ptr->lineno = lineno;
     333    *( void** ) ( ( int8_t* ) ( ptr + 1 ) + size ) = P_PS_MEMMAGIC;
    328334    ptr->previousBlock = NULL;
    329 
     335   
    330336    ptr->refCounter = 1;                // one user so far
    331 
     337   
    332338    // need exclusive access of the memory block list now...
    333     pthread_mutex_lock(&memBlockListMutex);
    334 
     339    pthread_mutex_lock( &memBlockListMutex );
     340   
    335341    // insert the new block to the front of the memBlock linked-list
    336342    ptr->nextBlock = lastMemBlockAllocated;
    337     if (ptr->nextBlock != NULL) {
    338         ptr->nextBlock->previousBlock = ptr;
    339     }
     343    if ( ptr->nextBlock != NULL ) {
     344            ptr->nextBlock->previousBlock = ptr;
     345        }
    340346    lastMemBlockAllocated = ptr;
    341 
    342     pthread_mutex_unlock(&memBlockListMutex);
    343 
     347   
     348    pthread_mutex_unlock( &memBlockListMutex );
     349   
    344350    //  Did the user ask to be informed about this allocation?
    345     if (ptr->id == p_psMemAllocateID) {
    346         p_psMemAllocateID += memAllocateCallback(ptr);
    347     }
    348 
     351    if ( ptr->id == p_psMemAllocateID ) {
     352            p_psMemAllocateID += memAllocateCallback( ptr );
     353        }
     354       
    349355    // And return the user the memory that they allocated
    350356    return ptr + 1;   // user memory
    351357}
    352358
    353 void *p_psRealloc(void *vptr, size_t size, const char *file, int lineno)
    354 {
    355     if (vptr == NULL) {
    356         return p_psAlloc(size, file, lineno);
    357     } else {
    358         psMemBlock *ptr = ((psMemBlock *)vptr) - 1;
    359         bool isBlockLast = false;
    360 
    361         if (checkMemBlock(ptr, __func__) != 0) {
    362             memProblemCallback(ptr, file, lineno);
    363             psAbort(file,"Realloc detected a memory corruption (id %ld @ %s:%d).",
    364                     ptr->id,ptr->file,ptr->lineno);
    365         }
    366 
    367         pthread_mutex_lock(&memBlockListMutex);
    368 
    369         isBlockLast = (ptr == lastMemBlockAllocated);
    370 
    371         ptr = (psMemBlock*)realloc(ptr, sizeof(psMemBlock) + size + sizeof(void*));
    372 
    373         if (ptr == NULL) {
    374             psAbort(__func__, "Failed to reallocate %ld bytes at %s:%d",
    375                     size, file, lineno);
    376         }
    377 
    378         ptr->userMemorySize = size;
    379         *(void**)((int8_t*)(ptr+1)+size) = P_PS_MEMMAGIC;
    380 
    381         if (isBlockLast) {
    382             lastMemBlockAllocated = ptr;
    383         }
    384 
    385         // the block location may have changed, so fix the linked list addresses.
    386         if (ptr->nextBlock != NULL) {
    387             ptr->nextBlock->previousBlock = ptr;
    388         }
    389         if (ptr->previousBlock != NULL) {
    390             ptr->previousBlock->nextBlock = ptr;
    391         }
    392 
    393         pthread_mutex_unlock(&memBlockListMutex);
    394 
    395         //  Did the user ask to be informed about this allocation?
    396         if (ptr->id == p_psMemAllocateID) {
    397             p_psMemAllocateID += memAllocateCallback(ptr);
    398         }
    399 
    400         return ptr + 1;   // usr memory
    401     }
    402 }
    403 
    404 void p_psFree(void *vptr, const char *file, int lineno)
    405 {
    406     (void)p_psMemDecrRefCounter(vptr,file,lineno);   // this handles the free, if required.
     359void *p_psRealloc( void *vptr, size_t size, const char *file, int lineno )
     360{
     361    if ( vptr == NULL ) {
     362            return p_psAlloc( size, file, lineno );
     363        } else {
     364            psMemBlock *ptr = ( ( psMemBlock * ) vptr ) - 1;
     365            bool isBlockLast = false;
     366           
     367            if ( checkMemBlock( ptr, __func__ ) != 0 ) {
     368                    memProblemCallback( ptr, file, lineno );
     369                    psAbort( file, "Realloc detected a memory corruption (id %ld @ %s:%d).",
     370                             ptr->id, ptr->file, ptr->lineno );
     371                }
     372               
     373            pthread_mutex_lock( &memBlockListMutex );
     374           
     375            isBlockLast = ( ptr == lastMemBlockAllocated );
     376           
     377            ptr = ( psMemBlock* ) realloc( ptr, sizeof( psMemBlock ) + size + sizeof( void* ) );
     378           
     379            if ( ptr == NULL ) {
     380                    psAbort( __func__, "Failed to reallocate %ld bytes at %s:%d",
     381                             size, file, lineno );
     382                }
     383               
     384            ptr->userMemorySize = size;
     385            *( void** ) ( ( int8_t* ) ( ptr + 1 ) + size ) = P_PS_MEMMAGIC;
     386           
     387            if ( isBlockLast ) {
     388                    lastMemBlockAllocated = ptr;
     389                }
     390               
     391            // the block location may have changed, so fix the linked list addresses.
     392            if ( ptr->nextBlock != NULL ) {
     393                    ptr->nextBlock->previousBlock = ptr;
     394                }
     395            if ( ptr->previousBlock != NULL ) {
     396                    ptr->previousBlock->nextBlock = ptr;
     397                }
     398               
     399            pthread_mutex_unlock( &memBlockListMutex );
     400           
     401            //  Did the user ask to be informed about this allocation?
     402            if ( ptr->id == p_psMemAllocateID ) {
     403                    p_psMemAllocateID += memAllocateCallback( ptr );
     404                }
     405               
     406            return ptr + 1;   // usr memory
     407        }
     408}
     409
     410void p_psFree( void *vptr, const char *file, int lineno )
     411{
     412    ( void ) p_psMemDecrRefCounter( vptr, file, lineno );   // this handles the free, if required.
    407413}
    408414
     
    410416 * Check for memory leaks.
    411417 */
    412 int psMemCheckLeaks(psMemoryId id0,psMemBlock ***arr,FILE *fd)
     418int psMemCheckLeaks( psMemoryId id0, psMemBlock ***arr, FILE *fd )
    413419{
    414420    int nleak = 0;
    415421    int j = 0;
    416422    psMemBlock* topBlock = lastMemBlockAllocated;
    417 
    418     pthread_mutex_lock(&memBlockListMutex);
    419 
    420     for (psMemBlock* iter = topBlock; iter != NULL; iter=iter->nextBlock) {
    421         if ( (psMemGetRefCounter(iter+1) > 0) && (iter->id >= id0) ) {
    422             nleak++;
    423 
    424             if (fd != NULL) {
    425                 if (nleak == 1) {
    426                     fprintf(fd, "   %20s:line ID\n", "file");
    427                 }
    428 
    429                 fprintf(fd, "   %20s:%-4d %ld\n", iter->file, iter->lineno, iter->id);
    430             }
    431         }
    432     }
    433 
    434     pthread_mutex_unlock(&memBlockListMutex);
    435 
    436     if (nleak == 0 || arr == NULL) {
    437         return nleak;
    438     }
    439 
    440     *arr = p_psAlloc(nleak*sizeof(psMemBlock), __FILE__, __LINE__);
    441     pthread_mutex_lock(&memBlockListMutex);
    442 
    443     for (psMemBlock* iter = topBlock; iter != NULL; iter=iter->nextBlock) {
    444         if ( (psMemGetRefCounter(iter+1) > 0) && (iter->id >= id0) ) {
    445             (*arr)[j++] = iter;
    446             if (j == nleak) { // found them all
    447                 break;
    448             }
    449         }
    450     }
    451 
    452     pthread_mutex_unlock(&memBlockListMutex);
    453 
     423   
     424    pthread_mutex_lock( &memBlockListMutex );
     425   
     426    for ( psMemBlock * iter = topBlock; iter != NULL; iter = iter->nextBlock ) {
     427            if ( ( psMemGetRefCounter( iter + 1 ) > 0 ) && ( iter->id >= id0 ) ) {
     428                    nleak++;
     429                   
     430                    if ( fd != NULL ) {
     431                            if ( nleak == 1 ) {
     432                                    fprintf( fd, "   %20s:line ID\n", "file" );
     433                                }
     434                               
     435                            fprintf( fd, "   %20s:%-4d %ld\n", iter->file, iter->lineno, iter->id );
     436                        }
     437                }
     438        }
     439       
     440    pthread_mutex_unlock( &memBlockListMutex );
     441   
     442    if ( nleak == 0 || arr == NULL ) {
     443            return nleak;
     444        }
     445       
     446    *arr = p_psAlloc( nleak * sizeof( psMemBlock ), __FILE__, __LINE__ );
     447    pthread_mutex_lock( &memBlockListMutex );
     448   
     449    for ( psMemBlock * iter = topBlock; iter != NULL; iter = iter->nextBlock ) {
     450            if ( ( psMemGetRefCounter( iter + 1 ) > 0 ) && ( iter->id >= id0 ) ) {
     451                    ( *arr ) [ j++ ] = iter;
     452                    if ( j == nleak ) { // found them all
     453                            break;
     454                        }
     455                }
     456        }
     457       
     458    pthread_mutex_unlock( &memBlockListMutex );
     459   
    454460    return nleak;
    455461}
     
    457463/*
    458464 * Reference counting APIs
    459  */
     465 */ 
    460466// return refCounter
    461 psReferenceCount psMemGetRefCounter(void *vptr)
    462 {
    463     psMemBlock *ptr;
     467psReferenceCount psMemGetRefCounter( void *vptr )
     468{
     469    psMemBlock * ptr;
    464470    unsigned int refCount;
    465 
    466     if (vptr == NULL) {
    467         return 0;
    468     }
    469 
    470     ptr = ((psMemBlock *)vptr) - 1;
    471 
    472     if (checkMemBlock(ptr, __func__) != 0) {
    473         memProblemCallback(ptr, __func__, __LINE__);
    474     }
    475 
    476     pthread_mutex_lock(&ptr->refCounterMutex);
     471   
     472    if ( vptr == NULL ) {
     473            return 0;
     474        }
     475       
     476    ptr = ( ( psMemBlock * ) vptr ) - 1;
     477   
     478    if ( checkMemBlock( ptr, __func__ ) != 0 ) {
     479            memProblemCallback( ptr, __func__, __LINE__ );
     480        }
     481       
     482    pthread_mutex_lock( &ptr->refCounterMutex );
    477483    refCount = ptr->refCounter;
    478     pthread_mutex_unlock(&ptr->refCounterMutex);
    479 
     484    pthread_mutex_unlock( &ptr->refCounterMutex );
     485   
    480486    return refCount;
    481487}
    482488// increment and return refCounter
    483 void* p_psMemIncrRefCounter(void *vptr, const char *file, int lineno)
    484 {
    485     psMemBlock *ptr;
    486 
    487     if (vptr == NULL) {
    488         return vptr;
    489     }
    490 
    491     ptr = ((psMemBlock *)vptr) - 1;
    492 
    493     if (checkMemBlock(ptr, __func__)) {
    494         memProblemCallback(ptr, file,lineno);
    495     }
    496 
    497     pthread_mutex_lock(&ptr->refCounterMutex);
     489void* p_psMemIncrRefCounter( void *vptr, const char *file, int lineno )
     490{
     491    psMemBlock * ptr;
     492   
     493    if ( vptr == NULL ) {
     494            return vptr;
     495        }
     496       
     497    ptr = ( ( psMemBlock * ) vptr ) - 1;
     498   
     499    if ( checkMemBlock( ptr, __func__ ) ) {
     500            memProblemCallback( ptr, file, lineno );
     501        }
     502       
     503    pthread_mutex_lock( &ptr->refCounterMutex );
    498504    ptr->refCounter++;
    499     pthread_mutex_unlock(&ptr->refCounterMutex);
    500 
     505    pthread_mutex_unlock( &ptr->refCounterMutex );
     506   
    501507    return vptr;
    502508}
    503509
    504510// decrement and return refCounter
    505 void* p_psMemDecrRefCounter(void *vptr,const char *file, int lineno)
    506 {
    507     if (vptr == NULL) {
    508         return NULL;
    509     }
    510 
    511     psMemBlock *ptr = ((psMemBlock *)vptr) - 1;
    512 
    513     if (checkMemBlock(ptr, __func__) != 0) {
    514         memProblemCallback(ptr, file, lineno);
    515         return NULL;
    516     }
    517 
    518     pthread_mutex_lock(&ptr->refCounterMutex);
    519 
    520     if (ptr->refCounter > 1) {
    521         /// XXX - Probably should have another mutex here.
    522         ptr->refCounter--;          // multiple references, just decrement the count.
    523         pthread_mutex_unlock(&ptr->refCounterMutex);
    524 
    525     } else {
    526         pthread_mutex_unlock(&ptr->refCounterMutex);
    527 
    528         // Did the user ask to be informed about this deallocation?
    529         if (ptr->id == p_psMemFreeID) {
    530             p_psMemFreeID += memFreeCallback(ptr);
    531         }
    532 
    533         if (ptr->freeFcn != NULL) {
    534             ptr->freeFcn(vptr);
    535         }
    536 
    537         pthread_mutex_lock(&memBlockListMutex);
    538 
    539         // cut the memBlock out of the memBlock list
    540         if (ptr->nextBlock != NULL) {
    541             ptr->nextBlock->previousBlock = ptr->previousBlock;
    542         }
    543         if (ptr->previousBlock != NULL) {
    544             ptr->previousBlock->nextBlock = ptr->nextBlock;
    545         }
    546         if (lastMemBlockAllocated == ptr) {
    547             lastMemBlockAllocated = ptr->nextBlock;
    548         }
    549 
    550         pthread_mutex_unlock(&memBlockListMutex);
    551 
    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 
     511void* p_psMemDecrRefCounter( void *vptr, const char *file, int lineno )
     512{
     513    if ( vptr == NULL ) {
     514            return NULL;
     515        }
     516       
     517    psMemBlock *ptr = ( ( psMemBlock * ) vptr ) - 1;
     518   
     519    if ( checkMemBlock( ptr, __func__ ) != 0 ) {
     520            memProblemCallback( ptr, file, lineno );
     521            return NULL;
     522        }
     523       
     524    pthread_mutex_lock( &ptr->refCounterMutex );
     525   
     526    if ( ptr->refCounter > 1 ) {
     527            /// XXX - Probably should have another mutex here.
     528            ptr->refCounter--;          // multiple references, just decrement the count.
     529            pthread_mutex_unlock( &ptr->refCounterMutex );
     530           
    573531        } 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 
    592         pthread_mutex_destroy(&ptr->refCounterMutex);
    593 
    594 
    595         vptr = NULL;    // since we freed it, make sure we return NULL.
    596     }
    597 
     532            pthread_mutex_unlock( &ptr->refCounterMutex );
     533           
     534            // Did the user ask to be informed about this deallocation?
     535            if ( ptr->id == p_psMemFreeID ) {
     536                    p_psMemFreeID += memFreeCallback( ptr );
     537                }
     538               
     539            if ( ptr->freeFcn != NULL ) {
     540                    ptr->freeFcn( vptr );
     541                }
     542               
     543            pthread_mutex_lock( &memBlockListMutex );
     544           
     545            // cut the memBlock out of the memBlock list
     546            if ( ptr->nextBlock != NULL ) {
     547                    ptr->nextBlock->previousBlock = ptr->previousBlock;
     548                }
     549            if ( ptr->previousBlock != NULL ) {
     550                    ptr->previousBlock->nextBlock = ptr->nextBlock;
     551                }
     552            if ( lastMemBlockAllocated == ptr ) {
     553                    lastMemBlockAllocated = ptr->nextBlock;
     554                }
     555               
     556            pthread_mutex_unlock( &memBlockListMutex );
     557           
     558           
     559            // do we need to recycle?
     560            if ( ptr->userMemorySize < P_PS_LARGE_BLOCK_SIZE ) {
     561           
     562                    int level = 1;
     563                    while ( ptr->userMemorySize >= recycleBinSize[ level ] ) {
     564                            level++;
     565                        }
     566                    level--;
     567                   
     568                    ptr->refCounter = 0;
     569                    ptr->previousBlock = NULL;
     570                   
     571                    pthread_mutex_lock( &recycleMemBlockListMutex );
     572                    ptr->nextBlock = recycleMemBlockList[ level ];
     573                    if ( recycleMemBlockList[ level ] != NULL ) {
     574                            recycleMemBlockList[ level ] ->previousBlock = ptr;
     575                        }
     576                    recycleMemBlockList[ level ] = ptr;
     577                    pthread_mutex_unlock( &recycleMemBlockListMutex );
     578                   
     579                } else {
     580                    // memory is larger than I want to recycle.
     581                    #ifdef PS_MEM_DEBUG
     582                    ( void ) p_psRealloc( vptr, 0, file, lineno );
     583                    ptr->previousBlock = NULL;
     584                    ptr->nextBlock = deadBlockList;
     585                    if ( deadBlockList != NULL ) {
     586                            deadBlockList->previous = ptr;
     587                        }
     588                    deadBlockList = ptr;
     589                    #else
     590                   
     591                    pthread_mutex_destroy( &ptr->refCounterMutex );
     592                    free( ptr );
     593                    #endif
     594                   
     595                }
     596               
     597            vptr = NULL;    // since we freed it, make sure we return NULL.
     598        }
     599       
    598600    return vptr;
    599601}
    600602
    601 void p_psMemSetDeallocator(void* vptr, psFreeFcn freeFcn)
    602 {
    603     if (vptr == NULL) {
    604         return;
    605     }
    606 
    607     psMemBlock *ptr = ((psMemBlock *)vptr) - 1;
    608 
    609     if (checkMemBlock(ptr, __func__) != 0) {
    610         memProblemCallback(ptr, __func__, __LINE__);
    611     }
    612 
     603void p_psMemSetDeallocator( void* vptr, psFreeFcn freeFcn )
     604{
     605    if ( vptr == NULL ) {
     606            return ;
     607        }
     608       
     609    psMemBlock *ptr = ( ( psMemBlock * ) vptr ) - 1;
     610   
     611    if ( checkMemBlock( ptr, __func__ ) != 0 ) {
     612            memProblemCallback( ptr, __func__, __LINE__ );
     613        }
     614       
    613615    ptr->freeFcn = freeFcn;
    614 
    615 }
    616 psFreeFcn p_psMemGetDeallocator(void* vptr)
    617 {
    618     if (vptr == NULL) {
    619         return NULL;
    620     }
    621 
    622     psMemBlock *ptr = ((psMemBlock *)vptr) - 1;
    623 
    624     if (checkMemBlock(ptr, __func__) != 0) {
    625         memProblemCallback(ptr, __func__, __LINE__);
    626     }
    627 
     616   
     617}
     618psFreeFcn p_psMemGetDeallocator( void* vptr )
     619{
     620    if ( vptr == NULL ) {
     621            return NULL;
     622        }
     623       
     624    psMemBlock *ptr = ( ( psMemBlock * ) vptr ) - 1;
     625   
     626    if ( checkMemBlock( ptr, __func__ ) != 0 ) {
     627            memProblemCallback( ptr, __func__, __LINE__ );
     628        }
     629       
    628630    return ptr->freeFcn;
    629631}
  • trunk/psLib/src/sys/psType.h

    r1292 r1360  
    11/** @file  psType.h
    2  *
    3  *  @brief Contains support for basic types
    4  *
    5  *  This file defines common datatypes used throughout psLib.
    6  *
    7  *  @ingroup DataContainer
    8  *
    9  *  @author Robert DeSonia, MHPCC
    10  *  @author Ross Harman, MHPCC
    11  *
    12  *  @version $Revision: 1.14 $ $Name: not supported by cvs2svn $
    13  *  @date $Date: 2004-07-24 02:00:21 $
    14  *
    15  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
    16  */
     2*
     3*  @brief Contains support for basic types
     4*
     5*  This file defines common datatypes used throughout psLib.
     6*
     7*  @ingroup DataContainer
     8*
     9*  @author Robert DeSonia, MHPCC
     10*  @author Ross Harman, MHPCC
     11*
     12*  @version $Revision: 1.15 $ $Name: not supported by cvs2svn $
     13*  @date $Date: 2004-07-31 02:28:10 $
     14*
     15*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     16*/
    1717
    1818#ifndef PS_TYPE_H
     
    3737 */
    3838
    39 typedef uint8_t         psU8;           ///< 8-bit unsigned int
    40 typedef uint16_t        psU16;          ///< 16-bit unsigned int
    41 typedef uint32_t        psU32;          ///< 32-bit unsigned int
    42 typedef uint64_t        psU64;          ///< 64-bit unsigned int
    43 typedef int8_t          psS8;           ///< 8-bit signed int
    44 typedef int16_t         psS16;          ///< 16-bit signed int
    45 typedef int32_t         psS32;          ///< 32-bit signed int
    46 typedef int64_t         psS64;          ///< 64-bit signed int
    47 typedef float           psF32;          ///< 32-bit floating point
    48 typedef double          psF64;          ///< 64-bit floating point
    49 typedef complex float   psC32;          ///< complex with 32-bit floating point Real and Imagary numbers
    50 typedef complex double  psC64;          ///< complex with 64-bit floating point Real and Imagary numbers
    51 typedef void*           psPTR;           ///< void pointer
     39typedef uint8_t psU8;           ///< 8-bit unsigned int
     40typedef uint16_t psU16;          ///< 16-bit unsigned int
     41typedef uint32_t psU32;          ///< 32-bit unsigned int
     42typedef uint64_t psU64;          ///< 64-bit unsigned int
     43typedef int8_t psS8;           ///< 8-bit signed int
     44typedef int16_t psS16;          ///< 16-bit signed int
     45typedef int32_t psS32;          ///< 32-bit signed int
     46typedef int64_t psS64;          ///< 64-bit signed int
     47typedef float psF32;          ///< 32-bit floating point
     48typedef double psF64;          ///< 64-bit floating point
     49typedef complex float psC32;          ///< complex with 32-bit floating point Real and Imagary numbers
     50typedef complex double psC64;          ///< complex with 64-bit floating point Real and Imagary numbers
     51typedef void* psPTR;           ///< void pointer
    5252
    5353
    5454typedef enum {
    55     PS_TYPE_S8               = 0x0101,  ///< Character.
    56     PS_TYPE_S16              = 0x0102,  ///< Short integer.
    57     PS_TYPE_S32              = 0x0104,  ///< Integer.
    58     PS_TYPE_S64              = 0x0108,  ///< Long integer.
    59     PS_TYPE_U8               = 0x0301,  ///< Unsigned character.
    60     PS_TYPE_U16              = 0x0302,  ///< Unsigned short integer.
    61     PS_TYPE_U32              = 0x0304,  ///< Unsigned integer.
    62     PS_TYPE_U64              = 0x0308,  ///< Unsigned long integer.
    63     PS_TYPE_F32              = 0x0404,  ///< Single-precision Floating point.
    64     PS_TYPE_F64              = 0x0408,  ///< Double-precision floating point.
    65     PS_TYPE_C32              = 0x0808,  ///< Complex numbers consisting of single-precision floating point.
    66     PS_TYPE_C64              = 0x0810,  ///< Complex numbers consisting of double-precision floating point.
    67     PS_TYPE_PTR              = 0x0000   ///< Something else that's not supported for arithmetic.
     55    PS_TYPE_S8 = 0x0101,   ///< Character.
     56    PS_TYPE_S16 = 0x0102,   ///< Short integer.
     57    PS_TYPE_S32 = 0x0104,   ///< Integer.
     58    PS_TYPE_S64 = 0x0108,   ///< Long integer.
     59    PS_TYPE_U8 = 0x0301,   ///< Unsigned character.
     60    PS_TYPE_U16 = 0x0302,   ///< Unsigned short integer.
     61    PS_TYPE_U32 = 0x0304,   ///< Unsigned integer.
     62    PS_TYPE_U64 = 0x0308,   ///< Unsigned long integer.
     63    PS_TYPE_F32 = 0x0404,   ///< Single-precision Floating point.
     64    PS_TYPE_F64 = 0x0408,   ///< Double-precision floating point.
     65    PS_TYPE_C32 = 0x0808,   ///< Complex numbers consisting of single-precision floating point.
     66    PS_TYPE_C64 = 0x0810,   ///< Complex numbers consisting of double-precision floating point.
     67    PS_TYPE_PTR = 0x0000   ///< Something else that's not supported for arithmetic.
    6868} psElemType;
    6969
    7070#define PS_TYPE_MASK PS_TYPE_U8         ///< the psElemType to use for mask image
     71#define PS_TYPE_MASK_DATA U8            ///< the data member to use for mask image
    7172#define PS_TYPE_MASK_NAME "psU8"
    7273typedef psU8 psMaskType;                ///< the C datatype for a mask image
     
    127128 */
    128129typedef enum {
    129     PS_DIMEN_SCALAR,    ///< Scalar.
    130     PS_DIMEN_VECTOR,    ///< Vector.
    131     PS_DIMEN_TRANSV,    ///< Transposed vector.
    132     PS_DIMEN_IMAGE,     ///< Image.
     130    PS_DIMEN_SCALAR,     ///< Scalar.
     131    PS_DIMEN_VECTOR,     ///< Vector.
     132    PS_DIMEN_TRANSV,     ///< Transposed vector.
     133    PS_DIMEN_IMAGE,      ///< Image.
    133134    PS_DIMEN_OTHER      ///< Something else that's not supported for arithmetic.
    134135} psDimen;
     
    141142 */
    142143typedef struct
    143 {
    144     psElemType type;    ///< Primitive type.
    145     psDimen dimen;      ///< Dimensionality.
    146 }
     144    {
     145        psElemType type;    ///< Primitive type.
     146        psDimen dimen;      ///< Dimensionality.
     147    }
    147148psType;
    148149
  • trunk/psLib/src/sysUtils/psMemory.c

    r1240 r1360  
    11/** @file  psMemory.c
    2  *
    3  *  @brief Contains the definitions for the memory management system
    4  *
    5  *  psMemory.h has additional information and documentation of the routines found in this file.
    6  *
    7  *  @author Robert DeSonia, MHPCC
    8  *  @author Robert Lupton, Princeton University
    9  *
    10  *  @version $Revision: 1.29 $ $Name: not supported by cvs2svn $
    11  *  @date $Date: 2004-07-19 20:45:53 $
    12  *
    13  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
    14  */
     2*
     3*  @brief Contains the definitions for the memory management system
     4*
     5*  psMemory.h has additional information and documentation of the routines found in this file.
     6*
     7*  @author Robert DeSonia, MHPCC
     8*  @author Robert Lupton, Princeton University
     9*
     10*  @version $Revision: 1.30 $ $Name: not supported by cvs2svn $
     11*  @date $Date: 2004-07-31 02:28:10 $
     12*
     13*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     14*/
    1515
    1616#define PS_ALLOW_MALLOC                 // we're allowed to call malloc()
     
    3030#define P_PS_LARGE_BLOCK_SIZE 65536    // size where under, we try to recycle
    3131
    32 static int checkMemBlock(const psMemBlock *m, const char* funcName);
     32static int checkMemBlock( const psMemBlock *m, const char* funcName );
    3333static psMemBlock *lastMemBlockAllocated = NULL;
    3434static pthread_mutex_t memBlockListMutex = PTHREAD_MUTEX_INITIALIZER;
     
    3838
    3939static int recycleBins = 13;
    40 static int recycleBinSize[14] = {8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,P_PS_LARGE_BLOCK_SIZE};
     40static int recycleBinSize[ 14 ] =
     41    {
     42        8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, P_PS_LARGE_BLOCK_SIZE
     43    };
    4144// N.B. recycleBinSize should be terminated by P_PS_LARGE_BLOCK_SIZE (simplifies search loops)
    42 static psMemBlock* recycleMemBlockList[13] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
    43 
     45static psMemBlock* recycleMemBlockList[ 13 ] =
     46    {
     47        NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
     48    };
     49   
    4450#ifdef PS_MEM_DEBUG
    4551static psMemBlock* deadBlockList;    // a place to put dead memBlocks in debug mode.
     
    5359 *  Default memExhausted callback.
    5460 */
    55 static void *memExhaustedCallbackDefault(size_t size)
    56 {
    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 
     61static void *memExhaustedCallbackDefault( size_t size )
     62{
     63    void * ptr = NULL;
     64   
     65    pthread_mutex_lock( &recycleMemBlockListMutex );
     66    int level = recycleBins - 1;
     67    while ( level >= 0 && ptr == NULL ) {
     68            while ( recycleMemBlockList[ level ] != NULL && ptr == NULL ) {
     69                    psMemBlock * old = recycleMemBlockList[ level ];
     70                    recycleMemBlockList[ level ] = recycleMemBlockList[ level ] ->nextBlock;
     71                    free( old );
     72                    ptr = malloc( size );
     73                }
     74            level--;
     75        }
     76    pthread_mutex_unlock( &recycleMemBlockListMutex );
     77   
    7278    return ptr;
    7379}
     
    7581static psMemExhaustedCallback memExhaustedCallback = memExhaustedCallbackDefault;
    7682
    77 psMemExhaustedCallback psMemExhaustedCallbackSet(psMemExhaustedCallback func)
     83psMemExhaustedCallback psMemExhaustedCallbackSet( psMemExhaustedCallback func )
    7884{
    7985    psMemExhaustedCallback old = memExhaustedCallback;
    80 
    81     if (func != NULL) {
    82         memExhaustedCallback = func;
    83     } else {
    84         memExhaustedCallback = memExhaustedCallbackDefault;
    85     }
    86 
     86   
     87    if ( func != NULL ) {
     88            memExhaustedCallback = func;
     89        } else {
     90            memExhaustedCallback = memExhaustedCallbackDefault;
     91        }
     92       
    8793    return old;
    8894}
    8995
    90 static void memProblemCallbackDefault(const psMemBlock *ptr,
    91                                       const char *file, int lineno)
    92 {
    93     if (ptr->refCounter < 1) {
    94         psError(__func__,
    95                 "Block %ld allocated at %s:%d freed more than once at %s:%d\n",
    96                 ptr->id, ptr->file, ptr->lineno, file, lineno);
    97     }
    98 
    99     if (lineno > 0) {
    100         psAbort(__func__, "Detected a problem in the memory system at %s:%d", file, lineno);
    101     }
     96static void memProblemCallbackDefault( const psMemBlock *ptr,
     97                                       const char *file, int lineno )
     98{
     99    if ( ptr->refCounter < 1 ) {
     100            psError( __func__,
     101                     "Block %ld allocated at %s:%d freed more than once at %s:%d\n",
     102                     ptr->id, ptr->file, ptr->lineno, file, lineno );
     103        }
     104       
     105    if ( lineno > 0 ) {
     106            psAbort( __func__, "Detected a problem in the memory system at %s:%d", file, lineno );
     107        }
    102108}
    103109static psMemProblemCallback memProblemCallback = memProblemCallbackDefault;
    104110
    105 psMemProblemCallback psMemProblemCallbackSet(psMemProblemCallback func)
     111psMemProblemCallback psMemProblemCallbackSet( psMemProblemCallback func )
    106112{
    107113    psMemProblemCallback old = memProblemCallback;
    108 
    109     if (func != NULL) {
    110         memProblemCallback = func;
    111     } else {
    112         memProblemCallback = memProblemCallbackDefault;
    113     }
    114 
     114   
     115    if ( func != NULL ) {
     116            memProblemCallback = func;
     117        } else {
     118            memProblemCallback = memProblemCallbackDefault;
     119        }
     120       
    115121    return old;
    116122}
     
    123129psMemoryId p_psMemFreeID = 0;   // notify user this block is freed
    124130
    125 psMemoryId psMemAllocateCallbackSetID(psMemoryId id)
     131psMemoryId psMemAllocateCallbackSetID( psMemoryId id )
    126132{
    127133    psMemoryId old = p_psMemAllocateID;
    128134    p_psMemAllocateID = id;
    129 
     135   
    130136    return old;
    131137}
    132138
    133 psMemoryId psMemFreeCallbackSetID(psMemoryId id)
     139psMemoryId psMemFreeCallbackSetID( psMemoryId id )
    134140{
    135141    psMemoryId old = p_psMemFreeID;
    136142    p_psMemFreeID = id;
    137 
     143   
    138144    return old;
    139145}
     
    145151 * isn't resignalled)
    146152 */
    147 static psMemoryId memAllocateCallbackDefault(const psMemBlock *ptr)
     153static psMemoryId memAllocateCallbackDefault( const psMemBlock *ptr )
    148154{
    149155    static psMemoryId incr = 0;  // "p_psMemAllocateID += incr"
    150 
     156   
    151157    return incr;
    152158}
    153159
    154 static psMemoryId memFreeCallbackDefault(const psMemBlock *ptr)
     160static psMemoryId memFreeCallbackDefault( const psMemBlock *ptr )
    155161{
    156162    static psMemoryId incr = 0;  // "p_psMemFreeID += incr"
    157 
     163   
    158164    return incr;
    159165}
     
    165171static psMemFreeCallback memFreeCallback = memFreeCallbackDefault;
    166172
    167 psMemAllocateCallback psMemAllocateCallbackSet(psMemAllocateCallback func)
     173psMemAllocateCallback psMemAllocateCallbackSet( psMemAllocateCallback func )
    168174{
    169175    psMemFreeCallback old = memAllocateCallback;
    170 
    171     if (func != NULL) {
    172         memAllocateCallback = func;
    173     } else {
    174         memAllocateCallback = memAllocateCallbackDefault;
    175     }
    176 
     176   
     177    if ( func != NULL ) {
     178            memAllocateCallback = func;
     179        } else {
     180            memAllocateCallback = memAllocateCallbackDefault;
     181        }
     182       
    177183    return old;
    178184}
    179185
    180 psMemFreeCallback psMemFreeCallbackSet(psMemFreeCallback func)
     186psMemFreeCallback psMemFreeCallbackSet( psMemFreeCallback func )
    181187{
    182188    psMemFreeCallback old = memFreeCallback;
    183 
    184     if (func != NULL) {
    185         memFreeCallback = func;
    186     } else {
    187         memFreeCallback = memFreeCallbackDefault;
    188     }
    189 
     189   
     190    if ( func != NULL ) {
     191            memFreeCallback = func;
     192        } else {
     193            memFreeCallback = memFreeCallbackDefault;
     194        }
     195       
    190196    return old;
    191197}
     
    194200 * Return memory ID counter for next block to be allocated
    195201 */
    196 psMemoryId psMemGetId(void)
     202psMemoryId psMemGetId( void )
    197203{
    198204    psMemoryId id;
    199     pthread_mutex_lock(&memIdMutex);
     205    pthread_mutex_lock( &memIdMutex );
    200206    id = memid + 1;
    201     pthread_mutex_unlock(&memIdMutex);
    202 
     207    pthread_mutex_unlock( &memIdMutex );
     208   
    203209    return id;
    204210}
     
    210216 */
    211217
    212 static int checkMemBlock(const psMemBlock *m, const char* funcName)
     218static int checkMemBlock( const psMemBlock *m, const char* funcName )
    213219{
    214220    // n.b. since this is called by psMemCheckCorruption while the memblock list is mutex locked,
    215221    // we shouldn't call such things as p_psAlloc/p_psFree here.
    216 
    217     if (m == NULL) {
    218         psError(funcName,"Memory Corruption: NULL memory block found.");
    219         return 1;
    220     }
    221 
    222     if (m->refCounter == 0) {
    223         // using an unreferenced block of memory, are you?
    224         psError(__func__,"Memory Corruption: memory block %ld was freed but still used.",
    225                 m->id);
    226         return 1;
    227     }
    228 
    229     if (m->startblock != P_PS_MEMMAGIC || m->endblock != P_PS_MEMMAGIC) {
    230         psError(funcName, "Memory Corruption: memory block %ld is corrupted (buffer underflow)",
    231                 m->id);
    232         return 1;
    233     }
    234     if (*(void**)((int8_t*)(m+1)+m->userMemorySize) != P_PS_MEMMAGIC) {
    235         psError(funcName, "Memory Corruption: memory block %ld is corrupted (buffer overflow)",
    236                 m->id);
    237         return 1;
    238     }
    239 
     222   
     223    if ( m == NULL ) {
     224            psError( funcName, "Memory Corruption: NULL memory block found." );
     225            return 1;
     226        }
     227       
     228    if ( m->refCounter == 0 ) {
     229            // using an unreferenced block of memory, are you?
     230            psError( __func__, "Memory Corruption: memory block %ld was freed but still used.",
     231                     m->id );
     232            return 1;
     233        }
     234       
     235    if ( m->startblock != P_PS_MEMMAGIC || m->endblock != P_PS_MEMMAGIC ) {
     236            psError( funcName, "Memory Corruption: memory block %ld is corrupted (buffer underflow)",
     237                     m->id );
     238            return 1;
     239        }
     240    if ( *( void** ) ( ( int8_t* ) ( m + 1 ) + m->userMemorySize ) != P_PS_MEMMAGIC ) {
     241            psError( funcName, "Memory Corruption: memory block %ld is corrupted (buffer overflow)",
     242                     m->id );
     243            return 1;
     244        }
     245       
    240246    return 0;
    241247}
    242248
    243 int psMemCheckCorruption(bool abort_on_error)
     249int psMemCheckCorruption( bool abort_on_error )
    244250{
    245251    int nbad = 0;                       // number of bad blocks
    246 
     252   
    247253    // get exclusive access to the memBlock list to avoid it changing on us while we use it.
    248     pthread_mutex_lock(&memBlockListMutex);
    249 
    250     for (psMemBlock* iter=lastMemBlockAllocated; iter != NULL; iter=iter->nextBlock) {
    251         if (checkMemBlock(iter, __func__)) {
    252             nbad++;
    253 
    254             memProblemCallback(iter, __func__, __LINE__);
    255 
    256             if (abort_on_error) {
    257                 // release the lock on the memblock list
    258                 pthread_mutex_unlock(&memBlockListMutex);
    259                 psAbort(__func__, "Detected memory corruption");
    260                 return nbad;
    261             }
    262         }
    263     }
    264 
     254    pthread_mutex_lock( &memBlockListMutex );
     255   
     256    for ( psMemBlock * iter = lastMemBlockAllocated; iter != NULL; iter = iter->nextBlock ) {
     257            if ( checkMemBlock( iter, __func__ ) ) {
     258                    nbad++;
     259                   
     260                    memProblemCallback( iter, __func__, __LINE__ );
     261                   
     262                    if ( abort_on_error ) {
     263                            // release the lock on the memblock list
     264                            pthread_mutex_unlock( &memBlockListMutex );
     265                            psAbort( __func__, "Detected memory corruption" );
     266                            return nbad;
     267                        }
     268                }
     269        }
     270       
    265271    // release the lock on the memblock list
    266     pthread_mutex_unlock(&memBlockListMutex);
     272    pthread_mutex_unlock( &memBlockListMutex );
    267273    return nbad;
    268274}
    269275
    270 void *p_psAlloc(size_t size, const char *file, int lineno)
    271 {
    272 
    273     psMemBlock *ptr = NULL;
    274 
     276void *p_psAlloc( size_t size, const char *file, int lineno )
     277{
     278
     279    psMemBlock * ptr = NULL;
     280   
    275281    // 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     }
    301 
    302     if (ptr == NULL) {
    303         ptr = malloc(sizeof(psMemBlock) + size + sizeof(void*));
    304 
    305         if (ptr == NULL) {
    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);
    317     }
    318 
     282    if ( size < P_PS_LARGE_BLOCK_SIZE ) {
     283            // find the bin we need.
     284            int level = 0;
     285            while ( size > recycleBinSize[ level ] ) {
     286                    level++;
     287                }
     288            // Are we in one of the bins
     289            if ( level < recycleBins ) {
     290           
     291                    size = recycleBinSize[ level ];  // round-up size to next sized bin.
     292                   
     293                    pthread_mutex_lock( &recycleMemBlockListMutex );
     294                   
     295                    if ( recycleMemBlockList[ level ] != NULL ) {
     296                            ptr = recycleMemBlockList[ level ];
     297                            recycleMemBlockList[ level ] = ptr->nextBlock;
     298                            if ( recycleMemBlockList[ level ] != NULL ) {
     299                                    recycleMemBlockList[ level ] ->previousBlock = NULL;
     300                                }
     301                            size = ptr->userMemorySize;
     302                        }
     303                       
     304                    pthread_mutex_unlock( &recycleMemBlockListMutex );
     305                }
     306        }
     307       
     308    if ( ptr == NULL ) {
     309            ptr = malloc( sizeof( psMemBlock ) + size + sizeof( void* ) );
     310           
     311            if ( ptr == NULL ) {
     312                    ptr = memExhaustedCallback( size );
     313                    if ( ptr == NULL ) {
     314                            psAbort( __func__, "Failed to allocate %u bytes at %s:%d",
     315                                     size, file, lineno );
     316                        }
     317                }
     318               
     319            ptr->startblock = P_PS_MEMMAGIC;
     320            ptr->endblock = P_PS_MEMMAGIC;
     321            ptr->userMemorySize = size;
     322            pthread_mutex_init( &ptr->refCounterMutex, NULL );
     323        }
     324       
    319325    // increment the memory id safely.
    320     pthread_mutex_lock(&memBlockListMutex);
    321     *(psMemoryId*)&ptr->id = ++memid;
    322     pthread_mutex_unlock(&memBlockListMutex);
    323 
     326    pthread_mutex_lock( &memBlockListMutex );
     327    *( psMemoryId* ) & ptr->id = ++memid;
     328    pthread_mutex_unlock( &memBlockListMutex );
     329   
    324330    ptr->file = file;
    325331    ptr->freeFcn = NULL;
    326     *(unsigned int*)&ptr->lineno = lineno;
    327     *(void**)((int8_t*)(ptr+1)+size) = P_PS_MEMMAGIC;
     332    *( unsigned int* ) & ptr->lineno = lineno;
     333    *( void** ) ( ( int8_t* ) ( ptr + 1 ) + size ) = P_PS_MEMMAGIC;
    328334    ptr->previousBlock = NULL;
    329 
     335   
    330336    ptr->refCounter = 1;                // one user so far
    331 
     337   
    332338    // need exclusive access of the memory block list now...
    333     pthread_mutex_lock(&memBlockListMutex);
    334 
     339    pthread_mutex_lock( &memBlockListMutex );
     340   
    335341    // insert the new block to the front of the memBlock linked-list
    336342    ptr->nextBlock = lastMemBlockAllocated;
    337     if (ptr->nextBlock != NULL) {
    338         ptr->nextBlock->previousBlock = ptr;
    339     }
     343    if ( ptr->nextBlock != NULL ) {
     344            ptr->nextBlock->previousBlock = ptr;
     345        }
    340346    lastMemBlockAllocated = ptr;
    341 
    342     pthread_mutex_unlock(&memBlockListMutex);
    343 
     347   
     348    pthread_mutex_unlock( &memBlockListMutex );
     349   
    344350    //  Did the user ask to be informed about this allocation?
    345     if (ptr->id == p_psMemAllocateID) {
    346         p_psMemAllocateID += memAllocateCallback(ptr);
    347     }
    348 
     351    if ( ptr->id == p_psMemAllocateID ) {
     352            p_psMemAllocateID += memAllocateCallback( ptr );
     353        }
     354       
    349355    // And return the user the memory that they allocated
    350356    return ptr + 1;   // user memory
    351357}
    352358
    353 void *p_psRealloc(void *vptr, size_t size, const char *file, int lineno)
    354 {
    355     if (vptr == NULL) {
    356         return p_psAlloc(size, file, lineno);
    357     } else {
    358         psMemBlock *ptr = ((psMemBlock *)vptr) - 1;
    359         bool isBlockLast = false;
    360 
    361         if (checkMemBlock(ptr, __func__) != 0) {
    362             memProblemCallback(ptr, file, lineno);
    363             psAbort(file,"Realloc detected a memory corruption (id %ld @ %s:%d).",
    364                     ptr->id,ptr->file,ptr->lineno);
    365         }
    366 
    367         pthread_mutex_lock(&memBlockListMutex);
    368 
    369         isBlockLast = (ptr == lastMemBlockAllocated);
    370 
    371         ptr = (psMemBlock*)realloc(ptr, sizeof(psMemBlock) + size + sizeof(void*));
    372 
    373         if (ptr == NULL) {
    374             psAbort(__func__, "Failed to reallocate %ld bytes at %s:%d",
    375                     size, file, lineno);
    376         }
    377 
    378         ptr->userMemorySize = size;
    379         *(void**)((int8_t*)(ptr+1)+size) = P_PS_MEMMAGIC;
    380 
    381         if (isBlockLast) {
    382             lastMemBlockAllocated = ptr;
    383         }
    384 
    385         // the block location may have changed, so fix the linked list addresses.
    386         if (ptr->nextBlock != NULL) {
    387             ptr->nextBlock->previousBlock = ptr;
    388         }
    389         if (ptr->previousBlock != NULL) {
    390             ptr->previousBlock->nextBlock = ptr;
    391         }
    392 
    393         pthread_mutex_unlock(&memBlockListMutex);
    394 
    395         //  Did the user ask to be informed about this allocation?
    396         if (ptr->id == p_psMemAllocateID) {
    397             p_psMemAllocateID += memAllocateCallback(ptr);
    398         }
    399 
    400         return ptr + 1;   // usr memory
    401     }
    402 }
    403 
    404 void p_psFree(void *vptr, const char *file, int lineno)
    405 {
    406     (void)p_psMemDecrRefCounter(vptr,file,lineno);   // this handles the free, if required.
     359void *p_psRealloc( void *vptr, size_t size, const char *file, int lineno )
     360{
     361    if ( vptr == NULL ) {
     362            return p_psAlloc( size, file, lineno );
     363        } else {
     364            psMemBlock *ptr = ( ( psMemBlock * ) vptr ) - 1;
     365            bool isBlockLast = false;
     366           
     367            if ( checkMemBlock( ptr, __func__ ) != 0 ) {
     368                    memProblemCallback( ptr, file, lineno );
     369                    psAbort( file, "Realloc detected a memory corruption (id %ld @ %s:%d).",
     370                             ptr->id, ptr->file, ptr->lineno );
     371                }
     372               
     373            pthread_mutex_lock( &memBlockListMutex );
     374           
     375            isBlockLast = ( ptr == lastMemBlockAllocated );
     376           
     377            ptr = ( psMemBlock* ) realloc( ptr, sizeof( psMemBlock ) + size + sizeof( void* ) );
     378           
     379            if ( ptr == NULL ) {
     380                    psAbort( __func__, "Failed to reallocate %ld bytes at %s:%d",
     381                             size, file, lineno );
     382                }
     383               
     384            ptr->userMemorySize = size;
     385            *( void** ) ( ( int8_t* ) ( ptr + 1 ) + size ) = P_PS_MEMMAGIC;
     386           
     387            if ( isBlockLast ) {
     388                    lastMemBlockAllocated = ptr;
     389                }
     390               
     391            // the block location may have changed, so fix the linked list addresses.
     392            if ( ptr->nextBlock != NULL ) {
     393                    ptr->nextBlock->previousBlock = ptr;
     394                }
     395            if ( ptr->previousBlock != NULL ) {
     396                    ptr->previousBlock->nextBlock = ptr;
     397                }
     398               
     399            pthread_mutex_unlock( &memBlockListMutex );
     400           
     401            //  Did the user ask to be informed about this allocation?
     402            if ( ptr->id == p_psMemAllocateID ) {
     403                    p_psMemAllocateID += memAllocateCallback( ptr );
     404                }
     405               
     406            return ptr + 1;   // usr memory
     407        }
     408}
     409
     410void p_psFree( void *vptr, const char *file, int lineno )
     411{
     412    ( void ) p_psMemDecrRefCounter( vptr, file, lineno );   // this handles the free, if required.
    407413}
    408414
     
    410416 * Check for memory leaks.
    411417 */
    412 int psMemCheckLeaks(psMemoryId id0,psMemBlock ***arr,FILE *fd)
     418int psMemCheckLeaks( psMemoryId id0, psMemBlock ***arr, FILE *fd )
    413419{
    414420    int nleak = 0;
    415421    int j = 0;
    416422    psMemBlock* topBlock = lastMemBlockAllocated;
    417 
    418     pthread_mutex_lock(&memBlockListMutex);
    419 
    420     for (psMemBlock* iter = topBlock; iter != NULL; iter=iter->nextBlock) {
    421         if ( (psMemGetRefCounter(iter+1) > 0) && (iter->id >= id0) ) {
    422             nleak++;
    423 
    424             if (fd != NULL) {
    425                 if (nleak == 1) {
    426                     fprintf(fd, "   %20s:line ID\n", "file");
    427                 }
    428 
    429                 fprintf(fd, "   %20s:%-4d %ld\n", iter->file, iter->lineno, iter->id);
    430             }
    431         }
    432     }
    433 
    434     pthread_mutex_unlock(&memBlockListMutex);
    435 
    436     if (nleak == 0 || arr == NULL) {
    437         return nleak;
    438     }
    439 
    440     *arr = p_psAlloc(nleak*sizeof(psMemBlock), __FILE__, __LINE__);
    441     pthread_mutex_lock(&memBlockListMutex);
    442 
    443     for (psMemBlock* iter = topBlock; iter != NULL; iter=iter->nextBlock) {
    444         if ( (psMemGetRefCounter(iter+1) > 0) && (iter->id >= id0) ) {
    445             (*arr)[j++] = iter;
    446             if (j == nleak) { // found them all
    447                 break;
    448             }
    449         }
    450     }
    451 
    452     pthread_mutex_unlock(&memBlockListMutex);
    453 
     423   
     424    pthread_mutex_lock( &memBlockListMutex );
     425   
     426    for ( psMemBlock * iter = topBlock; iter != NULL; iter = iter->nextBlock ) {
     427            if ( ( psMemGetRefCounter( iter + 1 ) > 0 ) && ( iter->id >= id0 ) ) {
     428                    nleak++;
     429                   
     430                    if ( fd != NULL ) {
     431                            if ( nleak == 1 ) {
     432                                    fprintf( fd, "   %20s:line ID\n", "file" );
     433                                }
     434                               
     435                            fprintf( fd, "   %20s:%-4d %ld\n", iter->file, iter->lineno, iter->id );
     436                        }
     437                }
     438        }
     439       
     440    pthread_mutex_unlock( &memBlockListMutex );
     441   
     442    if ( nleak == 0 || arr == NULL ) {
     443            return nleak;
     444        }
     445       
     446    *arr = p_psAlloc( nleak * sizeof( psMemBlock ), __FILE__, __LINE__ );
     447    pthread_mutex_lock( &memBlockListMutex );
     448   
     449    for ( psMemBlock * iter = topBlock; iter != NULL; iter = iter->nextBlock ) {
     450            if ( ( psMemGetRefCounter( iter + 1 ) > 0 ) && ( iter->id >= id0 ) ) {
     451                    ( *arr ) [ j++ ] = iter;
     452                    if ( j == nleak ) { // found them all
     453                            break;
     454                        }
     455                }
     456        }
     457       
     458    pthread_mutex_unlock( &memBlockListMutex );
     459   
    454460    return nleak;
    455461}
     
    457463/*
    458464 * Reference counting APIs
    459  */
     465 */ 
    460466// return refCounter
    461 psReferenceCount psMemGetRefCounter(void *vptr)
    462 {
    463     psMemBlock *ptr;
     467psReferenceCount psMemGetRefCounter( void *vptr )
     468{
     469    psMemBlock * ptr;
    464470    unsigned int refCount;
    465 
    466     if (vptr == NULL) {
    467         return 0;
    468     }
    469 
    470     ptr = ((psMemBlock *)vptr) - 1;
    471 
    472     if (checkMemBlock(ptr, __func__) != 0) {
    473         memProblemCallback(ptr, __func__, __LINE__);
    474     }
    475 
    476     pthread_mutex_lock(&ptr->refCounterMutex);
     471   
     472    if ( vptr == NULL ) {
     473            return 0;
     474        }
     475       
     476    ptr = ( ( psMemBlock * ) vptr ) - 1;
     477   
     478    if ( checkMemBlock( ptr, __func__ ) != 0 ) {
     479            memProblemCallback( ptr, __func__, __LINE__ );
     480        }
     481       
     482    pthread_mutex_lock( &ptr->refCounterMutex );
    477483    refCount = ptr->refCounter;
    478     pthread_mutex_unlock(&ptr->refCounterMutex);
    479 
     484    pthread_mutex_unlock( &ptr->refCounterMutex );
     485   
    480486    return refCount;
    481487}
    482488// increment and return refCounter
    483 void* p_psMemIncrRefCounter(void *vptr, const char *file, int lineno)
    484 {
    485     psMemBlock *ptr;
    486 
    487     if (vptr == NULL) {
    488         return vptr;
    489     }
    490 
    491     ptr = ((psMemBlock *)vptr) - 1;
    492 
    493     if (checkMemBlock(ptr, __func__)) {
    494         memProblemCallback(ptr, file,lineno);
    495     }
    496 
    497     pthread_mutex_lock(&ptr->refCounterMutex);
     489void* p_psMemIncrRefCounter( void *vptr, const char *file, int lineno )
     490{
     491    psMemBlock * ptr;
     492   
     493    if ( vptr == NULL ) {
     494            return vptr;
     495        }
     496       
     497    ptr = ( ( psMemBlock * ) vptr ) - 1;
     498   
     499    if ( checkMemBlock( ptr, __func__ ) ) {
     500            memProblemCallback( ptr, file, lineno );
     501        }
     502       
     503    pthread_mutex_lock( &ptr->refCounterMutex );
    498504    ptr->refCounter++;
    499     pthread_mutex_unlock(&ptr->refCounterMutex);
    500 
     505    pthread_mutex_unlock( &ptr->refCounterMutex );
     506   
    501507    return vptr;
    502508}
    503509
    504510// decrement and return refCounter
    505 void* p_psMemDecrRefCounter(void *vptr,const char *file, int lineno)
    506 {
    507     if (vptr == NULL) {
    508         return NULL;
    509     }
    510 
    511     psMemBlock *ptr = ((psMemBlock *)vptr) - 1;
    512 
    513     if (checkMemBlock(ptr, __func__) != 0) {
    514         memProblemCallback(ptr, file, lineno);
    515         return NULL;
    516     }
    517 
    518     pthread_mutex_lock(&ptr->refCounterMutex);
    519 
    520     if (ptr->refCounter > 1) {
    521         /// XXX - Probably should have another mutex here.
    522         ptr->refCounter--;          // multiple references, just decrement the count.
    523         pthread_mutex_unlock(&ptr->refCounterMutex);
    524 
    525     } else {
    526         pthread_mutex_unlock(&ptr->refCounterMutex);
    527 
    528         // Did the user ask to be informed about this deallocation?
    529         if (ptr->id == p_psMemFreeID) {
    530             p_psMemFreeID += memFreeCallback(ptr);
    531         }
    532 
    533         if (ptr->freeFcn != NULL) {
    534             ptr->freeFcn(vptr);
    535         }
    536 
    537         pthread_mutex_lock(&memBlockListMutex);
    538 
    539         // cut the memBlock out of the memBlock list
    540         if (ptr->nextBlock != NULL) {
    541             ptr->nextBlock->previousBlock = ptr->previousBlock;
    542         }
    543         if (ptr->previousBlock != NULL) {
    544             ptr->previousBlock->nextBlock = ptr->nextBlock;
    545         }
    546         if (lastMemBlockAllocated == ptr) {
    547             lastMemBlockAllocated = ptr->nextBlock;
    548         }
    549 
    550         pthread_mutex_unlock(&memBlockListMutex);
    551 
    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 
     511void* p_psMemDecrRefCounter( void *vptr, const char *file, int lineno )
     512{
     513    if ( vptr == NULL ) {
     514            return NULL;
     515        }
     516       
     517    psMemBlock *ptr = ( ( psMemBlock * ) vptr ) - 1;
     518   
     519    if ( checkMemBlock( ptr, __func__ ) != 0 ) {
     520            memProblemCallback( ptr, file, lineno );
     521            return NULL;
     522        }
     523       
     524    pthread_mutex_lock( &ptr->refCounterMutex );
     525   
     526    if ( ptr->refCounter > 1 ) {
     527            /// XXX - Probably should have another mutex here.
     528            ptr->refCounter--;          // multiple references, just decrement the count.
     529            pthread_mutex_unlock( &ptr->refCounterMutex );
     530           
    573531        } 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 
    592         pthread_mutex_destroy(&ptr->refCounterMutex);
    593 
    594 
    595         vptr = NULL;    // since we freed it, make sure we return NULL.
    596     }
    597 
     532            pthread_mutex_unlock( &ptr->refCounterMutex );
     533           
     534            // Did the user ask to be informed about this deallocation?
     535            if ( ptr->id == p_psMemFreeID ) {
     536                    p_psMemFreeID += memFreeCallback( ptr );
     537                }
     538               
     539            if ( ptr->freeFcn != NULL ) {
     540                    ptr->freeFcn( vptr );
     541                }
     542               
     543            pthread_mutex_lock( &memBlockListMutex );
     544           
     545            // cut the memBlock out of the memBlock list
     546            if ( ptr->nextBlock != NULL ) {
     547                    ptr->nextBlock->previousBlock = ptr->previousBlock;
     548                }
     549            if ( ptr->previousBlock != NULL ) {
     550                    ptr->previousBlock->nextBlock = ptr->nextBlock;
     551                }
     552            if ( lastMemBlockAllocated == ptr ) {
     553                    lastMemBlockAllocated = ptr->nextBlock;
     554                }
     555               
     556            pthread_mutex_unlock( &memBlockListMutex );
     557           
     558           
     559            // do we need to recycle?
     560            if ( ptr->userMemorySize < P_PS_LARGE_BLOCK_SIZE ) {
     561           
     562                    int level = 1;
     563                    while ( ptr->userMemorySize >= recycleBinSize[ level ] ) {
     564                            level++;
     565                        }
     566                    level--;
     567                   
     568                    ptr->refCounter = 0;
     569                    ptr->previousBlock = NULL;
     570                   
     571                    pthread_mutex_lock( &recycleMemBlockListMutex );
     572                    ptr->nextBlock = recycleMemBlockList[ level ];
     573                    if ( recycleMemBlockList[ level ] != NULL ) {
     574                            recycleMemBlockList[ level ] ->previousBlock = ptr;
     575                        }
     576                    recycleMemBlockList[ level ] = ptr;
     577                    pthread_mutex_unlock( &recycleMemBlockListMutex );
     578                   
     579                } else {
     580                    // memory is larger than I want to recycle.
     581                    #ifdef PS_MEM_DEBUG
     582                    ( void ) p_psRealloc( vptr, 0, file, lineno );
     583                    ptr->previousBlock = NULL;
     584                    ptr->nextBlock = deadBlockList;
     585                    if ( deadBlockList != NULL ) {
     586                            deadBlockList->previous = ptr;
     587                        }
     588                    deadBlockList = ptr;
     589                    #else
     590                   
     591                    pthread_mutex_destroy( &ptr->refCounterMutex );
     592                    free( ptr );
     593                    #endif
     594                   
     595                }
     596               
     597            vptr = NULL;    // since we freed it, make sure we return NULL.
     598        }
     599       
    598600    return vptr;
    599601}
    600602
    601 void p_psMemSetDeallocator(void* vptr, psFreeFcn freeFcn)
    602 {
    603     if (vptr == NULL) {
    604         return;
    605     }
    606 
    607     psMemBlock *ptr = ((psMemBlock *)vptr) - 1;
    608 
    609     if (checkMemBlock(ptr, __func__) != 0) {
    610         memProblemCallback(ptr, __func__, __LINE__);
    611     }
    612 
     603void p_psMemSetDeallocator( void* vptr, psFreeFcn freeFcn )
     604{
     605    if ( vptr == NULL ) {
     606            return ;
     607        }
     608       
     609    psMemBlock *ptr = ( ( psMemBlock * ) vptr ) - 1;
     610   
     611    if ( checkMemBlock( ptr, __func__ ) != 0 ) {
     612            memProblemCallback( ptr, __func__, __LINE__ );
     613        }
     614       
    613615    ptr->freeFcn = freeFcn;
    614 
    615 }
    616 psFreeFcn p_psMemGetDeallocator(void* vptr)
    617 {
    618     if (vptr == NULL) {
    619         return NULL;
    620     }
    621 
    622     psMemBlock *ptr = ((psMemBlock *)vptr) - 1;
    623 
    624     if (checkMemBlock(ptr, __func__) != 0) {
    625         memProblemCallback(ptr, __func__, __LINE__);
    626     }
    627 
     616   
     617}
     618psFreeFcn p_psMemGetDeallocator( void* vptr )
     619{
     620    if ( vptr == NULL ) {
     621            return NULL;
     622        }
     623       
     624    psMemBlock *ptr = ( ( psMemBlock * ) vptr ) - 1;
     625   
     626    if ( checkMemBlock( ptr, __func__ ) != 0 ) {
     627            memProblemCallback( ptr, __func__, __LINE__ );
     628        }
     629       
    628630    return ptr->freeFcn;
    629631}
  • trunk/psLib/src/sysUtils/psType.h

    r1292 r1360  
    11/** @file  psType.h
    2  *
    3  *  @brief Contains support for basic types
    4  *
    5  *  This file defines common datatypes used throughout psLib.
    6  *
    7  *  @ingroup DataContainer
    8  *
    9  *  @author Robert DeSonia, MHPCC
    10  *  @author Ross Harman, MHPCC
    11  *
    12  *  @version $Revision: 1.14 $ $Name: not supported by cvs2svn $
    13  *  @date $Date: 2004-07-24 02:00:21 $
    14  *
    15  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
    16  */
     2*
     3*  @brief Contains support for basic types
     4*
     5*  This file defines common datatypes used throughout psLib.
     6*
     7*  @ingroup DataContainer
     8*
     9*  @author Robert DeSonia, MHPCC
     10*  @author Ross Harman, MHPCC
     11*
     12*  @version $Revision: 1.15 $ $Name: not supported by cvs2svn $
     13*  @date $Date: 2004-07-31 02:28:10 $
     14*
     15*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     16*/
    1717
    1818#ifndef PS_TYPE_H
     
    3737 */
    3838
    39 typedef uint8_t         psU8;           ///< 8-bit unsigned int
    40 typedef uint16_t        psU16;          ///< 16-bit unsigned int
    41 typedef uint32_t        psU32;          ///< 32-bit unsigned int
    42 typedef uint64_t        psU64;          ///< 64-bit unsigned int
    43 typedef int8_t          psS8;           ///< 8-bit signed int
    44 typedef int16_t         psS16;          ///< 16-bit signed int
    45 typedef int32_t         psS32;          ///< 32-bit signed int
    46 typedef int64_t         psS64;          ///< 64-bit signed int
    47 typedef float           psF32;          ///< 32-bit floating point
    48 typedef double          psF64;          ///< 64-bit floating point
    49 typedef complex float   psC32;          ///< complex with 32-bit floating point Real and Imagary numbers
    50 typedef complex double  psC64;          ///< complex with 64-bit floating point Real and Imagary numbers
    51 typedef void*           psPTR;           ///< void pointer
     39typedef uint8_t psU8;           ///< 8-bit unsigned int
     40typedef uint16_t psU16;          ///< 16-bit unsigned int
     41typedef uint32_t psU32;          ///< 32-bit unsigned int
     42typedef uint64_t psU64;          ///< 64-bit unsigned int
     43typedef int8_t psS8;           ///< 8-bit signed int
     44typedef int16_t psS16;          ///< 16-bit signed int
     45typedef int32_t psS32;          ///< 32-bit signed int
     46typedef int64_t psS64;          ///< 64-bit signed int
     47typedef float psF32;          ///< 32-bit floating point
     48typedef double psF64;          ///< 64-bit floating point
     49typedef complex float psC32;          ///< complex with 32-bit floating point Real and Imagary numbers
     50typedef complex double psC64;          ///< complex with 64-bit floating point Real and Imagary numbers
     51typedef void* psPTR;           ///< void pointer
    5252
    5353
    5454typedef enum {
    55     PS_TYPE_S8               = 0x0101,  ///< Character.
    56     PS_TYPE_S16              = 0x0102,  ///< Short integer.
    57     PS_TYPE_S32              = 0x0104,  ///< Integer.
    58     PS_TYPE_S64              = 0x0108,  ///< Long integer.
    59     PS_TYPE_U8               = 0x0301,  ///< Unsigned character.
    60     PS_TYPE_U16              = 0x0302,  ///< Unsigned short integer.
    61     PS_TYPE_U32              = 0x0304,  ///< Unsigned integer.
    62     PS_TYPE_U64              = 0x0308,  ///< Unsigned long integer.
    63     PS_TYPE_F32              = 0x0404,  ///< Single-precision Floating point.
    64     PS_TYPE_F64              = 0x0408,  ///< Double-precision floating point.
    65     PS_TYPE_C32              = 0x0808,  ///< Complex numbers consisting of single-precision floating point.
    66     PS_TYPE_C64              = 0x0810,  ///< Complex numbers consisting of double-precision floating point.
    67     PS_TYPE_PTR              = 0x0000   ///< Something else that's not supported for arithmetic.
     55    PS_TYPE_S8 = 0x0101,   ///< Character.
     56    PS_TYPE_S16 = 0x0102,   ///< Short integer.
     57    PS_TYPE_S32 = 0x0104,   ///< Integer.
     58    PS_TYPE_S64 = 0x0108,   ///< Long integer.
     59    PS_TYPE_U8 = 0x0301,   ///< Unsigned character.
     60    PS_TYPE_U16 = 0x0302,   ///< Unsigned short integer.
     61    PS_TYPE_U32 = 0x0304,   ///< Unsigned integer.
     62    PS_TYPE_U64 = 0x0308,   ///< Unsigned long integer.
     63    PS_TYPE_F32 = 0x0404,   ///< Single-precision Floating point.
     64    PS_TYPE_F64 = 0x0408,   ///< Double-precision floating point.
     65    PS_TYPE_C32 = 0x0808,   ///< Complex numbers consisting of single-precision floating point.
     66    PS_TYPE_C64 = 0x0810,   ///< Complex numbers consisting of double-precision floating point.
     67    PS_TYPE_PTR = 0x0000   ///< Something else that's not supported for arithmetic.
    6868} psElemType;
    6969
    7070#define PS_TYPE_MASK PS_TYPE_U8         ///< the psElemType to use for mask image
     71#define PS_TYPE_MASK_DATA U8            ///< the data member to use for mask image
    7172#define PS_TYPE_MASK_NAME "psU8"
    7273typedef psU8 psMaskType;                ///< the C datatype for a mask image
     
    127128 */
    128129typedef enum {
    129     PS_DIMEN_SCALAR,    ///< Scalar.
    130     PS_DIMEN_VECTOR,    ///< Vector.
    131     PS_DIMEN_TRANSV,    ///< Transposed vector.
    132     PS_DIMEN_IMAGE,     ///< Image.
     130    PS_DIMEN_SCALAR,     ///< Scalar.
     131    PS_DIMEN_VECTOR,     ///< Vector.
     132    PS_DIMEN_TRANSV,     ///< Transposed vector.
     133    PS_DIMEN_IMAGE,      ///< Image.
    133134    PS_DIMEN_OTHER      ///< Something else that's not supported for arithmetic.
    134135} psDimen;
     
    141142 */
    142143typedef struct
    143 {
    144     psElemType type;    ///< Primitive type.
    145     psDimen dimen;      ///< Dimensionality.
    146 }
     144    {
     145        psElemType type;    ///< Primitive type.
     146        psDimen dimen;      ///< Dimensionality.
     147    }
    147148psType;
    148149
  • trunk/psLib/test/psTest.c

    r1193 r1360  
    2727#define HEADER_BOTTOM "\\**********************************************************************************/\n\n"
    2828
    29 bool p_runTestSuite(FILE *fp, const char* testPointFile, const char* packageName,
    30                     testDescription tests[], int argc, char * const argv[])
     29bool p_runTestSuite( FILE *fp, const char* testPointFile, const char* packageName,
     30                     testDescription tests[], int argc, char * const argv[] )
    3131{
    3232    bool success = true;
     
    3737    int n;
    3838    extern char *optarg;
    39 
    40     if (argc > 0) {
    41         while ( (c=getopt(argc,argv,"lhn:dt:")) != -1) {
    42             switch (c) {
    43             case 'h':
    44                 printf("Usage: %s [-l] [-d] [-h] [-n=Testpoint#] [-t=TestpointName]\n"
    45                        "    where:\n"
    46                        "           -l  : lists the testpoints contained in this test driver executable\n"
    47                        "           -d  : turns on debugger-friendly mode (no forking, aborts/signals are not handled)\n"
    48                        "           -h  : prints this help\n"
    49                        "           -n  : specifies a particular testpoint by number to run\n"
    50                        "           -t  : specifies a particular testpoint by name to run\n"
    51                        "    (if no -l, -n or -t options are given, all testpoints are run)\n",
    52                        argv[0]);
    53                 runAll = false;
    54                 break;
    55             case 'd':
    56                 useFork = false;
    57                 break;
    58             case 'l':
    59                 printf("Test Driver:  %s\n",testPointFile);
    60                 printf("Package Name: %s\n",packageName);
    61                 printf("Testpoints:\n");
    62                 runAll = false;
    63                 for (int index=0; tests[index].fcn != NULL; index++) {
    64                     printf("    %6d - %s \n",tests[index].testPointNumber,
    65                            tests[index].testPointName);
    66                 }
    67                 printf("\n");
    68                 break;
    69             case 't':
    70                 runAll = false;
    71                 for (int index=0; tests[index].fcn != NULL; index++) {
    72                     if (strcmp(optarg,tests[index].testPointName) == 0) {
    73                         success = p_runTest(fp,
    74                                             testPointFile,
    75                                             packageName,
    76                                             tests[index].testPointName,
    77                                             tests[index].fcn,
    78                                             tests[index].expectedReturn,
    79                                             useFork) && success;
    80                     }
    81                 }
    82                 break;
    83             case 'n':
    84                 runAll = false;
    85                 if (sscanf(optarg,"%i",&n) != 1) {
    86                     psError(__func__,"Failed to parse the testpoint number (%s).",
    87                             optarg);
    88                     break;
    89                 }
    90                 found = false;
    91                 for (int index=0; tests[index].fcn != NULL; index++) {
    92                     if (n==tests[index].testPointNumber) {
    93                         found = true;
    94                         success = p_runTest(fp,
    95                                             testPointFile,
    96                                             packageName,
    97                                             tests[index].testPointName,
    98                                             tests[index].fcn,
    99                                             tests[index].expectedReturn,
    100                                             useFork) && success;
    101                     }
    102                 }
    103                 if (! found) {
    104                     psError(__func__,"The specified testpoint number (%d) doesn't exist in this test driver.",
    105                             n);
    106                     break;
    107                 }
    108                 break;
    109             case '?':
    110                 psError(__func__,"Option %s is not recognized and is ignored.",optarg);
    111                 break;
    112             }
    113         }
    114     }
    115 
    116     if (runAll) {
    117         for (int index=0; tests[index].fcn != NULL; index++) {
    118             if (! tests[index].isDuplicateEntry) {
    119                 success = p_runTest(fp,
    120                                     testPointFile,
    121                                     packageName,
    122                                     tests[index].testPointName,
    123                                     tests[index].fcn,
    124                                     tests[index].expectedReturn,
    125                                     useFork) && success;
    126             }
    127         }
    128     }
     39   
     40    if ( argc > 0 ) {
     41            while ( ( c = getopt( argc, argv, "lhn:dt:" ) ) != -1 ) {
     42                    switch ( c ) {
     43                            case 'h':
     44                            printf( "Usage: %s [-l] [-d] [-h] [-n=Testpoint#] [-t=TestpointName]\n"
     45                                    "    where:\n"
     46                                    "           -l  : lists the testpoints contained in this test driver executable\n"
     47                                    "           -d  : turns on debugger-friendly mode (no forking, aborts/signals are not handled)\n"
     48                                    "           -h  : prints this help\n"
     49                                    "           -n  : specifies a particular testpoint by number to run\n"
     50                                    "           -t  : specifies a particular testpoint by name to run\n"
     51                                    "    (if no -l, -n or -t options are given, all testpoints are run)\n",
     52                                    argv[ 0 ] );
     53                            runAll = false;
     54                            break;
     55                            case 'd':
     56                            useFork = false;
     57                            break;
     58                            case 'l':
     59                            printf( "Test Driver:  %s\n", testPointFile );
     60                            printf( "Package Name: %s\n", packageName );
     61                            printf( "Testpoints:\n" );
     62                            runAll = false;
     63                            for ( int index = 0; tests[ index ].fcn != NULL; index++ ) {
     64                                    printf( "    %6d - %s \n", tests[ index ].testPointNumber,
     65                                            tests[ index ].testPointName );
     66                                }
     67                            printf( "\n" );
     68                            break;
     69                            case 't':
     70                            runAll = false;
     71                            for ( int index = 0; tests[ index ].fcn != NULL; index++ ) {
     72                                    if ( strcmp( optarg, tests[ index ].testPointName ) == 0 ) {
     73                                            success = p_runTest( fp,
     74                                                                 testPointFile,
     75                                                                 packageName,
     76                                                                 tests[ index ].testPointName,
     77                                                                 tests[ index ].fcn,
     78                                                                 tests[ index ].expectedReturn,
     79                                                                 useFork ) && success;
     80                                        }
     81                                }
     82                            break;
     83                            case 'n':
     84                            runAll = false;
     85                            if ( sscanf( optarg, "%i", &n ) != 1 ) {
     86                                    psError( __func__, "Failed to parse the testpoint number (%s).",
     87                                             optarg );
     88                                    break;
     89                                }
     90                            found = false;
     91                            for ( int index = 0; tests[ index ].fcn != NULL; index++ ) {
     92                                    if ( n == tests[ index ].testPointNumber ) {
     93                                            found = true;
     94                                            success = p_runTest( fp,
     95                                                                 testPointFile,
     96                                                                 packageName,
     97                                                                 tests[ index ].testPointName,
     98                                                                 tests[ index ].fcn,
     99                                                                 tests[ index ].expectedReturn,
     100                                                                 useFork ) && success;
     101                                        }
     102                                }
     103                            if ( ! found ) {
     104                                    psError( __func__, "The specified testpoint number (%d) doesn't exist in this test driver.",
     105                                             n );
     106                                    break;
     107                                }
     108                            break;
     109                            case '?':
     110                            psError( __func__, "Option %s is not recognized and is ignored.", optarg );
     111                            break;
     112                        }
     113                }
     114        }
     115       
     116    if ( runAll ) {
     117            for ( int index = 0; tests[ index ].fcn != NULL; index++ ) {
     118                    if ( ! tests[ index ].isDuplicateEntry ) {
     119                            success = p_runTest( fp,
     120                                                 testPointFile,
     121                                                 packageName,
     122                                                 tests[ index ].testPointName,
     123                                                 tests[ index ].fcn,
     124                                                 tests[ index ].expectedReturn,
     125                                                 useFork ) && success;
     126                        }
     127                }
     128        }
     129       
     130    if ( ! success ) {
     131            psError( testPointFile, "One or more tests failed" );
     132        }
     133       
    129134    return success;
    130135}
    131136
    132 bool p_runTest(FILE *fp, const char* testPointFile, const char* packageName, const char* testPointName,
    133                testFcn fcn, int expectedReturn, bool useFork)
     137bool p_runTest( FILE *fp, const char* testPointFile, const char* packageName, const char* testPointName,
     138                testFcn fcn, int expectedReturn, bool useFork )
    134139{
    135140    int childReturn = 0;
    136141    pid_t child;
    137 
    138     p_printPositiveTestHeader(fp,testPointFile,packageName,testPointName);
    139 
    140     if (useFork) {
    141         child = fork();
    142         if (child == 0) {                   // I am the child process, run the test
     142   
     143    p_printPositiveTestHeader( fp, testPointFile, packageName, testPointName );
     144   
     145    if ( useFork ) {
     146            child = fork();
     147            if ( child == 0 ) {                   // I am the child process, run the test
     148                    int currentId = psMemGetId();
     149                    int retVal = fcn();
     150                    if ( retVal == 0 ) { // only bother checking memory if test executed to end.
     151                            if ( psMemCheckLeaks( currentId, NULL, stderr ) != 0 ) {
     152                                    psError( __func__, "Memory Leaks Detected" );
     153                                    retVal = 64;
     154                                }
     155                            psMemCheckCorruption( 1 );
     156                        }
     157                    exit( retVal );
     158                } else if ( child < 0 ) {
     159                    fprintf( fp, "Couldn't fork a process to run a negative test (%s|%s)",
     160                             packageName, testPointName );
     161                    abort();
     162                }
     163               
     164            waitpid( child, &childReturn, 0 );
     165            if ( WIFSIGNALED( childReturn ) ) {
     166                    childReturn = -WTERMSIG( childReturn );
     167                } else {
     168                    childReturn = WEXITSTATUS( childReturn );
     169                }
     170        } else {
    143171            int currentId = psMemGetId();
    144             int retVal = fcn();
    145             if (retVal == 0) { // only bother checking memory if test executed to end.
    146                 if (psMemCheckLeaks(currentId,NULL,stderr) != 0) {
    147                     psError(__func__,"Memory Leaks Detected");
    148                     retVal = 64;
    149                 }
    150                 psMemCheckCorruption(1);
    151             }
    152             exit(retVal);
    153         } else if (child < 0) {
    154             fprintf(fp,"Couldn't fork a process to run a negative test (%s|%s)",
    155                     packageName, testPointName);
    156             abort();
    157         }
    158 
    159         waitpid(child,&childReturn,0);
    160         if (WIFSIGNALED(childReturn)) {
    161             childReturn =  -WTERMSIG(childReturn);
     172            childReturn = fcn();
     173            if ( childReturn == 0 ) { // only bother checking memory if test executed to end.
     174                    if ( psMemCheckLeaks( currentId, NULL, stderr ) != 0 ) {
     175                            psError( __func__, "Memory Leaks Detected" );
     176                            childReturn = 64;
     177                        }
     178                    psMemCheckCorruption( 1 );
     179                }
     180        }
     181       
     182       
     183    if ( childReturn != expectedReturn ) {
     184            fprintf( fp, "Return value mismatch: expected %d, got %d",
     185                     expectedReturn, childReturn );
     186        }
     187       
     188    p_printFooter( fp, testPointFile, packageName, testPointName,
     189                   ( childReturn == expectedReturn ) );
     190                   
     191    return ( childReturn == expectedReturn );
     192}
     193
     194void p_printPositiveTestHeader( FILE *fp,
     195                                const char* testPointFile,
     196                                const char* packageName,
     197                                const char* testPointName )
     198{
     199    char TP[ 80 ];
     200   
     201    snprintf( TP, 80, "%s{%s}", packageName, testPointName );
     202   
     203    fprintf( fp, HEADER_TOP );
     204    fprintf( fp, HEADER_LINE_STRING, "TestFile", testPointFile );
     205    fprintf( fp, HEADER_LINE_STRING, "TestPoint", TP );
     206    fprintf( fp, HEADER_LINE_STRING, "TestType", "Positive" );
     207    fprintf( fp, HEADER_BOTTOM );
     208}
     209
     210void p_printNegativeTestHeader( FILE *fp,
     211                                const char* testPointFile,
     212                                const char* packageName,
     213                                const char* testPointName,
     214                                const char* expectedError,
     215                                int exitValue )
     216{
     217    char TP[ 80 ];
     218   
     219    snprintf( TP, 80, "%s{%s}", packageName, testPointName );
     220   
     221    fprintf( fp, HEADER_TOP );
     222    fprintf( fp, HEADER_LINE_STRING, "TestFile", testPointFile );
     223    fprintf( fp, HEADER_LINE_STRING, "TestPoint", TP );
     224    fprintf( fp, HEADER_LINE_STRING, "TestType", "Negative" );
     225    fprintf( fp, HEADER_LINE_STRING, "ExpectedErrorText", expectedError );
     226    fprintf( fp, HEADER_LINE_INT, "ExpectedStatusValue", exitValue );
     227    fprintf( fp, HEADER_BOTTOM );
     228}
     229
     230
     231void p_printFooter( FILE *fp,
     232                    const char* testPointFile,
     233                    const char* packageName,
     234                    const char* testPointName,
     235                    bool success )
     236{
     237    if ( success ) {
     238            fprintf( fp, "\n---> TESTPOINT PASSED (%s{%s} | %s)\n\n", packageName, testPointName, testPointFile );
    162239        } else {
    163             childReturn = WEXITSTATUS(childReturn);
    164         }
    165     } else {
    166         int currentId = psMemGetId();
    167         childReturn = fcn();
    168         if (childReturn == 0) { // only bother checking memory if test executed to end.
    169             if (psMemCheckLeaks(currentId,NULL,stderr) != 0) {
    170                 psError(__func__,"Memory Leaks Detected");
    171                 childReturn = 64;
    172             }
    173             psMemCheckCorruption(1);
    174         }
    175     }
    176 
    177 
    178     if (childReturn != expectedReturn) {
    179         fprintf(fp,"Return value mismatch: expected %d, got %d",
    180                 expectedReturn,childReturn);
    181     }
    182 
    183     p_printFooter(fp,testPointFile,packageName,testPointName,
    184                   (childReturn==expectedReturn));
    185 
    186     return (childReturn==expectedReturn);
    187 }
    188 
    189 void p_printPositiveTestHeader(FILE *fp,
    190                                const char* testPointFile,
    191                                const char* packageName,
    192                                const char* testPointName)
    193 {
    194     char TP[80];
    195 
    196     snprintf(TP,80,"%s{%s}",packageName,testPointName);
    197 
    198     fprintf(fp, HEADER_TOP);
    199     fprintf(fp, HEADER_LINE_STRING, "TestFile", testPointFile);
    200     fprintf(fp, HEADER_LINE_STRING, "TestPoint", TP);
    201     fprintf(fp, HEADER_LINE_STRING, "TestType","Positive");
    202     fprintf(fp, HEADER_BOTTOM);
    203 }
    204 
    205 void p_printNegativeTestHeader(FILE *fp,
    206                                const char* testPointFile,
    207                                const char* packageName,
    208                                const char* testPointName,
    209                                const char* expectedError,
    210                                int exitValue)
    211 {
    212     char TP[80];
    213 
    214     snprintf(TP,80,"%s{%s}",packageName,testPointName);
    215 
    216     fprintf(fp, HEADER_TOP);
    217     fprintf(fp, HEADER_LINE_STRING, "TestFile", testPointFile);
    218     fprintf(fp, HEADER_LINE_STRING, "TestPoint", TP);
    219     fprintf(fp, HEADER_LINE_STRING,"TestType","Negative");
    220     fprintf(fp, HEADER_LINE_STRING,"ExpectedErrorText",expectedError);
    221     fprintf(fp, HEADER_LINE_INT,"ExpectedStatusValue",exitValue);
    222     fprintf(fp, HEADER_BOTTOM);
    223 }
    224 
    225 
    226 void p_printFooter(FILE *fp,
    227                    const char* testPointFile,
    228                    const char* packageName,
    229                    const char* testPointName,
    230                    bool success)
    231 {
    232     if (success) {
    233         fprintf(fp, "\n---> TESTPOINT PASSED (%s{%s} | %s)\n\n", packageName,testPointName, testPointFile);
    234     } else {
    235         fprintf(fp, "\n---> TESTPOINT FAILED (%s{%s} | %s)\n\n", packageName,testPointName,testPointFile);
    236     }
    237 }
     240            fprintf( fp, "\n---> TESTPOINT FAILED (%s{%s} | %s)\n\n", packageName, testPointName, testPointFile );
     241        }
     242}
Note: See TracChangeset for help on using the changeset viewer.