eg_mem.h

Go to the documentation of this file.
00001 /* EGlib "Efficient General Library" provides some basic structures and
00002  * algorithms commons in many optimization algorithms.
00003  *
00004  * Copyright (C) 2005 Daniel Espinoza and Marcos Goycoolea.
00005  * 
00006  * This library is free software; you can redistribute it and/or modify it
00007  * under the terms of the GNU Lesser General Public License as published by the
00008  * Free Software Foundation; either version 2.1 of the License, or (at your
00009  * option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful, but 
00012  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
00013  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
00014  * License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public License
00017  * along with this library; if not, write to the Free Software Foundation,
00018  * Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA 
00019  * */
00020 /* ========================================================================= */
00021 /** @defgroup EGmem EGmem
00022  *
00023  * Here we define some usefull macros to deal with memory issues, for example,
00024  * assert that we always return memory when posible, and if no memory is found,
00025  * then we just exit to the system (because if there is trully no memory....
00026  * there is no much else to do... unless we start using shrinkable memory
00027  * pools, like for example @ref EGmemSlab , but that is still a long way off,
00028  * it will also perform (if debugging enabled) some allocation / freeing
00029  * checkings and so on.
00030  *
00031  * @version 0.0.1
00032  * @par History:
00033  * -2005-09-05
00034  *          - Add EGrealloc, wich is a wrapper of realloc but that assures us
00035  *          to have memory, if there is no  memory, we exit. The idea of these
00036  *          functions is that in the future they would interact with the
00037  *          memory pools to use any memory still in the pools.
00038  * -2005-08-20
00039  *          - Move memory align definitions here, and set the aligment of
00040  *            memory to 8 bytes (i.e. 64 bits). This is to simplify compilation
00041  *            in diferent architectures like Sun, opteron 64 and intel 32.
00042  * -2005-08-01
00043  *          - Fix calloc call to the right type (size_t), and some printing
00044  *            issues while compiling on 64-bit architectures.
00045  * -2005-07-30
00046  *          - First Implementation
00047  * */
00048 /** @file
00049  * @ingroup EGmem */
00050 /** @addtogroup EGmem */
00051 /** @{ */
00052 #ifndef __EG_MEM_H__
00053 #define __EG_MEM_H__
00054 #include <unistd.h>
00055 #include <string.h>
00056 #include <strings.h>
00057 #include "eg_macros.h"
00058 
00059 /* ========================================================================= */
00060 /** @brief size of a normal word in this machine (a word is just big enough to
00061  * store a pointer) */
00062 #define EG_MEM_WORD_SIZE (sizeof(void*))
00063 /* ========================================================================= */
00064 /** @brief memory aligment used by EG alloc functions. */
00065 #define EG_MEM_ALIGNMENT 8U
00066 
00067 /* ========================================================================= */
00068 /** @brief \f$log_2(EG_MEM_ALIGNMENT)\f$. */
00069 #define EG_MEM_ALIGNMENT_SHIFT 3U
00070 
00071 /* ========================================================================= */
00072 /** @brief Given a pointer, return it's aligned value. */
00073 #define EG_MEM_ALIGN(ptr) \
00074   ((((size_t)ptr)+EG_MEM_ALIGNMENT-1)&(~(EG_MEM_ALIGNMENT-1)))
00075 
00076 /* ========================================================================= */
00077 /** @brief type of the free functions that recive only one parameter */
00078 typedef void (*EGfree_f) (void *);
00079 
00080 /* ========================================================================= */
00081 /** @brief this is the the data free that does nothing, use it when you don't 
00082  * want/need to free the internal list data becouse you will do it 
00083  * elsewere */
00084 #define nullFree ((EGfree_f)0)
00085 
00086 /* ========================================================================= */
00087 /** @brief type for constructor functions. Given a pointer to an element of
00088  * some type, do the internal initialization necesary so that we can work with
00089  * the lement, such initialization may include allocating some internal memory
00090  * needed by the structure (not done by the user). This functions must never
00091  * fail. if some unexpected error does happen inside, then the function should
00092  * not return. (a call to exit(1) would do the trick). */
00093 typedef void (*EGconstructor_f) (void *);
00094 
00095 /* ========================================================================= */
00096 /** @brief Null constructor function (do nothing) */
00097 #define nullConstructor ((EGconstructor_f)0)
00098 
00099 /* ========================================================================= */
00100 /** @brief type for destructor functions. Given a pointer to an element of some
00101  * type, free all internal memory related to the element allocated during the
00102  * construction phase. (but not the pointer itself). This function must always
00103  * succed, if an error happen, the function should never return. (a call to
00104  * exit(1) would do the trick). */
00105 typedef void (*EGdestructor_f) (void *);
00106 
00107 /* ========================================================================= */
00108 /** @brief Null destructor function (do nothing) */
00109 #define nullDestructor ((EGdestructor_f)0)
00110 
00111 /* ========================================================================= */
00112 /** @brief this function replace malloc, check if the memory is not zero, if 
00113  * it is, it exit from the program, and display who called it and how much 
00114  * memory it tryed to alloc.
00115  * @param A number of bytes to allocate.
00116  * @return a void* pointer to the newly allocated memory, note that if the 
00117  * function returns at all, it will return with the amount of memory required, 
00118  * so no NULL checking is ever necesary after an EGmalloc call. 
00119  * */
00120 #define EGmalloc(A) ({\
00121   size_t const _EGmp_sz_ = (A);\
00122   void * _EGmp_res_ = 0;\
00123   /*WARNINGL(0,!_EGmp_sz_,"Allocating 0 bytes");*/\
00124   if(_EGmp_sz_)\
00125   {\
00126     _EGmp_res_ = calloc((size_t)1,_EGmp_sz_);\
00127     EXIT(!_EGmp_res_,"Not enough memory while allocating %zd bytes",_EGmp_sz_);\
00128   }\
00129   _EGmp_res_;})
00130 
00131 /* ========================================================================= */
00132 /** @brief This function allocate 'count' elements of type 'type' and return 
00133  * a pointer of type 'type*'. If the memory is not available the program will 
00134  * exit indicating where it was trying to get memory and how much, it will also
00135  * check some common errors like allocating zero bytes.
00136  * @param type type of the element required.
00137  * @param count number of contiguous elements of the given type required.
00138  * @return pointer to the beggining of the allocated array of the apropiate
00139  * type (so no casting is needed). Note that if this function returns at all,
00140  * then the memory has been allocated and thus no NULL checking return is
00141  * necesary. */
00142 #define EGsMalloc(type,count) (type*)EGmalloc(sizeof(type)*(count))
00143 
00144 /* ========================================================================= */
00145 /** @brief Realloc a given pointer to the new size, and check that we find
00146  * enough memory to return. If we don't, we exit the execution.
00147  * @param __ptr pointer to reallocate.
00148  * @param __sz new number of bytes to reallocate.
00149  * @return pointer to the new block of memory */
00150 #define EGrealloc(__ptr,__sz) ({\
00151   const size_t ____sz = (size_t)(__sz);\
00152   (__ptr) = realloc((__ptr),____sz);\
00153   EXIT(!(__ptr)&&(____sz),"not enough memory while reallocating %zd",____sz);\
00154   (__ptr);})
00155 
00156 /* ========================================================================= */
00157 /** @brief this is used to enable malloc/free tracking and extra debugging */
00158 #ifndef __EG_MEM_FREE_CHECK__
00159 #define __EG_MEM_FREE_CHECK__  (1 && DEBUG)
00160 #endif
00161 
00162 /* ========================================================================= */
00163 /** @brief This function replace free, the idea of this is to HOPEFULLY later 
00164  * develop a memory leack checker that tell us who and where asked for memory 
00165  * and didn't free it, in hte meantime they do nothing.
00166  * @param A pointer to the piece of memory to be freed, if debuging is enabled,
00167  * the function will test for freing NULL pointers, for suspicios address
00168  * freing and so on. note that the given pointer will point to NULL after this
00169  * call, thus reducing the posibility of freeing multiple times the same piece
00170  * of memory, or of allocating it after freeing it. */
00171 #if __EG_MEM_FREE_CHECK__
00172 #define EGfree(A) ({\
00173     EXIT(((A) && !(((size_t)(A))>>19)),"Trying to free pointer "#A\
00174         " with value %zd\nThis is probably an error",(size_t)(A));\
00175     if(A) free(A);\
00176     else WARNING(1,"Trying to free "#A", a NULL pointer");\
00177     (A) = 0;})
00178 #else
00179 #define EGfree(A) ({free(A);(A)=0;})
00180 #endif
00181 
00182 /* ========================================================================= */
00183 /* end of eg_mem.h */
00184 /** @} */
00185 #endif

Generated on Wed Nov 21 09:38:13 2007 for MTgomory by  doxygen 1.4.6