Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

Doxygen Source Code Documentation


Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search  

niml_malloc.c File Reference

#include "niml_private.h"

Go to the source code of this file.


Data Structures

struct  NI_mallitem

Defines

#define MAGIC   ((char) 0xd7)
#define NEXTRA   (2*sizeof(int))
#define UINT   unsigned int
#define SLOTS   1031
#define INLINE
#define shift_tracker(fff)   ptr_tracker( ((char *)(fff)) - NEXTRA )
#define JBASE   32768
#define QS_STACK   1024
#define QS_SWAPF(x, y)   ( temp=(x),(x)=(y),(y)= temp)
#define QS_SWAPI(i, j)   (itemp=(i),(i)=(j),(j)=itemp)
#define QS_CUTOFF   10

Functions

int NI_malloc_replace (void *(*um)(size_t), void *(*ur)(void *, size_t), void(*uf)(void *))
NI_mallitemptr_tracker (void *)
NI_mallitemfind_empty_slot (int)
void add_tracker (void *, size_t, char *, int)
void * malloc_track (size_t, char *, int)
void probe_track (NI_mallitem *, char *, int)
void * realloc_track (NI_mallitem *, size_t, char *, int)
void * calloc_track (size_t, size_t, char *, int)
void free_track (NI_mallitem *)
void qsort_intint (int, int *, int *)
INLINE UINT mallkey (char *fred)
char * NI_malloc_status (void)
void NI_malloc_dump (void)
void NI_malloc_enable_tracking (void)
int NI_malloc_tracking_enabled (void)
void * hidden_NI_malloc (size_t n, char *fnam, int lnum)
void * hidden_NI_realloc (void *fred, size_t n, char *fnam, int lnum)
void hidden_NI_free (void *fred, char *fnam, int lnum)
void isort_intint (int n, int *ar, int *iar)
void qsrec_intint (int n, int *ar, int *iar, int cutoff)
void NI_free (void *p)

Variables

void *(* user_malloc )(size_t)=NULL
void *(* user_realloc )(void *, size_t)=NULL
void(* user_free )(void *)=NULL
int use_userfunc = 0
int ni_mall_used = 0
NI_mallitem ** htab = NULL
int * nhtab = NULL
UINT serial = 0
int use_tracking = 0

Define Documentation

#define INLINE
 

Definition at line 147 of file niml_malloc.c.

Referenced by mallkey().

#define JBASE   32768
 

#define MAGIC   ((char) 0xd7)
 

18 Nov 2002: keep track of mallocs, as in mcw_malloc.[ch] ******

Definition at line 111 of file niml_malloc.c.

Referenced by malloc_track(), probe_track(), and realloc_track().

#define NEXTRA   (2*sizeof(int))
 

Definition at line 112 of file niml_malloc.c.

Referenced by malloc_track(), probe_track(), and realloc_track().

#define QS_CUTOFF   10
 

Sort an array partially recursively, and partially insertion.

Definition at line 760 of file niml_malloc.c.

Referenced by qsort_intint().

#define QS_STACK   1024
 

Recursive part of quicksort (stack implementation).

Definition at line 673 of file niml_malloc.c.

Referenced by qsrec_intint().

#define QS_SWAPF x,
y       ( temp=(x),(x)=(y),(y)= temp)
 

Definition at line 674 of file niml_malloc.c.

#define QS_SWAPI i,
j       (itemp=(i),(i)=(j),(j)=itemp)
 

Definition at line 675 of file niml_malloc.c.

#define shift_tracker fff       ptr_tracker( ((char *)(fff)) - NEXTRA )
 

Definition at line 205 of file niml_malloc.c.

#define SLOTS   1031
 

set hash table size (to a prime number, please) *

Definition at line 131 of file niml_malloc.c.

Referenced by add_tracker(), NI_malloc_dump(), NI_malloc_enable_tracking(), NI_malloc_status(), ptr_tracker(), and realloc_track().

#define UINT   unsigned int
 

Definition at line 115 of file niml_malloc.c.

Referenced by mallkey(), and NI_malloc_status().


Function Documentation

void add_tracker void *    fred,
size_t    n,
char *    fn,
int    ln
[static]
 

Add an entry to the hash table, given the address, the user's size, and the filename and line number. ------------------------------------------------------------------

Definition at line 240 of file niml_malloc.c.

References find_empty_slot(), mallkey(), NI_mallitem::pfn, NI_mallitem::pln, NI_mallitem::pmt, NI_mallitem::pss, NI_mallitem::psz, serial, and SLOTS.

Referenced by malloc_track(), and realloc_track().

00241 {
00242    int jj ;
00243    NI_mallitem *ip ;
00244 
00245    if( fred == NULL ) return ;   /* bad news */
00246 
00247    jj = mallkey((char *)fred) % SLOTS ;  /* which hash list to use */
00248    ip = find_empty_slot(jj) ;            /* get an empty slot in this list */
00249 
00250    /* now put the data into the hash table */
00251 
00252    ip->pmt = fred ;
00253    ip->psz = n ;
00254    ip->pfn = fn ;
00255    ip->pln = ln ;
00256    ip->pss = ++serial ;
00257 
00258    return ;
00259 }

void * calloc_track size_t    n,
size_t    m,
char *    fn,
int    ln
[static]
 

Tracking replacement for calloc(). -------------------------------------------------------------------

Definition at line 366 of file niml_malloc.c.

References malloc_track().

Referenced by hidden_NI_malloc(), mcw_calloc(), and mcw_XtCalloc().

00367 {
00368    void *fred ;
00369    size_t nn = n*m ;
00370 
00371    fred = malloc_track(nn,fn,ln) ; if( fred == NULL ) return NULL ;
00372    memset( fred , 0 , nn ) ;
00373    return fred ;
00374 }

NI_mallitem * find_empty_slot int    jj [static]
 

Find an empty entry in the hash table list [jj] and return a pointer to it. Will create the entry, if need be. -------------------------------------------------------------------

Definition at line 212 of file niml_malloc.c.

References malloc, nhtab, NI_mallitem::pmt, and realloc.

Referenced by add_tracker().

00213 {
00214    int kk ;
00215 
00216    if( htab[jj] == NULL ){                                    /* must make new list  */
00217      htab[jj] = (NI_mallitem *) malloc(sizeof(NI_mallitem)) ; /* of length 1 at [jj] */
00218     nhtab[jj] = 1 ;
00219      kk       = 0 ;
00220      htab[jj][0].pmt = NULL ;  /* mark as empty */
00221    } else {
00222      for( kk=nhtab[jj]-1 ; kk >= 0 ; kk-- )    /* scan (backwards) for NULL entry */
00223        if( htab[jj][kk].pmt == NULL ) break ;  /* found it? */
00224 
00225      if( kk < 0 ){                             /* must make list longer */
00226        kk = nhtab[jj] ; nhtab[jj]++ ;
00227        htab[jj] = (NI_mallitem *) realloc( htab[jj], sizeof(NI_mallitem)*nhtab[jj] ) ;
00228        htab[jj][kk].pmt = NULL ;  /* mark as empty */
00229      }
00230    }
00231 
00232    return (htab[jj]+kk) ;
00233 }

void free_track NI_mallitem   ip [static]
 

Tracking replacement for free(). -------------------------------------------------------------------

Definition at line 380 of file niml_malloc.c.

References free, ni_mall_used, NI_mallitem::pmt, and probe_track().

Referenced by hidden_NI_free(), mcw_free(), and mcw_XtFree().

00381 {
00382    char *cfred ;
00383 
00384    if( ip == NULL ) return ;
00385    cfred = (char *) ip->pmt ;
00386    if( cfred == NULL ) return ;
00387 
00388    probe_track(ip,NULL,0) ;  /* check for integrity before freeing */
00389 
00390    ni_mall_used = 1 ;
00391    free(cfred) ; ip->pmt = NULL ; return ;
00392 }

void hidden_NI_free void *    fred,
char *    fnam,
int    lnum
 

Definition at line 623 of file niml_malloc.c.

References free, free_track(), NI_dpr(), shift_tracker, use_tracking, and user_free.

Referenced by NI_free().

00624 {
00625    NI_mallitem *ip ;
00626 
00627    if( fred == NULL ) return ;
00628 
00629    if( use_userfunc )                                          user_free(fred) ;
00630    else if( use_tracking && (ip=shift_tracker(fred)) != NULL ) free_track( ip ) ;
00631    else                                                        free( fred ) ;
00632 
00633 #ifdef NIML_DEBUG
00634 NI_dpr("hidden_NI_free: called from %s#%d\n",fnam,lnum) ;
00635 #endif
00636 
00637 }

void* hidden_NI_malloc size_t    n,
char *    fnam,
int    lnum
 

Allocate memory (actually uses calloc); calls exit() if it fails. ----------------------------------------------------------------------------

Definition at line 568 of file niml_malloc.c.

References calloc, calloc_track(), NI_dpr(), NI_sleep(), p, and user_malloc.

Referenced by hidden_NI_realloc().

00569 {
00570    void *p ;
00571 
00572         if( use_userfunc ){ p = user_malloc(n); if(p)memset(p,0,n); }
00573    else if( use_tracking )  p = calloc_track(1,n,fnam,lnum) ;
00574    else                     p = calloc(1,n) ;
00575 
00576    if( p == NULL ){
00577      fprintf(stderr,"** ERROR: NI_malloc() fails. Aauugghh!\n") ;
00578      NI_sleep(333); exit(1);
00579    }
00580 
00581 #ifdef NIML_DEBUG
00582 NI_dpr("hidden_NI_malloc: called from %s#%d\n",fnam,lnum) ;
00583 #endif
00584 
00585    return p ;
00586 }

void* hidden_NI_realloc void *    fred,
size_t    n,
char *    fnam,
int    lnum
 

Reallocate memory; calls exit() if it fails. ----------------------------------------------------------------------------

Definition at line 592 of file niml_malloc.c.

References hidden_NI_malloc(), NI_dpr(), NI_sleep(), q, realloc, realloc_track(), shift_tracker, use_tracking, and user_realloc.

00593 {
00594    NI_mallitem *ip ;
00595    void *q ;
00596 
00597    if( fred == NULL )
00598       return hidden_NI_malloc( n , fnam , lnum ) ;
00599 
00600    if( use_userfunc )
00601      q = user_realloc( fred , n ) ;
00602    else if( use_tracking && (ip=shift_tracker(fred)) != NULL )
00603      q = realloc_track( ip , n , fnam,lnum ) ;
00604    else
00605      q = realloc( fred , n ) ;
00606 
00607    if( q == NULL && n > 0 ){
00608       fprintf(stderr,"** ERROR: NI_realloc() fails. Ooooogg!\n");
00609       NI_sleep(333); exit(1);
00610    }
00611 
00612 #ifdef NIML_DEBUG
00613 NI_dpr("hidden_NI_realloc: called from %s#%d\n",fnam,lnum) ;
00614 #endif
00615 
00616    return q ;
00617 }

void isort_intint int    n,
int *    ar,
int *    iar
[static]
 

Insertion_sort : sort an array of int + int.

Definition at line 642 of file niml_malloc.c.

References a, and p.

Referenced by qsort_intint().

00643 {
00644    register int  j , p ;  /* array indices */
00645    register int   temp ;  /* a[j] holding place */
00646    register int  itemp ;
00647    register int * a = ar ;
00648    register int  * ia = iar ;
00649 
00650    if( n < 2 ) return ;
00651 
00652    for( j=1 ; j < n ; j++ ){
00653 
00654      if( a[j] < a[j-1] ){   /* out of order */
00655         p    = j ;
00656         temp = a[j] ; itemp = ia[j] ;
00657 
00658        do{
00659            a[p] =  a[p-1] ; /* at this point, a[p-1] > temp, so move it up */
00660           ia[p] = ia[p-1] ;
00661           p-- ;
00662         } while( p > 0 && temp < a[p-1] ) ;
00663 
00664         a[p] = temp ;       /* finally, put temp in its place */
00665        ia[p] = itemp ;
00666      }
00667    }
00668 }

INLINE UINT mallkey char *    fred [static]
 

Compute a unique non-negative integer key from an address -----------------------------------------------------------------

Definition at line 171 of file niml_malloc.c.

References INLINE, q, and UINT.

Referenced by add_tracker(), ptr_tracker(), and realloc_track().

00172 {
00173    UINT q = (UINT) fred ;
00174 
00175    q =   ((q & 0xf0f0f0f0) >> 4)   /* swap nibbles */
00176        | ((q & 0x0f0f0f0f) << 4) ;
00177 
00178    return q ;
00179 }

void * malloc_track size_t    n,
char *    fn,
int    ln
[static]
 

The tracking replacement for malloc(). -------------------------------------------------------------------

Definition at line 265 of file niml_malloc.c.

References add_tracker(), MAGIC, malloc, NEXTRA, and ni_mall_used.

Referenced by calloc_track(), mcw_malloc(), and mcw_XtMalloc().

00266 {
00267    char *fred ;
00268    size_t nn = n + 2*NEXTRA ;
00269    int ii ;
00270 
00271    fred = (char *)malloc(nn) ;
00272    if( fred == NULL ) return NULL ;  /* real bad news */
00273 
00274    /* mark overrun buffers */
00275 
00276    memset( fred           , MAGIC , NEXTRA ) ;
00277    memset( fred+(n+NEXTRA), MAGIC , NEXTRA ) ;
00278 
00279    ni_mall_used = 1 ;
00280    add_tracker(fred,n,fn,ln) ;      /* put in hash table */
00281    return (void *)(fred+NEXTRA) ;
00282 }

void NI_free void *    p
 

17 Dec 2003: In case a true NI_free() call gets thru somehow.

Definition at line 777 of file niml_malloc.c.

References hidden_NI_free(), and p.

00778 {
00779   hidden_NI_free( p , (char *)"Nada" , 0 ) ;
00780 }

void NI_malloc_dump void   
 

Write a file with lots of info about the current status. -------------------------------------------------------------------

Definition at line 425 of file niml_malloc.c.

References free, malloc, nhtab, NI_is_file, NI_malloc_status(), NI_mallitem::pmt, NI_mallitem::pss, qsort_intint(), SLOTS, and use_tracking.

00426 {
00427    int ii,jj,kk ;
00428    char fname[32] , *str ;
00429    FILE *fp = NULL ;
00430    int nptr=0 ;
00431    int *ss , *jk ;
00432 
00433    if( ! use_tracking ) return ;
00434 
00435    /* find and open an output file */
00436 
00437    for( ii=1 ; ii < 1000 ; ii++ ){
00438      sprintf(fname,"NI_malldump.%03d",ii) ;
00439      if( NI_is_file(fname) ) continue ;
00440      fp = fopen( fname , "w" ) ;
00441      if( fp == NULL ){
00442        fprintf(stderr,"** Unable to open file %s for malloc table dump!\n",
00443                fname ) ;
00444        return ;
00445      }
00446      break ;
00447    }
00448 
00449    if( fp == NULL ){
00450      fprintf(stderr,"** Attempt to exceed 999 malloc table dump files!\n") ;
00451      return ;
00452    }
00453 
00454    /* count number of entries in the hash table */
00455 
00456    for( jj=0 ; jj < SLOTS ; jj++ ){
00457      for( kk=0 ; kk < nhtab[jj] ; kk++ ){
00458        if( htab[jj][kk].pmt != NULL ) nptr++ ;
00459      }
00460    }
00461 
00462    if( nptr < 1 ){
00463      fprintf(fp    ,"--- Nothing is malloc()-ed !? ---\n") ;
00464      fprintf(stderr,"--- Nothing is malloc()-ed !? ---\n") ;
00465      fclose(fp) ;
00466    }
00467 
00468    /* setup to sort by serial number */
00469 
00470    ss = (int *) malloc(sizeof(int)*nptr) ;  /* serial number */
00471    jk = (int *) malloc(sizeof(int)*nptr) ;  /* holds combination of jj and kk */
00472 
00473 #define JBASE 32768  /* JBASE * SLOTS must be less than max int */
00474 
00475    /* scan table for non-NULL entries */
00476 
00477    for( ii=jj=0 ; jj < SLOTS ; jj++ ){
00478      for( kk=0 ; kk < nhtab[jj] ; kk++ ){
00479        if( htab[jj][kk].pmt != NULL ){
00480          ss[ii] = htab[jj][kk].pss ;   /* save serial number */
00481          jk[ii] = JBASE*jj + kk ;      /* save jj and kk */
00482          ii++ ;
00483        }
00484      }
00485    }
00486 
00487    qsort_intint( nptr , ss , jk ) ;  /* sort by ss, carrying jk along */
00488 
00489    /* now print table in serial number order */
00490 
00491    fprintf(fp, "MCW Malloc Table Dump:\n"
00492                "serial# size       source file          line# address    hash(j,k)\n"
00493                "------- ---------- -------------------- ----- ---------- ---------\n") ;
00494 
00495    for( ii=0 ; ii < nptr ; ii++ ){
00496      jj = jk[ii] / JBASE ;           /* retrieve jj and kk */
00497      kk = jk[ii] % JBASE ;
00498      if( htab[jj][kk].pmt != NULL ){
00499        fprintf(fp,"%7u %10u %-20.30s %5d %10p %5d %3d",
00500                htab[jj][kk].pss , (unsigned int)htab[jj][kk].psz ,
00501                htab[jj][kk].pfn , htab[jj][kk].pln , htab[jj][kk].pmt ,
00502                jj,kk ) ;
00503        fprintf(fp,"\n") ;
00504      }
00505      else
00506        fprintf(fp,"*** Error at ii=%d jj=%d kk=%d\n",ii,jj,kk) ;
00507    }
00508 
00509    free(ss) ; free(jk) ;
00510 
00511    /* and print out the summary line (to the file and screen) */
00512 
00513    str = NI_malloc_status() ;
00514    fprintf(fp,"----- Summary: %s\n",str) ;
00515    fclose(fp) ;
00516 
00517    fprintf(stderr,"** Malloc table dumped to file %s\n",fname) ;
00518    fprintf(stderr,"** Summary: %s\n",str) ;
00519 
00520    return ;
00521 }

void NI_malloc_enable_tracking void   
 

Turn on use of the tracking routines. ------------------------------------------------------------------

Definition at line 527 of file niml_malloc.c.

References getenv(), malloc, nhtab, ni_mall_used, SLOTS, and use_tracking.

Referenced by NI_stream_open().

00528 {
00529    char *str ;
00530 
00531    if( use_userfunc ) return ;   /* 25 Mar 2003 */
00532    ni_mall_used = 1 ;
00533 
00534    if( use_tracking ) return ;   /* 05 Nov 2001 */
00535 
00536    str = getenv("AFNI_NO_MCW_MALLOC") ;
00537    if( str == NULL )
00538      str = getenv("NIML_MALLOC_DISABLE") ;
00539 
00540    use_tracking = 1 ;
00541    if( str!=NULL && ( *str=='y' || *str=='Y') ) use_tracking = 0 ;
00542 
00543    if( use_tracking && htab == NULL ){  /* initialize hash table */
00544      int jj ;
00545      htab  = (NI_mallitem **) malloc( SLOTS * sizeof(NI_mallitem *) ) ;
00546      nhtab = (int *)          malloc( SLOTS * sizeof(int) ) ;
00547      for( jj=0 ; jj < SLOTS ; jj++ ){
00548        htab[jj] = NULL ; nhtab[jj] = 0 ;
00549      }
00550    }
00551 
00552    return ;
00553 }

int NI_malloc_replace void *(*    um)(size_t),
void *(*    ur)(void *, size_t),
void(*    uf)(void *)
 

Allow user to replace malloc(), realloc(), and free() functions used in NI_malloc(), NI_realloc(), and NI_free().

  • um = replacement for malloc()
  • ur = replacement for realloc()
  • uf = replacement for free()
  • all 3 must be non-NULL
  • this function must be called BEFORE any call to NI_malloc() etc. takes place, or this function will fail
  • return value is 1 if the replacement is accepted, 0 if not
  • note that NI_malloc() always 0 fills the result, even the one returned by um()
  • RWCox - 25 Mar 2003 (VR Day) ---------------------------------------------------------------------------

Definition at line 31 of file niml_malloc.c.

References ni_mall_used, use_userfunc, user_free, user_malloc, and user_realloc.

00033                                                     {
00034 
00035   if( ni_mall_used ||
00036       use_userfunc ||
00037       um == NULL   ||
00038       ur == NULL   ||
00039       uf == NULL     ) return 0 ;
00040 
00041   user_malloc  = um ;
00042   user_realloc = ur ;
00043   user_free    = uf ;
00044   use_userfunc = 1  ;
00045   return 1 ;
00046 }

char* NI_malloc_status void   
 

Definition at line 401 of file niml_malloc.c.

References nhtab, NI_mallitem::pmt, probe_track(), NI_mallitem::psz, SLOTS, UINT, and use_tracking.

Referenced by NI_dpr(), and NI_malloc_dump().

00402 {
00403    static char buf[128] = "\0" ;
00404    int jj,kk , nptr=0 ; size_t nbyt=0 ;
00405 
00406    if( ! use_tracking ) return "not enabled" ;
00407 
00408    for( jj=0 ; jj < SLOTS ; jj++ ){
00409      for( kk=0 ; kk < nhtab[jj] ; kk++ ){
00410        if( htab[jj][kk].pmt != NULL ){
00411          probe_track( htab[jj]+kk , NULL,0 ) ; /* check for integrity */
00412          nptr++ ; nbyt += htab[jj][kk].psz ;
00413        }
00414      }
00415    }
00416 
00417    sprintf(buf,"chunks=%d bytes=%u",nptr,(UINT)nbyt) ;
00418    return buf ;
00419 }

int NI_malloc_tracking_enabled void   
 

Lets the user check if the tracking routines are in use. -----------------------------------------------------------------

Definition at line 559 of file niml_malloc.c.

References use_tracking.

00560 {
00561   return (use_tracking != 0) ;
00562 }

void probe_track NI_mallitem   ip,
char *    fn,
int    ln
[static]
 

Check an entry in the hash table for local overrun integrity. -------------------------------------------------------------------

Definition at line 288 of file niml_malloc.c.

References MAGIC, NEXTRA, NI_mallitem::pfn, NI_mallitem::pln, NI_mallitem::pmt, NI_mallitem::pss, and NI_mallitem::psz.

Referenced by free_track(), mcw_malloc_status(), NI_malloc_status(), and realloc_track().

00289 {
00290    int ii ;
00291    size_t n ;
00292    char *fred ;
00293 
00294    if( ip == NULL ) return ; /* error */
00295    fred = (char *) ip->pmt ; if( fred == NULL ) return ;
00296    n = ip->psz ;
00297 
00298    for( ii=0 ; ii < NEXTRA ; ii++ )
00299      if( fred[ii] != MAGIC ){
00300        fprintf(stderr,"*** NI_malloc pre-corruption!  "
00301                       "serial=%u size=%u source=%s line#=%d\n",
00302                       ip->pss,(unsigned int)ip->psz,ip->pfn,ip->pln ) ;
00303        if( fn != NULL ) fprintf(stderr,"   Caller=%s line#=%d\n",fn,ln) ;
00304        break ;
00305      }
00306 
00307    for( ii=0 ; ii < NEXTRA ; ii++ )
00308      if( fred[n+NEXTRA+ii] != MAGIC ){
00309        fprintf(stderr,"*** NI_malloc post-corruption!  "
00310                       "serial=%u size=%u source=%s line#=%d\n",
00311                       ip->pss,(unsigned int)ip->psz,ip->pfn,ip->pln ) ;
00312        if( fn != NULL ) fprintf(stderr,"   Caller=%s line#=%d\n",fn,ln) ;
00313        break ;
00314      }
00315 
00316    return ;
00317 }

NI_mallitem * ptr_tracker void *    fred [static]
 

Find an address in the hash table; returns a pointer to the NI_mallitem that owns it (or NULL) ------------------------------------------------------------------

Definition at line 186 of file niml_malloc.c.

References mallkey(), nhtab, NI_mallitem::pmt, and SLOTS.

00187 {
00188    int jj,kk ;
00189 
00190    if( fred == NULL ) return NULL ;
00191 
00192    jj = mallkey((char *)fred) % SLOTS ;  /* hash table location */
00193 
00194    if( htab[jj] == NULL ) return NULL ;  /* nothing there */
00195 
00196    for( kk=0 ; kk < nhtab[jj] ; kk++ )   /* scan for match */
00197      if( htab[jj][kk].pmt == fred ) return (htab[jj]+kk) ;
00198 
00199    return NULL ; /* no match found */
00200 }

void qsort_intint int   ,
int *   ,
int *   
[static]
 

Definition at line 763 of file niml_malloc.c.

References a, isort_intint(), QS_CUTOFF, and qsrec_intint().

Referenced by mcw_malloc_dump(), mri_watershedize(), NI_malloc_dump(), rgb_to_XImage_clever(), and SUMA_make_vnlist().

00764 {
00765    qsrec_intint( n , a , ia , QS_CUTOFF ) ;
00766    isort_intint( n , a , ia ) ;
00767    return ;
00768 }

void qsrec_intint int    n,
int *    ar,
int *    iar,
int    cutoff
[static]
 

Definition at line 677 of file niml_malloc.c.

References a, i, left, QS_STACK, QS_SWAPF, QS_SWAPI, and right.

Referenced by qsort_intint().

00678 {
00679    register int i , j ;        /* scanning indices */
00680    register int temp , pivot ; /* holding places */
00681    register int  itemp , ipivot ;
00682    register int * a = ar ;
00683    register int  * ia = iar ;
00684 
00685    int left , right , mst , stack[QS_STACK] , nnew ;
00686 
00687    /* return if too short (insertion sort will clean up) */
00688 
00689    if( cutoff < 3 ) cutoff = 3 ;
00690    if( n < cutoff ) return ;
00691 
00692    /* initialize stack to start with whole array */
00693 
00694    stack[0] = 0   ;
00695    stack[1] = n-1 ;
00696    mst      = 2   ;
00697 
00698    /* loop while the stack is nonempty */
00699 
00700    while( mst > 0 ){
00701       right = stack[--mst] ;  /* work on subarray from left -> right */
00702       left  = stack[--mst] ;
00703 
00704       i = ( left + right ) / 2 ;           /* middle of subarray */
00705 
00706       /* sort the left, middle, and right a[]'s */
00707 
00708       if( a[left] > a[i]     ){ QS_SWAPF(a[left] ,a[i]    ); QS_SWAPI(ia[left] ,ia[i]    ); }
00709       if( a[left] > a[right] ){ QS_SWAPF(a[left] ,a[right]); QS_SWAPI(ia[left] ,ia[right]); }
00710       if( a[i] > a[right]    ){ QS_SWAPF(a[right],a[i]    ); QS_SWAPI(ia[right],ia[i]    ); }
00711 
00712       pivot  = a[i] ;                        /* a[i] is the median-of-3 pivot! */
00713       a[i]   = a[right] ;
00714       ipivot = ia[i] ;
00715       ia[i]  = ia[right] ;
00716 
00717       i = left ;                            /* initialize scanning */
00718       j = right ;
00719 
00720       /*----- partition:  move elements bigger than pivot up and elements
00721                           smaller than pivot down, scanning in from ends -----*/
00722 
00723       do{
00724         for( ; a[++i] < pivot ; ) ;  /* scan i up,   until a[i] >= pivot */
00725         for( ; a[--j] > pivot ; ) ;  /* scan j down, until a[j] <= pivot */
00726 
00727         if( j <= i ) break ;         /* if j meets i, quit */
00728 
00729         QS_SWAPF( a[i] , a[j] ) ; QS_SWAPI( ia[i] , ia[j] ) ;
00730       } while( 1 ) ;
00731 
00732       /*----- at this point, the array is partitioned -----*/
00733 
00734       a[right]  = a[i] ;           /*restore the pivot*/
00735       a[i]      = pivot ;
00736       ia[right] = ia[i] ;
00737       ia[i]     = ipivot ;
00738 
00739       /*----- push subarrays [left..i-1] and [i+1..right] onto stack, if big -----*/
00740 
00741       nnew = 0 ;
00742       if( (i-left)  > cutoff ){ stack[mst++] = left ; stack[mst++] = i-1   ; nnew++ ; }
00743       if( (right-i) > cutoff ){ stack[mst++] = i+1  ; stack[mst++] = right ; nnew++ ; }
00744 
00745       /* if just added two subarrays to stack, make sure shorter one comes first */
00746 
00747       if( nnew == 2 && stack[mst-3] - stack[mst-4] > stack[mst-1] - stack[mst-2] ){
00748          QS_SWAPI( stack[mst-4] , stack[mst-2] ) ;
00749          QS_SWAPI( stack[mst-3] , stack[mst-1] ) ;
00750       }
00751 
00752    }  /* end of while stack is non-empty */
00753 
00754 }

void * realloc_track NI_mallitem   ip,
size_t    n,
char *    fn,
int    ln
[static]
 

The tracking replacement for realloc(). ---------------------------------------------------------------------

Definition at line 323 of file niml_malloc.c.

References add_tracker(), MAGIC, mallkey(), NEXTRA, ni_mall_used, NI_mallitem::pfn, NI_mallitem::pln, NI_mallitem::pmt, probe_track(), NI_mallitem::pss, NI_mallitem::psz, realloc, serial, and SLOTS.

Referenced by hidden_NI_realloc(), mcw_realloc(), and mcw_XtRealloc().

00324 {
00325    char *nfred , *cfred ;
00326    size_t nn = n + 2*NEXTRA ;
00327    int ii , cjj,njj , kk ;
00328 
00329    if( ip == NULL ) return NULL ;  /* should not happen */
00330 
00331    probe_track(ip,fn,ln) ;    /* check for integrity before reallocation */
00332    cfred = (char *)ip->pmt ;  /* old address */
00333 
00334    ni_mall_used = 1 ;
00335    nfred = (char *)realloc( (void *)cfred , nn ) ;
00336    if( nfred == NULL ) return NULL ;  /* this is bad - real bad */
00337 
00338    memset( nfred           , MAGIC , NEXTRA ) ;
00339    memset( nfred+(n+NEXTRA), MAGIC , NEXTRA ) ;
00340 
00341    cjj = mallkey(cfred) % SLOTS ;  /* hash table list for old */
00342    njj = mallkey(nfred) % SLOTS ;  /* and for new address */
00343 
00344    if( cjj == njj ){  /* can just update old hashtable entry */
00345 
00346      ip->pmt = nfred ;
00347      ip->psz = n ;
00348      ip->pfn = fn ;
00349      ip->pln = ln ;
00350      ip->pss = ++serial ;
00351 
00352    } else {           /* must move into a different list */
00353 
00354      add_tracker( nfred , n , fn , ln ) ;
00355 
00356      ip->pmt = NULL ; /* mark old entry as free */
00357    }
00358 
00359    return (void *)(nfred+NEXTRA) ;
00360 }

Variable Documentation

NI_mallitem** htab = NULL [static]
 

define SLOTS 32003 *

Definition at line 139 of file niml_malloc.c.

int* nhtab = NULL [static]
 

Definition at line 140 of file niml_malloc.c.

Referenced by find_empty_slot(), NI_malloc_dump(), NI_malloc_enable_tracking(), NI_malloc_status(), and ptr_tracker().

int ni_mall_used = 0 [static]
 

Definition at line 14 of file niml_malloc.c.

Referenced by free_track(), malloc_track(), NI_malloc_enable_tracking(), NI_malloc_replace(), and realloc_track().

UINT serial = 0 [static]
 

Definition at line 141 of file niml_malloc.c.

Referenced by add_tracker(), and realloc_track().

int use_tracking = 0 [static]
 

Return a status string about the situation. This is stored in a static buffer, so don't free it. -------------------------------------------------------------------

Definition at line 399 of file niml_malloc.c.

Referenced by hidden_NI_free(), hidden_NI_realloc(), NI_malloc_dump(), NI_malloc_enable_tracking(), NI_malloc_status(), and NI_malloc_tracking_enabled().

int use_userfunc = 0 [static]
 

Definition at line 13 of file niml_malloc.c.

Referenced by NI_malloc_replace().

void(* user_free)(void *) = NULL [static]
 

Definition at line 12 of file niml_malloc.c.

Referenced by hidden_NI_free(), and NI_malloc_replace().

void*(* user_malloc)(size_t) = NULL [static]
 

25 Mar 2003: allow user to replace malloc, realloc, free functions *

Definition at line 10 of file niml_malloc.c.

Referenced by hidden_NI_malloc(), and NI_malloc_replace().

void*(* user_realloc)(void *,size_t) = NULL [static]
 

Definition at line 11 of file niml_malloc.c.

Referenced by hidden_NI_realloc(), and NI_malloc_replace().

 

Powered by Plone

This site conforms to the following standards: