summaryrefslogtreecommitdiffhomepage
path: root/src/nxt_malloc.c
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2017-01-17 20:00:00 +0300
committerIgor Sysoev <igor@sysoev.ru>2017-01-17 20:00:00 +0300
commit16cbf3c076a0aca6d47adaf3f719493674cf2363 (patch)
treee6530480020f62a2bdbf249988ec3e2a751d3927 /src/nxt_malloc.c
downloadunit-16cbf3c076a0aca6d47adaf3f719493674cf2363.tar.gz
unit-16cbf3c076a0aca6d47adaf3f719493674cf2363.tar.bz2
Initial version.
Diffstat (limited to 'src/nxt_malloc.c')
-rw-r--r--src/nxt_malloc.c210
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