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