comparison src/core/ngx_slab.c @ 6826:d0404c9a7675

Slab: simplified allocation from slots. Removed code that would cause an endless loop, and removed condition check that is always false. The first page in the slot list is guaranteed to satisfy an allocation.
author Ruslan Ermilov <ru@nginx.com>
date Wed, 07 Dec 2016 22:25:37 +0300
parents f6beb55792de
children 0e61510c56c4
comparison
equal deleted inserted replaced
6825:f6beb55792de 6826:d0404c9a7675
213 213
214 if (page->next != page) { 214 if (page->next != page) {
215 215
216 if (shift < ngx_slab_exact_shift) { 216 if (shift < ngx_slab_exact_shift) {
217 217
218 do { 218 bitmap = (uintptr_t *) ngx_slab_page_addr(pool, page);
219 bitmap = (uintptr_t *) ngx_slab_page_addr(pool, page); 219
220 220 map = (1 << (ngx_pagesize_shift - shift))
221 map = (1 << (ngx_pagesize_shift - shift)) 221 / (sizeof(uintptr_t) * 8);
222 / (sizeof(uintptr_t) * 8); 222
223 223 for (n = 0; n < map; n++) {
224 for (n = 0; n < map; n++) { 224
225 225 if (bitmap[n] != NGX_SLAB_BUSY) {
226 if (bitmap[n] != NGX_SLAB_BUSY) {
227
228 for (m = 1, i = 0; m; m <<= 1, i++) {
229 if (bitmap[n] & m) {
230 continue;
231 }
232
233 bitmap[n] |= m;
234
235 i = ((n * sizeof(uintptr_t) * 8) << shift)
236 + (i << shift);
237
238 if (bitmap[n] == NGX_SLAB_BUSY) {
239 for (n = n + 1; n < map; n++) {
240 if (bitmap[n] != NGX_SLAB_BUSY) {
241 p = (uintptr_t) bitmap + i;
242
243 goto done;
244 }
245 }
246
247 prev = ngx_slab_page_prev(page);
248 prev->next = page->next;
249 page->next->prev = page->prev;
250
251 page->next = NULL;
252 page->prev = NGX_SLAB_SMALL;
253 }
254
255 p = (uintptr_t) bitmap + i;
256
257 goto done;
258 }
259 }
260 }
261
262 page = page->next;
263
264 } while (page);
265
266 } else if (shift == ngx_slab_exact_shift) {
267
268 do {
269 if (page->slab != NGX_SLAB_BUSY) {
270 226
271 for (m = 1, i = 0; m; m <<= 1, i++) { 227 for (m = 1, i = 0; m; m <<= 1, i++) {
272 if (page->slab & m) { 228 if (bitmap[n] & m) {
273 continue; 229 continue;
274 } 230 }
275 231
276 page->slab |= m; 232 bitmap[n] |= m;
277 233
278 if (page->slab == NGX_SLAB_BUSY) { 234 i = ((n * sizeof(uintptr_t) * 8) << shift)
235 + (i << shift);
236
237 if (bitmap[n] == NGX_SLAB_BUSY) {
238 for (n = n + 1; n < map; n++) {
239 if (bitmap[n] != NGX_SLAB_BUSY) {
240 p = (uintptr_t) bitmap + i;
241
242 goto done;
243 }
244 }
245
279 prev = ngx_slab_page_prev(page); 246 prev = ngx_slab_page_prev(page);
280 prev->next = page->next; 247 prev->next = page->next;
281 page->next->prev = page->prev; 248 page->next->prev = page->prev;
282 249
283 page->next = NULL; 250 page->next = NULL;
284 page->prev = NGX_SLAB_EXACT; 251 page->prev = NGX_SLAB_SMALL;
285 } 252 }
286 253
287 p = ngx_slab_page_addr(pool, page) + (i << shift); 254 p = (uintptr_t) bitmap + i;
288 255
289 goto done; 256 goto done;
290 } 257 }
291 } 258 }
292 259 }
293 page = page->next; 260
294 261 } else if (shift == ngx_slab_exact_shift) {
295 } while (page); 262
263 for (m = 1, i = 0; m; m <<= 1, i++) {
264 if (page->slab & m) {
265 continue;
266 }
267
268 page->slab |= m;
269
270 if (page->slab == NGX_SLAB_BUSY) {
271 prev = ngx_slab_page_prev(page);
272 prev->next = page->next;
273 page->next->prev = page->prev;
274
275 page->next = NULL;
276 page->prev = NGX_SLAB_EXACT;
277 }
278
279 p = ngx_slab_page_addr(pool, page) + (i << shift);
280
281 goto done;
282 }
296 283
297 } else { /* shift > ngx_slab_exact_shift */ 284 } else { /* shift > ngx_slab_exact_shift */
298 285
299 n = ngx_pagesize_shift - (page->slab & NGX_SLAB_SHIFT_MASK); 286 n = ngx_pagesize_shift - (page->slab & NGX_SLAB_SHIFT_MASK);
300 n = 1 << n; 287 n = 1 << n;
301 n = ((uintptr_t) 1 << n) - 1; 288 n = ((uintptr_t) 1 << n) - 1;
302 mask = n << NGX_SLAB_MAP_SHIFT; 289 mask = n << NGX_SLAB_MAP_SHIFT;
303 290
304 do { 291 for (m = (uintptr_t) 1 << NGX_SLAB_MAP_SHIFT, i = 0;
305 if ((page->slab & NGX_SLAB_MAP_MASK) != mask) { 292 m & mask;
306 293 m <<= 1, i++)
307 for (m = (uintptr_t) 1 << NGX_SLAB_MAP_SHIFT, i = 0; 294 {
308 m & mask; 295 if (page->slab & m) {
309 m <<= 1, i++) 296 continue;
310 {
311 if (page->slab & m) {
312 continue;
313 }
314
315 page->slab |= m;
316
317 if ((page->slab & NGX_SLAB_MAP_MASK) == mask) {
318 prev = ngx_slab_page_prev(page);
319 prev->next = page->next;
320 page->next->prev = page->prev;
321
322 page->next = NULL;
323 page->prev = NGX_SLAB_BIG;
324 }
325
326 p = ngx_slab_page_addr(pool, page) + (i << shift);
327
328 goto done;
329 }
330 } 297 }
331 298
332 page = page->next; 299 page->slab |= m;
333 300
334 } while (page); 301 if ((page->slab & NGX_SLAB_MAP_MASK) == mask) {
335 } 302 prev = ngx_slab_page_prev(page);
303 prev->next = page->next;
304 page->next->prev = page->prev;
305
306 page->next = NULL;
307 page->prev = NGX_SLAB_BIG;
308 }
309
310 p = ngx_slab_page_addr(pool, page) + (i << shift);
311
312 goto done;
313 }
314 }
315
316 ngx_slab_error(pool, NGX_LOG_ALERT, "ngx_slab_alloc(): page is busy");
317 ngx_debug_point();
336 } 318 }
337 319
338 page = ngx_slab_alloc_pages(pool, 1); 320 page = ngx_slab_alloc_pages(pool, 1);
339 321
340 if (page) { 322 if (page) {