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)