alloc.h revision 269257
1255902Sedwin/* 2255902Sedwin * util/alloc.h - memory allocation service. 3270817Spluknet * 4255902Sedwin * Copyright (c) 2007, NLnet Labs. All rights reserved. 5255902Sedwin * 6270817Spluknet * This software is open source. 7270817Spluknet * 8255902Sedwin * Redistribution and use in source and binary forms, with or without 9255902Sedwin * modification, are permitted provided that the following conditions 10255902Sedwin * are met: 11255902Sedwin * 12255902Sedwin * Redistributions of source code must retain the above copyright notice, 13255902Sedwin * this list of conditions and the following disclaimer. 14255902Sedwin * 15255902Sedwin * Redistributions in binary form must reproduce the above copyright notice, 16255902Sedwin * this list of conditions and the following disclaimer in the documentation 17255902Sedwin * and/or other materials provided with the distribution. 18270817Spluknet * 19270817Spluknet * Neither the name of the NLNET LABS nor the names of its contributors may 20270817Spluknet * be used to endorse or promote products derived from this software without 21270817Spluknet * specific prior written permission. 22270817Spluknet * 23270817Spluknet * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24270817Spluknet * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25270817Spluknet * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26270817Spluknet * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 27270817Spluknet * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28270817Spluknet * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 29255902Sedwin * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30270817Spluknet * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31255902Sedwin * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32255902Sedwin * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33270817Spluknet * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34255902Sedwin */ 35255902Sedwin 36255902Sedwin/** 37255902Sedwin * \file 38255902Sedwin * 39255902Sedwin * This file contains memory allocation functions. 40255902Sedwin * 41270817Spluknet * The reasons for this service are: 42255902Sedwin * o Avoid locking costs of getting global lock to call malloc(). 43255902Sedwin * o The packed rrset type needs to be kept on special freelists, 44255902Sedwin * so that they are reused for other packet rrset allocations. 45255902Sedwin * 46255902Sedwin */ 47255902Sedwin 48255902Sedwin#ifndef UTIL_ALLOC_H 49255902Sedwin#define UTIL_ALLOC_H 50279707Sedwin 51255902Sedwin#include "util/locks.h" 52270817Spluknetstruct ub_packed_rrset_key; 53270817Spluknetstruct regional; 54270817Spluknet 55270817Spluknet/** The special type, packed rrset. Not allowed to be used for other memory */ 56255902Sedwintypedef struct ub_packed_rrset_key alloc_special_t; 57255902Sedwin/** clean the special type. Pass pointer. */ 58255902Sedwin#define alloc_special_clean(x) (x)->id = 0; 59255902Sedwin/** access next pointer. (in available spot). Pass pointer. */ 60255902Sedwin#define alloc_special_next(x) ((alloc_special_t*)((x)->entry.overflow_next)) 61255902Sedwin/** set next pointer. (in available spot). Pass pointers. */ 62255902Sedwin#define alloc_set_special_next(x, y) \ 63255902Sedwin ((x)->entry.overflow_next) = (struct lruhash_entry*)(y); 64328476Sphilip 65328476Sphilip/** how many blocks to cache locally. */ 66328476Sphilip#define ALLOC_SPECIAL_MAX 10 67328476Sphilip 68328476Sphilip/** 69328476Sphilip * Structure that provides allocation. Use one per thread. 70255902Sedwin * The one on top has a NULL super pointer. 71270817Spluknet */ 72270817Spluknetstruct alloc_cache { 73270817Spluknet /** lock, only used for the super. */ 74270817Spluknet lock_quick_t lock; 75270817Spluknet /** global allocator above this one. NULL for none (malloc/free) */ 76255902Sedwin struct alloc_cache* super; 77270817Spluknet /** singly linked lists of special type. These are free for use. */ 78255902Sedwin alloc_special_t* quar; 79270817Spluknet /** number of items in quarantine. */ 80255902Sedwin size_t num_quar; 81270817Spluknet /** thread number for id creation */ 82270817Spluknet int thread_num; 83270817Spluknet /** next id number to pass out */ 84255902Sedwin uint64_t next_id; 85255902Sedwin /** last id number possible */ 86270817Spluknet uint64_t last_id; 87270817Spluknet /** what function to call to cleanup when last id is reached */ 88255902Sedwin void (*cleanup)(void*); 89255902Sedwin /** user arg for cleanup */ 90255902Sedwin void* cleanup_arg; 91255902Sedwin 92255902Sedwin /** how many regional blocks to keep back max */ 93270817Spluknet size_t max_reg_blocks; 94270817Spluknet /** how many regional blocks are kept now */ 95270817Spluknet size_t num_reg_blocks; 96270817Spluknet /** linked list of regional blocks, using regional->next */ 97270817Spluknet struct regional* reg_list; 98270817Spluknet}; 99255902Sedwin 100255902Sedwin/** 101255902Sedwin * Init alloc (zeroes the struct). 102255902Sedwin * @param alloc: this parameter is allocated by the caller. 103255902Sedwin * @param super: super to use (init that before with super_init). 104255902Sedwin * Pass this argument NULL to init the toplevel alloc structure. 105255902Sedwin * @param thread_num: thread number for id creation of special type. 106255902Sedwin */ 107255902Sedwinvoid alloc_init(struct alloc_cache* alloc, struct alloc_cache* super, 108255902Sedwin int thread_num); 109255902Sedwin 110255902Sedwin/** 111255902Sedwin * Free the alloc. Pushes all the cached items into the super structure. 112255902Sedwin * Or deletes them if alloc->super is NULL. 113270817Spluknet * Does not free the alloc struct itself (it was also allocated by caller). 114255902Sedwin * @param alloc: is almost zeroed on exit (except some stats). 115255902Sedwin */ 116255902Sedwinvoid alloc_clear(struct alloc_cache* alloc); 117255902Sedwin 118255902Sedwin/** 119255902Sedwin * Get a new special_t element. 120255902Sedwin * @param alloc: where to alloc it. 121255902Sedwin * @return: memory block. Will not return NULL (instead fatal_exit). 122255902Sedwin * The block is zeroed. 123270817Spluknet */ 124270817Spluknetalloc_special_t* alloc_special_obtain(struct alloc_cache* alloc); 125270817Spluknet 126270817Spluknet/** 127255902Sedwin * Return special_t back to pool. 128270817Spluknet * The block is cleaned up (zeroed) which also invalidates the ID inside. 129270817Spluknet * @param alloc: where to alloc it. 130270817Spluknet * @param mem: block to free. 131270817Spluknet */ 132270817Spluknetvoid alloc_special_release(struct alloc_cache* alloc, alloc_special_t* mem); 133255902Sedwin 134255902Sedwin/** 135279707Sedwin * Set ID number of special type to a fresh new ID number. 136279707Sedwin * In case of ID number overflow, the rrset cache has to be cleared. 137279707Sedwin * @param alloc: the alloc cache 138279707Sedwin * @return: fresh id is returned. 139280414Sedwin */ 140280414Sedwinuint64_t alloc_get_id(struct alloc_cache* alloc); 141280414Sedwin 142280414Sedwin/** 143279707Sedwin * Get memory size of alloc cache, alloc structure including special types. 144255902Sedwin * @param alloc: on what alloc. 145255902Sedwin * @return size in bytes. 146255902Sedwin */ 147255902Sedwinsize_t alloc_get_mem(struct alloc_cache* alloc); 148255902Sedwin 149270817Spluknet/** 150255902Sedwin * Print debug information (statistics). 151307362Sbapt * @param alloc: on what alloc. 152255902Sedwin */ 153270817Spluknetvoid alloc_stats(struct alloc_cache* alloc); 154255902Sedwin 155255902Sedwin/** 156270817Spluknet * Get a new regional for query states 157255902Sedwin * @param alloc: where to alloc it. 158255902Sedwin * @return regional for use or NULL on alloc failure. 159307362Sbapt */ 160255902Sedwinstruct regional* alloc_reg_obtain(struct alloc_cache* alloc); 161255902Sedwin 162270817Spluknet/** 163270817Spluknet * Put regional for query states back into alloc cache. 164255902Sedwin * @param alloc: where to alloc it. 165255902Sedwin * @param r: regional to put back. 166255902Sedwin */ 167270817Spluknetvoid alloc_reg_release(struct alloc_cache* alloc, struct regional* r); 168270817Spluknet 169270817Spluknet/** 170270817Spluknet * Set cleanup on ID overflow callback function. This should remove all 171270817Spluknet * RRset ID references from the program. Clear the caches. 172270817Spluknet * @param alloc: the alloc 173270817Spluknet * @param cleanup: the callback function, called as cleanup(arg). 174270817Spluknet * @param arg: user argument to callback function. 175255902Sedwin */ 176270817Spluknetvoid alloc_set_id_cleanup(struct alloc_cache* alloc, void (*cleanup)(void*), 177255902Sedwin void* arg); 178270817Spluknet 179255902Sedwin#ifdef UNBOUND_ALLOC_LITE 180270817Spluknet# include <ldns/ldns.h> 181255902Sedwin# include <ldns/packet.h> 182255902Sedwin# ifdef HAVE_OPENSSL_SSL_H 183255902Sedwin# include <openssl/ssl.h> 184270817Spluknet# endif 185255902Sedwin# define malloc(s) unbound_stat_malloc_lite(s, __FILE__, __LINE__, __func__) 186255902Sedwin# define calloc(n,s) unbound_stat_calloc_lite(n, s, __FILE__, __LINE__, __func__) 187270817Spluknet# define free(p) unbound_stat_free_lite(p, __FILE__, __LINE__, __func__) 188270817Spluknet# define realloc(p,s) unbound_stat_realloc_lite(p, s, __FILE__, __LINE__, __func__) 189270817Spluknetvoid *unbound_stat_malloc_lite(size_t size, const char* file, int line, 190270817Spluknet const char* func); 191270817Spluknetvoid *unbound_stat_calloc_lite(size_t nmemb, size_t size, const char* file, 192270817Spluknet int line, const char* func); 193255902Sedwinvoid unbound_stat_free_lite(void *ptr, const char* file, int line, 194255902Sedwin const char* func); 195255902Sedwinvoid *unbound_stat_realloc_lite(void *ptr, size_t size, const char* file, 196270817Spluknet int line, const char* func); 197255902Sedwin# ifdef strdup 198255902Sedwin# undef strdup 199255902Sedwin# endif 200270817Spluknet# define strdup(s) unbound_strdup_lite(s, __FILE__, __LINE__, __func__) 201270817Spluknetchar* unbound_strdup_lite(const char* s, const char* file, int line, 202270817Spluknet const char* func); 203255902Sedwinchar* unbound_lite_wrapstr(char* s); 204270817Spluknet# define sldns_rr2str(rr) unbound_lite_wrapstr(sldns_rr2str(rr)) 205255902Sedwin# define sldns_rdf2str(rdf) unbound_lite_wrapstr(sldns_rdf2str(rdf)) 206255902Sedwin# define sldns_rr_type2str(t) unbound_lite_wrapstr(sldns_rr_type2str(t)) 207345671Sphilip# define sldns_rr_class2str(c) unbound_lite_wrapstr(sldns_rr_class2str(c)) 208345671Sphilip# define sldns_rr_list2str(r) unbound_lite_wrapstr(sldns_rr_list2str(r)) 209255902Sedwin# define sldns_pkt2str(p) unbound_lite_wrapstr(sldns_pkt2str(p)) 210345671Sphilip# define sldns_pkt_rcode2str(r) unbound_lite_wrapstr(sldns_pkt_rcode2str(r)) 211255902Sedwin# define sldns_pkt2wire(a, r, s) unbound_lite_pkt2wire(a, r, s) 212255902Sedwinsldns_status unbound_lite_pkt2wire(uint8_t **dest, const sldns_pkt *p, size_t *size); 213255902Sedwin# define i2d_DSA_SIG(d, s) unbound_lite_i2d_DSA_SIG(d, s) 214255902Sedwinint unbound_lite_i2d_DSA_SIG(DSA_SIG* dsasig, unsigned char** sig); 215255902Sedwin#endif /* UNBOUND_ALLOC_LITE */ 216255902Sedwin 217255902Sedwin#endif /* UTIL_ALLOC_H */ 218255902Sedwin