Doxygen Source Code Documentation
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_mallitem * | ptr_tracker (void *) | 
| NI_mallitem * | find_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
| 
 | 
| 
 Definition at line 147 of file niml_malloc.c. Referenced by mallkey(). | 
| 
 | 
| 
 | 
| 
 | 
| 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(). | 
| 
 | 
| 
 Definition at line 112 of file niml_malloc.c. Referenced by malloc_track(), probe_track(), and realloc_track(). | 
| 
 | 
| Sort an array partially recursively, and partially insertion. Definition at line 760 of file niml_malloc.c. Referenced by qsort_intint(). | 
| 
 | 
| Recursive part of quicksort (stack implementation). Definition at line 673 of file niml_malloc.c. Referenced by qsrec_intint(). | 
| 
 | 
| 
 Definition at line 674 of file niml_malloc.c. | 
| 
 | 
| 
 Definition at line 675 of file niml_malloc.c. | 
| 
 | 
| 
 Definition at line 205 of file niml_malloc.c. | 
| 
 | 
| 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(). | 
| 
 | 
| 
 Definition at line 115 of file niml_malloc.c. Referenced by mallkey(), and NI_malloc_status(). | 
Function Documentation
| 
 | ||||||||||||||||||||
| 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 }
 | 
| 
 | ||||||||||||||||||||
| 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 }
 | 
| 
 | 
| 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 }
 | 
| 
 | 
| 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 }
 | 
| 
 | ||||||||||||||||
| 
 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 }
 | 
| 
 | ||||||||||||||||
| 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 }
 | 
| 
 | ||||||||||||||||||||
| 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 }
 | 
| 
 | ||||||||||||||||
| Insertion_sort : sort an array of int + int. Definition at line 642 of file niml_malloc.c. 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 }
 | 
| 
 | 
| 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(). 
 | 
| 
 | ||||||||||||||||
| 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 }
 | 
| 
 | 
| 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 }
 | 
| 
 | 
| 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 }
 | 
| 
 | 
| 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 }
 | 
| 
 | ||||||||||||||||
| Allow user to replace malloc(), realloc(), and free() functions used in NI_malloc(), NI_realloc(), and NI_free(). 
 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 }
 | 
| 
 | 
| 
 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 }
 | 
| 
 | 
| 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 }
 | 
| 
 | ||||||||||||||||
| 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 }
 | 
| 
 | 
| 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 }
 | 
| 
 | ||||||||||||||||
| 
 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 }
 | 
| 
 | ||||||||||||||||||||
| 
 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 }
 | 
| 
 | ||||||||||||||||||||
| 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
| 
 | 
| define SLOTS 32003 * Definition at line 139 of file niml_malloc.c. | 
| 
 | 
| 
 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(). | 
| 
 | 
| 
 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(). | 
| 
 | 
| 
 Definition at line 141 of file niml_malloc.c. Referenced by add_tracker(), and realloc_track(). | 
| 
 | 
| 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(). | 
| 
 | 
| 
 Definition at line 13 of file niml_malloc.c. Referenced by NI_malloc_replace(). | 
| 
 | 
| 
 Definition at line 12 of file niml_malloc.c. Referenced by hidden_NI_free(), and NI_malloc_replace(). | 
| 
 | 
| 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(). | 
| 
 | 
| 
 Definition at line 11 of file niml_malloc.c. Referenced by hidden_NI_realloc(), and NI_malloc_replace(). | 
 
                             
                             
                             
                             
                             
                             
                             
                             
                             
                             
                             
                             
 
 
 
 
       
	   
	   
	   
	  