PageRenderTime 13ms CodeModel.GetById 1ms app.highlight 10ms RepoModel.GetById 1ms app.codeStats 0ms

/src/common/xmalloc.c

https://code.google.com/
C | 153 lines | 82 code | 18 blank | 53 comment | 14 complexity | e025446b7169135f6400e6fb1c74426e MD5 | raw file
  1/*****************************************************************************\
  2 *  $Id$
  3 *****************************************************************************
  4 *  Copyright (C) 2001-2006 The Regents of the University of California.
  5 *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
  6 *  Written by Jim Garlick <garlick@llnl.gov>.
  7 *  UCRL-CODE-2003-005.
  8 *  
  9 *  This file is part of Pdsh, a parallel remote shell program.
 10 *  For details, see <http://www.llnl.gov/linux/pdsh/>.
 11 *  
 12 *  Pdsh is free software; you can redistribute it and/or modify it under
 13 *  the terms of the GNU General Public License as published by the Free
 14 *  Software Foundation; either version 2 of the License, or (at your option)
 15 *  any later version.
 16 *  
 17 *  Pdsh is distributed in the hope that it will be useful, but WITHOUT ANY
 18 *  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 19 *  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 20 *  details.
 21 *  
 22 *  You should have received a copy of the GNU General Public License along
 23 *  with Pdsh; if not, write to the Free Software Foundation, Inc.,
 24 *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
 25\*****************************************************************************/
 26
 27#if     HAVE_CONFIG_H
 28#include "config.h"
 29#endif
 30
 31#include <stdlib.h>
 32#include <errno.h>
 33#include <string.h>
 34#include <stdio.h>
 35#include <limits.h>             /* for INT_MAX */
 36#include <assert.h>
 37
 38#include "xmalloc.h"
 39
 40#if	HAVE_UNSAFE_MALLOC
 41#include <pthread.h>
 42static pthread_mutex_t malloc_lock = PTHREAD_MUTEX_INITIALIZER;
 43#define MALLOC_LOCK()	pthread_mutex_lock(&malloc_lock)
 44#define MALLOC_UNLOCK()	pthread_mutex_unlock(&malloc_lock)
 45#else
 46#define MALLOC_LOCK()
 47#define MALLOC_UNLOCK()
 48#endif
 49
 50/*
 51 * "Safe" version of malloc().
 52 *   size (IN)	number of bytes to malloc
 53 *   RETURN	pointer to allocate heap space
 54 */
 55void *Malloc(size_t size)
 56{
 57    void *new;
 58    int *p;
 59
 60    assert(size > 0 && size <= INT_MAX);
 61    MALLOC_LOCK();
 62    p = (int *) malloc(size + 2 * sizeof(int));
 63    MALLOC_UNLOCK();
 64    if (!p) {
 65        fprintf(stderr, "Malloc(%ld) failed\n", (long) size);
 66        exit(1);
 67    }
 68    p[0] = XMALLOC_MAGIC;       /* add "secret" magic cookie */
 69    p[1] = size;                /* store size in buffer */
 70
 71    new = &p[2];
 72    memset(new, 0, size);
 73    return new;
 74}
 75
 76/* 
 77 * "Safe" version of realloc().  Args are different: pass in a pointer to
 78 * the object to be realloced instead of the object itself.
 79 *   item (IN/OUT)	double-pointer to allocated space
 80 *   newsize (IN)	requested size
 81 */
 82void Realloc(void **item, size_t newsize)
 83{
 84    int *p = (int *) *item - 2;
 85
 86    assert(*item != NULL);
 87    assert(newsize > 0 && newsize <= INT_MAX);
 88    assert(p[0] == XMALLOC_MAGIC);      /* magic cookie still there? */
 89
 90    MALLOC_LOCK();
 91    p = (int *) realloc(p, newsize + 2 * sizeof(int));
 92    MALLOC_UNLOCK();
 93    if (!p) {
 94        fprintf(stderr, "Realloc(%ld) failed\n", (long) newsize);
 95        exit(1);
 96    }
 97    assert(p[0] == XMALLOC_MAGIC);
 98    p[1] = newsize;
 99    *item = &p[2];
100}
101
102/*
103 * Duplicate a string.
104 *   str (IN)		string to duplicate
105 *   RETURN		copy of string
106 */
107char *Strdup(const char *str)
108{
109    char *result;
110
111    if (str == NULL)
112        return NULL;
113    else
114        result = Malloc(strlen(str) + 1);
115
116    return strcpy(result, str);
117}
118
119/*
120 * Return the size of a buffer.
121 *   item (IN)		pointer to allocated space
122 */
123int Size(void *item)
124{
125    int *p = (int *) item - 2;
126
127    assert(item != NULL);
128    assert(p[0] == XMALLOC_MAGIC);
129    return p[1];
130}
131
132/* 
133 * Free which takes a pointer to object to free, which it turns into a null
134 * object.
135 *   item (IN/OUT)	double-pointer to allocated space
136 */
137void Free(void **item)
138{
139    int *p = (int *) *item - 2;
140
141    if (*item != NULL) {
142        assert(p[0] == XMALLOC_MAGIC);  /* magic cookie still there? */
143        p[0] = 0;
144        MALLOC_LOCK();
145        free(p);
146        MALLOC_UNLOCK();
147        *item = NULL;
148    }
149}
150
151/*
152 * vi:tabstop=4 shiftwidth=4 expandtab
153 */