14c86fa59STrond Norbye /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ 24c86fa59STrond Norbye #ifndef CACHE_H 34c86fa59STrond Norbye #define CACHE_H 44c86fa59STrond Norbye #include <pthread.h> 54c86fa59STrond Norbye 64c86fa59STrond Norbye #ifdef HAVE_UMEM_H 74c86fa59STrond Norbye #include <umem.h> 84c86fa59STrond Norbye #define cache_t umem_cache_t 94c86fa59STrond Norbye #define cache_alloc(a) umem_cache_alloc(a, UMEM_DEFAULT) 104c86fa59STrond Norbye #define cache_free(a, b) umem_cache_free(a, b) 114c86fa59STrond Norbye #define cache_create(a,b,c,d,e) umem_cache_create((char*)a, b, c, d, e, NULL, NULL, NULL, 0) 124c86fa59STrond Norbye #define cache_destroy(a) umem_cache_destroy(a); 134c86fa59STrond Norbye 144c86fa59STrond Norbye #else 154c86fa59STrond Norbye 164c86fa59STrond Norbye #ifndef NDEBUG 174c86fa59STrond Norbye /* may be used for debug purposes */ 184c86fa59STrond Norbye extern int cache_error; 194c86fa59STrond Norbye #endif 204c86fa59STrond Norbye 21652884e3STrond Norbye /** 22652884e3STrond Norbye * Constructor used to initialize allocated objects 23652884e3STrond Norbye * 24652884e3STrond Norbye * @param obj pointer to the object to initialized. 25652884e3STrond Norbye * @param notused1 This parameter is currently not used. 26652884e3STrond Norbye * @param notused2 This parameter is currently not used. 27652884e3STrond Norbye * @return you should return 0, but currently this is not checked 28652884e3STrond Norbye */ 29652884e3STrond Norbye typedef int cache_constructor_t(void* obj, void* notused1, int notused2); 30652884e3STrond Norbye /** 31652884e3STrond Norbye * Destructor used to clean up allocated objects before they are 32652884e3STrond Norbye * returned to the operating system. 33652884e3STrond Norbye * 34*2f313508S祁冰 * @param obj pointer to the object to clean up. 35652884e3STrond Norbye * @param notused1 This parameter is currently not used. 36652884e3STrond Norbye * @param notused2 This parameter is currently not used. 37652884e3STrond Norbye * @return you should return 0, but currently this is not checked 38652884e3STrond Norbye */ 39652884e3STrond Norbye typedef void cache_destructor_t(void* obj, void* notused); 404c86fa59STrond Norbye 41652884e3STrond Norbye /** 42652884e3STrond Norbye * Definition of the structure to keep track of the internal details of 43652884e3STrond Norbye * the cache allocator. Touching any of these variables results in 44652884e3STrond Norbye * undefined behavior. 45652884e3STrond Norbye */ 464c86fa59STrond Norbye typedef struct { 47652884e3STrond Norbye /** Mutex to protect access to the structure */ 484c86fa59STrond Norbye pthread_mutex_t mutex; 49652884e3STrond Norbye /** Name of the cache objects in this cache (provided by the caller) */ 504c86fa59STrond Norbye char *name; 51652884e3STrond Norbye /** List of pointers to available buffers in this cache */ 524c86fa59STrond Norbye void **ptr; 53652884e3STrond Norbye /** The size of each element in this cache */ 544c86fa59STrond Norbye size_t bufsize; 55652884e3STrond Norbye /** The capacity of the list of elements */ 564c86fa59STrond Norbye int freetotal; 57652884e3STrond Norbye /** The current number of free elements */ 584c86fa59STrond Norbye int freecurr; 59652884e3STrond Norbye /** The constructor to be called each time we allocate more memory */ 604c86fa59STrond Norbye cache_constructor_t* constructor; 61652884e3STrond Norbye /** The destructor to be called each time before we release memory */ 624c86fa59STrond Norbye cache_destructor_t* destructor; 634c86fa59STrond Norbye } cache_t; 644c86fa59STrond Norbye 65652884e3STrond Norbye /** 66652884e3STrond Norbye * Create an object cache. 67652884e3STrond Norbye * 68652884e3STrond Norbye * The object cache will let you allocate objects of the same size. It is fully 69652884e3STrond Norbye * MT safe, so you may allocate objects from multiple threads without having to 70652884e3STrond Norbye * do any syncrhonization in the application code. 71652884e3STrond Norbye * 72652884e3STrond Norbye * @param name the name of the object cache. This name may be used for debug purposes 73652884e3STrond Norbye * and may help you track down what kind of object you have problems with 74652884e3STrond Norbye * (buffer overruns, leakage etc) 75652884e3STrond Norbye * @param bufsize the size of each object in the cache 76652884e3STrond Norbye * @param align the alignment requirements of the objects in the cache. 77652884e3STrond Norbye * @param constructor the function to be called to initialize memory when we need 78652884e3STrond Norbye * to allocate more memory from the os. 79652884e3STrond Norbye * @param destructor the function to be called before we release the memory back 80652884e3STrond Norbye * to the os. 81652884e3STrond Norbye * @return a handle to an object cache if successful, NULL otherwise. 82652884e3STrond Norbye */ 834c86fa59STrond Norbye cache_t* cache_create(const char* name, size_t bufsize, size_t align, 844c86fa59STrond Norbye cache_constructor_t* constructor, 854c86fa59STrond Norbye cache_destructor_t* destructor); 86652884e3STrond Norbye /** 87652884e3STrond Norbye * Destroy an object cache. 88652884e3STrond Norbye * 89652884e3STrond Norbye * Destroy and invalidate an object cache. You should return all buffers allocated 90652884e3STrond Norbye * with cache_alloc by using cache_free before calling this function. Not doing 91652884e3STrond Norbye * so results in undefined behavior (the buffers may or may not be invalidated) 92652884e3STrond Norbye * 93652884e3STrond Norbye * @param handle the handle to the object cache to destroy. 94652884e3STrond Norbye */ 95652884e3STrond Norbye void cache_destroy(cache_t* handle); 96652884e3STrond Norbye /** 97652884e3STrond Norbye * Allocate an object from the cache. 98652884e3STrond Norbye * 99652884e3STrond Norbye * @param handle the handle to the object cache to allocate from 100652884e3STrond Norbye * @return a pointer to an initialized object from the cache, or NULL if 101652884e3STrond Norbye * the allocation cannot be satisfied. 102652884e3STrond Norbye */ 103652884e3STrond Norbye void* cache_alloc(cache_t* handle); 104652884e3STrond Norbye /** 105652884e3STrond Norbye * Return an object back to the cache. 106652884e3STrond Norbye * 107652884e3STrond Norbye * The caller should return the object in an initialized state so that 108652884e3STrond Norbye * the object may be returned in an expected state from cache_alloc. 109652884e3STrond Norbye * 110652884e3STrond Norbye * @param handle handle to the object cache to return the object to 111652884e3STrond Norbye * @param ptr pointer to the object to return. 112652884e3STrond Norbye */ 113652884e3STrond Norbye void cache_free(cache_t* handle, void* ptr); 1144c86fa59STrond Norbye #endif 1154c86fa59STrond Norbye 1164c86fa59STrond Norbye #endif 117