1 2 /* 3 * Copyright (C) Igor Sysoev 4 * Copyright (C) NGINX, Inc. 5 */ 6 7 #ifndef _NXT_UNIX_MALLOC_H_INCLUDED_ 8 #define _NXT_UNIX_MALLOC_H_INCLUDED_ 9 10 11 NXT_EXPORT void *nxt_malloc(size_t size) 12 NXT_MALLOC_LIKE; 13 NXT_EXPORT void *nxt_zalloc(size_t size) 14 NXT_MALLOC_LIKE; 15 NXT_EXPORT void *nxt_realloc(void *p, size_t size) 16 NXT_MALLOC_LIKE; 17 NXT_EXPORT void *nxt_memalign(size_t alignment, size_t size) 18 NXT_MALLOC_LIKE; 19 20 21 #if (NXT_DEBUG) 22 23 NXT_EXPORT void nxt_free(void *p); 24 25 #else 26 27 #define \ 28 nxt_free(p) \ 29 free(p) 30 31 #endif 32 33 34 #if (NXT_HAVE_MALLOC_USABLE_SIZE) 35 36 /* 37 * Due to allocation strategies malloc() allocators may allocate more 38 * memory than is requested, so malloc_usable_size() allows to use all 39 * allocated memory. It is helpful for socket buffers or unaligned disk 40 * file I/O. However, they may be suboptimal for aligned disk file I/O. 41 */ 42 43 #if (NXT_LINUX) 44 45 /* 46 * Linux glibc stores bookkeeping information together with allocated 47 * memory itself. Size of the bookkeeping information is 12 or 24 bytes 48 * on 32-bit and 64-bit platforms respectively. Due to alignment there 49 * are usually 4 or 8 spare bytes respectively. However, if allocation 50 * is larger than about 128K, spare size may be up to one page: glibc aligns 51 * sum of allocation and bookkeeping size to a page. So if requirement 52 * of the large allocation size is not strict it is better to allocate 53 * with small cutback and then to adjust size with malloc_usable_size(). 54 * Glibc malloc_usable_size() is fast operation. 55 */ 56 57 #define \ 58 nxt_malloc_usable_size(p, size) \ 59 size = malloc_usable_size(p) 60 61 #define \ 62 nxt_malloc_cutback(cutback, size) \ 63 size = ((cutback) && size > 127 * 1024) ? size - 32 : size 64 65 #elif (NXT_FREEBSD) 66 67 /* 68 * FreeBSD prior to 7.0 (phkmalloc) aligns sizes to 69 * 16 - 2048 a power of two 70 * 2049 - ... aligned to 4K 71 * 72 * FreeBSD 7.0 (jemalloc) aligns sizes to: 73 * 2 - 8 a power of two 74 * 9 - 512 aligned to 16 75 * 513 - 2048 a power of two, i.e. aligned to 1K 76 * 2049 - 1M aligned to 4K 77 * 1M- ... aligned to 1M 78 * See table in src/lib/libc/stdlib/malloc.c 79 * 80 * FreeBSD 7.0 malloc_usable_size() is fast for allocations, which 81 * are lesser than 1M. Larger allocations require mutex acquiring. 82 */ 83 84 #define \ 85 nxt_malloc_usable_size(p, size) \ 86 size = malloc_usable_size(p) 87 88 #define \ 89 nxt_malloc_cutback(cutback, size) 90 91 #endif 92 93 #elif (NXT_HAVE_MALLOC_GOOD_SIZE) 94 95 /* 96 * MacOSX aligns sizes to 97 * 16 - 496 aligned to 16, 32-bit 98 * 16 - 992 aligned to 16, 64-bit 99 * 497/993 - 15K aligned to 512, if lesser than 1G RAM 100 * 497/993 - 127K aligned to 512, otherwise 101 * 15K/127K- ... aligned to 4K 102 * 103 * malloc_good_size() is faster than malloc_size() 104 */ 105 106 #define \ 107 nxt_malloc_usable_size(p, size) \ 108 size = malloc_good_size(size) 109 110 #define \ 111 nxt_malloc_cutback(cutback, size) 112 113 #else 114 115 #define \ 116 nxt_malloc_usable_size(p, size) 117 118 #define \ 119 nxt_malloc_cutback(cutback, size) 120 121 #endif 122 123 124 #if (NXT_HAVE_POSIX_MEMALIGN || NXT_HAVE_MEMALIGN) 125 #define NXT_MAX_MEMALIGN_SHIFT 32 126 127 #elif (NXT_FREEBSD) 128 #define NXT_MAX_MEMALIGN_SHIFT 12 129 130 #else 131 #define NXT_MAX_MEMALIGN_SHIFT 3 132 #endif 133 134 135 #endif /* _NXT_UNIX_MALLOC_H_INCLUDED_ */ 136