Doxygen Generated Documentation of Ben-Jose Trainable SAT Solver Library
bj_mem.h
1 
2 
3 /*************************************************************
4 
5 This file is part of ben-jose.
6 
7 ben-jose is free software: you can redistribute it and/or modify
8 it under the terms of the version 3 of the GNU General Public
9 License as published by the Free Software Foundation.
10 
11 ben-jose is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with ben-jose. If not, see <http://www.gnu.org/licenses/>.
18 
19 ------------------------------------------------------------
20 
21 Copyright (C) 2007-2012, 2014-2016. QUIROGA BELTRAN, Jose Luis.
22 Id (cedula): 79523732 de Bogota - Colombia.
23 See https://github.com/joseluisquiroga/ben-jose
24 
25 ben-jose is free software thanks to The Glory of Our Lord
26  Yashua Melej Hamashiaj.
27 Our Resurrected and Living, both in Body and Spirit,
28  Prince of Peace.
29 
30 ------------------------------------------------------------
31 
32 bj_mem.h
33 
34 Declaration of mem trace funcs and other.
35 
36 --------------------------------------------------------------*/
37 
38 #ifndef JLQ_MEM_H
39 #define JLQ_MEM_H
40 
41 #include <cstring>
42 #include <cstdlib>
43 
44 #include "platform.h"
45 #include "top_exception.h"
46 #include "bj_stream.h"
47 
48 
49 #define NULL_PT NULL
50 
51 template <bool> struct ILLEGAL_USE_OF_OBJECT;
52 template <> struct ILLEGAL_USE_OF_OBJECT<true>{};
53 #define OBJECT_COPY_ERROR ILLEGAL_USE_OF_OBJECT<false>()
54 
55 //======================================================================
56 // Using debug with pt_dir
57 
58 #if defined(FULL_DEBUG) && defined(DBG_GLB_MEM_USE) && defined(DBG_GLB_MEM_WITH_PT_DIR)
59 #define DBG_USING_PT_DIR
60 #endif
61 
62 #ifdef DBG_USING_PT_DIR
63 #define MEM_PT_DIR(prm) prm
64 #else
65 #define MEM_PT_DIR(prm)
66 #endif
67 
68 #ifdef DBG_USING_PT_DIR
69 extern bool dbg_keeping_ptdir;
70 
71 void dbg_add_to_ptdir(void* pt_val);
72 void dbg_del_from_ptdir(void* pt_val);
73 void dbg_print_ptdir();
74 #endif
75 
76 //======================================================================
77 // Assert related
78 
79 bool
80 call_assert(bool vv_ck, const char* file, int line,
81  const char* ck_str, const char* msg = NULL_PT);
82 
83 
84 inline
85 void* bj_memcpy(void *dest, const void *src, size_t n){
86  return memcpy(dest, src, n);
87 }
88 
89 inline
90 void* bj_memset(void *s, int c, size_t n){
91  return memset(s, c, n);
92 }
93 
94 #define glb_assert(vv) call_assert(vv, as_pt_char(__FILE__), __LINE__, as_pt_char(#vv))
95 
96 #define glb_assert_2(vv, ostmsg) \
97  call_assert(vv, as_pt_char(__FILE__), __LINE__, as_pt_char(#vv), (ostmsg))
98 
99 //--end_of_def
100 
101 #define DBG_COND_COMM(cond, comm) \
102  DBG( \
103  if(cond){ \
104  bj_ostream& os = bj_dbg; \
105  comm; \
106  os << bj_eol; \
107  os.flush(); \
108  } \
109  ) \
110 
111 //--end_of_def
112 
113 #define DBG_CK(prm) DBG(glb_assert(prm))
114 
115 #define DBG_CK_2(prm, comms1) \
116  DBG_COND_COMM((! (prm)), \
117  comms1; \
118  os << bj_eol; \
119  os.flush(); \
120  glb_assert(prm); \
121  ) \
122 
123 //--end_of_def
124 
125 
126 #define DBG_THROW(prm) DBG(prm)
127 //define DBG_THROW(prm) ;
128 #define DBG_THROW_CK(prm) DBG_CK(prm)
129 //define DBG_THROW_CK(prm) ;
130 
131 //======================================================================
132 // MEM_CTRL and SECURE_MEM
133 
134 // DO NOT use DBG_GLB_MEM_USE in concurrent apps
135 
136 #if defined(FULL_DEBUG) && defined(DBG_GLB_MEM_USE)
137 #define MEM_CTRL(prm) prm
138 #else
139 #define MEM_CTRL(prm)
140 #endif
141 
142 #ifdef SECURE_MEM
143 #define MEM_SRTY(prm) prm
144 #else
145 #define MEM_SRTY(prm) ;
146 #endif
147 
148 /*
149 include "stack_trace.h"
150 define DBG_TPL_ALLOC() \
151  DBG_COND_COMM(true, os << STACK_STR << "the_size=" << the_size << bj_eol)
152 
153 end_of_def
154 */
155 
156 #define DBG_TPL_ALLOC()
157 
158 //======================================================================
159 // other defs
160 
161 enum dbg_call_id {
162  dbg_call_1 = 201,
163  dbg_call_2,
164  dbg_call_3,
165  dbg_call_4,
166  dbg_call_5,
167  dbg_call_6,
168  dbg_call_7,
169  dbg_call_8,
170  dbg_call_9,
171  dbg_call_10,
172 };
173 
174 
175 typedef long error_code_t;
176 typedef unsigned long mem_size;
177 typedef char t_1byte;
178 typedef unsigned int t_4byte;
179 typedef t_4byte t_dword;
180 
181 #define MAX_UTYPE(type) ((type)(-1))
182 
183 #define MAX_MEM_SZ MAX_UTYPE(mem_size)
184 
185 //======================================================================
186 // mem_exception
187 
188 typedef enum {
189  mex_memout_in_mem_alloc_1,
190  mex_memout_in_mem_alloc_2,
191  mex_memout_in_mem_sec_re_alloc_1,
192  mex_memout_in_mem_re_alloc_1,
193  mex_memout_in_mem_re_alloc_2
194 } mem_ex_cod_t;
195 
196 
197 class mem_exception : public top_exception {
198 public:
199  mem_exception(long the_id = 0) : top_exception(the_id)
200  {}
201 };
202 
203 //======================================================================
204 // glb_mem_data
205 
206 #define MEM_CK(prm) MEM_CTRL(if(glb_pt_mem_stat != NULL){DBG_CK(prm);})
207 
208 #if defined(FULL_DEBUG) && defined(DBG_GLB_MEM_USE)
209 
210 class glb_mem_data;
211 
212 extern glb_mem_data* glb_pt_mem_stat;
213 extern glb_mem_data MEM_STATS;
214 
215 class glb_mem_data {
216 public:
217 
218  mem_size num_bytes_in_use;
219  mem_size num_bytes_available;
220 
221  glb_mem_data(){
222  num_bytes_in_use = 0;
223  num_bytes_available = 0;
224  }
225 
226  ~glb_mem_data(){
227  }
228 };
229 
230 inline
231 void
232 mem_start_stats(){
233  if(glb_pt_mem_stat != NULL){
234  abort_func(0);
235  }
236  glb_pt_mem_stat = &MEM_STATS;
237  MEM_CK(glb_pt_mem_stat->num_bytes_in_use == 0);
238 }
239 
240 inline
241 void
242 mem_finish_stats(){
243  if(glb_pt_mem_stat == NULL){
244  abort_func(0);
245  }
246  MEM_CK(glb_pt_mem_stat->num_bytes_in_use == 0);
247  glb_pt_mem_stat = NULL_PT;
248 }
249 
250 inline
251 mem_size
252 mem_get_num_by_in_use(){
253  if(glb_pt_mem_stat == NULL_PT){
254  return 0;
255  }
256  return glb_pt_mem_stat->num_bytes_in_use;
257 }
258 
259 inline
260 void
261 mem_inc_num_by_in_use(mem_size val){
262  if(glb_pt_mem_stat == NULL_PT){
263  return;
264  }
265  glb_pt_mem_stat->num_bytes_in_use += val;
266 }
267 
268 inline
269 void
270 mem_dec_num_by_in_use(mem_size val){
271  if(glb_pt_mem_stat == NULL_PT){
272  return;
273  }
274  glb_pt_mem_stat->num_bytes_in_use -= val;
275 }
276 
277 inline
278 mem_size
279 mem_get_num_by_available(){
280  if(glb_pt_mem_stat == NULL_PT){
281  return 0;
282  }
283  return glb_pt_mem_stat->num_bytes_available;
284 }
285 
286 inline
287 void
288 mem_set_num_by_available(mem_size val){
289  if(glb_pt_mem_stat == NULL_PT){
290  return;
291  }
292  glb_pt_mem_stat->num_bytes_available = val;
293 }
294 
295 #endif
296 
297 //======================================================================
298 // 'mem_alloc()'-style memory allocation -- never returns NULL_PT; aborts instead:
299 
300 template<class obj_t> static inline obj_t*
301 tpl_malloc(size_t the_size = 1){
302  DBG_TPL_ALLOC();
303  mem_size mem_sz = the_size * sizeof(obj_t);
304  MEM_CTRL(
305  MEM_CK((MAX_MEM_SZ - mem_sz) > mem_get_num_by_in_use());
306  mem_inc_num_by_in_use(mem_sz);
307 
308  if( (mem_get_num_by_available() > 0) &&
309  (mem_get_num_by_in_use() > mem_get_num_by_available()) )
310  {
311  throw mem_exception(mex_memout_in_mem_alloc_1);
312  }
313  );
314 
315  obj_t* tmp = (obj_t*)malloc(mem_sz);
316  if((tmp == NULL_PT) && (the_size != 0)){
317  throw mem_exception(mex_memout_in_mem_alloc_2);
318  }
319  MEM_PT_DIR(dbg_add_to_ptdir(tmp));
320  return tmp;
321 }
322 
323 template<class obj_t> static inline obj_t*
324 tpl_secure_realloc(obj_t* ptr, size_t old_size, size_t the_size){
325  DBG_TPL_ALLOC();
326  MEM_CK(the_size > old_size);
327 
328  mem_size mem_sz = the_size * sizeof(obj_t);
329  obj_t* tmp = (obj_t*)malloc(mem_sz);
330  if((tmp == NULL_PT) && (the_size != 0)){
331  throw mem_exception(mex_memout_in_mem_sec_re_alloc_1);
332  }
333  MEM_PT_DIR(dbg_add_to_ptdir(tmp));
334 
335  if(ptr != NULL_PT){
336  mem_size old_mem_sz = old_size * sizeof(obj_t);
337  bj_memcpy(tmp, ptr, old_mem_sz);
338  bj_memset(ptr, 0, old_mem_sz);
339  free(ptr);
340  MEM_PT_DIR(dbg_del_from_ptdir(ptr));
341  }
342  return tmp;
343 }
344 
345 template<class obj_t> static inline obj_t*
346 tpl_realloc(obj_t* ptr, size_t old_size, size_t the_size){
347  DBG_TPL_ALLOC();
348  mem_size mem_sz = the_size * sizeof(obj_t);
349  MEM_CTRL(
350  mem_size old_mem_sz = old_size * sizeof(obj_t);
351  MEM_CK(mem_get_num_by_in_use() >= old_mem_sz);
352  mem_dec_num_by_in_use(old_mem_sz);
353  MEM_CK((MAX_MEM_SZ - mem_sz) > mem_get_num_by_in_use());
354  mem_inc_num_by_in_use(mem_sz);
355 
356  if( (mem_get_num_by_available() > 0) &&
357  (mem_get_num_by_in_use() > mem_get_num_by_available()) )
358  {
359  throw mem_exception(mex_memout_in_mem_re_alloc_1);
360  }
361  );
362  MEM_PT_DIR(dbg_del_from_ptdir(ptr));
363  obj_t* tmp = (obj_t*)realloc((void*)ptr, mem_sz);
364  if((tmp == NULL_PT) && (the_size != 0)){
365  throw mem_exception(mex_memout_in_mem_re_alloc_2);
366  }
367  MEM_PT_DIR(dbg_add_to_ptdir(tmp));
368  return tmp;
369 }
370 
371 template<class obj_t> static inline void
372 tpl_free(obj_t*& ptr, size_t the_size = 1){
373  DBG_TPL_ALLOC();
374  if(ptr != NULL_PT){
375  MEM_SRTY(
376  mem_size s_old_mem_sz = the_size * sizeof(obj_t);
377  );
378  free(ptr);
379  MEM_PT_DIR(dbg_del_from_ptdir(ptr));
380  ptr = NULL_PT;
381  }
382  MEM_CTRL(
383  mem_size old_mem_sz = the_size * sizeof(obj_t);
384  MEM_CK(mem_get_num_by_in_use() >= old_mem_sz);
385  mem_dec_num_by_in_use(old_mem_sz);
386  );
387 }
388 
389 
390 
391 
392 #endif // JLQ_MEM_H
393 
394