1umem_cache_create(3MALLMOeCm)ory Allocation Library Functuimoenms_cache_create(3MALLOC)
2
3
4

NAME

6       umem_cache_create,         umem_cache_destroy,        umem_cache_alloc,
7       umem_cache_free - allocation cache manipulation
8

SYNOPSIS

10       cc [ flag ... ] file... -lumem [ library ... ]
11       #include <umem.h>
12
13       umem_cache_t *umem_cache_create(char *debug_name, size_t bufsize,
14            size_t align, umem_constructor_t *constructor,
15            umem_destructor_t *destructor, umem_reclaim_t *reclaim,
16            void *callback_data, vmem_t *source, int cflags);
17
18
19       void umem_cache_destroy(umem_cache_t *cache);
20
21
22       void *umem_cache_alloc(umem_cache_t *cache, int flags);
23
24
25       void umem_cache_free(umem_cache_t *cache, void *buffer);
26
27

DESCRIPTION

29       These functions create, destroy, and use an "object cache"   An  object
30       cache  is  a collection of buffers of a single size, with optional con‐
31       tent caching enabled by the use of  callbacks  (see  Cache  Callbacks).
32       Object  caches  are MT-Safe. Multiple allocations and freeing of memory
33       from different threads can proceed simultaneously.  Object  caches  are
34       faster   and  use  less  space  per  buffer  than  malloc(3MALLOC)  and
35       umem_alloc(3MALLOC).  For more information about  object  caching,  see
36       "The  Slab  Allocator:  An  Object-Caching Kernel Memory Allocator" and
37       "Magazines and vmem: Extending the Slab  Allocator  to  Many  CPUs  and
38       Arbitrary Resources".
39
40
41       The  umem_cache_create()  function  creates object caches. Once a cache
42       has been created, objects can be requested from  and  returned  to  the
43       cache  using  umem_cache_alloc() and umem_cache_free(), respectively. A
44       cache   with   no   outstanding   buffers   can   be   destroyed   with
45       umem_cache_destroy().
46
47   Creating and Destroying Caches
48       The  umem_cache_create()  function creates a cache of objects and takes
49       as arguments the following:
50
51       debug_name       A human-readable name for debugging purposes.
52
53
54       bufsize          The size, in bytes, of the buffers in this cache.
55
56
57       align            The minimum alignment required  for  buffers  in  this
58                        cache.  This  parameter must be a power of 2. If 0, it
59                        is replaced with the minimum  required  alignment  for
60                        the current architecture.
61
62
63       constructor      The callback to construct an object.
64
65
66       destructor       The callback to destroy an object.
67
68
69       reclaim          The callback to reclaim objects.
70
71
72       callback_data    An opaque pointer passed to the callbacks.
73
74
75       source           This parameter must be NULL.
76
77
78       cflags           This  parameter  must  be  either 0 or UMC_NODEBUG. If
79                        UMC_NODEBUG, all debugging features are  disabled  for
80                        this cache. See umem_debug(3MALLOC).
81
82
83
84       Each cache can have up to three associated callbacks:
85
86         int constructor(void *buffer, void *callback_data, int flags);
87         void destructor(void *buffer, void *callback_data);
88         void reclaim(void *callback_data);
89
90
91
92       The  callback_data  argument  is  always  equal  to the value passed to
93       umem_cache_create(), thereby allowing a client to use the same callback
94       functions for multiple caches, but with customized behavior.
95
96
97       The  reclaim  callback  is  called when the umem function is requesting
98       more memory from the operating system. This callback  can  be  used  by
99       clients  who  retain  objects longer than they are strictly needed (for
100       example, caching non-active state).  A typical reclaim  callback  might
101       return to the cache ten per cent of the unneeded buffers.
102
103
104       The  constructor and destructor callbacks enable the management of buf‐
105       fers with the constructed state. The constructor takes as  arguments  a
106       buffer  with  undefined  contents, some callback data, and the flags to
107       use for any allocations. This callback should transform the buffer into
108       the constructed state.
109
110
111       The  destructor  callback takes as an argument a constructed object and
112       prepares it for return to the general pool of memory.   The  destructor
113       should undo any state that the constructor created.  For debugging, the
114       destructor can also check that the buffer is in the constructed  state,
115       to  catch  incorrectly freed buffers.  See umem_debug(3MALLOC) for fur‐
116       ther information on debugging support.
117
118
119       The umem_cache_destroy() function destroys  an  object  cache.  If  the
120       cache has any outstanding allocations, the behavior is undefined.
121
122   Allocating Objects
123       The umem_cache_alloc() function takes as arguments:
124
125       cache    a cache pointer
126
127
128       flags    flags  that  determine  the  behavior if umem_cache_alloc() is
129                unable to fulfill the allocation request
130
131
132
133       If successful, umem_cache_alloc() returns a pointer to the beginning of
134       an object of bufsize length.
135
136
137       There are three cases to consider:
138
139           o      A  new  buffer needed to be allocated. If the cache was cre‐
140                  ated with a constructor, it is applied to the buffer and the
141                  resulting object is returned.
142
143           o      The  object cache was able to use a previously freed buffer.
144                  If the cache was created with a constructor, the  object  is
145                  returned unchanged from when it was freed.
146
147           o      The  allocation  of  a new buffer failed. The flags argument
148                  determines the behavior:
149
150
151                  UMEM_DEFAULT    The umem_cache_alloc() function returns NULL
152                                  if the allocation fails.
153
154
155                  UMEM_NOFAIL     The   umem_cache_alloc()   function   cannot
156                                  return NULL. A callback is used to determine
157                                  what  action occurs. See umem_alloc(3MALLOC)
158                                  for more information.
159
160
161
162   Freeing Objects
163       The umem_cache_free() function takes as arguments:
164
165       cache    a cache pointer
166
167
168       buf      a pointer previously returned  from  umem_cache_alloc().  This
169                argument must not be NULL.
170
171
172
173       If  the  cache was created with a constructor callback, the object must
174       be returned to the constructed state before it is freed.
175
176
177       Undefined behavior results if an object is freed multiple times, if  an
178       object  is  modified  after  it is freed, or if an object is freed to a
179       cache other than the one from which it was allocated.
180
181   Caches with Constructors
182       When a constructor callback is in use, there is essentially a  contract
183       between  the  cache  and  its  clients.   The cache guarantees that all
184       objects returned from umem_cache_alloc() will  be  in  the  constructed
185       state,  and the client guarantees that it will return the object to the
186       constructed state before handing it to umem_cache_free().
187

RETURN VALUES

189       Upon failure, the umem_cache_create() function returns a null pointer.
190

ERRORS

192       The umem_cache_create() function will fail if:
193
194       EAGAIN    There is not enough memory available to  allocate  the  cache
195                 data structure.
196
197
198       EINVAL    The  debug_name argument is NULL, the align argument is not a
199                 power of two or is larger than the system  pagesize,  or  the
200                 bufsize argument is 0.
201
202
203       ENOMEM    The  libumem library could not be initialized, or the bufsize
204                 argument is too large and its use would cause  integer  over‐
205                 flow to occur.
206
207

EXAMPLES

209       Example 1 Use a fixed-size structure with no constructor callback.
210
211         #include <umem.h>
212
213         typedef struct my_obj {
214              long my_data1;
215         } my_obj_t;
216
217         /*
218          * my_objs can be freed at any time.  The contents of
219          * my_data1 is undefined at allocation time.
220          */
221
222         umem_cache_t *my_obj_cache;
223
224         ...
225         my_obj_cache = umem_cache_create("my_obj", sizeof (my_obj_t),
226             0, NULL, NULL, NULL, NULL, NULL, 0);
227         ...
228         my_obj_t *cur = umem_cache_alloc(my_obj_cache, UMEM_DEFAULT);
229         ...
230         /* use cur */
231         ...
232         umem_cache_free(my_obj_cache, cur);
233         ...
234
235
236       Example 2 Use an object with a mutex.
237
238         #define _REENTRANT
239         #include <synch.h>
240         #include <umem.h>
241
242         typedef struct my_obj {
243                   mutex_t my_mutex;
244                   long my_data;
245         } my_obj_t;
246
247         /*
248          * my_objs can only be freed when my_mutex is unlocked.
249          */
250         int
251         my_obj_constructor(void *buf, void *ignored, int flags)
252         {
253                   my_obj_t *myobj = buf;
254
255                   (void) mutex_init(&my_obj->my_mutex, USYNC_THREAD, NULL);
256
257                   return (0);
258         }
259
260         void
261         my_obj_destructor(void *buf, void *ignored)
262         {
263                   my_obj_t *myobj = buf;
264
265                   (void) mutex_destroy(&my_obj->my_mutex);
266         }
267
268         umem_cache_t *my_obj_cache;
269
270         ...
271         my_obj_cache = umem_cache_create("my_obj", sizeof (my_obj_t),
272             0, my_obj_constructor, my_obj_destructor, NULL, NULL,
273                  NULL, 0);
274         ...
275         my_obj_t *cur = umem_cache_alloc(my_obj_cache, UMEM_DEFAULT);
276         cur->my_data = 0;       /* cannot assume anything about my_data */
277         ...
278         umem_cache_free(my_obj_cache, cur);
279         ...
280
281
282       Example 3 Use a more complex object with a mutex.
283
284         #define _REENTRANT
285         #include <assert.h>
286         #include <synch.h>
287         #include <umem.h>
288
289         typedef struct my_obj {
290                   mutex_t my_mutex;
291                   cond_t my_cv;
292                   struct bar *my_barlist;
293                   unsigned my_refcount;
294         } my_obj_t;
295
296         /*
297          * my_objs can only be freed when my_barlist == NULL,
298          * my_refcount == 0, there are no waiters on my_cv, and
299          * my_mutex is unlocked.
300          */
301
302         int
303         my_obj_constructor(void *buf, void *ignored, int flags)
304         {
305                   my_obj_t *myobj = buf;
306
307                   (void) mutex_init(&my_obj->my_mutex, USYNC_THREAD, NULL);
308                   (void) cond_init(&my_obj->my_cv, USYNC_THREAD, NULL);
309                   myobj->my_barlist = NULL;
310                   myobj->my_refcount = 0;
311
312                   return (0);
313         }
314
315         void
316         my_obj_destructor(void *buf, void *ignored)
317         {
318                   my_obj_t *myobj = buf;
319
320                   assert(myobj->my_refcount == 0);
321                   assert(myobj->my_barlist == NULL);
322                   (void) cond_destroy(&my_obj->my_cv);
323                   (void) mutex_destroy(&my_obj->my_mutex);
324         }
325
326         umem_cache_t *my_obj_cache;
327
328         ...
329         my_obj_cache = umem_cache_create("my_obj", sizeof (my_obj_t),
330             0, my_obj_constructor, my_obj_destructor, NULL, NULL,
331                  NULL, 0);
332         ...
333         my_obj_t *cur = umem_cache_alloc(my_obj_cache, UMEM_DEFAULT);
334         ...
335         /* use cur */
336         ...
337         umem_cache_free(my_obj_cache, cur);
338         ...
339
340
341       Example  4  Use  objects  with a subordinate buffer while reusing call‐
342       backs.
343
344         #include assert.h>
345         #include umem.h>
346
347         typedef struct my_obj {
348                   char *my_buffer;
349                   size_t my_size;
350         } my_obj_t;
351
352         /*
353          * my_size and the my_buffer pointer should never be changed
354          */
355
356         int
357         my_obj_constructor(void *buf, void *arg, int flags)
358         {
359                   size_t sz = (size_t)arg;
360
361                   my_obj_t *myobj = buf;
362
363                   if ((myobj->my_buffer = umem_alloc(sz, flags)) == NULL)
364                         return (1);
365
366                   my_size = sz;
367
368                   return (0);
369         }
370
371         void
372         my_obj_destructor(void *buf, void *arg)
373         {
374                   size_t sz = (size_t)arg;
375
376                   my_obj_t *myobj = buf;
377
378                   assert(sz == buf->my_size);
379                   umem_free(myobj->my_buffer, sz);
380         }
381
382         ...
383         umem_cache_t *my_obj_4k_cache;
384         umem_cache_t *my_obj_8k_cache;
385         ...
386         my_obj_cache_4k = umem_cache_create("my_obj_4k", sizeof (my_obj_t),
387                  0, my_obj_constructor, my_obj_destructor, NULL,
388                  (void *)4096, NULL, 0);
389
390         my_obj_cache_8k = umem_cache_create("my_obj_8k", sizeof (my_obj_t),
391                  0, my_obj_constructor, my_obj_destructor, NULL,
392                  (void *)8192, NULL, 0);
393         ...
394         my_obj_t *my_obj_4k = umem_cache_alloc(my_obj_4k_cache,
395                  UMEM_DEFAULT);
396         my_obj_t *my_obj_8k = umem_cache_alloc(my_obj_8k_cache,
397                  UMEM_DEFAULT);
398         /* no assumptions should be made about the contents
399         of the buffers */
400         ...
401         /* make sure to return them to the correct cache */
402         umem_cache_free(my_obj_4k_cache, my_obj_4k);
403         umem_cache_free(my_obj_8k_cache, my_obj_8k);
404         ...
405
406
407
408       See the EXAMPLES section of umem_alloc(3MALLOC) for examples  involving
409       the UMEM_NOFAIL flag.
410

ATTRIBUTES

412       See attributes(5) for descriptions of the following attributes:
413
414
415
416
417       ┌─────────────────────────────┬─────────────────────────────┐
418       │      ATTRIBUTE TYPE         │      ATTRIBUTE VALUE        │
419       ├─────────────────────────────┼─────────────────────────────┤
420       │Interface Stability          │Committed                    │
421       ├─────────────────────────────┼─────────────────────────────┤
422       │MT-Level                     │MT-Safe                      │
423       └─────────────────────────────┴─────────────────────────────┘
424

SEE ALSO

426       setcontext(2), atexit(3C), libumem(3LIB), longjmp(3C), swapcontext(3C),
427       thr_exit(3C), umem_alloc(3MALLOC), umem_debug(3MALLOC), attributes(5)
428
429
430       Bonwick, Jeff, "The Slab Allocator:  An  Object-Caching  Kernel  Memory
431       Allocator", Proceedings of the Summer 1994 Usenix Conference.
432
433
434       Bonwick,  Jeff  and  Jonathan Adams, "Magazines and vmem: Extending the
435       Slab Allocator to Many CPUs and Arbitrary  Resources",  Proceedings  of
436       the Summer 2001 Usenix Conference.
437

WARNINGS

439       Any of the following can cause undefined results:
440
441           o      Destroying a cache that has outstanding allocated buffers.
442
443           o      Using a cache after it has been destroyed.
444
445           o      Calling umem_cache_free() on the same buffer multiple times.
446
447           o      Passing a NULL pointer to umem_cache_free().
448
449           o      Writing past the end of a buffer.
450
451           o      Reading from or writing to a buffer after it has been freed.
452
453           o      Performing  UMEM_NOFAIL  allocations from an atexit(3C) han‐
454                  dler.
455
456
457       Per-cache callbacks can be called from a variety of contexts.  The  use
458       of  functions  that  modify  the active context, such as setcontext(2),
459       swapcontext(3C), and thr_exit(3C), or functions that are unsafe for use
460       in  multithreaded applications, such as longjmp(3C) and siglongjmp(3C),
461       result in undefined behavior.
462
463
464       A constructor callback that performs allocations must  pass  its  flags
465       argument  unchanged  to umem_alloc(3MALLOC) and umem_cache_alloc(). Any
466       allocations made with a different flags argument results  in  undefined
467       behavior.   The  constructor  must  correctly handle the failure of any
468       allocations it makes.
469

NOTES

471       Object caches make the following guarantees about objects:
472
473           o      If the cache has a constructor callback, it  is  applied  to
474                  every  object  before it is returned from umem_cache_alloc()
475                  for the first time.
476
477           o      If the cache has a constructor callback, an object passed to
478                  umem_cache_free() and later returned from umem_cache_alloc()
479                  is not modified between the two events.
480
481           o      If the cache has a destructor, it is applied to all  objects
482                  before their underlying storage is returned.
483
484
485       No  other guarantees are made. In particular, even if there are buffers
486       recently freed to the cache, umem_cache_alloc() can fail.
487
488
489
490SunOS 5.11                        24 Mar 2008       umem_cache_create(3MALLOC)
Impressum