1 
2 /*
3  * Copyright (C) Igor Sysoev
4  * Copyright (C) NGINX, Inc.
5  */
6 
7 #include <nxt_main.h>
8 #include "nxt_tests.h"
9 
10 
11 #define TIMES  1000
12 
13 
14 typedef struct {
15     size_t      size;
16     size_t      alignment;
17     nxt_bool_t  tight;
18 } nxt_malloc_size_t;
19 
20 
21 static nxt_malloc_size_t *
nxt_malloc_run_test(nxt_thread_t * thr,nxt_malloc_size_t * last,size_t size,nxt_uint_t times)22 nxt_malloc_run_test(nxt_thread_t *thr, nxt_malloc_size_t *last, size_t size,
23     nxt_uint_t times)
24 {
25     size_t         a, s, alignment;
26     uintptr_t      n;
27     nxt_uint_t     i, tight;
28     static u_char  *p[TIMES + 1];
29 
30     alignment = (size_t) -1;
31     tight = 0;
32 
33     for (i = 1; i < times; i++) {
34 
35         p[i] = nxt_malloc(size);
36         if (p[i] == NULL) {
37             return NULL;
38         }
39 
40         n = (uintptr_t) p[i];
41         a = 0;
42 
43         while ((n & 1) == 0) {
44             a++;
45             n >>= 1;
46         }
47 
48         alignment = nxt_min(alignment, a);
49     }
50 
51 
52     for (i = 1; i < times; i++) {
53         s = size;
54         nxt_malloc_usable_size(p[i], s);
55 
56         if (p[i - 1] + s == p[i] || p[i - 1] == p[i] + s) {
57             tight++;
58         }
59 
60         nxt_free(p[i]);
61     }
62 
63     alignment = 1 << alignment;
64 
65 #if 0
66     nxt_log_error(NXT_LOG_NOTICE, thr->log,
67                   "malloc: %uz, %uz, %ui", size, alignment, tight);
68 #endif
69 
70     while (last->alignment >= alignment) {
71         last--;
72     }
73 
74     last++;
75 
76     last->size = size;
77     last->alignment = alignment;
78     last->tight = times * 9 / 10 < tight;
79 
80     return last;
81 }
82 
83 
84 nxt_int_t
nxt_malloc_test(nxt_thread_t * thr)85 nxt_malloc_test(nxt_thread_t *thr)
86 {
87     size_t                    size;
88     nxt_malloc_size_t         *last, *s;
89     static nxt_malloc_size_t  sizes[100];
90 
91     nxt_log_error(NXT_LOG_NOTICE, thr->log, "malloc test started");
92 
93     last = &sizes[0];
94 
95     for (size = 1; size < 64; size++) {
96         last = nxt_malloc_run_test(thr, last, size, TIMES);
97         if (last == NULL) {
98             return NXT_ERROR;
99         }
100     }
101 
102     for (size = 64; size < 16384; size += 8) {
103         last = nxt_malloc_run_test(thr, last, size, TIMES / 4);
104         if (last == NULL) {
105             return NXT_ERROR;
106         }
107     }
108 
109     for (size = 16384; size < 512 * 1024 + 129; size += 128) {
110         last = nxt_malloc_run_test(thr, last, size, TIMES / 16);
111         if (last == NULL) {
112             return NXT_ERROR;
113         }
114     }
115 
116     for (s = &sizes[1]; s <= last; s++) {
117         nxt_log_error(NXT_LOG_NOTICE, thr->log,
118                       "malloc sizes: %uz-%uz alignment:%uz tight:%ui",
119                       s[-1].size + 1, s->size, s->alignment, s->tight);
120     }
121 
122     return NXT_OK;
123 }
124