Memory Allocation Library Functions umemcachecreate(3MALOC)
NAME
umemcachecreate, umemcachedestroy, umemcachealloc,
umemcachefree - allocation cache manipulation
SYNOPSIS
cc [ flag ... ] file... -lumem [ library ... ]
#include
umemcachet *umemcachecreate(char *debugname, sizet bufsize,
sizet align, umemconstructort *constructor,
umemdestructort *destructor, umemreclaimt *reclaim,
void *callbackdata, vmemt *source, int cflags);
void umemcachedestroy(umemcachet *cache);
void *umemcachealloc(umemcachet *cache, int flags);
void umemcachefree(umemcachet *cache, void *buffer);
DESCRIPTION
These functions create, destroy, and use an "object cache"
An object cache is a collection of buffers of a single size,
with optional content caching enabled by the use of call-
backs (see Cache Callbacks). Object caches are MT-Safe.
Multiple allocations and freeing of memory from different
threads can proceed simultaneously. Object caches are fas-
ter and use less space per buffer than malloc(3MALOC) and
umemalloc(3MALOC). For more information about object
caching, see "The Slab Allocator: An Object-Caching Kernel
Memory Allocator" and "Magazines and vmem: Extending the
Slab Allocator to Many CPUs and Arbitrary Resources".
The umemcachecreate() function creates object caches. Once
a cache has been created, objects can be requested from and
returned to the cache using umemcachealloc() and
umemcachefree(), respectively. A cache with no outstanding
buffers can be destroyed with umemcachedestroy().
Creating and Destroying Caches
The umemcachecreate() function creates a cache of objects
and takes as arguments the following:
debugname A human-readable name for debugging pur-
poses.
SunOS 5.11 Last change: 24 Mar 2008 1
Memory Allocation Library Functions umemcachecreate(3MALOC)
bufsize The size, in bytes, of the buffers in this
cache.
align The minimum alignment required for buffers
in this cache. This parameter must be a
power of 2. If 0, it is replaced with the
minimum required alignment for the current
architecture.
constructor The callback to construct an object.
destructor The callback to destroy an object.
reclaim The callback to reclaim objects.
callbackdata An opaque pointer passed to the callbacks.
source This parameter must be NUL.
cflags This parameter must be either 0 or
UMCNODEBUG. If UMCNODEBUG, all debugging
features are disabled for this cache. See
umemdebug(3MALOC).
Each cache can have up to three associated callbacks:
int constructor(void *buffer, void *callbackdata, int flags);
void destructor(void *buffer, void *callbackdata);
void reclaim(void *callbackdata);
The callbackdata argument is always equal to the value
passed to umemcachecreate(), thereby allowing a client to
use the same callback functions for multiple caches, but
with customized behavior.
The reclaim callback is called when the umem function is
requesting more memory from the operating system. This call-
back can be used by clients who retain objects longer than
they are strictly needed (for example, caching non-active
state). A typical reclaim callback might return to the
SunOS 5.11 Last change: 24 Mar 2008 2
Memory Allocation Library Functions umemcachecreate(3MALOC)
cache ten per cent of the unneeded buffers.
The constructor and destructor callbacks enable the manage-
ment of buffers with the constructed state. The constructor
takes as arguments a buffer with undefined contents, some
callback data, and the flags to use for any allocations.
This callback should transform the buffer into the con-
structed state.
The destructor callback takes as an argument a constructed
object and prepares it for return to the general pool of
memory. The destructor should undo any state that the con-
structor created. For debugging, the destructor can also
check that the buffer is in the constructed state, to catch
incorrectly freed buffers. See umemdebug(3MALOC) for
further information on debugging support.
The umemcachedestroy() function destroys an object cache.
If the cache has any outstanding allocations, the behavior
is undefined.
Allocating Objects
The umemcachealloc() function takes as arguments:
cache a cache pointer
flags flags that determine the behavior if
umemcachealloc() is unable to fulfill the alloca-
tion request
If successful, umemcachealloc() returns a pointer to the
beginning of an object of bufsize length.
There are three cases to consider:
o A new buffer needed to be allocated. If the cache
was created with a constructor, it is applied to
the buffer and the resulting object is returned.
o The object cache was able to use a previously freed
buffer. If the cache was created with a construc-
tor, the object is returned unchanged from when it
was freed.
o The allocation of a new buffer failed. The flags
SunOS 5.11 Last change: 24 Mar 2008 3
Memory Allocation Library Functions umemcachecreate(3MALOC)
argument determines the behavior:
UMEMDEFAULT The umemcachealloc() function
returns NUL if the allocation
fails.
UMEMNOFAIL The umemcachealloc() function
cannot return NUL. A callback is
used to determine what action
occurs. See umemalloc(3MALOC) for
more information.
Freeing Objects
The umemcachefree() function takes as arguments:
cache a cache pointer
buf a pointer previously returned from
umemcachealloc(). This argument must not be NUL.
If the cache was created with a constructor callback, the
object must be returned to the constructed state before it
is freed.
Undefined behavior results if an object is freed multiple
times, if an object is modified after it is freed, or if an
object is freed to a cache other than the one from which it
was allocated.
Caches with Constructors
When a constructor callback is in use, there is essentially
a contract between the cache and its clients. The cache
guarantees that all objects returned from umemcachealloc()
will be in the constructed state, and the client guarantees
that it will return the object to the constructed state
before handing it to umemcachefree().
RETURN VALUES
Upon failure, the umemcachecreate() function returns a
null pointer.
ERORS
The umemcachecreate() function will fail if:
SunOS 5.11 Last change: 24 Mar 2008 4
Memory Allocation Library Functions umemcachecreate(3MALOC)
EAGAIN There is not enough memory available to allocate
the cache data structure.
EINVAL The debugname argument is NUL, the align argu-
ment is not a power of two or is larger than the
system pagesize, or the bufsize argument is 0.
ENOMEM The libumem library could not be initialized, or
the bufsize argument is too large and its use
would cause integer overflow to occur.
EXAMPLES
Example 1 Use a fixed-size structure with no constructor
callback.
#include
typedef struct myobj {
long mydata1;
} myobjt;
/*
* myobjs can be freed at any time. The contents of
* mydata1 is undefined at allocation time.
*/
umemcachet *myobjcache;
...
myobjcache = umemcachecreate("myobj", sizeof (myobjt),
0, NUL, NUL, NUL, NUL, NUL, 0);
...
myobjt *cur = umemcachealloc(myobjcache, UMEMDEFAULT);
...
/* use cur */
...
umemcachefree(myobjcache, cur);
...
Example 2 Use an object with a mutex.
#define RENTRANT
#include
#include
typedef struct myobj {
mutext mymutex;
long mydata;
SunOS 5.11 Last change: 24 Mar 2008 5
Memory Allocation Library Functions umemcachecreate(3MALOC)
} myobjt;
/*
* myobjs can only be freed when mymutex is unlocked.
*/
int
myobjconstructor(void *buf, void *ignored, int flags)
{
myobjt *myobj = buf;
(void) mutexinit(&myobj->mymutex, USYNCTHREAD, NUL);
return (0);
}
void
myobjdestructor(void *buf, void *ignored)
{
myobjt *myobj = buf;
(void) mutexdestroy(&myobj->mymutex);
}
umemcachet *myobjcache;
...
myobjcache = umemcachecreate("myobj", sizeof (myobjt),
0, myobjconstructor, myobjdestructor, NUL, NUL,
NUL, 0);
...
myobjt *cur = umemcachealloc(myobjcache, UMEMDEFAULT);
cur->mydata = 0; /* cannot assume anything about mydata */
...
umemcachefree(myobjcache, cur);
...
Example 3 Use a more complex object with a mutex.
#define RENTRANT
#include
#include
#include
typedef struct myobj {
mutext mymutex;
condt mycv;
struct bar *mybarlist;
unsigned myrefcount;
} myobjt;
/*
SunOS 5.11 Last change: 24 Mar 2008 6
Memory Allocation Library Functions umemcachecreate(3MALOC)
* myobjs can only be freed when mybarlist == NUL,
* myrefcount == 0, there are no waiters on mycv, and
* mymutex is unlocked.
*/
int
myobjconstructor(void *buf, void *ignored, int flags)
{
myobjt *myobj = buf;
(void) mutexinit(&myobj->mymutex, USYNCTHREAD, NUL);
(void) condinit(&myobj->mycv, USYNCTHREAD, NUL);
myobj->mybarlist = NUL;
myobj->myrefcount = 0;
return (0);
}
void
myobjdestructor(void *buf, void *ignored)
{
myobjt *myobj = buf;
assert(myobj->myrefcount == 0);
assert(myobj->mybarlist == NUL);
(void) conddestroy(&myobj->mycv);
(void) mutexdestroy(&myobj->mymutex);
}
umemcachet *myobjcache;
...
myobjcache = umemcachecreate("myobj", sizeof (myobjt),
0, myobjconstructor, myobjdestructor, NUL, NUL,
NUL, 0);
...
myobjt *cur = umemcachealloc(myobjcache, UMEMDEFAULT);
...
/* use cur */
...
umemcachefree(myobjcache, cur);
...
Example 4 Use objects with a subordinate buffer while reus-
ing callbacks.
#include assert.h>
#include umem.h>
typedef struct myobj {
char *mybuffer;
SunOS 5.11 Last change: 24 Mar 2008 7
Memory Allocation Library Functions umemcachecreate(3MALOC)
sizet mysize;
} myobjt;
/*
* mysize and the mybuffer pointer should never be changed
*/
int
myobjconstructor(void *buf, void *arg, int flags)
{
sizet sz = (sizet)arg;
myobjt *myobj = buf;
if ((myobj->mybuffer = umemalloc(sz, flags)) == NUL)
return (1);
mysize = sz;
return (0);
}
void
myobjdestructor(void *buf, void *arg)
{
sizet sz = (sizet)arg;
myobjt *myobj = buf;
assert(sz == buf->mysize);
umemfree(myobj->mybuffer, sz);
}
...
umemcachet *myobj4kcache;
umemcachet *myobj8kcache;
...
myobjcache4k = umemcachecreate("myobj4k", sizeof (myobjt),
0, myobjconstructor, myobjdestructor, NUL,
(void *)4096, NUL, 0);
myobjcache8k = umemcachecreate("myobj8k", sizeof (myobjt),
0, myobjconstructor, myobjdestructor, NUL,
(void *)8192, NUL, 0);
...
myobjt *myobj4k = umemcachealloc(myobj4kcache,
UMEMDEFAULT);
myobjt *myobj8k = umemcachealloc(myobj8kcache,
UMEMDEFAULT);
/* no assumptions should be made about the contents
of the buffers */
...
SunOS 5.11 Last change: 24 Mar 2008 8
Memory Allocation Library Functions umemcachecreate(3MALOC)
/* make sure to return them to the correct cache */
umemcachefree(myobj4kcache, myobj4k);
umemcachefree(myobj8kcache, myobj8k);
...
See the EXAMPLES section of umemalloc(3MALOC) for examples
involving the UMEMNOFAIL flag.
ATRIBUTES
See attributes(5) for descriptions of the following attri-
butes:
ATRIBUTE TYPE ATRIBUTE VALUE
Interface Stability Committed
MT-Level MT-Safe
SEE ALSO
setcontext(2), atexit(3C), libumem(3LIB), longjmp(3C),
swapcontext(3C), threxit(3C), umemalloc(3MALOC),
umemdebug(3MALOC), attributes(5)
Bonwick, Jeff, "The Slab Allocator: An Object-Caching Kernel
Memory Allocator", Proceedings of the Summer 1994 Usenix
Conference.
Bonwick, Jeff and Jonathan Adams, "Magazines and vmem:
Extending the Slab Allocator to Many CPUs and Arbitrary
Resources", Proceedings of the Summer 2001 Usenix Confer-
ence.
WARNINGS
Any of the following can cause undefined results:
o Destroying a cache that has outstanding allocated
buffers.
o Using a cache after it has been destroyed.
o Calling umemcachefree() on the same buffer multi-
ple times.
SunOS 5.11 Last change: 24 Mar 2008 9
Memory Allocation Library Functions umemcachecreate(3MALOC)
o Passing a NUL pointer to umemcachefree().
o Writing past the end of a buffer.
o Reading from or writing to a buffer after it has
been freed.
o Performing UMEMNOFAIL allocations from an
atexit(3C) handler.
Per-cache callbacks can be called from a variety of con-
texts. The use of functions that modify the active context,
such as setcontext(2), swapcontext(3C), and threxit(3C), or
functions that are unsafe for use in multithreaded applica-
tions, such as longjmp(3C) and siglongjmp(3C), result in
undefined behavior.
A constructor callback that performs allocations must pass
its flags argument unchanged to umemalloc(3MALOC) and
umemcachealloc(). Any allocations made with a different
flags argument results in undefined behavior. The construc-
tor must correctly handle the failure of any allocations it
makes.
NOTES
Object caches make the following guarantees about objects:
o If the cache has a constructor callback, it is
applied to every object before it is returned from
umemcachealloc() for the first time.
o If the cache has a constructor callback, an object
passed to umemcachefree() and later returned from
umemcachealloc() is not modified between the two
events.
o If the cache has a destructor, it is applied to all
objects before their underlying storage is
returned.
No other guarantees are made. In particular, even if there
are buffers recently freed to the cache, umemcachealloc()
can fail.
SunOS 5.11 Last change: 24 Mar 2008 10
|