• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************/
2 #ifdef JEMALLOC_H_TYPES
3 
4 typedef struct extent_node_s extent_node_t;
5 
6 #endif /* JEMALLOC_H_TYPES */
7 /******************************************************************************/
8 #ifdef JEMALLOC_H_STRUCTS
9 
10 /* Tree of extents.  Use accessor functions for en_* fields. */
11 struct extent_node_s {
12 	/* Arena from which this extent came, if any. */
13 	arena_t			*en_arena;
14 
15 	/* Pointer to the extent that this tree node is responsible for. */
16 	void			*en_addr;
17 
18 	/* Total region size. */
19 	size_t			en_size;
20 
21 	/*
22 	 * Serial number (potentially non-unique).
23 	 *
24 	 * In principle serial numbers can wrap around on 32-bit systems if
25 	 * JEMALLOC_MUNMAP is defined, but as long as comparison functions fall
26 	 * back on address comparison for equal serial numbers, stable (if
27 	 * imperfect) ordering is maintained.
28 	 *
29 	 * Serial numbers may not be unique even in the absence of wrap-around,
30 	 * e.g. when splitting an extent and assigning the same serial number to
31 	 * both resulting adjacent extents.
32 	 */
33 	size_t			en_sn;
34 
35 	/*
36 	 * The zeroed flag is used by chunk recycling code to track whether
37 	 * memory is zero-filled.
38 	 */
39 	bool			en_zeroed;
40 
41 	/*
42 	 * True if physical memory is committed to the extent, whether
43 	 * explicitly or implicitly as on a system that overcommits and
44 	 * satisfies physical memory needs on demand via soft page faults.
45 	 */
46 	bool			en_committed;
47 
48 	/*
49 	 * The achunk flag is used to validate that huge allocation lookups
50 	 * don't return arena chunks.
51 	 */
52 	bool			en_achunk;
53 
54 	/* Profile counters, used for huge objects. */
55 	prof_tctx_t		*en_prof_tctx;
56 
57 	/* Linkage for arena's runs_dirty and chunks_cache rings. */
58 	arena_runs_dirty_link_t	rd;
59 	qr(extent_node_t)	cc_link;
60 
61 	union {
62 		/* Linkage for the size/sn/address-ordered tree. */
63 		rb_node(extent_node_t)	szsnad_link;
64 
65 		/* Linkage for arena's achunks, huge, and node_cache lists. */
66 		ql_elm(extent_node_t)	ql_link;
67 	};
68 
69 	/* Linkage for the address-ordered tree. */
70 	rb_node(extent_node_t)	ad_link;
71 };
72 typedef rb_tree(extent_node_t) extent_tree_t;
73 
74 #endif /* JEMALLOC_H_STRUCTS */
75 /******************************************************************************/
76 #ifdef JEMALLOC_H_EXTERNS
77 
78 rb_proto(, extent_tree_szsnad_, extent_tree_t, extent_node_t)
79 
80 rb_proto(, extent_tree_ad_, extent_tree_t, extent_node_t)
81 
82 #endif /* JEMALLOC_H_EXTERNS */
83 /******************************************************************************/
84 #ifdef JEMALLOC_H_INLINES
85 
86 #ifndef JEMALLOC_ENABLE_INLINE
87 arena_t	*extent_node_arena_get(const extent_node_t *node);
88 void	*extent_node_addr_get(const extent_node_t *node);
89 size_t	extent_node_size_get(const extent_node_t *node);
90 size_t	extent_node_sn_get(const extent_node_t *node);
91 bool	extent_node_zeroed_get(const extent_node_t *node);
92 bool	extent_node_committed_get(const extent_node_t *node);
93 bool	extent_node_achunk_get(const extent_node_t *node);
94 prof_tctx_t	*extent_node_prof_tctx_get(const extent_node_t *node);
95 void	extent_node_arena_set(extent_node_t *node, arena_t *arena);
96 void	extent_node_addr_set(extent_node_t *node, void *addr);
97 void	extent_node_size_set(extent_node_t *node, size_t size);
98 void	extent_node_sn_set(extent_node_t *node, size_t sn);
99 void	extent_node_zeroed_set(extent_node_t *node, bool zeroed);
100 void	extent_node_committed_set(extent_node_t *node, bool committed);
101 void	extent_node_achunk_set(extent_node_t *node, bool achunk);
102 void	extent_node_prof_tctx_set(extent_node_t *node, prof_tctx_t *tctx);
103 void	extent_node_init(extent_node_t *node, arena_t *arena, void *addr,
104     size_t size, size_t sn, bool zeroed, bool committed);
105 void	extent_node_dirty_linkage_init(extent_node_t *node);
106 void	extent_node_dirty_insert(extent_node_t *node,
107     arena_runs_dirty_link_t *runs_dirty, extent_node_t *chunks_dirty);
108 void	extent_node_dirty_remove(extent_node_t *node);
109 #endif
110 
111 #if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_EXTENT_C_))
112 JEMALLOC_INLINE arena_t *
extent_node_arena_get(const extent_node_t * node)113 extent_node_arena_get(const extent_node_t *node)
114 {
115 
116 	return (node->en_arena);
117 }
118 
119 JEMALLOC_INLINE void *
extent_node_addr_get(const extent_node_t * node)120 extent_node_addr_get(const extent_node_t *node)
121 {
122 
123 	return (node->en_addr);
124 }
125 
126 JEMALLOC_INLINE size_t
extent_node_size_get(const extent_node_t * node)127 extent_node_size_get(const extent_node_t *node)
128 {
129 
130 	return (node->en_size);
131 }
132 
133 JEMALLOC_INLINE size_t
extent_node_sn_get(const extent_node_t * node)134 extent_node_sn_get(const extent_node_t *node)
135 {
136 
137 	return (node->en_sn);
138 }
139 
140 JEMALLOC_INLINE bool
extent_node_zeroed_get(const extent_node_t * node)141 extent_node_zeroed_get(const extent_node_t *node)
142 {
143 
144 	return (node->en_zeroed);
145 }
146 
147 JEMALLOC_INLINE bool
extent_node_committed_get(const extent_node_t * node)148 extent_node_committed_get(const extent_node_t *node)
149 {
150 
151 	assert(!node->en_achunk);
152 	return (node->en_committed);
153 }
154 
155 JEMALLOC_INLINE bool
extent_node_achunk_get(const extent_node_t * node)156 extent_node_achunk_get(const extent_node_t *node)
157 {
158 
159 	return (node->en_achunk);
160 }
161 
162 JEMALLOC_INLINE prof_tctx_t *
extent_node_prof_tctx_get(const extent_node_t * node)163 extent_node_prof_tctx_get(const extent_node_t *node)
164 {
165 
166 	return (node->en_prof_tctx);
167 }
168 
169 JEMALLOC_INLINE void
extent_node_arena_set(extent_node_t * node,arena_t * arena)170 extent_node_arena_set(extent_node_t *node, arena_t *arena)
171 {
172 
173 	node->en_arena = arena;
174 }
175 
176 JEMALLOC_INLINE void
extent_node_addr_set(extent_node_t * node,void * addr)177 extent_node_addr_set(extent_node_t *node, void *addr)
178 {
179 
180 	node->en_addr = addr;
181 }
182 
183 JEMALLOC_INLINE void
extent_node_size_set(extent_node_t * node,size_t size)184 extent_node_size_set(extent_node_t *node, size_t size)
185 {
186 
187 	node->en_size = size;
188 }
189 
190 JEMALLOC_INLINE void
extent_node_sn_set(extent_node_t * node,size_t sn)191 extent_node_sn_set(extent_node_t *node, size_t sn)
192 {
193 
194 	node->en_sn = sn;
195 }
196 
197 JEMALLOC_INLINE void
extent_node_zeroed_set(extent_node_t * node,bool zeroed)198 extent_node_zeroed_set(extent_node_t *node, bool zeroed)
199 {
200 
201 	node->en_zeroed = zeroed;
202 }
203 
204 JEMALLOC_INLINE void
extent_node_committed_set(extent_node_t * node,bool committed)205 extent_node_committed_set(extent_node_t *node, bool committed)
206 {
207 
208 	node->en_committed = committed;
209 }
210 
211 JEMALLOC_INLINE void
extent_node_achunk_set(extent_node_t * node,bool achunk)212 extent_node_achunk_set(extent_node_t *node, bool achunk)
213 {
214 
215 	node->en_achunk = achunk;
216 }
217 
218 JEMALLOC_INLINE void
extent_node_prof_tctx_set(extent_node_t * node,prof_tctx_t * tctx)219 extent_node_prof_tctx_set(extent_node_t *node, prof_tctx_t *tctx)
220 {
221 
222 	node->en_prof_tctx = tctx;
223 }
224 
225 JEMALLOC_INLINE void
extent_node_init(extent_node_t * node,arena_t * arena,void * addr,size_t size,size_t sn,bool zeroed,bool committed)226 extent_node_init(extent_node_t *node, arena_t *arena, void *addr, size_t size,
227     size_t sn, bool zeroed, bool committed)
228 {
229 
230 	extent_node_arena_set(node, arena);
231 	extent_node_addr_set(node, addr);
232 	extent_node_size_set(node, size);
233 	extent_node_sn_set(node, sn);
234 	extent_node_zeroed_set(node, zeroed);
235 	extent_node_committed_set(node, committed);
236 	extent_node_achunk_set(node, false);
237 	if (config_prof)
238 		extent_node_prof_tctx_set(node, NULL);
239 }
240 
241 JEMALLOC_INLINE void
extent_node_dirty_linkage_init(extent_node_t * node)242 extent_node_dirty_linkage_init(extent_node_t *node)
243 {
244 
245 	qr_new(&node->rd, rd_link);
246 	qr_new(node, cc_link);
247 }
248 
249 JEMALLOC_INLINE void
extent_node_dirty_insert(extent_node_t * node,arena_runs_dirty_link_t * runs_dirty,extent_node_t * chunks_dirty)250 extent_node_dirty_insert(extent_node_t *node,
251     arena_runs_dirty_link_t *runs_dirty, extent_node_t *chunks_dirty)
252 {
253 
254 	qr_meld(runs_dirty, &node->rd, rd_link);
255 	qr_meld(chunks_dirty, node, cc_link);
256 }
257 
258 JEMALLOC_INLINE void
extent_node_dirty_remove(extent_node_t * node)259 extent_node_dirty_remove(extent_node_t *node)
260 {
261 
262 	qr_remove(&node->rd, rd_link);
263 	qr_remove(node, cc_link);
264 }
265 
266 #endif
267 
268 #endif /* JEMALLOC_H_INLINES */
269 /******************************************************************************/
270 
271