[BACK]Return to alloc.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gnuplot

Annotation of OpenXM_contrib/gnuplot/alloc.c, Revision 1.1.1.3

1.1       maekawa     1: #ifndef lint
1.1.1.3 ! ohara       2: static char *RCSid = "$Id: alloc.c,v 1.1.1.2.2.1 2001/06/25 16:06:34 broeker Exp $";
1.1       maekawa     3: #endif
                      4:
                      5: /* GNUPLOT - alloc.c */
                      6:
                      7: /*[
                      8:  * Copyright 1986 - 1993, 1998   Thomas Williams, Colin Kelley
                      9:  *
                     10:  * Permission to use, copy, and distribute this software and its
                     11:  * documentation for any purpose with or without fee is hereby granted,
                     12:  * provided that the above copyright notice appear in all copies and
                     13:  * that both that copyright notice and this permission notice appear
                     14:  * in supporting documentation.
                     15:  *
                     16:  * Permission to modify the software is granted, but not the right to
                     17:  * distribute the complete modified source code.  Modifications are to
                     18:  * be distributed as patches to the released version.  Permission to
                     19:  * distribute binaries produced by compiling modified sources is granted,
                     20:  * provided you
                     21:  *   1. distribute the corresponding source modifications from the
                     22:  *    released version in the form of a patch file along with the binaries,
                     23:  *   2. add special version identification to distinguish your version
                     24:  *    in addition to the base release version number,
                     25:  *   3. provide your name and address as the primary contact for the
                     26:  *    support of your modified version, and
                     27:  *   4. retain our contact information in regard to use of the base
                     28:  *    software.
                     29:  * Permission to distribute the released version of the source code along
                     30:  * with corresponding source modifications in the form of a patch file is
                     31:  * granted with same provisions 2 through 4 for binary distributions.
                     32:  *
                     33:  * This software is provided "as is" without express or implied warranty
                     34:  * to the extent permitted by applicable law.
                     35: ]*/
                     36:
                     37: /*
                     38:  * AUTHORS
                     39:  *
                     40:  * Alexander Lehmann (collected functions from misc.c and binary.c)
                     41:  *
                     42:  */
                     43:
                     44: #include "plot.h" /* includes "alloc.h" */
                     45:
                     46: #if defined(MSDOS) && defined(__TURBOC__) && !defined(DOSX286)
                     47: #include <alloc.h>             /* for farmalloc, farrealloc */
                     48: #endif
                     49:
                     50: #if defined(_Windows) && !defined(WIN32)
                     51: #include <windows.h>
                     52: #include <windowsx.h>
                     53: #define farmalloc(s) GlobalAllocPtr(GHND,s)
                     54: #define farrealloc(p,s) GlobalReAllocPtr(p,s,GHND)
                     55: #endif
                     56:
                     57: #ifndef NO_GIH
                     58: #include "help.h"
                     59: #endif
                     60:
                     61: #ifndef GP_FARMALLOC
                     62: # ifdef FARALLOC
                     63: #  define GP_FARMALLOC(size) farmalloc ((size))
                     64: #  define GP_FARREALLOC(p,size) farrealloc ((p), (size))
                     65: # else
                     66: #  define GP_FARMALLOC(size) malloc ((size_t)(size))
                     67: #  define GP_FARREALLOC(p,size) realloc ((p), (size_t)(size))
                     68: # endif
                     69: #endif
                     70:
                     71: /* uncomment if you want to trace all allocs */
                     72: #define TRACE_ALLOC(x) /*printf x*/
                     73:
                     74:
                     75: #ifdef CHECK_HEAP_USE
                     76:
                     77: /* This is in no way supported, and in particular it breaks the
                     78:  * online help. But it is useful to leave it in in case any
                     79:  * heap-corruption bugs turn up. Wont work with FARALLOC
                     80:  */
                     81:
                     82: struct frame_struct {
                     83:        char *use;
                     84:        int requested_size;
                     85:        int pad; /* preserve 8-byte alignment */
                     86:        int checksum;
                     87: };
                     88:
                     89: struct leak_struct {
                     90:        char *file;
                     91:        int line;
                     92:        int allocated;
                     93: };
                     94:
                     95: static struct leak_struct leak_stack[40];  /* up to 40 nested leak checks */
                     96: static struct leak_struct *leak_frame = leak_stack;
                     97:
                     98: static long bytes_allocated = 0;
                     99:
                    100: #define RESERVED_SIZE sizeof(struct frame_struct)
                    101: #define CHECKSUM_INT 0xcaac5e1f
                    102: #define CHECKSUM_FREE 0xf3eed222
                    103: #define CHECKSUM_CHAR 0xc5
                    104:
                    105: static void mark(p, size, usage)
                    106: struct frame_struct *p;
                    107: unsigned long size;
                    108: char *usage;
                    109: {
                    110:        p->use = usage;
                    111:        p->requested_size = size;
                    112:        p->checksum = (CHECKSUM_INT ^ (int)(p->use) ^ size);
                    113:        ((unsigned char *)(p+1))[size] = CHECKSUM_CHAR;
                    114: }
                    115:
                    116: #define mark_free(p) ( ((struct frame_struct *)p)[-1].checksum = CHECKSUM_FREE)
                    117:
                    118: static void validate(x)
                    119: void *x;
                    120: {
                    121:        struct frame_struct *p = (struct frame_struct *)x - 1;
                    122:        if (p->checksum != (CHECKSUM_INT ^ (int)(p->use) ^ p->requested_size))
                    123:        {
                    124:                fprintf(stderr, "Heap corruption at start of block for %s\n", p->use);
                    125:                if (p->checksum == CHECKSUM_FREE)
                    126:                        fprintf(stderr, "Looks like it has already been freed ?\n");
                    127:                abort();
                    128:        }
                    129:
                    130:        if ( ((unsigned char *)(p+1))[p->requested_size] != CHECKSUM_CHAR)
                    131:        {
                    132:                fprintf(stderr, "Heap corruption at end of block for %-60s\n", p->use);
                    133:                int_error("Argh !", NO_CARET);
                    134:        }
                    135: }
                    136:
                    137: /* used to confirm that a pointer is inside an allocated region via
                    138:  * macro CHECK_POINTER. Nowhere near as good as using a bounds-checking
                    139:  * compiler (such as gcc-with-bounds-checking), but when we do
                    140:  * come across problems, we can add these guards to the code until
                    141:  * we find the problem, and then leave the guards in (as CHECK_POINTER
                    142:  * macros which expand to nothing, until we need to re-enable them)
                    143:  */
                    144:
                    145: void check_pointer_in_block(void *block, void *p, int size, char *file, int line)
                    146: {
                    147:        struct frame_struct *f = (struct frame_struct *)block - 1;
                    148:        validate(block);
                    149:        if (p < block || p >= (block + f->requested_size))
                    150:        {
                    151:                fprintf(stderr, "argh - pointer %p outside block %p->%p for %s at %s:%d\n",
                    152:                  p, block, (char *)block + f->requested_size, f->use, file, line);
                    153:                int_error("argh - pointer misuse !", NO_CARET);
                    154:        }
                    155: }
                    156:
1.1.1.3 ! ohara     157: generic *
        !           158: gp_alloc(size, usage)
        !           159:     unsigned long size;
        !           160:     char *usage;
1.1       maekawa   161: {
                    162:        struct frame_struct *p;
                    163:        unsigned long total_size = size + RESERVED_SIZE + 1;
                    164:
                    165:        TRACE_ALLOC(("gp_alloc %d for %s\n", (int) size, usage?usage:"<unknown>"));
                    166:
                    167:        p=malloc(total_size);
                    168:        if (!p) int_error("Out of memory", NO_CARET);
                    169:
                    170:        bytes_allocated += size;
                    171:
                    172:        mark(p,size,usage);
                    173:
                    174:        return (char *)(p+1);
                    175: }
                    176:
                    177: generic *gp_realloc(old, size, usage)
                    178: generic *old;
                    179: unsigned long size;
                    180: char *usage;
                    181: {
                    182:        if (!old) return gp_alloc(size, usage);
                    183:        validate(old);
                    184:        mark_free(old); /* if block gets moved, old block is marked free */
                    185:                        /* if not, we'll remark it later */
                    186:
                    187:
                    188:        {
                    189:                struct frame_struct *p = (struct frame_struct *)old - 1;
                    190:                unsigned long total = size + RESERVED_SIZE + 1;
                    191:
                    192:                p = realloc(p, total);
                    193:
                    194:                if (!p) int_error("Out of memory", NO_CARET);
                    195:
                    196:                TRACE_ALLOC(("gp_realloc %d for %s (was %d)\n",
                    197:                  (int)size, usage?usage:"<unknown>", p->requested_size));
                    198:
                    199:                bytes_allocated += size - p->requested_size;
                    200:
                    201:                mark(p,size,usage);
                    202:
                    203:                return (generic *)(p+1);
                    204:        }
                    205: }
                    206:
                    207: #undef free
                    208:
                    209: void checked_free(p)
                    210: void *p;
                    211: {
                    212:        validate(p);
                    213:        mark_free(p);  /* trap attempts to free twice */
                    214:        TRACE_ALLOC(("free %d for %s\n",
                    215:          ((struct frame_struct *)p - 1)->requested_size,
                    216:          ((struct frame_struct *)p - 1)->use));
                    217:        bytes_allocated -= ((struct frame_struct *)p - 1) -> requested_size;
                    218:        free( (struct frame_struct *) p - 1);
                    219: }
                    220:
                    221:
                    222: /* this leak checking stuff will be broken by first int_error or interrupt */
                    223:
                    224: void start_leak_check(char *file, int line)
                    225: {
                    226:        if (leak_frame >= leak_stack+40)
                    227:        {
                    228:                fprintf(stderr, "too many nested memory-leak checks - %s:%d\n", file, line);
                    229:                return;
                    230:        }
                    231:
                    232:        leak_frame->file = file;
                    233:        leak_frame->line = line;
                    234:        leak_frame->allocated = bytes_allocated;
                    235:
                    236:        ++leak_frame;
                    237: }
                    238:
                    239: void end_leak_check(char *file, int line)
                    240: {
                    241:        if (--leak_frame < leak_stack)
                    242:        {
                    243:                fprintf(stderr, "memory-leak stack underflow at %s:%d\n", file, line);
                    244:                return;
                    245:        }
                    246:
                    247:        if (leak_frame->allocated != bytes_allocated)
                    248:        {
                    249:                fprintf(stderr, "net change of %+d heap bytes between %s:%d and %s:%d\n",
                    250:                        (int)(bytes_allocated - leak_frame->allocated),
                    251:                        leak_frame->file, leak_frame->line, file, line);
                    252:        }
                    253: }
                    254:
                    255: #else  /* CHECK_HEAP_USE */
                    256:
                    257: /* gp_alloc:
                    258:  * allocate memory
                    259:  * This is a protected version of malloc. It causes an int_error
                    260:  * if there is not enough memory, but first it tries FreeHelp()
                    261:  * to make some room, and tries again. If message is NULL, we
                    262:  * allow NULL return. Otherwise, we handle the error, using the
                    263:  * message to create the int_error string. Note cp/sp_extend uses realloc,
                    264:  * so it depends on this using malloc().
                    265:  */
                    266:
1.1.1.3 ! ohara     267: generic *
1.1       maekawa   268: gp_alloc(size, message)
                    269:        unsigned long size;             /* # of bytes */
                    270:        char *message;                  /* description of what is being allocated */
                    271: {
                    272:     char *p;                           /* the new allocation */
                    273:     char errbuf[100];          /* error message string */
                    274:
                    275: #ifndef NO_GIH
                    276:     p = GP_FARMALLOC(size);
                    277:     if (p == (char *)NULL) {
                    278:           FreeHelp();                  /* out of memory, try to make some room */
                    279: #endif /* NO_GIH */
                    280:           p = GP_FARMALLOC(size);      /* try again */
                    281:           if (p == (char *)NULL) {
                    282:                  /* really out of memory */
                    283:                  if (message != NULL) {
                    284:                         (void) sprintf(errbuf, "out of memory for %s", message);
                    285:                         int_error(errbuf, NO_CARET);
                    286:                         /* NOTREACHED */
                    287:                  }
                    288:                  /* else we return NULL */
                    289:           }
                    290: #ifndef NO_GIH
                    291:     }
                    292: #endif
                    293:     return(p);
                    294: }
                    295:
                    296: /*
                    297:  * note gp_realloc assumes that failed realloc calls leave the original mem block
                    298:  * allocated. If this is not the case with any C compiler, a substitue
                    299:  * realloc function has to be used.
                    300:  */
                    301:
                    302: generic *
                    303: gp_realloc(p, size, message)
                    304:        generic *p;                     /* old mem block */
                    305:        unsigned long size;             /* # of bytes */
                    306:        char *message;                  /* description of what is being allocated */
                    307: {
                    308:     char *res;                         /* the new allocation */
                    309:     char errbuf[100];          /* error message string */
                    310:
                    311:     /* realloc(NULL,x) is meant to do malloc(x), but doesn't always */
                    312:     if (!p)
                    313:        return gp_alloc(size,message);
                    314:
                    315: #ifndef NO_GIH
                    316:     res = GP_FARREALLOC(p,size);
                    317:     if (res == (char *)NULL) {
                    318:           FreeHelp();                  /* out of memory, try to make some room */
                    319: #endif /* NO_GIH */
                    320:           res = GP_FARREALLOC(p,size); /* try again */
                    321:           if (res == (char *)NULL) {
                    322:                  /* really out of memory */
                    323:                  if (message != NULL) {
                    324:                         (void) sprintf(errbuf, "out of memory for %s", message);
                    325:                         int_error(errbuf, NO_CARET);
                    326:                         /* NOTREACHED */
                    327:                  }
                    328:                  /* else we return NULL */
                    329:           }
                    330: #ifndef NO_GIH
                    331:     }
                    332: #endif
                    333:     return(res);
                    334: }
                    335:
                    336: #endif /* CHECK_HEAP_USE */
                    337:
                    338: #ifdef FARALLOC
                    339: void gpfree(p)
                    340: generic *p;
                    341: {
                    342: #ifdef _Windows
                    343: HGLOBAL hGlobal = GlobalHandle(SELECTOROF(p));
                    344:        GlobalUnlock(hGlobal);
                    345:        GlobalFree(hGlobal);
                    346: #else
                    347:        farfree(p);
                    348: #endif
                    349: }
                    350: #endif

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>