Coverage Report

Created: 2026-01-09 07:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/unit/src/nxt_malloc.c
Line
Count
Source
1
2
/*
3
 * Copyright (C) Igor Sysoev
4
 * Copyright (C) NGINX, Inc.
5
 */
6
7
#include <nxt_main.h>
8
9
10
static nxt_log_moderation_t  nxt_malloc_log_moderation = {
11
    NXT_LOG_ALERT, 2, "memory allocation failed", NXT_LOG_MODERATION
12
};
13
14
15
static nxt_log_t *
16
nxt_malloc_log(void)
17
0
{
18
0
    nxt_thread_t  *thr;
19
20
0
    thr = nxt_thread();
21
22
0
    if (thr != NULL && thr->log != NULL) {
23
0
        return thr->log;
24
0
    }
25
26
0
    return &nxt_main_log;
27
0
}
28
29
30
void *
31
nxt_malloc(size_t size)
32
5.60k
{
33
5.60k
    void  *p;
34
35
5.60k
    p = malloc(size);
36
37
5.60k
    if (nxt_fast_path(p != NULL)) {
38
5.60k
        nxt_log_debug(nxt_malloc_log(), "malloc(%uz): %p", size, p);
39
40
5.60k
    } else {
41
0
        nxt_log_alert_moderate(&nxt_malloc_log_moderation, nxt_malloc_log(),
42
0
                               "malloc(%uz) failed %E", size, nxt_errno);
43
0
    }
44
45
5.60k
    return p;
46
5.60k
}
47
48
49
void *
50
nxt_zalloc(size_t size)
51
5.60k
{
52
5.60k
    void  *p;
53
54
5.60k
    p = nxt_malloc(size);
55
56
5.60k
    if (nxt_fast_path(p != NULL)) {
57
5.60k
        nxt_memzero(p, size);
58
5.60k
    }
59
60
5.60k
    return p;
61
5.60k
}
62
63
64
void *
65
nxt_realloc(void *p, size_t size)
66
0
{
67
0
    void       *n;
68
0
    uintptr_t  ptr;
69
70
    /*
71
     * Workaround for a warning on GCC 12 about using "p" pointer in debug log
72
     * after realloc().
73
     */
74
0
    ptr = (uintptr_t) p;
75
76
0
    n = realloc(p, size);
77
78
0
    if (nxt_fast_path(n != NULL)) {
79
0
        nxt_log_debug(nxt_malloc_log(), "realloc(%p, %uz): %p", ptr, size, n);
80
81
0
    } else {
82
0
        nxt_log_alert_moderate(&nxt_malloc_log_moderation, nxt_malloc_log(),
83
0
                               "realloc(%p, %uz) failed %E",
84
0
                               ptr, size, nxt_errno);
85
0
    }
86
87
0
    return n;
88
0
}
89
90
91
/* nxt_lvlhsh_* functions moved here to avoid references from nxt_lvlhsh.c. */
92
93
void *
94
nxt_lvlhsh_alloc(void *data, size_t size)
95
2
{
96
2
    return nxt_memalign(size, size);
97
2
}
98
99
100
void
101
nxt_lvlhsh_free(void *data, void *p)
102
0
{
103
0
    nxt_free(p);
104
0
}
105
106
107
#if (NXT_DEBUG)
108
109
void
110
nxt_free(void *p)
111
{
112
    nxt_log_debug(nxt_malloc_log(), "free(%p)", p);
113
114
    free(p);
115
}
116
117
118
#endif
119
120
121
#if (NXT_HAVE_POSIX_MEMALIGN)
122
123
/*
124
 * posix_memalign() presents in Linux glibc 2.1.91, FreeBSD 7.0,
125
 * Solaris 11, MacOSX 10.6 (Snow Leopard), NetBSD 5.0.
126
 */
127
128
void *
129
nxt_memalign(size_t alignment, size_t size)
130
5.65k
{
131
5.65k
    void        *p;
132
5.65k
    nxt_err_t   err;
133
134
5.65k
    err = posix_memalign(&p, alignment, size);
135
136
5.65k
    if (nxt_fast_path(err == 0)) {
137
5.65k
        nxt_thread_log_debug("posix_memalign(%uz, %uz): %p",
138
5.65k
                             alignment, size, p);
139
5.65k
        return p;
140
5.65k
    }
141
142
0
    nxt_log_alert_moderate(&nxt_malloc_log_moderation, nxt_malloc_log(),
143
0
                           "posix_memalign(%uz, %uz) failed %E",
144
0
                           alignment, size, err);
145
    return NULL;
146
5.65k
}
147
148
#elif (NXT_HAVE_MEMALIGN)
149
150
/* memalign() presents in Solaris, HP-UX. */
151
152
void *
153
nxt_memalign(size_t alignment, size_t size)
154
{
155
    void  *p;
156
157
    p = memalign(alignment, size);
158
159
    if (nxt_fast_path(p != NULL)) {
160
        nxt_thread_log_debug("memalign(%uz, %uz): %p",
161
                             alignment, size, p);
162
        return p;
163
    }
164
165
    nxt_log_alert_moderate(&nxt_malloc_log_moderation, nxt_malloc_log(),
166
                           "memalign(%uz, %uz) failed %E",
167
                           alignment, size, nxt_errno);
168
    return NULL;
169
}
170
171
#elif (NXT_FREEBSD)
172
173
/*
174
 * FreeBSD prior to 7.0 lacks posix_memalign(), but if a requested size
175
 * is lesser than or equal to 4K, then phkmalloc aligns the size to the
176
 * next highest power of 2 and allocates memory with the same alignment.
177
 * Allocations larger than 2K are always aligned to 4K.
178
 */
179
180
void *
181
nxt_memalign(size_t alignment, size_t size)
182
{
183
    size_t     aligned_size;
184
    u_char     *p;
185
    nxt_err_t  err;
186
187
    if (nxt_slow_path((alignment - 1) & alignment) != 0) {
188
        /* Alignment must be a power of 2. */
189
        err = NXT_EINVAL;
190
        goto fail;
191
    }
192
193
    if (nxt_slow_path(alignment > 4096)) {
194
        err = NXT_EOPNOTSUPP;
195
        goto fail;
196
    }
197
198
    if (nxt_fast_path(size <= 2048)) {
199
        aligned_size = nxt_max(size, alignment);
200
201
    } else {
202
        /* Align to 4096. */
203
        aligned_size = size;
204
    }
205
206
    p = malloc(aligned_size);
207
208
    if (nxt_fast_path(p != NULL)) {
209
        nxt_thread_log_debug("nxt_memalign(%uz, %uz): %p", alignment, size, p);
210
211
    } else {
212
        nxt_log_alert_moderate(&nxt_malloc_log_moderation, nxt_malloc_log(),
213
                               "malloc(%uz) failed %E", size, nxt_errno);
214
    }
215
216
    return p;
217
218
fail:
219
220
    nxt_thread_log_alert("nxt_memalign(%uz, %uz) failed %E",
221
                         alignment, size, err);
222
    return NULL;
223
}
224
225
#else
226
227
#error no memalign() implementation.
228
229
#endif