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 "eg_config.h" 00055 #include "eg_macros.h" 00056 00057 /* ========================================================================= */ 00058 /** @brief size of a normal word in this machine (a word is just big enough to 00059 * store a pointer) */ 00060 #define EG_MEM_WORD_SIZE (sizeof(void*)) 00061 /* ========================================================================= */ 00062 /** @brief memory aligment used by EG alloc functions. */ 00063 #define EG_MEM_ALIGNMENT 8U 00064 00065 /* ========================================================================= */ 00066 /** @brief \f$log_2(EG_MEM_ALIGNMENT)\f$. */ 00067 #define EG_MEM_ALIGNMENT_SHIFT 3U 00068 00069 /* ========================================================================= */ 00070 /** @brief Given a pointer, return it's aligned value. */ 00071 #define EG_MEM_ALIGN(__ptr) \ 00072 ((((size_t)__ptr)+EG_MEM_ALIGNMENT-1)&(~(EG_MEM_ALIGNMENT-1))) 00073 00074 /* ========================================================================= */ 00075 /** @brief type of the free functions that recive only one parameter */ 00076 typedef void (*EGfree_f) (void *); 00077 00078 /* ========================================================================= */ 00079 /** @brief this is the the data free that does nothing, use it when you don't 00080 * want/need to free the internal list data becouse you will do it 00081 * elsewere */ 00082 #define nullFree ((EGfree_f)0) 00083 00084 /* ========================================================================= */ 00085 /** @brief custom allocation functions prototype: This class of functions 00086 * receive some user-provided data (udata), and given a size (psz), return a pointer of the given size */ 00087 typedef void*(*EGualloc_f)(void*udata,size_t psz); 00088 00089 /* ========================================================================= */ 00090 /** @brief custom free functions prototype: This class of functions receive 00091 * some user-provided data (udata), and a pointer (ptr), and should free (or 00092 * manage de-alocation) of the provided pointer. */ 00093 typedef void (*EGufree_f)(void*udata,void*ptr); 00094 00095 /* ========================================================================= */ 00096 /** @brief type for constructor functions. Given a pointer to an element of 00097 * some type, do the internal initialization necesary so that we can work with 00098 * the lement, such initialization may include allocating some internal memory 00099 * needed by the structure (not done by the user). This functions must never 00100 * fail. if some unexpected error does happen inside, then the function should 00101 * not return. (a call to exit(1) would do the trick). */ 00102 typedef void (*EGconstructor_f) (void *); 00103 00104 /* ========================================================================= */ 00105 /** @brief Null constructor function (do nothing) */ 00106 #define nullConstructor ((EGconstructor_f)0) 00107 00108 /* ========================================================================= */ 00109 /** @brief type for destructor functions. Given a pointer to an element of some 00110 * type, free all internal memory related to the element allocated during the 00111 * construction phase. (but not the pointer itself). This function must always 00112 * succed, if an error happen, the function should never return. (a call to 00113 * exit(1) would do the trick). */ 00114 typedef void (*EGdestructor_f) (void *); 00115 00116 /* ========================================================================= */ 00117 /** @brief Null destructor function (do nothing) */ 00118 #define nullDestructor ((EGdestructor_f)0) 00119 00120 /* ========================================================================= */ 00121 /** @brief this function replace malloc, check if the memory is not zero, if 00122 * it is, it exit from the program, and display who called it and how much 00123 * memory it tryed to alloc. 00124 * @param __A number of bytes to allocate. 00125 * @return a void* pointer to the newly allocated memory, note that if the 00126 * function returns at all, it will return with the amount of memory required, 00127 * so no NULL checking is ever necesary after an EGmalloc call. 00128 * */ 00129 #define EGmalloc(__A) ({\ 00130 size_t const _EGmp_sz_ = (size_t)(__A);\ 00131 void * _EGmp_res_ = 0;\ 00132 /*WARNINGL(0,!_EGmp_sz_,"Allocating 0 bytes");*/\ 00133 if(_EGmp_sz_)\ 00134 {\ 00135 _EGmp_res_ = calloc((size_t)1,_EGmp_sz_);\ 00136 EXIT(!_EGmp_res_,"Not enough memory while allocating %zd bytes",_EGmp_sz_);\ 00137 }\ 00138 _EGmp_res_;}) 00139 00140 /* ========================================================================= */ 00141 /** @brief This function allocate 'count' elements of type 'type' and return 00142 * a pointer of type 'type*'. If the memory is not available the program will 00143 * exit indicating where it was trying to get memory and how much, it will also 00144 * check some common errors like allocating zero bytes. 00145 * @param __type type of the element required. 00146 * @param __count number of contiguous elements of the given type required. 00147 * @return pointer to the beggining of the allocated array of the apropiate 00148 * type (so no casting is needed). Note that if this function returns at all, 00149 * then the memory has been allocated and thus no NULL checking return is 00150 * necesary. */ 00151 #define EGsMalloc(__type,__count) (__type*)EGmalloc(sizeof(__type)*((size_t)(__count))) 00152 00153 /* ========================================================================= */ 00154 /** @brief Realloc a given pointer to the new size, and check that we find 00155 * enough memory to return. If we don't, we exit the execution. 00156 * @param __ptr pointer to reallocate. 00157 * @param __sz new number of bytes to reallocate. 00158 * @return pointer to the new block of memory */ 00159 #define EGrealloc(__ptr,__sz) ({\ 00160 const size_t ____sz = (size_t)(__sz);\ 00161 (__ptr) = realloc((__ptr),____sz);\ 00162 EXIT(!(__ptr)&&(____sz),"not enough memory while reallocating %zd",____sz);\ 00163 (__ptr);}) 00164 00165 /* ========================================================================= */ 00166 /** @brief this is used to enable malloc/free tracking and extra debugging */ 00167 #ifndef __EG_MEM_FREE_CHECK__ 00168 #define __EG_MEM_FREE_CHECK__ (1 && DEBUG) 00169 #endif 00170 00171 /* ========================================================================= */ 00172 /** @brief This function replace free, the idea of this is to HOPEFULLY later 00173 * develop a memory leack checker that tell us who and where asked for memory 00174 * and didn't free it, in hte meantime they do nothing. 00175 * @param __A pointer to the piece of memory to be freed, if debuging is enabled, 00176 * the function will test for freing NULL pointers, for suspicios address 00177 * freing and so on. note that the given pointer will point to NULL after this 00178 * call, thus reducing the posibility of freeing multiple times the same piece 00179 * of memory, or of allocating it after freeing it. */ 00180 #if __EG_MEM_FREE_CHECK__ 00181 #define EGfree(__A) ({\ 00182 EXIT(((__A) && !(((size_t)(__A))>>19)),"Trying to free pointer "#__A\ 00183 " with value %zd\nThis is probably an error",(size_t)(__A));\ 00184 if(__A) free(__A);\ 00185 else WARNING(1,"Trying to free "#__A", a NULL pointer");\ 00186 (__A) = 0;}) 00187 #else 00188 #define EGfree(__A) ({free(__A);(__A)=0;}) 00189 #endif 00190 00191 /* ========================================================================= */ 00192 /* end of eg_mem.h */ 00193 /** @} */ 00194 #endif
1.7.1