diff options
author | Igor Sysoev <igor@sysoev.ru> | 2017-01-17 20:00:00 +0300 |
---|---|---|
committer | Igor Sysoev <igor@sysoev.ru> | 2017-01-17 20:00:00 +0300 |
commit | 16cbf3c076a0aca6d47adaf3f719493674cf2363 (patch) | |
tree | e6530480020f62a2bdbf249988ec3e2a751d3927 /src/nxt_malloc.c | |
download | unit-16cbf3c076a0aca6d47adaf3f719493674cf2363.tar.gz unit-16cbf3c076a0aca6d47adaf3f719493674cf2363.tar.bz2 |
Initial version.
Diffstat (limited to 'src/nxt_malloc.c')
-rw-r--r-- | src/nxt_malloc.c | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/src/nxt_malloc.c b/src/nxt_malloc.c new file mode 100644 index 00000000..568f04c6 --- /dev/null +++ b/src/nxt_malloc.c @@ -0,0 +1,210 @@ + +/* + * Copyright (C) Igor Sysoev + * Copyright (C) NGINX, Inc. + */ + +#include <nxt_main.h> + + +static nxt_log_moderation_t nxt_malloc_log_moderation = { + NXT_LOG_ALERT, 2, "memory allocation failed", NXT_LOG_MODERATION +}; + + +static nxt_log_t * +nxt_malloc_log(void) +{ + nxt_thread_t *thr; + + thr = nxt_thread(); + + if (thr != NULL && thr->log != NULL) { + return thr->log; + } + + return &nxt_main_log; +} + + +void * +nxt_malloc(size_t size) +{ + void *p; + + p = malloc(size); + + if (nxt_fast_path(p != NULL)) { + nxt_log_debug(nxt_malloc_log(), "malloc(%uz): %p", size, p); + + } else { + nxt_log_moderate(&nxt_malloc_log_moderation, + NXT_LOG_ALERT, nxt_malloc_log(), + "malloc(%uz) failed %E", size, nxt_errno); + } + + return p; +} + + +void * +nxt_zalloc(size_t size) +{ + void *p; + + p = nxt_malloc(size); + + if (nxt_fast_path(p != NULL)) { + nxt_memzero(p, size); + } + + return p; +} + + +void * +nxt_realloc(void *p, size_t size) +{ + void *n; + + n = realloc(p, size); + + if (nxt_fast_path(n != NULL)) { + nxt_log_debug(nxt_malloc_log(), "realloc(%p, %uz): %p", p, size, n); + + } else { + nxt_log_moderate(&nxt_malloc_log_moderation, + NXT_LOG_ALERT, nxt_malloc_log(), + "realloc(%p, %uz) failed %E", p, size, nxt_errno); + } + + return n; +} + + +#if (NXT_DEBUG) + +void +nxt_free(void *p) +{ + nxt_log_debug(nxt_malloc_log(), "free(%p)", p); + + free(p); +} + + +#endif + + +#if (NXT_HAVE_POSIX_MEMALIGN) + +/* + * posix_memalign() presents in Linux glibc 2.1.91, FreeBSD 7.0, + * Solaris 11, MacOSX 10.6 (Snow Leopard), NetBSD 5.0. + */ + +void * +nxt_memalign(size_t alignment, size_t size) +{ + void *p; + nxt_err_t err; + + err = posix_memalign(&p, alignment, size); + + if (nxt_fast_path(err == 0)) { + nxt_thread_log_debug("posix_memalign(%uz, %uz): %p", + alignment, size, p); + return p; + } + + nxt_log_moderate(&nxt_malloc_log_moderation, + NXT_LOG_ALERT, nxt_malloc_log(), + "posix_memalign(%uz, %uz) failed %E", + alignment, size, err); + return NULL; +} + +#elif (NXT_HAVE_MEMALIGN) + +/* memalign() presents in Solaris, HP-UX. */ + +void * +nxt_memalign(size_t alignment, size_t size) +{ + void *p; + + p = memalign(alignment, size); + + if (nxt_fast_path(p != NULL)) { + nxt_thread_log_debug("memalign(%uz, %uz): %p", + alignment, size, p); + return p; + } + + nxt_log_moderate(&nxt_malloc_log_moderation, + NXT_LOG_ALERT, nxt_malloc_log(), + "memalign(%uz, %uz) failed %E", + alignment, size, nxt_errno); + return NULL; +} + +#elif (NXT_FREEBSD) + +/* + * FreeBSD prior to 7.0 lacks posix_memalign(), but if a requested size + * is lesser than or equal to 4K, then phkmalloc aligns the size to the + * next highest power of 2 and allocates memory with the same alignment. + * Allocations larger than 2K are always aligned to 4K. + */ + +void * +nxt_memalign(size_t alignment, size_t size) +{ + size_t aligned_size; + u_char *p; + nxt_err_t err; + + if (nxt_slow_path((alignment - 1) & alignment) != 0) { + /* Alignment must be a power of 2. */ + err = NXT_EINVAL; + goto fail; + } + + if (nxt_slow_path(alignment > 4096)) { + err = NXT_EOPNOTSUPP; + goto fail; + } + + if (nxt_fast_path(size <= 2048)) { + aligned_size = nxt_max(size, alignment); + + } else { + /* Align to 4096. */ + aligned_size = size; + } + + p = malloc(aligned_size); + + if (nxt_fast_path(p != NULL)) { + nxt_thread_log_debug("nxt_memalign(%uz, %uz): %p", alignment, size, p); + + } else { + nxt_log_moderate(&nxt_malloc_log_moderation, + NXT_LOG_ALERT, nxt_malloc_log(), + "malloc(%uz) failed %E", size, nxt_errno); + } + + return p; + +fail: + + nxt_thread_log_alert("nxt_memalign(%uz, %uz) failed %E", + alignment, size, err); + return NULL; +} + +#else + +#error no memalign() implementation. + +#endif |