X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/disorder/blobdiff_plain/320598d40fb55001274c097d4a1a09c31b8d0335..ff56519f303d58db08eadf5e36356afcc27234fc:/lib/mem.c diff --git a/lib/mem.c b/lib/mem.c index c2dd40c..22b7228 100644 --- a/lib/mem.c +++ b/lib/mem.c @@ -1,34 +1,30 @@ /* * This file is part of DisOrder. - * Copyright (C) 2004, 2005, 2006, 2007 Richard Kettlewell + * Copyright (C) 2004, 2005, 2006, 2007, 2009 Richard Kettlewell * - * This program is free software; you can redistribute it and/or modify + * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA + * along with this program. If not, see . + */ +/** @file lib/mem.c + * @brief Memory management */ -#include -#include "types.h" +#include "common.h" #if GC #include #endif #include -#include -#include -#include -#include #include "mem.h" #include "log.h" @@ -36,6 +32,10 @@ #include "disorder.h" +/** @brief Allocate and zero out + * @param n Number of bytes to allocate + * @return Pointer to allocated memory, or 0 + */ static void *malloc_and_zero(size_t n) { void *ptr = malloc(n); @@ -55,6 +55,12 @@ static void *(*do_malloc_atomic)(size_t) = malloc; static void (*do_free)(void *) = free; #endif +/** @brief Initialize memory management + * + * Must be called by all programs that use garbage collection. Define + * @c ${DISORDER_GC} to @c no to suppress use of the collector + * (e.g. for debugging purposes). + */ void mem_init(void) { #if GC const char *e; @@ -66,65 +72,140 @@ void mem_init(void) { do_free = free; } else { GC_init(); +#ifdef HAVE_GC_GET_ALL_INTERIOR_POINTERS + assert(GC_get_all_interior_pointers()); +#else assert(GC_all_interior_pointers); +#endif } #endif } +/** @brief Allocate memory + * @param n Bytes to allocate + * @return Pointer to allocated memory + * + * Terminates the process on error. The allocated memory is always + * 0-filled. + */ void *xmalloc(size_t n) { void *ptr; if(!(ptr = do_malloc(n)) && n) - fatal(errno, "error allocating memory"); + disorder_fatal(errno, "error allocating memory"); return ptr; } +/** @brief Reallocate memory + * @param ptr Block to reallocated + * @param n Bytes to allocate + * @return Pointer to allocated memory + * + * Terminates the process on error. It is NOT guaranteed that any + * additional memory allocated is 0-filled. + */ void *xrealloc(void *ptr, size_t n) { if(!(ptr = do_realloc(ptr, n)) && n) - fatal(errno, "error allocating memory"); + disorder_fatal(errno, "error allocating memory"); return ptr; } +/** @brief Allocate memory + * @param count Number of objects to allocate + * @param size Size of one object + * @return Pointer to allocated memory + * + * Terminates the process on error. The allocated memory is always + * 0-filled. + */ void *xcalloc(size_t count, size_t size) { if(count > SIZE_MAX / size) - fatal(0, "excessively large calloc"); + disorder_fatal(0, "excessively large calloc"); return xmalloc(count * size); } +/** @brief Allocate memory + * @param n Bytes to allocate + * @return Pointer to allocated memory + * + * Terminates the process on error. The allocated memory is not + * guaranteed to be 0-filled and is not suitable for storing pointers + * in. + */ void *xmalloc_noptr(size_t n) { void *ptr; if(!(ptr = do_malloc_atomic(n)) && n) - fatal(errno, "error allocating memory"); + disorder_fatal(errno, "error allocating memory"); return ptr; } +/** @brief Allocate memory + * @param count Number of objects to allocate + * @param size Size of one object + * @return Pointer to allocated memory + * + * Terminates the process on error. IMPORTANT: the allocated memory is NOT + * 0-filled (unlike @c calloc()). + */ +void *xcalloc_noptr(size_t count, size_t size) { + if(count > SIZE_MAX / size) + disorder_fatal(0, "excessively large calloc"); + return xmalloc_noptr(count * size); +} + +/** @brief Reallocate memory + * @param ptr Block to reallocated + * @param n Bytes to allocate + * @return Pointer to allocated memory + * + * Terminates the processf on error. It is NOT guaranteed that any + * additional memory allocated is 0-filled. The block must have been + * allocated with xmalloc_noptr() (or xrealloc_noptr()) initially. + */ void *xrealloc_noptr(void *ptr, size_t n) { if(ptr == 0) return xmalloc_noptr(n); if(!(ptr = do_realloc(ptr, n)) && n) - fatal(errno, "error allocating memory"); + disorder_fatal(errno, "error allocating memory"); return ptr; } +/** @brief Duplicate a string + * @param s String to copy + * @return New copy of string + * + * This uses the equivalent of xmalloc_noptr() to allocate the new string. + */ char *xstrdup(const char *s) { char *t; if(!(t = do_malloc_atomic(strlen(s) + 1))) - fatal(errno, "error allocating memory"); + disorder_fatal(errno, "error allocating memory"); return strcpy(t, s); } +/** @brief Duplicate a prefix of a string + * @param s String to copy + * @param n Prefix of string to copy + * @return New copy of string + * + * This uses the equivalent of xmalloc_noptr() to allocate the new string. + * @p n must not exceed the length of the string. + */ char *xstrndup(const char *s, size_t n) { char *t; if(!(t = do_malloc_atomic(n + 1))) - fatal(errno, "error allocating memory"); + disorder_fatal(errno, "error allocating memory"); memcpy(t, s, n); t[n] = 0; return t; } +/** @brief Free memory + * @param ptr Block to free or 0 + */ void xfree(void *ptr) { do_free(ptr); } @@ -133,5 +214,7 @@ void xfree(void *ptr) { Local Variables: c-basic-offset:2 comment-column:40 +fill-column:79 +indent-tabs-mode:nil End: */