IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 31663


Ignore:
Timestamp:
Jun 22, 2011, 12:33:45 AM (15 years ago)
Author:
eugene
Message:

merged from eam_branches/ipp-20110505: allow managed memory (with linked list a la psLib); add csv to mana; allow read-only dvo databases

Location:
trunk/Ohana/src
Files:
14 edited
2 copied

Legend:

Unmodified
Added
Removed
  • trunk/Ohana/src/libdvo/include/dvo.h

    r31635 r31663  
    7878# define LOAD_MISS      0x04
    7979# define LOAD_SECF      0x08
    80 # define LOAD_MEAS_META 0x10
     80# define SKIP_AVES      0x10
     81# define SKIP_MEAS      0x20
     82# define SKIP_MISS      0x40
     83# define SKIP_SECF      0x80
     84
     85// # define LOAD_MEAS_META 0x100 -- is this used??
    8186
    8287/* photometry code types */
  • trunk/Ohana/src/libdvo/src/coordops.c

    r29001 r31663  
    440440int GetCoords (Coords *coords, Header *header) {
    441441 
    442   int status, itmp, Polynomial, Polyterm;
    443   double Lambda, rotate, scale;
     442  int status, status1, status2, itmp, Polynomial, Polyterm;
     443  double Lambda, rotate, rotate1, rotate2, scale;
    444444  double equinox;
    445445  char *ctype;
     
    456456  mode = COORD_TYPE_NONE;
    457457  {   
    458     int haveCTYPE, haveCDELT, haveCROTA, haveCDij, havePCij, haveRAo;
     458    int haveCTYPE, haveCDELT, haveCROTA, haveCROTA1, haveCROTA2, haveCDij, havePCij, haveRAo;
    459459    float tmp;
    460460    char stmp[80];
     
    463463    // set: (CDELTi + CROTAi), (CDELTi + PCij), (CDij),
    464464
    465     haveCTYPE = gfits_scan (header, "CTYPE2",   "%s", 1, stmp);
    466     haveCDELT = gfits_scan (header, "CDELT1",   "%f", 1, &tmp);
    467     haveCROTA = gfits_scan (header, "CROTA1",   "%f", 1, &tmp);
    468     haveCDij  = gfits_scan (header, "CD1_1",    "%f", 1, &tmp);
    469     havePCij  = gfits_scan (header, "PC001001", "%f", 1, &tmp);
    470     haveRAo   = gfits_scan (header, "RA_O",     "%f", 1, &tmp);
     465    haveCTYPE  = gfits_scan (header, "CTYPE2",   "%s", 1, stmp);
     466    haveCDELT  = gfits_scan (header, "CDELT1",   "%f", 1, &tmp);
     467    haveCROTA1 = gfits_scan (header, "CROTA1",   "%f", 1, &tmp);
     468    haveCROTA2 = gfits_scan (header, "CROTA2",   "%f", 1, &tmp);
     469    haveCDij   = gfits_scan (header, "CD1_1",    "%f", 1, &tmp);
     470    havePCij   = gfits_scan (header, "PC001001", "%f", 1, &tmp);
     471    haveRAo    = gfits_scan (header, "RA_O",     "%f", 1, &tmp);
    471472   
     473    haveCROTA = haveCROTA1 || haveCROTA2;
     474
    472475    if (haveCTYPE && havePCij  && haveCDELT) { mode = COORD_TYPE_PC;   goto gotit; }
    473476    if (haveCTYPE && haveCROTA && haveCDELT) { mode = COORD_TYPE_ROT;  goto gotit; }
     
    540543      status &= gfits_scan (header, "CDELT2", "%f", 1, &coords[0].cdelt2);
    541544
    542       status &= gfits_scan (header, "CROTA2", "%lf", 1, &rotate);
     545      status1 = gfits_scan (header, "CROTA1", "%lf", 1, &rotate1);
     546      status2 = gfits_scan (header, "CROTA2", "%lf", 1, &rotate2);
     547      status &= status1 || status2;
     548
     549      rotate = rotate2;
     550      if (status1 && !status2) rotate = rotate1;
     551      if (!status1 && !status2) rotate = 0.0;
     552
    543553      Lambda = coords[0].cdelt2 / coords[0].cdelt1;
    544554      coords[0].pc1_1 =  cos(rotate*RAD_DEG);
  • trunk/Ohana/src/libdvo/src/dvo_catalog.c

    r29938 r31663  
    9090  catalog[0].secfilt = NULL;
    9191 
     92  catalog[0].averageT = NULL;
     93  catalog[0].measureT = NULL;
     94
    9295  catalog[0].objID = 0;
    9396  catalog[0].catID = 0;
  • trunk/Ohana/src/libdvo/src/dvo_catalog_split.c

    r31450 r31663  
    172172  header.buffer = NULL;
    173173  primary = NULL;
     174  status = FALSE;
    174175
    175176  /* get the components from the header - these duplicate information in the split files (NAXIS2) */
     
    239240
    240241  /*** Measure Table ***/
    241   status = dvo_catalog_open_subcat (catalog, &catalog[0].measure_catalog, ftable.header, "MEASURE", VERBOSE);
    242   if (status == DVO_CAT_OPEN_FAIL) {
    243     return (FALSE);
    244   }
    245   if ((status == DVO_CAT_OPEN_EMPTY) && (catalog[0].Nmeas_disk > 0)) {
    246     return (FALSE);
     242  if (!(catalog[0].catflags & SKIP_MEAS)) {
     243    // unless we specify 'skip', we still need to load the
     244    status = dvo_catalog_open_subcat (catalog, &catalog[0].measure_catalog, ftable.header, "MEASURE", VERBOSE);
     245    if (status == DVO_CAT_OPEN_FAIL) {
     246      return (FALSE);
     247    }
     248    if ((status == DVO_CAT_OPEN_EMPTY) && (catalog[0].Nmeas_disk > 0)) {
     249      return (FALSE);
     250    }
    247251  }
    248252  if ((status != DVO_CAT_OPEN_EMPTY) && (catalog[0].catflags & LOAD_MEAS)) {
     
    262266  } else {
    263267    // XXX is it necessary to generate a template header here?
     268    // XXX this is a memory leak, right?
     269    if (catalog[0].measure_catalog) {
     270      gfits_free_header (&catalog[0].measure_catalog[0].header);
     271    } else {
     272      ALLOCATE (catalog[0].measure_catalog, Catalog, 1);
     273      dvo_catalog_init (catalog[0].measure_catalog, TRUE);
     274    }
    264275    gfits_create_header (&catalog[0].measure_catalog[0].header);
    265276    ALLOCATE (catalog[0].measure, Measure, 1);
  • trunk/Ohana/src/libfits/Makefile

    r23724 r31663  
    5454$(TABL)/F_set_column.$(ARCH).o                  $(TABL)/F_get_column.$(ARCH).o   \
    5555$(TABL)/F_table_row.$(ARCH).o                   $(TABL)/F_free_T.$(ARCH).o       \
    56 $(TABL)/F_table_varlength.$(ARCH).o
     56$(TABL)/F_table_varlength.$(ARCH).o             $(TABL)/F_copy_T.$(ARCH).o
    5757
    5858EXTERN_OBJ = \
  • trunk/Ohana/src/libfits/include/gfitsio.h

    r29938 r31663  
    6363  Header                 *header;
    6464  char                   *buffer;
    65   off_t                   datasize;
    66   off_t                   validsize;
     65  off_t                   datasize; // size of the buffer (including block padding at the end)
     66  off_t                   validsize;  // size of the valid portion of the table (< validsize if file is short)
    6767} FTable;
    6868
     
    199199int     gfits_vtable_from_ftable       PROTO((FTable *ftable, VTable *vtable, off_t *row, off_t Nrow));
    200200int     gfits_write_table              PROTO((char *filename, FTable *ftable));
     201int     gfits_copy_ftable              PROTO((FTable *in, FTable *out));
     202int     gfits_copy_vtable              PROTO((VTable *in, VTable *out));
    201203
    202204int     gfits_create_Theader           PROTO((Header *header, char *type));
  • trunk/Ohana/src/libfits/matrix/F_copy_M.c

    r27435 r31663  
    33
    44/*********************** fits copy header ***********************************/
    5 int gfits_copy_matrix (Matrix *matrix1, Matrix *matrix2) {
     5int gfits_copy_matrix (Matrix *in, Matrix *out) {
    66
    77  int i;
    88
    9   matrix2[0].unsign   = matrix1[0].unsign;
    10   matrix2[0].bitpix   = matrix1[0].bitpix;
    11   matrix2[0].datasize = matrix1[0].datasize;
    12   matrix2[0].bzero    = matrix1[0].bzero;
    13   matrix2[0].bscale   = matrix1[0].bscale;
    14   matrix2[0].Naxes    = matrix1[0].Naxes;
     9  out[0].unsign   = in[0].unsign;
     10  out[0].bitpix   = in[0].bitpix;
     11  out[0].datasize = in[0].datasize;
     12  out[0].bzero    = in[0].bzero;
     13  out[0].bscale   = in[0].bscale;
     14  out[0].Naxes    = in[0].Naxes;
    1515  for (i = 0; i < FT_MAX_NAXES; i++)
    16     matrix2[0].Naxis[i] = matrix1[0].Naxis[i];
     16    out[0].Naxis[i] = in[0].Naxis[i];
    1717
    18   if (matrix2[0].buffer != NULL) free (matrix2[0].buffer);
    19   ALLOCATE (matrix2[0].buffer, char, matrix2[0].datasize);
     18  if (out[0].buffer != NULL) free (out[0].buffer);
     19  ALLOCATE (out[0].buffer, char, out[0].datasize);
    2020 
    21   memcpy (matrix2[0].buffer, matrix1[0].buffer, matrix2[0].datasize);
     21  memcpy (out[0].buffer, in[0].buffer, out[0].datasize);
    2222
    2323  return (TRUE);
  • trunk/Ohana/src/libkapa/src/bDrawFuncs.c

    r31559 r31663  
    7878
    7979void bDrawSetStyle (bDrawBuffer *buffer, bDrawColor color, int lw, int lt) {
    80   buffer->bColor = color;
    81   buffer->bColor_R = buffer->palette[color].red;
    82   buffer->bColor_G = buffer->palette[color].green;
    83   buffer->bColor_B = buffer->palette[color].blue;
     80  if (color >= 0) {
     81    buffer->bColor = color;
     82    buffer->bColor_R = buffer->palette[color].red;
     83    buffer->bColor_G = buffer->palette[color].green;
     84    buffer->bColor_B = buffer->palette[color].blue;
     85  }
    8486  buffer->bWeight = lw;
    8587  buffer->bType = lt;
  • trunk/Ohana/src/libohana/Makefile

    r31635 r31663  
    5353
    5454TEST = \
    55 $(TESTDIR)/string.$(ARCH)
     55$(TESTDIR)/memtest.$(ARCH)
     56# $(TESTDIR)/string.$(ARCH)
    5657
    5758testcode: install $(TEST)
    5859test:
    5960        $(MAKE) testcode
     61        for i in $(TEST); do $$i; done
     62
     63quicktest:
    6064        for i in $(TEST); do $$i; done
    6165
  • trunk/Ohana/src/libohana/include/ohana.h

    r31635 r31663  
    1919# include <readline/readline.h>
    2020
     21// comment this out to avoid the internal Ohana memory management code
     22// # define OHANA_MEMORY
     23
    2124// XXX I was including these before, but RHL claims they are not needed
    2225// # include <malloc.h>
     
    234237int     scan_line              PROTO((FILE *f, char *line));
    235238int     dparse                 PROTO((double *X, int NX, char *line));
     239int     dparse_csv             PROTO((double *X, int NX, char *line));
    236240int     fparse                 PROTO((float *X, int NX, char *line));
    237241int     get_argument           PROTO((int argc, char **argv, char *arg));
  • trunk/Ohana/src/libohana/include/ohana_allocate.h

    r30726 r31663  
    11# ifndef OHANA_ALLOCATE
    22# define OHANA_ALLOCATE
     3
     4typedef struct {
     5  int    exists; // has the memory management system been created?
     6  size_t Ntotal; // number of blocks currently allocated
     7  size_t Nbytes; // number of bytes currently allocated
     8  size_t Ngood;  // number of good blocks
     9  size_t Nbad;   // number of bad blocks
     10} OhanaMemstats;
     11
     12OhanaMemstats ohana_memstats (int mode);
    313
    414/* default is to use basic system memory functions */
    515# ifdef OHANA_MEMORY
    616
    7 void *ohana_malloc (char *file, int line, int Nelem, size_t esize);
    8 void *ohana_realloc (char *file, int line, void *in, int Nelem, size_t esize);
    9 void  ohana_free (char *file, int line, void *in);
    10 void  ohana_memregister_func (char *file, int line, void *ptr);
     17void *ohana_malloc (const char *file, int line, const char *func, size_t Nelem, size_t esize);
     18void *ohana_realloc (const char *file, int line, const char *func, void *in, size_t Nelem, size_t esize);
     19void  ohana_free (const char *file, int line, const char *func, void *in);
    1120void  ohana_memdump_func (int mode);
    1221void  ohana_memcheck_func (int mode);
     22void  real_free (void *in);
    1323
    14 # define ohana_memregister(X) ohana_memregister_func (__FILE__, __LINE__, (X));
    1524# define ohana_memcheck(X) ohana_memcheck_func (X);
    1625# define ohana_memdump(X) ohana_memdump_func (X);
    1726
    18 # define ALLOCATE(PTR,TYPE,SIZE) \
    19   { PTR = (TYPE *) ohana_malloc (__FILE__, __LINE__, (SIZE), sizeof(TYPE)) }
    20 # define ALLOCATE_ZERO(PTR,TYPE,SIZE)                                   \
    21   { PTR = (TYPE *) ohana_malloc (__FILE__, __LINE__, (SIZE), sizeof(TYPE)); memset (PTR, 0, (SIZE)*sizeof(TYPE)); }
    22 # define REALLOCATE(PTR,TYPE,SIZE) \
    23   { PTR = (TYPE *) ohana_realloc(__FILE__, __LINE__, PTR, (SIZE), sizeof(TYPE)); }
    24 # define CHECK_REALLOCATE(PTR,TYPE,SIZE,NCURR,DELTA) {                  \
    25   if ((NCURR) >= (SIZE)) { SIZE += DELTA;                               \
    26     PTR = (TYPE *) ohana_realloc(__FILE__, __LINE__, PTR, (SIZE), sizeof(TYPE)); } }
    27 # define FREE(PTR) { if (PTR != NULL) { ohana_free (__FILE__, __LINE__, PTR); } }
    28 # define free(PTR) { ohana_free(__FILE__, __LINE__, PTR); }
     27# define ALLOCATE(PTR,TYPE,SIZE) { \
     28    PTR = (TYPE *) ohana_malloc (__FILE__, __LINE__, __func__, (SIZE), sizeof(TYPE)); \
     29  }
    2930
    30 # else
    31 # define ohana_memregister(X) /* NOP */
     31# define ALLOCATE_ZERO(PTR,TYPE,SIZE) { \
     32    PTR = (TYPE *) ohana_malloc (__FILE__, __LINE__, __func__, (SIZE), sizeof(TYPE)); \
     33    memset (PTR, 0, (SIZE)*sizeof(TYPE)); \
     34  }
     35
     36# define REALLOCATE(PTR,TYPE,SIZE) { \
     37    PTR = (TYPE *) ohana_realloc(__FILE__, __LINE__, __func__, PTR, (SIZE), sizeof(TYPE)); \
     38  }
     39
     40# define CHECK_REALLOCATE(PTR,TYPE,SIZE,NCURR,DELTA) { \
     41  if ((NCURR) >= (SIZE)) { \
     42    SIZE += DELTA; \
     43    PTR = (TYPE *) ohana_realloc(__FILE__, __LINE__, __func__, PTR, (SIZE), sizeof(TYPE)); \
     44  } }
     45
     46# define FREE(PTR) { if (PTR != NULL) { ohana_free (__FILE__, __LINE__, __func__, PTR); } }
     47# define free(PTR) { ohana_free(__FILE__, __LINE__, __func__, PTR); }
     48
     49# else  /* below: not OHANA_MEMORY */
     50
    3251# define ohana_memcheck(X) /* NOP */
    3352# define ohana_memdump(X) /* NOP */
    34 # endif /* OHANA_MEMORY */
     53void  real_free (void *in);
    3554
    36 # ifndef ALLOCATE
    3755# define ALLOCATE(PTR,TYPE,SIZE) {                                      \
    3856  PTR = (TYPE *) malloc ((size_t)(MAX(((SIZE)*((int)sizeof(TYPE))),1))); \
     
    6381
    6482# define FREE(PTR) { if (PTR != NULL) { free (PTR); } }
    65 # endif /* ALLOCATE */
     83# endif /* OHANA_MEMORY */
    6684
    6785# endif /* OHANA_ALLOCATE */
  • trunk/Ohana/src/libohana/src/ohana_allocate.c

    r27491 r31663  
    22# include <stdlib.h>
    33# include <stdarg.h>
     4# include <stdint.h>
     5# include <pthread.h>
     6
     7# undef OHANA_MEMORY
     8# include "ohana_allocate.h"
    49
    510/* need an internal version that does not use ohana_memory functions */
     
    712# define TRUE 1
    813# define MAX(X,Y) ((X) > (Y) ? (X) : (Y))
    9 # define OHANA_ALLOCATE(X,T,S)  \
    10   X = (T *) malloc ((unsigned)(MAX(((S)*((int)sizeof(T))),1))); \
    11   if (X == NULL) { \
    12     fprintf(stderr,"failed malloc at %d in %s\n", __LINE__, __FILE__);\
    13     abort(); }
    14 # define OHANA_REALLOCATE(X,T,S) \
    15   X = (T *) realloc(X,(unsigned)(MAX(((S)*((int)sizeof(T))),1))); \
    16   if (X == NULL) { \
    17     fprintf(stderr,"failed realloc at %d in %s\n", __LINE__, __FILE__);\
    18     abort(); }
    19 # define OHANA_CHECK_REALLOCATE(X,T,S,N,D) \
    20   if ((N) >= (S)) { \
    21     S += D; \
    22     X = (T *) realloc(X,(unsigned)(MAX(((S)*((int)sizeof(T))),1))); \
    23     if (X == NULL) { \
    24       fprintf(stderr,"failed realloc increment at %d in %s\n", __LINE__, __FILE__);\
    25       abort(); } }
    26 # define OHANA_FREE(X) free(X)
    27 
    28 # define STATE_ALLOC    0
    29 # define STATE_REALLOC  1
    30 # define STATE_FREE     2
    31 # define STATE_EXTERNAL 3
    32 
    33 typedef struct {
    34   char *file;
    35   int   line;
    36   void *ptr;   // location of externally visible entry
    37   int   size;
    38   int   state;
    39 } Memlist;
    40 
    41 // XXX consider fixing the memory tracking model (list?)
    42 // static long *memsort;
    43 // static long *memhash;
    44 static Memlist *memlist = NULL;
    45 int Nmemlist = 0;
    46 int NMEMLIST = 0;
    47 int NMEMBYTE = 0;
     14
     15# define OHANA_MEMMAGIC (uint32_t) 0xdeadbeef
     16
     17typedef struct Memblock {
     18  uint32_t startblock;        // endpost marker
     19  struct Memblock *prevBlock; // previously allocated memory
     20  struct Memblock *nextBlock; // next allocated memory
     21  size_t size;                // size of memory
     22  const char *file;           // file (re)allocated
     23  const char *func;           // func (re)allocated
     24  int line;                   // line (re)allocated
     25  uint32_t endblock;          // endpost marker
     26} Memblock;
     27
     28static Memblock *lastBlock = NULL;
     29
     30static pthread_mutex_t memBlockListMutex = PTHREAD_MUTEX_INITIALIZER;
    4831
    4932void ohana_meminit () {
    50   Nmemlist = 0;
    51   NMEMLIST = 1000;
    52   OHANA_ALLOCATE (memlist, Memlist, NMEMLIST);
    53   // OHANA_ALLOCATE (memsort, long, NMEMLIST);
    54   // OHANA_ALLOCATE (memhash, long, NMEMLIST);
    55   NMEMBYTE = sizeof(size_t);
     33  return;
    5634}
    5735
     
    6543}
    6644
    67 void *ohana_malloc (char *file, int line, int Nelem, size_t esize) {
    68 
    69   void *ptr, *new;
    70   int size;
    71   size_t *marker;
    72 
    73   if (memlist == NULL) ohana_meminit ();
     45void *ohana_malloc (const char *file, int line, const char *func, size_t Nelem, size_t esize) {
     46
     47  void *ptr;                  // actual user memory allocated
     48  Memblock *new;              // new memblock created to track the user memory
     49  size_t size;                // total number of bytes requested (not items)
    7450
    7551  Nelem = MAX (1, Nelem);
    7652  size = Nelem * esize;
    7753
    78   new = malloc (size + 2*NMEMBYTE); /* 2 extra locations to save endposts */
    79   if (new == NULL) ohana_memabort ("failed to allocate memory (%s, %d)\n", file, line);
    80   ptr = new + NMEMBYTE;
    81 
    82   marker = (size_t *) new;
    83   *marker = 0xdeadbeef;
    84   marker = (size_t *)(new + size + NMEMBYTE);
    85   *marker = 0xdeadbeef;
    86 
    87   /* new memory, add to stack */
    88   memlist[Nmemlist].ptr  = ptr;
    89   memlist[Nmemlist].file = file;
    90   memlist[Nmemlist].line = line;
    91   memlist[Nmemlist].size = size;
    92   memlist[Nmemlist].state = STATE_ALLOC;
    93 
    94   // before each free, we sort this pair to speed up searching
    95   // memsort[Nmemlist] = ptr;
    96   // memhash[Nmemlist] = Nmemlist;
    97 
    98   Nmemlist ++;
    99   if (Nmemlist == NMEMLIST) {
    100     NMEMLIST += 1000;
    101     OHANA_REALLOCATE (memlist, Memlist, NMEMLIST);
    102   }
     54  // total size is : memblock + data + endpost
     55  new = (Memblock *) malloc (sizeof(Memblock) + size + sizeof(void *));
     56  if (new == NULL) ohana_memabort ("failed to allocate memory (%s, %d, %s)\n", file, line, func);
     57
     58  // pointer to the start of the user memory
     59  ptr = (char *)(new + 1);
     60
     61  // set the end-post values
     62  new->startblock = OHANA_MEMMAGIC;
     63  new->endblock = OHANA_MEMMAGIC;
     64  *(uint32_t *)(ptr + size) = OHANA_MEMMAGIC;
     65
     66  // set the memory metadata
     67  new->size = size;
     68  new->file = file;
     69  new->line = line;
     70  new->func = func;
     71
     72  // new memblock becomes the 'lastBlock':
     73  // lastBlock = new
     74  // new->prev = (new - 1)
     75  // (new - 1)->next = new
     76
     77  // for memory allocated in the order m0, m1, m2
     78  // m0->next = m1, m1->next = m2, m2->next = NULL
     79  // m2->prev = m1, m1->prev = m0, m0->prev = NULL
     80  // lastBlock = m2
     81
     82  // set up the pointers
     83  new->nextBlock = NULL;
     84
     85  // protect the list during this operation
     86  pthread_mutex_lock(&memBlockListMutex);
     87
     88  if (lastBlock) {
     89    lastBlock->nextBlock = new;
     90  }
     91  new->prevBlock = lastBlock;
     92  lastBlock = new;
     93
     94  pthread_mutex_unlock(&memBlockListMutex);
     95
    10396  return (ptr);
    10497}
    10598
    106 void *ohana_realloc (char *file, int line, void *in, int Nelem, size_t esize) {
    107 
    108   int i, size;
    109   void *ptr, *ref, *new;
    110   size_t *marker;
    111 
    112   if (memlist == NULL) ohana_memabort ("REALLOCATE before ALLOCATE");
     99void *ohana_realloc (const char *file, int line, const char *func, void *in, size_t Nelem, size_t esize) {
     100
     101  void *ptr;                  // actual user memory allocated
     102  Memblock *old;              // original memblock associated with user memory
     103  Memblock *new;              // new memblock associated with user memory
     104  size_t size;
     105
     106  // just allocate if not previously allocated
     107  if (!in) {
     108    ptr = ohana_malloc (file, line, func, Nelem, esize);
     109    return ptr;
     110  }
     111
     112  // memblock of supplied pointer
     113  old = (Memblock *) in - 1;
    113114
    114115  Nelem = MAX (1, Nelem);
    115116  size = Nelem * esize;
    116117
    117   ref = in - NMEMBYTE;
    118 
    119   /* find old entry, update ptr, file, line */
    120   for (i = 0; i < Nmemlist; i++) {
    121     if (memlist[i].state == STATE_FREE) continue;
    122     if (memlist[i].ptr == in) {
    123 
    124       if (memlist[i].state == STATE_EXTERNAL) ohana_memabort ("ERROR: realloc of external memory");
    125 
    126       /* ask for new memory */
    127       new = realloc (ref, size + 2*NMEMBYTE); /* 2 extra slots to save endposts */
    128       if (new == NULL) ohana_memabort ("failed to reallocate memory (%s, %d)\n", file, line);
    129       ptr = new + NMEMBYTE;
    130      
    131       /* set the marker */
    132       marker = (size_t *) new;
    133       *marker = 0xdeadbeef;
    134       marker = (size_t *)(ptr + size);
    135       *marker = 0xdeadbeef;
    136 
    137       /* otherwise, update memory new location */
    138       memlist[i].ptr = ptr;
    139       memlist[i].size = size;
    140       memlist[i].state = STATE_REALLOC;
    141 
    142       /* if new memory in new location, update references */
    143       if (ptr != in) {
    144         memlist[i].file = file;
    145         memlist[i].line = line;
    146       }
    147 
    148       return (ptr);
    149     }
    150   }
    151   ohana_memabort ("allocated memory not found for realloc (%s, %d)\n", file, line);
    152   return (NULL);
     118  // requested same size as current allocation
     119  if (size == old->size) {
     120    return in;
     121  }
     122
     123  pthread_mutex_lock(&memBlockListMutex);
     124
     125  Memblock *nextBlock = old->nextBlock;
     126  Memblock *prevBlock = old->prevBlock;
     127
     128  int isLast = (old == lastBlock);
     129
     130  // ask for new memory
     131  // total size is : memblock + data + endpost
     132  new = (Memblock *) realloc (old, sizeof(Memblock) + size + sizeof(void *));
     133  if (new == NULL) ohana_memabort ("failed to reallocate memory (%s, %d, %s)\n", file, line, func);
     134  ptr = (char *) (new + 1);
     135 
     136  // give the realloc location:
     137  new->size = size;
     138  new->file = file;
     139  new->line = line;
     140  new->func = func;
     141
     142  // update the endpost (the others were set originally
     143  *(uint32_t *)(ptr + size) = OHANA_MEMMAGIC;
     144
     145  // need to reset lastBlock in case we moved
     146  if (isLast) {
     147    lastBlock = new;
     148  }
     149
     150  // need to adjust the neighbors' pointers:
     151  if (nextBlock) {
     152    nextBlock->prevBlock = new;
     153  }
     154  if (prevBlock) {
     155    prevBlock->nextBlock = new;
     156  }
     157 
     158  pthread_mutex_unlock(&memBlockListMutex);
     159
     160  return (ptr);
     161}
     162
     163void real_free (void *in) {
     164
     165  if (!in) return;
     166  free (in);
     167  return;
    153168}
    154169
    155170// this is very slow.  should we speed this up by indexing on the ptr?
    156 void ohana_free (char *file, int line, void *in) {
    157 
    158   int i;
    159 
    160   if (memlist == NULL) ohana_memabort ("FREE before ALLOCATE");
    161 
    162   /* find old entry, set state */
    163   for (i = 0; i < Nmemlist; i++) {
    164     if (memlist[i].state == STATE_FREE) continue;
    165     if (memlist[i].ptr == in) {
    166       memlist[i].state = STATE_FREE;
    167       return;
    168     }
    169   }
    170 
    171   /* find already freed examples */
    172   for (i = 0; i < Nmemlist; i++) {
    173     if (memlist[i].ptr == in) {
    174       fprintf (stderr, "used here: %4d %s %d\n", i, memlist[i].file, memlist[i].line);
    175     }
    176   }
    177 
    178   ohana_memabort ("allocated memory not found for free (%s, %d : %x)\n", file, line, in);
    179   return;
    180 }
    181 
    182 /* register externally allocated memory with ohana memory manager */
    183 void ohana_memregister_func (char *file, int line, void *ptr) {
    184 
    185   if (memlist == NULL) ohana_meminit ();
    186 
    187   /* add to stack */
    188   memlist[Nmemlist].ptr  = ptr;
    189   memlist[Nmemlist].file = file;
    190   memlist[Nmemlist].line = line;
    191   memlist[Nmemlist].state = STATE_EXTERNAL;
    192   Nmemlist ++;
    193   if (Nmemlist == NMEMLIST) {
    194     NMEMLIST += 1000;
    195     OHANA_REALLOCATE (memlist, Memlist, NMEMLIST);
    196   }
     171void ohana_free (const char *file, int line, const char *func, void *in) {
     172
     173  Memblock *ref;
     174
     175  if (!in) return;
     176
     177  ref = (Memblock *) in - 1;
     178
     179  pthread_mutex_lock(&memBlockListMutex);
     180 
     181  Memblock *nextBlock = ref->nextBlock;
     182  Memblock *prevBlock = ref->prevBlock;
     183
     184  if (nextBlock) {
     185    nextBlock->prevBlock = prevBlock;
     186  }
     187  if (prevBlock) {
     188    prevBlock->nextBlock = nextBlock;
     189  }
     190  if (lastBlock == ref) {
     191    lastBlock = prevBlock;
     192  }
     193 
     194  pthread_mutex_unlock(&memBlockListMutex);
     195 
     196  free (ref);
     197
    197198  return;
    198199}
     
    200201void ohana_memcheck_func (int allmemory) {
    201202
    202   int i, j, next, prev, header;
    203   size_t *marker;
    204   char top, bottom;
    205 
    206   if (Nmemlist == 0) {
     203  if (!lastBlock) {
    207204    fprintf (stderr, "no memory allocated\n");
    208205    return;
    209206  }
    210207
    211   header = FALSE;
    212   fprintf (stderr, "checking %d memory blocks\n", Nmemlist);
    213   for (i = 0; i < Nmemlist; i++) {
    214     if (memlist[i].state == STATE_EXTERNAL) continue;
    215     if ((allmemory == 0) && (memlist[i].state == STATE_FREE)) continue;
    216 
    217     top = bottom = 'Y';
    218     marker = (size_t *)(memlist[i].ptr - NMEMBYTE);
    219     if (*marker == 0xdeadbeef) bottom = 'N';
    220     marker = (size_t *)(memlist[i].ptr + memlist[i].size);
    221     if (*marker == 0xdeadbeef) top = 'N';
     208  Memblock *thisBlock = lastBlock;
     209
     210  size_t Ngood  = 0;
     211  size_t Nbad   = 0;
     212  size_t Ntotal = 0;
     213  size_t Nbytes = 0;
     214
     215  while (thisBlock) {
     216
     217    int good = TRUE;
    222218   
    223     if ((top == 'N') && (bottom == 'N')) continue;
    224     if (!header) {
    225       fprintf (stderr, "         Nmem start end file            line\n");
    226       header = TRUE;
     219    if (thisBlock->startblock != OHANA_MEMMAGIC) good = FALSE;
     220    if (thisBlock->endblock != OHANA_MEMMAGIC) good = FALSE;
     221
     222    // pointer to the start of the user memory
     223    char *ptr = (char *)(thisBlock + 1) + thisBlock->size;
     224    uint32_t endpost = *(uint32_t *)ptr;
     225    if (endpost != OHANA_MEMMAGIC) good = FALSE;
     226
     227    // XXX keep checking even if memory is corrupted?
     228    if (!good) {
     229      if (Nbad < 1) {
     230        fprintf (stderr, "memory corruption\n");
     231      }
     232      if (Nbad < 100) {
     233        fprintf (stderr, "  file: %s, line: %d, func: %s\n", thisBlock->file, thisBlock->line, thisBlock->func);
     234      }
     235      Nbad ++;
     236    } else {
     237      Ngood ++;
    227238    }
    228     fprintf (stderr, "corrupt:  %3d   %c    %c  %-15s %3d\n", i, bottom, top, memlist[i].file, memlist[i].line);
    229     prev = next = -1;
    230     for (j = 0; j < Nmemlist; j++) {
    231       if (memlist[j].ptr < memlist[i].ptr) {
    232         if (prev == -1) prev = j;
    233         if (memlist[j].ptr > memlist[prev].ptr) prev = j;
    234       }
    235       if (memlist[j].ptr > memlist[i].ptr) {
    236         if (next == -1) next = j;
    237         if (memlist[j].ptr < memlist[next].ptr) next = j;
    238       }
    239     }     
    240     if (prev == -1) {
    241       fprintf (stderr, "no previous memory block\n");
    242     } else {
    243       fprintf (stderr, "prev:     %3d           %-15s %3d\n", prev, memlist[prev].file, memlist[prev].line);
    244     }
    245     if (next == -1) {
    246       fprintf (stderr, "no next memory block\n");
    247     } else {
    248       fprintf (stderr, "next:     %3d           %-15s %3d\n", next, memlist[next].file, memlist[next].line);
    249     }
    250   }
     239    Ntotal ++;
     240    Nbytes += thisBlock->size;
     241
     242    thisBlock = thisBlock->prevBlock;
     243  }
     244 
     245  fprintf (stderr, "%zd memory blocks allocated (%zd bytes total), %zd good, %zd bad\n", Ntotal, Nbytes, Ngood, Nbad);
     246
    251247  return;
    252248}
     
    254250void ohana_memdump_func (int allmemory) {
    255251
    256   int i, Ns[4], N;
    257   char S[4];
    258 
    259   if (Nmemlist == 0) {
     252  if (!lastBlock) {
    260253    fprintf (stderr, "no memory allocated\n");
    261254    return;
    262255  }
    263256
    264   S[0] = 'A';
    265   S[1] = 'R';
    266   S[2] = 'F';
    267   S[3] = 'X';
    268   Ns[0] = Ns[1] = Ns[2] = Ns[3] = 0;
    269   N = 0;
    270 
    271   for (i = 0; i < Nmemlist; i++) {
    272     if (memlist[i].state == STATE_ALLOC)    N = 0;
    273     if (memlist[i].state == STATE_REALLOC)  N = 1;
    274     if (memlist[i].state == STATE_FREE)     N = 2;
    275     if (memlist[i].state == STATE_EXTERNAL) N = 2;
    276     Ns[N] ++;
    277     if ((allmemory == 0) && (memlist[i].state == STATE_FREE)) continue;
    278     if (memlist[i].state == STATE_EXTERNAL) {
    279       fprintf (stderr, "%3d %4d %lx : %lx - extern (extern     extern) %c %s %d\n",
    280                Ns[N], i, (long)memlist[i].ptr, (long)memlist[i].ptr,
    281                S[N], memlist[i].file, memlist[i].line);
     257  Memblock *thisBlock = lastBlock;
     258
     259  size_t Ntotal = 0;
     260  size_t Nbytes = 0;
     261
     262  fprintf (stderr, " entry | bytes | cumulative | STATUS | file | line | function\n");
     263
     264  while (thisBlock) {
     265
     266    int good = TRUE;
     267   
     268    if (thisBlock->startblock != OHANA_MEMMAGIC) good = FALSE;
     269    if (thisBlock->endblock != OHANA_MEMMAGIC) good = FALSE;
     270
     271    // pointer to the start of the user memory
     272    char *ptr = (char *)(thisBlock + 1) + thisBlock->size;
     273    uint32_t endpost = *(uint32_t *)ptr;
     274    if (endpost != OHANA_MEMMAGIC) good = FALSE;
     275
     276    // XXX keep checking even if memory is corrupted?
     277    Ntotal ++;
     278    Nbytes += thisBlock->size;
     279
     280    if (Ntotal < 100) {
     281      if (good) {
     282        fprintf (stderr, "  %zd  %zd  %zd  GOOD  %s %d, func: %s\n", Ntotal, thisBlock->size, Nbytes, thisBlock->file, thisBlock->line, thisBlock->func);
     283      } else {
     284        fprintf (stderr, "  %zd  %zd  %zd  BAD   %s %d, func: %s\n", Ntotal, thisBlock->size, Nbytes, thisBlock->file, thisBlock->line, thisBlock->func);
     285      }
     286    }
     287
     288    thisBlock = thisBlock->prevBlock;
     289  }
     290  fprintf (stderr, "%zd memory blocks allocated (%zd bytes total)\n", Ntotal, Nbytes);
     291
     292  return;
     293}
     294
     295OhanaMemstats ohana_memstats (int allmemory) {
     296
     297  OhanaMemstats memstats;
     298
     299  memstats.exists = 0;
     300  memstats.Ntotal = 0;
     301  memstats.Nbytes = 0;
     302  memstats.Ngood = 0;
     303  memstats.Nbad = 0;
     304 
     305  Memblock *thisBlock = lastBlock;
     306
     307  while (thisBlock) {
     308
     309    memstats.exists = TRUE;
     310
     311    int good = TRUE;
     312   
     313    if (thisBlock->startblock != OHANA_MEMMAGIC) good = FALSE;
     314    if (thisBlock->endblock != OHANA_MEMMAGIC) good = FALSE;
     315
     316    // pointer to the start of the user memory
     317    char *ptr = (char *)(thisBlock + 1) + thisBlock->size;
     318    uint32_t endpost = *(uint32_t *)ptr;
     319    if (endpost != OHANA_MEMMAGIC) good = FALSE;
     320
     321    memstats.Ntotal ++;
     322    memstats.Nbytes += thisBlock->size;
     323
     324    if (good) {
     325      memstats.Ngood ++;
    282326    } else {
    283       fprintf (stderr, "%3d %4d %lx : %lx - %lx (%lx %lx) %c %s %d\n",
    284                Ns[N], i, (long)memlist[i].ptr, (long)(memlist[i].ptr - NMEMBYTE), (long)(memlist[i].ptr + memlist[i].size + NMEMBYTE),
    285                *(long *)(memlist[i].ptr - NMEMBYTE), *(long *)(memlist[i].ptr + memlist[i].size),
    286                S[N], memlist[i].file, memlist[i].line);
     327      memstats.Nbad ++;
    287328    }
    288   }
    289   fprintf (stderr, "Nused: %d (Nalloc: %d, Nrealloc: %d), Nfree: %d\n",
    290            Ns[0]+Ns[1], Ns[0], Ns[1], Ns[2]);
    291   return;
    292 }
     329
     330    thisBlock = thisBlock->prevBlock;
     331  }
     332
     333  return memstats;
     334}
  • trunk/Ohana/src/libohana/src/string.c

    r27435 r31663  
    153153}
    154154
     155// advance to the next word, separated by commas:
     156// AA,BB,CC : go from AA to BB to CC to 0
     157// AA,,CC : go from AA to , to CC to 0
     158// ,,, : go from , to , to , to 0
     159
     160char *_parse_nextword_csv (char *string) {
     161
     162  if (string == (char *) NULL) return ((char *) NULL);
     163
     164  for (; (*string != 0) && (*string != ','); string++);
     165  if (*string == ',') string ++;
     166  return (string);
     167}
     168
    155169int dparse (double *X, int NX, char *line) {
    156170
     
    162176  for (i = 0; i < NX - 1; i++)
    163177    word = _parse_nextword (word);
     178
     179  *X = strtod (word, &ptr);
     180  if (ptr == word) return (FALSE);
     181  if (word[0] == '-') return (-1);
     182  return (1);
     183}
     184
     185int dparse_csv (double *X, int NX, char *line) {
     186
     187  int i;
     188  char *word;
     189  char *ptr;
     190
     191  word = line;
     192  for (i = 0; i < NX - 1; i++)
     193    word = _parse_nextword_csv (word);
     194 
     195  if (word[0] == '"') word[0] = ' ';
     196  if (word[0] == ',') {
     197      *X = NAN;
     198      return 1;
     199  }
    164200
    165201  *X = strtod (word, &ptr);
  • trunk/Ohana/src/libohana/test/typetest.c

    r31160 r31663  
    7474
    7575    big_value = 10;
    76     fprintf (stderr, "this is a bit int: "OFF_T_FMT" n'est pas?\n", big_value);
     76    fprintf (stderr, "this is a big int: "OFF_T_FMT" n'est pas?\n", big_value);
     77
     78    // we could move the % out of the FMT and allow constructions like this:
     79    // # define OFF_T_FMT "jd"
     80    // fprintf (stderr, "this is a big int: %06"OFF_T_FMT_ALT" n'est pas?\n", big_value);
     81    // still kind of ugly...
    7782
    7883    exit (status);
Note: See TracChangeset for help on using the changeset viewer.