annotate src/core/ngx_slab.c @ 391:1d9bef53cd8e

Range filter: late_ranges functionality. Add one more filtering point after postpone filter. This allows to serve range capable replies with subrequests. It's not as efficient as range filtering for static data (i.e. doesn't save us from reading data from disk if some filter needs them in memory), but it may save some network bandwidth for us and for our users.
author Maxim Dounin <mdounin@mdounin.ru>
date Mon, 21 Jul 2008 05:33:01 +0400
parents 9121a0a91f47
children ce4f9ff90bfa
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
258
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
1
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
2 /*
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
3 * Copyright (C) Igor Sysoev
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
4 */
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
5
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
6 #include <ngx_config.h>
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
7 #include <ngx_core.h>
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
8
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
9 /*
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
10
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
11 12
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
12 2048 2 11
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
13 1024 4 10
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
14 512 8 9
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
15 256 16 8
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
16
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
17 128 32 4 32 7
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
18
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
19 64 64 8 63 6 1
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
20 32 128 16 127 5 1
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
21 16 256 32 254 4 2
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
22 8 512 64 504 3 8
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
23
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
24 */
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
25
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
26
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
27 #define NGX_SLAB_PAGE_MASK 3
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
28 #define NGX_SLAB_PAGE 0
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
29 #define NGX_SLAB_BIG 1
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
30 #define NGX_SLAB_EXACT 2
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
31 #define NGX_SLAB_SMALL 3
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
32
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
33 #if (NGX_PTR_SIZE == 4)
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
34
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
35 #define NGX_SLAB_PAGE_FREE 0
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
36 #define NGX_SLAB_PAGE_BUSY 0xffffffff
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
37 #define NGX_SLAB_PAGE_START 0x80000000
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
38
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
39 #define NGX_SLAB_SHIFT_MASK 0x0000000f
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
40 #define NGX_SLAB_MAP_MASK 0xffff0000
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
41 #define NGX_SLAB_MAP_SHIFT 16
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
42
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
43 #define NGX_SLAB_BUSY 0xffffffff
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
44
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
45 #else /* (NGX_PTR_SIZE == 8) */
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
46
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
47 #define NGX_SLAB_PAGE_FREE 0
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
48 #define NGX_SLAB_PAGE_BUSY 0xffffffffffffffff
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
49 #define NGX_SLAB_PAGE_START 0x8000000000000000
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
50
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
51 #define NGX_SLAB_SHIFT_MASK 0x000000000000000f
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
52 #define NGX_SLAB_MAP_MASK 0xffffffff00000000
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
53 #define NGX_SLAB_MAP_SHIFT 32
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
54
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
55 #define NGX_SLAB_BUSY 0xffffffffffffffff
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
56
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
57 #endif
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
58
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
59
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
60 #if (NGX_DEBUG_MALLOC)
358
9121a0a91f47 nginx 0.6.23
Igor Sysoev <http://sysoev.ru>
parents: 348
diff changeset
61
9121a0a91f47 nginx 0.6.23
Igor Sysoev <http://sysoev.ru>
parents: 348
diff changeset
62 #define ngx_slab_junk(p, size) ngx_memset(p, 0xD0, size)
9121a0a91f47 nginx 0.6.23
Igor Sysoev <http://sysoev.ru>
parents: 348
diff changeset
63
258
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
64 #else
358
9121a0a91f47 nginx 0.6.23
Igor Sysoev <http://sysoev.ru>
parents: 348
diff changeset
65
9121a0a91f47 nginx 0.6.23
Igor Sysoev <http://sysoev.ru>
parents: 348
diff changeset
66 #if (NGX_FREEBSD)
9121a0a91f47 nginx 0.6.23
Igor Sysoev <http://sysoev.ru>
parents: 348
diff changeset
67
9121a0a91f47 nginx 0.6.23
Igor Sysoev <http://sysoev.ru>
parents: 348
diff changeset
68 #define ngx_slab_junk(p, size) \
9121a0a91f47 nginx 0.6.23
Igor Sysoev <http://sysoev.ru>
parents: 348
diff changeset
69 if (ngx_freebsd_debug_malloc) ngx_memset(p, 0xD0, size)
9121a0a91f47 nginx 0.6.23
Igor Sysoev <http://sysoev.ru>
parents: 348
diff changeset
70
9121a0a91f47 nginx 0.6.23
Igor Sysoev <http://sysoev.ru>
parents: 348
diff changeset
71 #else
9121a0a91f47 nginx 0.6.23
Igor Sysoev <http://sysoev.ru>
parents: 348
diff changeset
72
258
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
73 #define ngx_slab_junk(p, size)
358
9121a0a91f47 nginx 0.6.23
Igor Sysoev <http://sysoev.ru>
parents: 348
diff changeset
74
9121a0a91f47 nginx 0.6.23
Igor Sysoev <http://sysoev.ru>
parents: 348
diff changeset
75 #endif
9121a0a91f47 nginx 0.6.23
Igor Sysoev <http://sysoev.ru>
parents: 348
diff changeset
76
258
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
77 #endif
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
78
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
79 static ngx_slab_page_t *ngx_slab_alloc_pages(ngx_slab_pool_t *pool,
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
80 ngx_uint_t pages);
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
81 static void ngx_slab_free_pages(ngx_slab_pool_t *pool, ngx_slab_page_t *page,
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
82 ngx_uint_t pages);
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
83
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
84
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
85 static ngx_uint_t ngx_slab_max_size;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
86 static ngx_uint_t ngx_slab_exact_size;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
87 static ngx_uint_t ngx_slab_exact_shift;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
88
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
89
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
90 void
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
91 ngx_slab_init(ngx_slab_pool_t *pool)
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
92 {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
93 u_char *p;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
94 size_t size;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
95 ngx_int_t m;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
96 ngx_uint_t i, n, pages;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
97 ngx_slab_page_t *slots;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
98
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
99 /* STUB */
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
100 if (ngx_slab_max_size == 0) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
101 ngx_slab_max_size = ngx_pagesize / 2;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
102 ngx_slab_exact_size = ngx_pagesize / (8 * sizeof(uintptr_t));
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
103 for (n = ngx_slab_exact_size; n >>= 1; ngx_slab_exact_shift++) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
104 /* void */
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
105 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
106 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
107 /**/
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
108
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
109 pool->min_size = 1 << pool->min_shift;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
110
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
111 p = (u_char *) pool + sizeof(ngx_slab_pool_t);
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
112 size = pool->end - p;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
113
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
114 ngx_slab_junk(p, size);
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
115
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
116 slots = (ngx_slab_page_t *) p;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
117 n = ngx_pagesize_shift - pool->min_shift;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
118
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
119 for (i = 0; i < n; i++) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
120 slots[i].slab = 0;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
121 slots[i].next = &slots[i];
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
122 slots[i].prev = 0;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
123 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
124
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
125 p += n * sizeof(ngx_slab_page_t);
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
126
348
e10168d6e371 nginx 0.6.18
Igor Sysoev <http://sysoev.ru>
parents: 274
diff changeset
127 pages = (ngx_uint_t) (size / (ngx_pagesize + sizeof(ngx_slab_page_t)));
258
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
128
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
129 ngx_memzero(p, pages * sizeof(ngx_slab_page_t));
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
130
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
131 pool->pages = (ngx_slab_page_t *) p;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
132
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
133 pool->free.prev = 0;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
134 pool->free.next = (ngx_slab_page_t *) p;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
135
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
136 pool->pages->slab = pages;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
137 pool->pages->next = &pool->free;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
138 pool->pages->prev = (uintptr_t) &pool->free;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
139
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
140 pool->start = (u_char *)
274
052a7b1d40e5 nginx 0.5.7
Igor Sysoev <http://sysoev.ru>
parents: 272
diff changeset
141 ngx_align_ptr((uintptr_t) p + pages * sizeof(ngx_slab_page_t),
258
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
142 ngx_pagesize);
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
143
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
144 m = pages - (pool->end - pool->start) / ngx_pagesize;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
145 if (m > 0) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
146 pages -= m;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
147 pool->pages->slab = pages;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
148 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
149
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
150 #if 0
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
151 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "slab: %p, %p, %ui, %d",
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
152 pool, pool->start, pages,
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
153 (pool->end - pool->start) / ngx_pagesize - pages);
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
154 #endif
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
155 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
156
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
157
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
158 void *
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
159 ngx_slab_alloc(ngx_slab_pool_t *pool, size_t size)
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
160 {
272
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
161 void *p;
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
162
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
163 ngx_shmtx_lock(&pool->mutex);
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
164
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
165 p = ngx_slab_alloc_locked(pool, size);
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
166
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
167 ngx_shmtx_unlock(&pool->mutex);
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
168
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
169 return p;
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
170 }
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
171
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
172
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
173 void *
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
174 ngx_slab_alloc_locked(ngx_slab_pool_t *pool, size_t size)
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
175 {
258
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
176 size_t s;
260
0effe91f6083 nginx 0.5.0
Igor Sysoev <http://sysoev.ru>
parents: 258
diff changeset
177 uintptr_t p, n, m, mask, *bitmap;
0effe91f6083 nginx 0.5.0
Igor Sysoev <http://sysoev.ru>
parents: 258
diff changeset
178 ngx_uint_t i, slot, shift, map;
258
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
179 ngx_slab_page_t *page, *prev, *slots;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
180
272
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
181 if (size >= ngx_slab_max_size) {
258
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
182
272
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
183 ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0,
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
184 "slab alloc: %uz", size);
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
185
258
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
186 page = ngx_slab_alloc_pages(pool, (size + ngx_pagesize - 1)
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
187 >> ngx_pagesize_shift);
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
188 if (page) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
189 p = (page - pool->pages) << ngx_pagesize_shift;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
190 p += (uintptr_t) pool->start;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
191
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
192 } else {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
193 p = 0;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
194 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
195
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
196 goto done;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
197 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
198
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
199 if (size > pool->min_size) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
200 shift = 1;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
201 for (s = size - 1; s >>= 1; shift++) { /* void */ }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
202 slot = shift - pool->min_shift;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
203
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
204 } else {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
205 size = pool->min_size;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
206 shift = pool->min_shift;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
207 slot = 0;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
208 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
209
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
210 ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0,
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
211 "slab alloc: %uz slot: %ui", size, slot);
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
212
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
213 slots = (ngx_slab_page_t *) ((u_char *) pool + sizeof(ngx_slab_pool_t));
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
214 page = slots[slot].next;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
215
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
216 if (page->next != page) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
217
272
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
218 if (shift < ngx_slab_exact_shift) {
258
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
219
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
220 do {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
221 p = (page - pool->pages) << ngx_pagesize_shift;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
222 bitmap = (uintptr_t *) (pool->start + p);
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
223
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
224 map = (1 << (ngx_pagesize_shift - shift))
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
225 / (sizeof(uintptr_t) * 8);
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
226
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
227 for (n = 0; n < map; n++) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
228
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
229 if (bitmap[n] != NGX_SLAB_BUSY) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
230
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
231 for (m = 1, i = 0; m; m <<= 1, i++) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
232 if ((bitmap[n] & m)) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
233 continue;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
234 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
235
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
236 bitmap[n] |= m;
272
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
237
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
238 i = ((n * sizeof(uintptr_t) * 8) << shift)
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
239 + (i << shift);
258
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
240
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
241 if (bitmap[n] == NGX_SLAB_BUSY) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
242 for (n = n + 1; n < map; n++) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
243 if (bitmap[n] != NGX_SLAB_BUSY) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
244 p = (uintptr_t) bitmap + i;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
245
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
246 goto done;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
247 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
248 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
249
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
250 prev = (ngx_slab_page_t *)
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
251 (page->prev & ~NGX_SLAB_PAGE_MASK);
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
252 prev->next = page->next;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
253 page->next->prev = page->prev;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
254
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
255 page->next = NULL;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
256 page->prev = NGX_SLAB_SMALL;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
257 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
258
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
259 p = (uintptr_t) bitmap + i;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
260
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
261 goto done;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
262 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
263 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
264 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
265
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
266 page = page->next;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
267
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
268 } while (page);
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
269
272
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
270 } else if (shift == ngx_slab_exact_shift) {
258
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
271
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
272 do {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
273 if (page->slab != NGX_SLAB_BUSY) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
274
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
275 for (m = 1, i = 0; m; m <<= 1, i++) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
276 if ((page->slab & m)) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
277 continue;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
278 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
279
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
280 page->slab |= m;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
281
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
282 if (page->slab == NGX_SLAB_BUSY) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
283 prev = (ngx_slab_page_t *)
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
284 (page->prev & ~NGX_SLAB_PAGE_MASK);
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
285 prev->next = page->next;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
286 page->next->prev = page->prev;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
287
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
288 page->next = NULL;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
289 page->prev = NGX_SLAB_EXACT;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
290 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
291
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
292 p = (page - pool->pages) << ngx_pagesize_shift;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
293 p += i << shift;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
294 p += (uintptr_t) pool->start;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
295
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
296 goto done;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
297 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
298 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
299
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
300 page = page->next;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
301
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
302 } while (page);
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
303
272
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
304 } else { /* shift > ngx_slab_exact_shift */
258
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
305
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
306 n = ngx_pagesize_shift - (page->slab & NGX_SLAB_SHIFT_MASK);
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
307 n = 1 << n;
274
052a7b1d40e5 nginx 0.5.7
Igor Sysoev <http://sysoev.ru>
parents: 272
diff changeset
308 n = ((uintptr_t) 1 << n) - 1;
258
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
309 mask = n << NGX_SLAB_MAP_SHIFT;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
310
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
311 do {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
312 if ((page->slab & NGX_SLAB_MAP_MASK) != mask) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
313
260
0effe91f6083 nginx 0.5.0
Igor Sysoev <http://sysoev.ru>
parents: 258
diff changeset
314 for (m = (uintptr_t) 1 << NGX_SLAB_MAP_SHIFT, i = 0;
258
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
315 m & mask;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
316 m <<= 1, i++)
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
317 {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
318 if ((page->slab & m)) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
319 continue;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
320 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
321
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
322 page->slab |= m;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
323
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
324 if ((page->slab & NGX_SLAB_MAP_MASK) == mask) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
325 prev = (ngx_slab_page_t *)
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
326 (page->prev & ~NGX_SLAB_PAGE_MASK);
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
327 prev->next = page->next;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
328 page->next->prev = page->prev;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
329
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
330 page->next = NULL;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
331 page->prev = NGX_SLAB_BIG;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
332 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
333
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
334 p = (page - pool->pages) << ngx_pagesize_shift;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
335 p += i << shift;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
336 p += (uintptr_t) pool->start;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
337
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
338 goto done;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
339 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
340 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
341
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
342 page = page->next;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
343
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
344 } while (page);
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
345 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
346 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
347
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
348 page = ngx_slab_alloc_pages(pool, 1);
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
349
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
350 if (page) {
272
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
351 if (shift < ngx_slab_exact_shift) {
258
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
352 p = (page - pool->pages) << ngx_pagesize_shift;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
353 bitmap = (uintptr_t *) (pool->start + p);
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
354
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
355 s = 1 << shift;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
356 n = (1 << (ngx_pagesize_shift - shift)) / 8 / s;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
357
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
358 if (n == 0) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
359 n = 1;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
360 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
361
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
362 bitmap[0] = (2 << n) - 1;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
363
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
364 map = (1 << (ngx_pagesize_shift - shift)) / (sizeof(uintptr_t) * 8);
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
365
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
366 for (i = 1; i < map; i++) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
367 bitmap[i] = 0;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
368 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
369
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
370 page->slab = shift;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
371 page->next = &slots[slot];
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
372 page->prev = (uintptr_t) &slots[slot] | NGX_SLAB_SMALL;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
373
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
374 slots[slot].next = page;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
375
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
376 p = ((page - pool->pages) << ngx_pagesize_shift) + s * n;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
377 p += (uintptr_t) pool->start;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
378
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
379 goto done;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
380
272
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
381 } else if (shift == ngx_slab_exact_shift) {
258
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
382
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
383 page->slab = 1;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
384 page->next = &slots[slot];
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
385 page->prev = (uintptr_t) &slots[slot] | NGX_SLAB_EXACT;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
386
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
387 slots[slot].next = page;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
388
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
389 p = (page - pool->pages) << ngx_pagesize_shift;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
390 p += (uintptr_t) pool->start;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
391
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
392 goto done;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
393
272
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
394 } else { /* shift > ngx_slab_exact_shift */
258
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
395
260
0effe91f6083 nginx 0.5.0
Igor Sysoev <http://sysoev.ru>
parents: 258
diff changeset
396 page->slab = ((uintptr_t) 1 << NGX_SLAB_MAP_SHIFT) | shift;
258
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
397 page->next = &slots[slot];
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
398 page->prev = (uintptr_t) &slots[slot] | NGX_SLAB_BIG;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
399
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
400 slots[slot].next = page;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
401
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
402 p = (page - pool->pages) << ngx_pagesize_shift;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
403 p += (uintptr_t) pool->start;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
404
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
405 goto done;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
406 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
407 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
408
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
409 p = 0;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
410
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
411 done:
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
412
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
413 ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0, "slab alloc: %p", p);
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
414
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
415 return (void *) p;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
416 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
417
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
418
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
419 void
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
420 ngx_slab_free(ngx_slab_pool_t *pool, void *p)
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
421 {
272
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
422 ngx_shmtx_lock(&pool->mutex);
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
423
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
424 ngx_slab_free_locked(pool, p);
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
425
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
426 ngx_shmtx_unlock(&pool->mutex);
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
427 }
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
428
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
429
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
430 void
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
431 ngx_slab_free_locked(ngx_slab_pool_t *pool, void *p)
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
432 {
258
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
433 size_t size;
274
052a7b1d40e5 nginx 0.5.7
Igor Sysoev <http://sysoev.ru>
parents: 272
diff changeset
434 uintptr_t slab, m, *bitmap;
052a7b1d40e5 nginx 0.5.7
Igor Sysoev <http://sysoev.ru>
parents: 272
diff changeset
435 ngx_uint_t n, type, slot, shift, map;
258
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
436 ngx_slab_page_t *slots, *page;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
437
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
438 ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0, "slab free: %p", p);
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
439
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
440 if ((u_char *) p < pool->start || (u_char *) p > pool->end) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
441 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
442 "ngx_slab_free(): outside of pool");
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
443 goto fail;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
444 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
445
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
446 n = ((u_char *) p - pool->start) >> ngx_pagesize_shift;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
447 page = &pool->pages[n];
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
448 slab = page->slab;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
449 type = page->prev & NGX_SLAB_PAGE_MASK;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
450
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
451 switch (type) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
452
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
453 case NGX_SLAB_SMALL:
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
454
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
455 shift = slab & NGX_SLAB_SHIFT_MASK;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
456 size = 1 << shift;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
457
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
458 if ((uintptr_t) p & (size - 1)) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
459 goto wrong_chunk;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
460 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
461
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
462 n = ((uintptr_t) p & (ngx_pagesize - 1)) >> shift;
274
052a7b1d40e5 nginx 0.5.7
Igor Sysoev <http://sysoev.ru>
parents: 272
diff changeset
463 m = (uintptr_t) 1 << (n & (sizeof(uintptr_t) * 8 - 1));
258
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
464 n /= (sizeof(uintptr_t) * 8);
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
465 bitmap = (uintptr_t *) ((uintptr_t) p & ~(ngx_pagesize - 1));
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
466
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
467 if (bitmap[n] & m) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
468
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
469 if (page->next == NULL) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
470 slots = (ngx_slab_page_t *)
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
471 ((u_char *) pool + sizeof(ngx_slab_pool_t));
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
472 slot = shift - pool->min_shift;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
473
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
474 page->next = slots[slot].next;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
475 slots[slot].next = page;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
476
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
477 page->prev = (uintptr_t) &slots[slot] | NGX_SLAB_SMALL;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
478 page->next->prev = (uintptr_t) page | NGX_SLAB_SMALL;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
479 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
480
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
481 bitmap[n] &= ~m;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
482
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
483 n = (1 << (ngx_pagesize_shift - shift)) / 8 / (1 << shift);
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
484
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
485 if (n == 0) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
486 n = 1;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
487 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
488
274
052a7b1d40e5 nginx 0.5.7
Igor Sysoev <http://sysoev.ru>
parents: 272
diff changeset
489 if (bitmap[0] & ~(((uintptr_t) 1 << n) - 1)) {
258
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
490 goto done;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
491 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
492
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
493 map = (1 << (ngx_pagesize_shift - shift)) / (sizeof(uintptr_t) * 8);
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
494
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
495 for (n = 1; n < map; n++) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
496 if (bitmap[n]) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
497 goto done;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
498 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
499 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
500
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
501 ngx_slab_free_pages(pool, page, 1);
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
502
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
503 goto done;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
504 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
505
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
506 goto chunk_already_free;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
507
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
508 case NGX_SLAB_EXACT:
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
509
274
052a7b1d40e5 nginx 0.5.7
Igor Sysoev <http://sysoev.ru>
parents: 272
diff changeset
510 m = (uintptr_t) 1 <<
052a7b1d40e5 nginx 0.5.7
Igor Sysoev <http://sysoev.ru>
parents: 272
diff changeset
511 (((uintptr_t) p & (ngx_pagesize - 1)) >> ngx_slab_exact_shift);
258
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
512 size = ngx_slab_exact_size;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
513
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
514 if ((uintptr_t) p & (size - 1)) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
515 goto wrong_chunk;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
516 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
517
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
518 if (slab & m) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
519 if (slab == NGX_SLAB_BUSY) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
520 slots = (ngx_slab_page_t *)
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
521 ((u_char *) pool + sizeof(ngx_slab_pool_t));
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
522 slot = ngx_slab_exact_shift - pool->min_shift;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
523
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
524 page->next = slots[slot].next;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
525 slots[slot].next = page;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
526
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
527 page->prev = (uintptr_t) &slots[slot] | NGX_SLAB_EXACT;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
528 page->next->prev = (uintptr_t) page | NGX_SLAB_EXACT;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
529 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
530
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
531 page->slab &= ~m;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
532
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
533 if (page->slab) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
534 goto done;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
535 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
536
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
537 ngx_slab_free_pages(pool, page, 1);
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
538
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
539 goto done;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
540 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
541
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
542 goto chunk_already_free;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
543
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
544 case NGX_SLAB_BIG:
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
545
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
546 shift = slab & NGX_SLAB_SHIFT_MASK;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
547 size = 1 << shift;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
548
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
549 if ((uintptr_t) p & (size - 1)) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
550 goto wrong_chunk;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
551 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
552
274
052a7b1d40e5 nginx 0.5.7
Igor Sysoev <http://sysoev.ru>
parents: 272
diff changeset
553 m = (uintptr_t) 1 << ((((uintptr_t) p & (ngx_pagesize - 1)) >> shift)
052a7b1d40e5 nginx 0.5.7
Igor Sysoev <http://sysoev.ru>
parents: 272
diff changeset
554 + NGX_SLAB_MAP_SHIFT);
258
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
555
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
556 if (slab & m) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
557
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
558 if (page->next == NULL) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
559 slots = (ngx_slab_page_t *)
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
560 ((u_char *) pool + sizeof(ngx_slab_pool_t));
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
561 slot = shift - pool->min_shift;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
562
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
563 page->next = slots[slot].next;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
564 slots[slot].next = page;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
565
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
566 page->prev = (uintptr_t) &slots[slot] | NGX_SLAB_BIG;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
567 page->next->prev = (uintptr_t) page | NGX_SLAB_BIG;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
568 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
569
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
570 page->slab &= ~m;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
571
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
572 if (page->slab & NGX_SLAB_MAP_MASK) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
573 goto done;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
574 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
575
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
576 ngx_slab_free_pages(pool, page, 1);
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
577
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
578 goto done;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
579 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
580
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
581 goto chunk_already_free;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
582
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
583 case NGX_SLAB_PAGE:
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
584
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
585 if ((uintptr_t) p & (ngx_pagesize - 1)) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
586 goto wrong_chunk;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
587 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
588
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
589 if (slab == NGX_SLAB_PAGE_FREE) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
590 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
591 "ngx_slab_free(): page is already free");
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
592 goto fail;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
593 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
594
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
595 if (slab == NGX_SLAB_PAGE_BUSY) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
596 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
597 "ngx_slab_free(): pointer to wrong page");
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
598 goto fail;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
599 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
600
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
601 n = ((u_char *) p - pool->start) >> ngx_pagesize_shift;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
602 size = slab & ~NGX_SLAB_PAGE_START;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
603
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
604 ngx_slab_free_pages(pool, &pool->pages[n], size);
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
605
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
606 size <<= ngx_pagesize_shift;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
607
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
608 goto done;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
609 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
610
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
611 /* not reached */
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
612
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
613 return;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
614
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
615 done:
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
616
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
617 ngx_slab_junk(p, size);
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
618
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
619 return;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
620
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
621 wrong_chunk:
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
622
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
623 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
624 "ngx_slab_free(): pointer to wrong chunk");
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
625
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
626 goto fail;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
627
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
628 chunk_already_free:
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
629
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
630 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
631 "ngx_slab_free(): chunk is already free");
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
632
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
633 fail:
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
634
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
635 return;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
636 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
637
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
638
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
639 static ngx_slab_page_t *
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
640 ngx_slab_alloc_pages(ngx_slab_pool_t *pool, ngx_uint_t pages)
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
641 {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
642 ngx_slab_page_t *page, *p;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
643
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
644 for (page = pool->free.next; page != &pool->free; page = page->next) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
645
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
646 if (page->slab >= pages) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
647
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
648 if (page->slab > pages) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
649 page[pages].slab = page->slab - pages;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
650 page[pages].next = page->next;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
651 page[pages].prev = page->prev;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
652
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
653 p = (ngx_slab_page_t *) page->prev;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
654 p->next = &page[pages];
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
655 page->next->prev = (uintptr_t) &page[pages];
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
656
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
657 } else {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
658 p = (ngx_slab_page_t *) page->prev;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
659 p->next = page->next;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
660 page->next->prev = page->prev;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
661 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
662
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
663 page->slab = pages | NGX_SLAB_PAGE_START;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
664
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
665 #if (NGX_DEBUG)
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
666 page->next = NULL;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
667 page->prev = NGX_SLAB_PAGE;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
668 #endif
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
669
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
670 if (--pages == 0) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
671 return page;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
672 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
673
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
674 for (p = page + 1; pages; pages--) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
675 p->slab = NGX_SLAB_PAGE_BUSY;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
676 #if (NGX_DEBUG)
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
677 p->next = NULL;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
678 p->prev = NGX_SLAB_PAGE;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
679 #endif
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
680 p++;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
681 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
682
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
683 return page;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
684 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
685 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
686
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
687 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, NGX_ENOMEM,
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
688 "ngx_slab_alloc(): failed");
272
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
689
258
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
690 return NULL;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
691 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
692
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
693
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
694 static void
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
695 ngx_slab_free_pages(ngx_slab_pool_t *pool, ngx_slab_page_t *page,
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
696 ngx_uint_t pages)
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
697 {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
698 ngx_slab_page_t *prev;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
699
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
700 page->slab = pages--;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
701
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
702 if (pages) {
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
703 ngx_memzero(&page[1], pages * sizeof(ngx_slab_page_t));
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
704 }
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
705
272
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
706 if (page->next) {
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
707 prev = (ngx_slab_page_t *) (page->prev & ~NGX_SLAB_PAGE_MASK);
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
708 prev->next = page->next;
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
709 page->next->prev = page->prev;
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
710 }
258
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
711
272
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
712 page->prev = (uintptr_t) &pool->free;
258
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
713 page->next = pool->free.next;
272
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
714
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
715 page->next->prev = (uintptr_t) page;
29a6403156b0 nginx 0.5.6
Igor Sysoev <http://sysoev.ru>
parents: 260
diff changeset
716
258
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
717 pool->free.next = page;
6ae1357b7b7c nginx 0.4.14
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
718 }