UMEM_ALLOC(3MALLOC) Memory Allocation Library Functions UMEM_ALLOC(3MALLOC)
NAME
umem_alloc, umem_zalloc, umem_free, umem_nofail_callback - fast,
scalable memory allocation
SYNOPSIS
cc [
flag ... ]
file...
-lumem [
library ... ]
#include <umem.h>
void *umem_alloc(
size_t size,
int flags);
void *umem_zalloc(
size_t size,
int flags);
void umem_free(
void *buf,
size_t size);
void umem_nofail_callback(
(int (*callback)(void));
void *malloc(
size_t size);
void *calloc(
size_t nelem,
size_t elsize);
void free(
void *ptr);
void *memalign(
size_t alignment,
size_t size);
void *realloc(
void *ptr,
size_t size);
void *valloc(
size_t size);
DESCRIPTION
The
umem_alloc() function returns a pointer to a block of
size bytes
suitably aligned for any variable type. The initial contents of
memory allocated using
umem_alloc() is undefined. The
flags argument
determines the behavior of
umem_alloc() if it is unable to fulfill
the request. The
flags argument can take the following values:
UMEM_DEFAULT Return
NULL on failure.
UMEM_NOFAIL Call an optional
callback (set with
umem_nofail_callback()) on failure. The
callback takes no arguments and can finish by:
o returning
UMEM_CALLBACK_RETRY, in which
case the allocation will be retried. If
the allocation fails, the callback will be
invoked again.
o returning
UMEM_CALLBACK_EXIT(
status), in
which case
exit(2) is invoked with
status as its argument. The
exit() function is
called only once. If multiple threads
return from the
UMEM_NOFAIL callback with
UMEM_CALLBACK_EXIT(
status), one will call
exit() while the other blocks until
exit() terminates the program.
o invoking a context-changing function
(
setcontext(2)) or a non-local jump
(
longjmp(3C) or
siglongjmp(3C)), or ending
the current thread of control
(
thr_exit(3C) or
pthread_exit(3C)). The
application is responsible for any
necessary cleanup. The state of
libumem remains consistent.
If no callback has been set or the callback has been
set to
NULL,
umem_alloc(...,
UMEM_NOFAIL) behaves as
though the callback returned
UMEM_CALLBACK_EXIT(255).
The
libumem library can call callbacks from any place
that a
UMEM_NOFAIL allocation is issued. In
multithreaded applications, callbacks are expected to
perform their own concurrency management.
The function call
umem_alloc(0,
flag) always returns
NULL. The
function call
umem_free(
NULL, 0) is allowed.
The
umem_zalloc() function has the same semantics as
umem_alloc(),
but the block of memory is initialized to zeros before it is
returned.
The
umem_free() function frees blocks previously allocated using
umem_alloc() and
umem_zalloc(). The buffer address and size must
exactly match the original allocation. Memory must not be returned
piecemeal.
The
umem_nofail_callback() function sets the process-wide UMEM_NOFAIL
callback. See the description of UMEM_NOFAIL for more information.
The
malloc(),
calloc(),
free(),
memalign(),
realloc(), and
valloc() functions are as described in
malloc(3C). The
libumem library
provides these functions for backwards-compatibility with the
standard functions.
ENVIRONMENT VARIABLES
See
umem_debug(3MALLOC) for environment variables that effect the
debugging features of the
libumem library.
UMEM_OPTIONS Contains a list of comma-separated options.
Unrecognized options are ignored. The options that
are supported are:
backend=
sbrk backend=
mmap Set the underlying function used to
allocate memory. This option can be
set to
sbrk (the default) for an
sbrk(2)-based source or
mmap for an
mmap(2)-based source. If set to a
value that is not supported,
sbrk will be used.
perthread_cache=
size libumem allows for each thread to
cache recently freed small
allocations for future allocations.
The size argument, which accepts k,
m, g, and t, suffixes denotes the
maximum amount of memory each thread
can use for this purpose. The default
amount used is 1 MB. Any buffers in
the per-thread cache are freed when
the thread exits. The efficacy of the
per-thread cache can be determined
with the
::umastat mdb(1)
dcmd debugger command.
allocator=
best allocator=
first allocator=
instant allocator=
next Set the underlying allocation
strategy. The
best fit strategy tells
libumem to use the smallest free
segment possible. The
instant fit
strategy approximates the best fit
strategy in constant cpu time. The
first fit strategy takes the first
free segment that can honor the
allocation. The
next fit strategy
uses the next free segment after the
previously allocated one.
EXAMPLES
Example 1: Using the umem_alloc() function.
#include <stdio.h>
#include <umem.h>
...
char *buf = umem_alloc(1024, UMEM_DEFAULT);
if (buf == NULL) {
fprintf(stderr, "out of memory\n");
return (1);
}
/* cannot assume anything about buf's contents */
...
umem_free(buf, 1024);
...
Example 2: Using the umem_zalloc() function
#include <stdio.h>
#include <umem.h>
...
char *buf = umem_zalloc(1024, UMEM_DEFAULT);
if (buf == NULL) {
fprintf(stderr, "out of memory\n");
return (1);
}
/* buf contains zeros */
...
umem_free(buf, 1024);
...
Example 3: Using UMEM_NOFAIL
#include <stdlib.h>
#include <stdio.h>
#include <umem.h>
/*
* Note that the allocation code below does not have to
* check for umem_alloc() returning NULL
*/
int
my_failure_handler(void)
{
(void) fprintf(stderr, "out of memory\n");
return (UMEM_CALLBACK_EXIT(255));
}
...
umem_nofail_callback(my_failure_handler);
...
int i;
char *buf[100];
for (i = 0; i < 100; i++)
buf[i] = umem_alloc(1024 * 1024, UMEM_NOFAIL);
...
for (i = 0; i < 100; i++)
umem_free(buf[i], 1024 * 1024);
...
Example 4: Using UMEM_NOFAIL in a multithreaded application
#define _REENTRANT
#include <thread.h>
#include <stdio.h>
#include <umem.h>
void *
start_func(void *the_arg)
{
int *info = (int *)the_arg;
char *buf = umem_alloc(1024 * 1024, UMEM_NOFAIL);
/* does not need to check for buf == NULL */
buf[0] = 0;
...
/*
* if there were other UMEM_NOFAIL allocations,
* we would need to arrange for buf to be
* umem_free()ed upon failure.
*/
...
umem_free(buf, 1024 * 1024);
return (the_arg);
}
...
int
my_failure_handler(void)
{
/* terminate the current thread with status NULL */
thr_exit(NULL);
}
...
umem_nofail_callback(my_failure_handler);
...
int my_arg;
thread_t tid;
void *status;
(void) thr_create(NULL, NULL, start_func, &my_arg, 0,
NULL);
...
while (thr_join(0, &tid, &status) != 0)
;
if (status == NULL) {
(void) fprintf(stderr, "thread %d ran out of memory\n",
tid);
}
...
ATTRIBUTES
See
attributes(7) for descriptions of the following attributes:
+--------------------+-----------------+
| ATTRIBUTE TYPE | ATTRIBUTE VALUE |
+--------------------+-----------------+
|Interface Stability | Committed |
+--------------------+-----------------+
|MT-Level | MT-Safe |
+--------------------+-----------------+
|Standard | See below. |
+--------------------+-----------------+
For
malloc(),
calloc(),
free(),
realloc(), and
valloc(), see
standards(7).
SEE ALSO
exit(2),
mmap(2),
sbrk(2),
longjmp(3C),
malloc(3C),
pthread_exit(3C),
thr_exit(3C),
libumem(3LIB),
bsdmalloc(3MALLOC),
malloc(3MALLOC),
mapmalloc(3MALLOC),
umem_cache_create(3MALLOC),
umem_debug(3MALLOC),
watchmalloc(3MALLOC),
attributes(7),
standards(7) Modular Debugger Guide:
https://illumos.org/books/mdb/
WARNINGS
Any of the following can cause undefined results:
o Passing a pointer returned from
umem_alloc() or
umem_zalloc() to
free() or
realloc().
o Passing a pointer returned from
malloc(),
calloc(),
valloc(),
memalign(), or
realloc() to
umem_free().
o Writing past the end of a buffer allocated using
umem_alloc() or
umem_zalloc() o Performing
UMEM_NOFAIL allocations from an
atexit(3C) handler.
If the
UMEM_NOFAIL callback performs
UMEM_NOFAIL allocations,
infinite recursion can occur.
NOTES
The following list compares the features of the
malloc(3C),
bsdmalloc(3MALLOC),
malloc(3MALLOC),
mtmalloc(3MALLOC) , and the
libumem functions.
o The
malloc(3C),
bsdmalloc(3MALLOC), and
malloc(3MALLOC) functions have no support for concurrency. The
libumem and
mtmalloc(3MALLOC) functions support concurrent
allocations.
o The
bsdmalloc(3MALLOC) functions afford better performance
but are space-inefficient.
o The
malloc(3MALLOC) functions are space-efficient but have
slower performance.
o The standard, fully SCD-compliant
malloc(3C) functions are
a trade-off between performance and space-efficiency.
o The
mtmalloc(3MALLOC) functions provide fast, concurrent
malloc() implementations that are not space-efficient.
o The
libumem functions provide a fast, concurrent
allocation implementation that in most cases is more
space-efficient than
mtmalloc(3MALLOC).
December 9, 2017 UMEM_ALLOC(3MALLOC)