]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/slab/include/slab.h
update
[l4.git] / l4 / pkg / slab / include / slab.h
1 /*****************************************************************************/
2 /**
3  * \file    slab/include/slab.h
4  * \brief   Slab allocator API.
5  *
6  * \date   2006-12-18
7  * \author Lars Reuther <reuther@os.inf.tu-dresden.de>
8  * \author Christian Helmuth <ch12@os.inf.tu-dresden.de>
9  */
10 /*****************************************************************************/
11
12 /*
13  * (c) 2006-2009 Author(s)
14  *     economic rights: Technische Universität Dresden (Germany)
15  *
16  * This file is part of TUD:OS and distributed under the terms of the
17  * GNU General Public License 2.
18  * Please see the COPYING-GPL-2 file for details.
19  */
20
21 /* This version supports multi-page slabs (slab size stored in cache.slab_size)
22  * and tries to follow Bonwicks original suggestion to limit internal
23  * fragmentation to 1/8 (12.5 %).
24  *                                    -- Krishna
25  */
26
27 #ifndef _L4SLAB_SLAB_H
28 #define _L4SLAB_SLAB_H
29
30 /* L4env includes */
31 #include <l4/sys/linkage.h>
32 #include <l4/sys/l4int.h>
33 #include <l4/sys/compiler.h>
34
35 /*****************************************************************************
36  *** typedefs
37  *****************************************************************************/
38
39 /**
40  * Slab descriptor type
41  */
42 typedef struct l4slab_slab l4slab_slab_t;
43
44 /**
45  * \brief   Slab cache descriptor type
46  * \ingroup api_init
47  */
48 typedef struct l4slab_cache l4slab_cache_t;
49
50 /**
51  * \brief   Cache grow callback function
52  * \ingroup api_init
53  *
54  * \param   cache        Descriptor of the slab cache which requests
55  *                       the memory
56  * \retval  data         Slab user data pointer, the contents is returned
57  *                       with the slab to the release callback function.
58  *
59  * \return  Pointer to the allocated slab.
60  *
61  * This function is called by a slab cache to allocate a new slab for the
62  * cache. It must return a pointer to a memory area with the size of
63  * cache->slab_size and which is slab_size aligned.
64  */
65 typedef L4_CV void * (* l4slab_grow_fn_t) (l4slab_cache_t * cache,
66                                            void ** data);
67
68 /**
69  * \brief   Cache release callback function
70  * \ingroup api_init
71  *
72  * \param   cache        Slab cache descriptor
73  * \param   buffer       Slab address
74  * \param   data         Slab user data pointer
75  *
76  * Cache release callback function. It is called by a slab cache to release
77  * slabs which are no longer needed by the cache. Slab have a size of
78  * cache->slab_size!
79  */
80 typedef L4_CV void (* l4slab_release_fn_t) (l4slab_cache_t * cache,
81                                             void * buffer, void * data);
82
83 /**
84  * Slab cache descriptor
85  */
86 struct l4slab_cache
87 {
88   l4_size_t            obj_size;   ///< size of cache objects
89   l4_size_t            slab_size;  ///< size of one slab
90   int                  num_objs;   ///< number of objects per slab
91   int                  num_slabs;  ///< number of slabs in cache
92   int                  num_free;   ///< number of unused slabs
93   int                  max_free;   ///< max. allowed unused slabs
94
95   l4slab_slab_t *      slabs_full; ///< list of completely used slabs
96   l4slab_slab_t *      slabs_part; ///< list of partially used slabs
97   l4slab_slab_t *      slabs_free; ///< list of unused slabs
98
99   l4slab_grow_fn_t     grow_fn;    ///< cache grow callback
100   l4slab_release_fn_t  release_fn; ///< slab release callback
101
102   void *               data;       ///< application data pointer
103 };
104
105 #define L4SLAB_LOG_CACHE(cp) do { \
106         LOG("\033[34;1mcache at %p\033[0m", cp); \
107         LOG("\033[34;1m  obj_size %u\033[0m", cp->obj_size); \
108         LOG("\033[34;1m  slab_size %u\033[0m", cp->slab_size); \
109         LOG("\033[34;1m  objs per slab %d\033[0m", cp->num_objs); \
110         LOG("\033[34;1m  num_free %d\033[0m", cp->num_free); \
111         LOG("\033[34;1m  data ptr %p\033[0m", cp->data); \
112 } while (0)
113
114
115 /*****************************************************************************
116  *** prototypes
117  *****************************************************************************/
118
119 __BEGIN_DECLS;
120
121 /*****************************************************************************/
122 /**
123  * \brief   Initialize slab cache.
124  * \ingroup api_init
125  *
126  * \param   cache        Slab cache descriptor
127  * \param   size         Size of the cache objects
128  * \param   max_free     Maximum number of free slabs allowed in the cache.
129  *                       If more slabs in the slab cache are freed, they are
130  *                       released  (if a release callback function is
131  *                       specified).
132  * \param   grow_fn      Cache grow callback function, called by the slab cache
133  *                       to allocate new buffers for the cache. If no function
134  *                       is  specified the cache cannot allocate buffers on
135  *                       demand.
136  * \param   release_fn   Slab release callback function, called by the cache to
137  *                       release unused buffers. If no function is specified
138  *                       unused buffers are not released.
139  *
140  * \return  0 on success (initialized cache descriptor), error code otherwise:
141  *          - -L4_EINVAL  size too big / invalid cache descriptor
142  *
143  * Setup cache descriptor. The function initializes the internal cache
144  * descriptor structures, but does not allocate any memory. Memory can be
145  * added using the l4slab_add_slab() function or memory is allocated
146  * on demand by the cache if the grow callback function is specified.
147  */
148 /*****************************************************************************/
149 L4_CV int
150 l4slab_cache_init(l4slab_cache_t * cache, l4_size_t size,
151                   unsigned int max_free, l4slab_grow_fn_t grow_fn,
152                   l4slab_release_fn_t release_fn);
153
154 /*****************************************************************************/
155 /**
156  * \brief   Destroy slab cache
157  * \ingroup api_init
158  *
159  * \param   cache        Cache descriptor
160  *
161  * Release slab descriptor and free all allocated memory. This function is
162  * only useful if a release callback function is specified for the cache,
163  * otherwise it has no effect.
164  */
165 /*****************************************************************************/
166 L4_CV void
167 l4slab_destroy(l4slab_cache_t * cache);
168
169 /*****************************************************************************/
170 /**
171  * \brief   Allocate object
172  * \ingroup api_alloc
173  *
174  * \param   cache        Cache descriptor
175  *
176  * \return pointer to object, NULL if allocation failed.
177  */
178 /*****************************************************************************/
179 L4_CV void *
180 l4slab_alloc(l4slab_cache_t * cache);
181
182 /*****************************************************************************/
183 /**
184  * \brief   Release object
185  * \ingroup api_alloc
186  *
187  * \param   cache        Cache descriptor
188  * \param   objp         Pointer to object
189  */
190 /*****************************************************************************/
191 L4_CV void
192 l4slab_free(l4slab_cache_t * cache, void * objp);
193
194 /*****************************************************************************/
195 /**
196  * \brief   Add a slab to the slab cache
197  * \ingroup api_init
198  *
199  * \param   cache        Cache descriptor
200  * \param   buffer       Pointer to new slab
201  * \param   data         Application data
202  *
203  * Add the slab (buffer) to the slab cache. Buffer must be
204  * cache->slab_size-sized and slab_size aligned in memory.
205  */
206 /*****************************************************************************/
207 L4_CV void
208 l4slab_add_slab(l4slab_cache_t * cache, void * buffer, void * data);
209
210 /*****************************************************************************/
211 /**
212  * \brief   Set cache application data pointer.
213  * \ingroup api_init
214  *
215  * \param   cache        Cache descriptor
216  * \param   data         Application data pointer
217  */
218 /*****************************************************************************/
219 L4_CV void
220 l4slab_set_data(l4slab_cache_t * cache, void * data);
221
222 /*****************************************************************************/
223 /**
224  * \brief   Get cache application data.
225  * \ingroup api_init
226  *
227  * \param   cache        Cache descriptor
228  *
229  * \return Application data pointer, NULL if invalid cache descriptor or no
230  *         data pointer set.
231  */
232 /*****************************************************************************/
233 L4_CV void *
234 l4slab_get_data(l4slab_cache_t * cache);
235
236 /*****************************************************************************/
237 /**
238  * \brief   Dump cache slab list
239  * \ingroup api_debug
240  *
241  * \param   cache        Cache descriptor
242  * \param   dump_free    Dump free list of slabs
243  */
244 /*****************************************************************************/
245 L4_CV void
246 l4slab_dump_cache(l4slab_cache_t * cache, int dump_free);
247
248 /*****************************************************************************/
249 /**
250  * \brief   Dump cache free slab list
251  * \ingroup api_debug
252  *
253  * \param   cache        Cache descriptor
254  */
255 /*****************************************************************************/
256 L4_CV void
257 l4slab_dump_cache_free(l4slab_cache_t * cache);
258
259 __END_DECLS;
260
261 #endif /* !_L4SLAB_SLAB_H */