comparison src/core/ngx_palloc.c @ 2049:2a92804f4109

*) back out r2040 *) refactor ngx_palloc() *) introduce ngx_pnalloc() *) additional pool blocks have smaller header
author Igor Sysoev <igor@sysoev.ru>
date Tue, 17 Jun 2008 15:00:30 +0000
parents 4d8140271204
children cca975b532bf
comparison
equal deleted inserted replaced
2048:824615f3b4ec 2049:2a92804f4109
6 6
7 #include <ngx_config.h> 7 #include <ngx_config.h>
8 #include <ngx_core.h> 8 #include <ngx_core.h>
9 9
10 10
11 static void *ngx_palloc_block(ngx_pool_t *pool, size_t size);
12 static void *ngx_palloc_large(ngx_pool_t *pool, size_t size);
13
14
11 ngx_pool_t * 15 ngx_pool_t *
12 ngx_create_pool(size_t size, ngx_log_t *log) 16 ngx_create_pool(size_t size, ngx_log_t *log)
13 { 17 {
14 ngx_pool_t *p; 18 ngx_pool_t *p;
15 19
16 p = ngx_alloc(size, log); 20 p = ngx_alloc(size, log);
17 if (p == NULL) { 21 if (p == NULL) {
18 return NULL; 22 return NULL;
19 } 23 }
20 24
21 p->last = (u_char *) p + sizeof(ngx_pool_t); 25 p->d.last = (u_char *) p + sizeof(ngx_pool_t);
22 p->end = (u_char *) p + size; 26 p->d.end = (u_char *) p + size;
27 p->d.next = NULL;
28
29 p->max = (size < NGX_MAX_ALLOC_FROM_POOL) ? size - sizeof(ngx_pool_t):
30 NGX_MAX_ALLOC_FROM_POOL;
23 p->current = p; 31 p->current = p;
24 p->chain = NULL; 32 p->chain = NULL;
25 p->next = NULL;
26 p->large = NULL; 33 p->large = NULL;
27 p->cleanup = NULL; 34 p->cleanup = NULL;
28 p->log = log; 35 p->log = log;
29 36
30 return p; 37 return p;
60 /* 67 /*
61 * we could allocate the pool->log from this pool 68 * we could allocate the pool->log from this pool
62 * so we can not use this log while the free()ing the pool 69 * so we can not use this log while the free()ing the pool
63 */ 70 */
64 71
65 for (p = pool, n = pool->next; /* void */; p = n, n = n->next) { 72 for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) {
66 ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, pool->log, 0, 73 ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
67 "free: %p, unused: %uz", p, p->end - p->last); 74 "free: %p, unused: %uz", p, p->d.end - p->d.last);
68 75
69 if (n == NULL) { 76 if (n == NULL) {
70 break; 77 break;
71 } 78 }
72 } 79 }
73 80
74 #endif 81 #endif
75 82
76 for (p = pool, n = pool->next; /* void */; p = n, n = n->next) { 83 for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) {
77 ngx_free(p); 84 ngx_free(p);
78 85
79 if (n == NULL) { 86 if (n == NULL) {
80 break; 87 break;
81 } 88 }
84 91
85 92
86 void * 93 void *
87 ngx_palloc(ngx_pool_t *pool, size_t size) 94 ngx_palloc(ngx_pool_t *pool, size_t size)
88 { 95 {
89 u_char *m; 96 u_char *m;
90 ngx_pool_t *p, *n, *current; 97 ngx_pool_t *p;
91 ngx_pool_large_t *large; 98
92 99 if (size <= pool->max) {
93 if (size <= (size_t) NGX_MAX_ALLOC_FROM_POOL 100
94 && size <= (size_t) (pool->end - (u_char *) pool)
95 - (size_t) ngx_align_ptr(sizeof(ngx_pool_t), NGX_ALIGNMENT))
96 {
97 p = pool->current; 101 p = pool->current;
98 current = p; 102
99 103 do {
100 for ( ;; ) { 104 m = ngx_align_ptr(p->d.last, NGX_ALIGNMENT);
101 105
102 /* 106 if ((size_t) (p->d.end - m) >= size) {
103 * allow non-aligned memory blocks for small allocations (1, 2, 107 p->d.last = m + size;
104 * or 3 bytes) and for odd length strings (struct's have aligned
105 * size)
106 */
107
108 if (size < sizeof(int) || (size & 1)) {
109 m = p->last;
110
111 } else {
112 m = ngx_align_ptr(p->last, NGX_ALIGNMENT);
113 }
114
115 if ((size_t) (p->end - m) >= size) {
116 p->last = m + size;
117 108
118 return m; 109 return m;
119 } 110 }
120 111
121 if ((size_t) (p->end - m) < NGX_ALIGNMENT) { 112 p = p->d.next;
122 current = p->next; 113
114 } while (p);
115
116 return ngx_palloc_block(pool, size);
117 }
118
119 return ngx_palloc_large(pool, size);
120 }
121
122
123 void *
124 ngx_pnalloc(ngx_pool_t *pool, size_t size)
125 {
126 u_char *m;
127 ngx_pool_t *p;
128
129 if (size <= pool->max) {
130
131 p = pool->current;
132
133 do {
134 m = p->d.last;
135
136 if ((size_t) (p->d.end - m) >= size) {
137 p->d.last = m + size;
138
139 return m;
123 } 140 }
124 141
125 if (p->next == NULL) { 142 p = p->d.next;
126 break; 143
127 } 144 } while (p);
128 145
129 p = p->next; 146 return ngx_palloc_block(pool, size);
130 pool->current = current; 147 }
131 } 148
132 149 return ngx_palloc_large(pool, size);
133 /* allocate a new pool block */ 150 }
134 151
135 n = ngx_create_pool((size_t) (p->end - (u_char *) p), p->log); 152
136 if (n == NULL) { 153 static void *
137 return NULL; 154 ngx_palloc_block(ngx_pool_t *pool, size_t size)
138 } 155 {
139 156 u_char *m;
140 pool->current = current ? current : n; 157 ngx_pool_t *p, *new, *current;
141 158
142 p->next = n; 159 new = ngx_create_pool((size_t) (pool->d.end - (u_char *) pool), pool->log);
143 m = ngx_align_ptr(n->last, NGX_ALIGNMENT); 160 if (new == NULL) {
144 n->last = m + size; 161 return NULL;
145 162 }
146 return m; 163
147 } 164 current = pool->current;
165
166 for (p = current; p->d.next; p = p->d.next) {
167 if ((size_t) (p->d.end - p->d.last) < NGX_ALIGNMENT) {
168 current = p->d.next;
169 }
170 }
171
172 p->d.next = new;
173
174 pool->current = current ? current : new;
175
176 m = (u_char *) new + sizeof(ngx_pool_data_t);
177 new->d.last = m + size;
178
179 return m;
180 }
181
182
183 static void *
184 ngx_palloc_large(ngx_pool_t *pool, size_t size)
185 {
186 void *p;
187 ngx_pool_large_t *large;
148 188
149 #if 0 189 #if 0
150 p = ngx_memalign(ngx_pagesize, size, pool->log); 190 p = ngx_memalign(ngx_pagesize, size, pool->log);
151 if (p == NULL) { 191 if (p == NULL) {
152 return NULL; 192 return NULL;
167 large->alloc = p; 207 large->alloc = p;
168 large->next = pool->large; 208 large->next = pool->large;
169 pool->large = large; 209 pool->large = large;
170 210
171 return p; 211 return p;
172 }
173
174
175 void *
176 ngx_palloc_aligned(ngx_pool_t *pool, size_t size)
177 {
178 if (size & 1) {
179 size++;
180 }
181
182 return ngx_palloc(pool, size);
183 } 212 }
184 213
185 214
186 ngx_int_t 215 ngx_int_t
187 ngx_pfree(ngx_pool_t *pool, void *p) 216 ngx_pfree(ngx_pool_t *pool, void *p)