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