1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386
|
/*
* Dkpool.h
*
* $Id$
*
* Temp memory pool for objects that should be allocated one by one but freed
* together.
*
* This file is part of the OpenLink Software Virtuoso Open-Source (VOS)
* project.
*
* Copyright (C) 1998-2012 OpenLink Software
*
* This project 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; only version 2 of the License, dated June 1991.
*
* 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.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef __DKPOOL_H
#define __DKPOOL_H
#include <stdio.h>
void mp_free (mem_pool_t * mp);
#ifdef VALGRIND
#define LACERATED_POOL
#endif
#ifdef MALLOC_DEBUG
#define LACERATED_POOL
#endif
#ifdef LACERATED_POOL
struct mem_pool_s
{
int mp_fill;
int mp_size;
caddr_t * mp_allocs;
size_t mp_bytes;
dk_hash_t * mp_unames;
dk_set_t mp_trash; /* dk_alloc_box boxes that must be freed with the mp */
#if defined (DEBUG) || defined (MALLOC_DEBUG)
const char * mp_alloc_file;
int mp_alloc_line;
#endif
#ifdef MALLOC_DEBUG
const char * mp_list_alloc_file;
int mp_list_alloc_line;
#endif
};
#else
struct mem_block_s
{
struct mem_block_s * mb_next;
size_t mb_fill;
size_t mb_size;
};
typedef struct mem_block_s mem_block_t;
struct mem_pool_s
{
mem_block_t * mp_first;
int mp_block_size;
size_t mp_bytes;
dk_hash_t * mp_unames;
dk_set_t mp_trash;
#if defined (DEBUG) || defined (MALLOC_DEBUG)
const char * mp_alloc_file;
int mp_alloc_line;
#endif
};
#endif
#if defined (DEBUG) || defined (MALLOC_DEBUG)
extern mem_pool_t *dbg_mem_pool_alloc (const char *file, int line);
#define mem_pool_alloc() dbg_mem_pool_alloc (__FILE__, __LINE__)
#else
extern mem_pool_t *mem_pool_alloc (void);
#endif
#ifdef MALLOC_DEBUG
extern caddr_t dbg_mp_alloc_box (const char *file, int line, mem_pool_t * mp, size_t len, dtp_t dtp);
extern caddr_t dbg_mp_box_string (const char *file, int line, mem_pool_t * mp, const char *str);
extern caddr_t dbg_mp_box_substr (const char *file, int line, mem_pool_t * mp, ccaddr_t str, int n1, int n2);
extern box_t dbg_mp_box_dv_short_nchars (const char *file, int line, mem_pool_t * mp, const char *str, size_t len);
extern caddr_t dbg_mp_box_dv_uname_string (const char *file, int line, mem_pool_t * mp, const char *str);
extern box_t dbg_mp_box_dv_uname_nchars (const char *file, int line, mem_pool_t * mp, const char *str, size_t len);
extern caddr_t dbg_mp_box_copy (const char *file, int line, mem_pool_t * mp, caddr_t box);
extern caddr_t dbg_mp_box_copy_tree (const char *file, int line, mem_pool_t * mp, caddr_t box);
extern caddr_t dbg_mp_full_box_copy_tree (const char *file, int line, mem_pool_t * mp, caddr_t box);
extern caddr_t dbg_mp_box_num (const char *file, int line, mem_pool_t * mp, boxint num);
#define mp_alloc_box(mp,len,dtp) dbg_mp_alloc_box (__FILE__, __LINE__, (mp), (len), (dtp))
#define mp_box_string(mp, str) dbg_mp_box_string (__FILE__, __LINE__, (mp), (str))
#define mp_box_substr(mp, str, n1, n2) dbg_mp_box_substr (__FILE__, __LINE__, (mp), (str), (n1), (n2))
#define mp_box_dv_short_nchars(mp, str, len) dbg_mp_box_dv_short_nchars (__FILE__, __LINE__, (mp), (str), (len))
#define mp_box_dv_uname_string(mp, str) dbg_mp_box_dv_uname_string (__FILE__, __LINE__, (mp), (str))
#define mp_box_dv_uname_nchars(mp, str, len) dbg_mp_box_dv_uname_nchars (__FILE__, __LINE__, (mp), (str), (len))
#define mp_box_copy(mp, box) dbg_mp_box_copy (__FILE__, __LINE__, (mp), (box))
#define mp_box_copy_tree(mp, box) dbg_mp_box_copy_tree (__FILE__, __LINE__, (mp), (box))
#define mp_full_box_copy_tree(mp, box) dbg_mp_full_box_copy_tree (__FILE__, __LINE__, (mp), (box))
#define mp_box_num(mp, num) dbg_mp_box_num (__FILE__, __LINE__, (mp), (num))
#else
extern caddr_t mp_alloc_box (mem_pool_t * mp, size_t len, dtp_t dtp);
extern caddr_t mp_box_string (mem_pool_t * mp, const char *str);
extern caddr_t mp_box_substr (mem_pool_t * mp, ccaddr_t str, int n1, int n2);
extern box_t mp_box_dv_short_nchars (mem_pool_t * mp, const char *str, size_t len);
extern caddr_t mp_box_dv_uname_string (mem_pool_t * mp, const char *str);
extern box_t mp_box_dv_uname_nchars (mem_pool_t * mp, const char *str, size_t len);
extern caddr_t mp_box_copy (mem_pool_t * mp, caddr_t box);
extern caddr_t mp_box_copy_tree (mem_pool_t * mp, caddr_t box);
extern caddr_t mp_full_box_copy_tree (mem_pool_t * mp, caddr_t box);
extern caddr_t mp_box_num (mem_pool_t * mp, boxint num);
#endif
#ifdef LACERATED_POOL
void mp_alloc_box_assert (mem_pool_t * mp, caddr_t box);
#else
#define mp_alloc_box_assert(mp,box) ;
#endif
caddr_t *mp_list (mem_pool_t * mp, long n, ...);
#define mp_alloc(mp, n) mp_alloc_box (mp, n, DV_CUSTOM)
#define THR_TMP_POOL ((mem_pool_t *) THREAD_CURRENT_THREAD->thr_tmp_pool)
#define SET_THR_TMP_POOL(v) (THREAD_CURRENT_THREAD->thr_tmp_pool = (void*) v)
#ifdef DEBUG /* Not MALLOC_DEBUG */
#define MP_START() \
do { \
mem_pool_t *thread_mem_pool = THR_TMP_POOL; \
if (thread_mem_pool != NULL) \
GPF_T1 ("MP reallocated"); \
SET_THR_TMP_POOL (dbg_mem_pool_alloc (__FILE__, __LINE__)); \
} while (0)
#else
#define MP_START() \
do { \
if (THR_TMP_POOL != NULL) \
GPF_T1 ("MP reallocated"); \
SET_THR_TMP_POOL (mem_pool_alloc ()); \
} while (0)
#endif
#define MP_DONE() \
do { \
mp_free (THR_TMP_POOL); \
SET_THR_TMP_POOL (NULL); \
} while (0)
#ifdef _DEBUG
#define mp_box_tag_modify_impl(box,new_tag) \
do { \
box_tag_aux((box)) = (new_tag); \
} while (0)
#else
#define mp_box_tag_modify_impl(box,new_tag) (box_tag_aux((box)) = (new_tag))
#endif
#ifdef MALLOC_DEBUG
#define mp_box_tag_modify(box,new_tag) \
do { \
if (DV_UNAME == new_tag) \
GPF_T1 ("Can't make UNAME by mp_box_tag_modify"); \
if (DV_UNAME == box_tag_aux(box)) \
GPF_T1 ("Can't alter UNAME by mp_box_tag_modify"); \
if (DV_REFERENCE == new_tag) \
GPF_T1 ("Can't make REFERENCE by mp_box_tag_modify"); \
if (DV_REFERENCE == box_tag_aux(box)) \
GPF_T1 ("Can't alter REFERENCE by mp_box_tag_modify"); \
if (TAG_FREE == new_tag) \
GPF_T1 ("Can't make TAG_FREE box by mp_box_tag_modify"); \
if (TAG_FREE == box_tag_aux(box)) \
GPF_T1 ("Can't alter TAG_FREE by mp_box_tag_modify"); \
if (TAG_BAD == new_tag) \
GPF_T1 ("Can't make TAG_BAD box by mp_box_tag_modify"); \
if (TAG_BAD == box_tag_aux(box)) \
GPF_T1 ("Can't alter TAG_BAD by mp_box_tag_modify"); \
mp_box_tag_modify_impl(box,new_tag); \
} while (0);
#else
#define mp_box_tag_modify(box,new_tag) mp_box_tag_modify_impl(box,new_tag)
#endif
#define dbg_t_alloc_box(len,dtp) dbg_mp_alloc_box (DBG_ARGS THR_TMP_POOL, (len), (dtp))
#define dbg_t_box_string(str) dbg_mp_box_string (DBG_ARGS THR_TMP_POOL, (str))
#define dbg_t_box_substr(str,n1,n2) dbg_mp_box_substr (DBG_ARGS THR_TMP_POOL, (str), (n1), (n2))
#define dbg_t_box_dv_short_nchars(str,len) dbg_mp_box_dv_short_nchars (DBG_ARGS THR_TMP_POOL, (str), (len))
#define dbg_t_box_dv_uname_string(str) dbg_mp_box_dv_uname_string (DBG_ARGS THR_TMP_POOL, (str))
#define dbg_t_box_dv_uname_nchars(str,len) dbg_mp_box_dv_uname_nchars (DBG_ARGS THR_TMP_POOL, (str), (len))
#define dbg_t_box_copy(box) dbg_mp_box_copy (DBG_ARGS THR_TMP_POOL, (box))
#define dbg_t_box_copy_tree(box) dbg_mp_box_copy_tree (DBG_ARGS THR_TMP_POOL, (box))
#define dbg_t_full_box_copy_tree(box) dbg_mp_full_box_copy_tree (DBG_ARGS THR_TMP_POOL, (box))
#define t_alloc_box(len,dtp) mp_alloc_box (THR_TMP_POOL, (len), (dtp))
#define t_box_string(str) mp_box_string (THR_TMP_POOL, (str))
#define t_box_substr(str,n1,n2) mp_box_substr (THR_TMP_POOL, (str), (n1), (n2))
#define t_box_dv_short_nchars(str,len) mp_box_dv_short_nchars (THR_TMP_POOL, (str), (len))
#define t_box_dv_uname_string(str) mp_box_dv_uname_string (THR_TMP_POOL, (str))
#define t_box_dv_uname_nchars(str,len) mp_box_dv_uname_nchars (THR_TMP_POOL, (str), (len))
#define t_box_copy(box) mp_box_copy (THR_TMP_POOL, (box))
#define t_box_copy_tree(box) mp_box_copy_tree (THR_TMP_POOL, (box))
#define t_full_box_copy_tree(box) mp_full_box_copy_tree (THR_TMP_POOL, (box))
#define t_alloc_list(n) ((caddr_t *)t_alloc_box ((n) * sizeof (caddr_t), DV_ARRAY_OF_POINTER))
extern caddr_t *t_list_concat_tail (caddr_t list, long n, ...);
extern caddr_t *t_list_concat (caddr_t list1, caddr_t list2);
extern caddr_t *t_list_remove_nth (caddr_t list, int pos);
extern caddr_t *t_list_insert_before_nth (caddr_t list, caddr_t new_item, int pos);
extern caddr_t *t_list_insert_many_before_nth (caddr_t list, caddr_t * new_items, int ins_count, int pos);
caddr_t *t_sc_list (long n, ...);
#define t_NEW_DB_NULL t_alloc_box (0, DV_DB_NULL)
#ifdef MALLOC_DEBUG
caddr_t dbg_t_box_num (const char *file, int line, boxint box);
caddr_t dbg_t_box_num_and_zero (const char *file, int line, boxint box);
box_t dbg_t_box_double (const char *file, int line, double d);
box_t dbg_t_box_float (const char *file, int line, float d);
caddr_t dbg_t_box_iri_id (const char *file, int line, int64 n);
#define t_box_num(box) dbg_t_box_num (__FILE__, __LINE__, (box))
#define t_box_double(d) dbg_t_box_double (__FILE__, __LINE__, (d))
#define t_box_float(d) dbg_t_box_float (__FILE__, __LINE__, (d))
#define t_box_iri_id(d) dbg_t_box_iri_id (__FILE__, __LINE__, (d))
#define t_box_num_and_zero(box) dbg_t_box_num_and_zero (__FILE__, __LINE__, (box))
extern caddr_t *t_list_impl (long n, ...);
typedef caddr_t *(*t_list_impl_ptr_t) (long n, ...);
extern t_list_impl_ptr_t t_list_cock (const char *file, int line);
#define t_list (t_list_cock (__FILE__, __LINE__))
#else
caddr_t t_box_num (boxint box);
caddr_t t_box_num_and_zero (boxint box);
box_t t_box_double (double d);
box_t t_box_float (float d);
caddr_t t_box_iri_id (int64 n);
extern caddr_t *t_list (long n, ...);
#endif
#define t_alloc(sz) t_alloc_box ((sz), DV_CUSTOM)
#define t_box_num_nonull t_box_num_and_zero
#define t_box_dv_short_string t_box_string
#define TNEW(dt, v) \
dt * v = (dt *) t_alloc (sizeof (dt))
#define t_NEW_VARZ(dt, v) \
TNEW(dt, v); \
memset (v, 0, sizeof (dt))
#define t_NEW_VAR(dt, v) \
TNEW(dt, v)
#ifdef MALLOC_DEBUG
void dbg_mp_set_push (const char *file, int line, mem_pool_t * mp, dk_set_t * set, void *elt);
dk_set_t dbg_t_cons (const char *file, int line, void *car, dk_set_t cdr);
void dbg_t_set_push (const char *file, int line, dk_set_t * set, void *elt);
int dbg_t_set_pushnew (const char *file, int line, s_node_t ** set, void *item);
int dbg_t_set_push_new_string (const char *file, int line, s_node_t ** set, void *item);
void *dbg_t_set_pop (const char *file, int line, dk_set_t * set);
dk_set_t dbg_t_set_union (const char *file, int line, dk_set_t s1, dk_set_t s2);
dk_set_t dbg_t_set_intersect (const char *file, int line, dk_set_t s1, dk_set_t s2);
dk_set_t dbg_t_set_diff (const char *file, int line, dk_set_t s1, dk_set_t s2);
caddr_t *dbg_t_list_to_array (const char *file, int line, dk_set_t list);
caddr_t *dbg_t_revlist_to_array (const char *file, int line, dk_set_t list);
int dbg_t_set_delete (const char *file, int line, dk_set_t * set, void *item);
dk_set_t dbg_t_set_copy (const char *file, int line, dk_set_t s);
#define mp_set_push(mp,set,elt) dbg_mp_set_push (__FILE__, __LINE__, (mp), (set), (elt))
#define t_cons(car,cdr) dbg_t_cons (__FILE__, __LINE__, (car), (cdr))
#define t_set_push(set,elt) dbg_t_set_push (__FILE__, __LINE__, (set), (elt))
#define t_set_pushnew(set,item) dbg_t_set_pushnew (__FILE__, __LINE__, (set), (item))
#define t_set_push_new_string(set,item) dbg_t_set_push_new_string (__FILE__, __LINE__, (set), (item))
#define t_set_pop(set) dbg_t_set_pop (__FILE__, __LINE__, (set))
#define t_set_union(s1,s2) dbg_t_set_union (__FILE__, __LINE__, (s1), (s2))
#define t_set_intersect(s1,s2) dbg_t_set_intersect (__FILE__, __LINE__, (s1), (s2))
#define t_set_diff(s1,s2) dbg_t_set_diff (__FILE__, __LINE__, (s1), (s2))
#define t_list_to_array(list) dbg_t_list_to_array (__FILE__, __LINE__, (list))
#define t_revlist_to_array(list) dbg_t_revlist_to_array (__FILE__, __LINE__, (list))
#define t_set_delete(set,item) dbg_t_set_delete (__FILE__, __LINE__, (set), (item))
#define t_set_copy(s) dbg_t_set_copy (__FILE__, __LINE__, (s))
#else
void mp_set_push (mem_pool_t * mp, dk_set_t * set, void *elt);
dk_set_t t_cons (void *car, dk_set_t cdr);
void t_set_push (dk_set_t * set, void *elt);
int t_set_pushnew (s_node_t ** set, void *item);
int t_set_push_new_string (s_node_t ** set, void *item);
void *t_set_pop (dk_set_t * set);
dk_set_t t_set_union (dk_set_t s1, dk_set_t s2);
dk_set_t t_set_intersect (dk_set_t s1, dk_set_t s2);
dk_set_t t_set_diff (dk_set_t s1, dk_set_t s2);
caddr_t *t_list_to_array (dk_set_t list);
caddr_t *t_revlist_to_array (dk_set_t list);
int t_set_delete (dk_set_t * set, void *item);
dk_set_t t_set_copy (dk_set_t s);
#endif
#define mp_set_nreverse(mp,s) dk_set_nreverse((s))
#define t_set_nreverse(s) dk_set_nreverse((s))
#define t_revlist_to_array_or_null(list) ((NULL != (list)) ? t_revlist_to_array ((list)) : NULL)
#ifdef MALLOC_DEBUG
void mp_check_tree (mem_pool_t * mp, box_t box);
#define t_check_tree(box) mp_check_tree (THR_TMP_POOL, (box))
#else
#define mp_check_tree(mp,box) ;
#define t_check_tree(box) ;
#endif
#ifdef _DKSYSTEM_H
caddr_t t_box_vsprintf (size_t buflen_eval, const char *format, va_list tail);
caddr_t t_box_sprintf (size_t buflen_eval, const char *format, ...);
#endif
void mp_trash (mem_pool_t * mp, caddr_t box);
caddr_t mp_alloc_box_ni (mem_pool_t * mp, int len, dtp_t dtp);
extern box_tmp_copy_f box_tmp_copier[256];
#ifdef LACERATED_POOL
#define MP_BYTES(x, mp, len) x = mp_alloc_box (mp, len, DV_NON_BOX)
#else
#define MP_BYTES(x, mp, len2) \
{ \
int __len = ALIGN_8 (len2); \
mem_block_t * f = mp->mp_first; \
if (f && f->mb_fill + __len <= f->mb_size) \
{ \
x = ((char*)f) + f->mb_fill; \
f->mb_fill += __len; \
} \
else \
x = mp_alloc_box (mp, len2, DV_NON_BOX); \
}
#endif
#define MP_INT(x, mp, v, tag_word) \
{ \
MP_BYTES (x, mp, 16); \
x = ((char *)x) + 8; \
*(int64 *)x = v; \
((int32*)x)[-1] = tag_word; \
}
typedef struct auto_pool_s
{
caddr_t ap_area;
int ap_size;
int ap_fill;
} auto_pool_t;
#define AUTO_POOL(n) \
int64 area[n]; \
auto_pool_t ap; \
ap.ap_area = (caddr_t) &area; \
ap.ap_fill = 0; \
ap.ap_size = sizeof (area); \
caddr_t ap_box_num (auto_pool_t * ap, int64 i);
caddr_t ap_alloc_box (auto_pool_t * ap, int n, dtp_t tag);
caddr_t *ap_list (auto_pool_t * apool, long n, ...);
caddr_t ap_box_iri_id (auto_pool_t * ap, int64 n);
#define WITHOUT_TMP_POOL \
{ \
mem_pool_t * __mp = THR_TMP_POOL; \
SET_THR_TMP_POOL (NULL);
#define END_WITHOUT_TMP_POOL \
SET_THR_TMP_POOL (__mp); \
}
#define NO_TMP_POOL \
if (THR_TMP_POOL) GPF_T1 ("not supposed to have a tmp pool in effect here");
#endif /* ifdef __DKPOOL_H */
|