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 	 * The zeroed flag is used by chunk recycling code to track whether
23 	 * memory is zero-filled.
24 	 */
25 	bool			en_zeroed;
26 
27 	/*
28 	 * True if physical memory is committed to the extent, whether
29 	 * explicitly or implicitly as on a system that overcommits and
30 	 * satisfies physical memory needs on demand via soft page faults.
31 	 */
32 	bool			en_committed;
33 
34 	/*
35 	 * The achunk flag is used to validate that huge allocation lookups
36 	 * don't return arena chunks.
37 	 */
38 	bool			en_achunk;
39 
40 	/* Profile counters, used for huge objects. */
41 	prof_tctx_t		*en_prof_tctx;
42 
43 	/* Linkage for arena's runs_dirty and chunks_cache rings. */
44 	arena_runs_dirty_link_t	rd;
45 	qr(extent_node_t)	cc_link;
46 
47 	union {
48 		/* Linkage for the size/address-ordered tree. */
49 		rb_node(extent_node_t)	szad_link;
50 
51 		/* Linkage for arena's huge and node_cache lists. */
52 		ql_elm(extent_node_t)	ql_link;
53 	};
54 
55 	/* Linkage for the address-ordered tree. */
56 	rb_node(extent_node_t)	ad_link;
57 };
58 typedef rb_tree(extent_node_t) extent_tree_t;
59 
60 #endif /* JEMALLOC_H_STRUCTS */
61 /******************************************************************************/
62 #ifdef JEMALLOC_H_EXTERNS
63 
64 rb_proto(, extent_tree_szad_, extent_tree_t, extent_node_t)
65 
66 rb_proto(, extent_tree_ad_, extent_tree_t, extent_node_t)
67 
68 #endif /* JEMALLOC_H_EXTERNS */
69 /******************************************************************************/
70 #ifdef JEMALLOC_H_INLINES
71 
72 #ifndef JEMALLOC_ENABLE_INLINE
73 arena_t	*extent_node_arena_get(const extent_node_t *node);
74 void	*extent_node_addr_get(const extent_node_t *node);
75 size_t	extent_node_size_get(const extent_node_t *node);
76 bool	extent_node_zeroed_get(const extent_node_t *node);
77 bool	extent_node_committed_get(const extent_node_t *node);
78 bool	extent_node_achunk_get(const extent_node_t *node);
79 prof_tctx_t	*extent_node_prof_tctx_get(const extent_node_t *node);
80 void	extent_node_arena_set(extent_node_t *node, arena_t *arena);
81 void	extent_node_addr_set(extent_node_t *node, void *addr);
82 void	extent_node_size_set(extent_node_t *node, size_t size);
83 void	extent_node_zeroed_set(extent_node_t *node, bool zeroed);
84 void	extent_node_committed_set(extent_node_t *node, bool committed);
85 void	extent_node_achunk_set(extent_node_t *node, bool achunk);
86 void	extent_node_prof_tctx_set(extent_node_t *node, prof_tctx_t *tctx);
87 void	extent_node_init(extent_node_t *node, arena_t *arena, void *addr,
88     size_t size, bool zeroed, bool committed);
89 void	extent_node_dirty_linkage_init(extent_node_t *node);
90 void	extent_node_dirty_insert(extent_node_t *node,
91     arena_runs_dirty_link_t *runs_dirty, extent_node_t *chunks_dirty);
92 void	extent_node_dirty_remove(extent_node_t *node);
93 #endif
94 
95 #if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_EXTENT_C_))
96 JEMALLOC_INLINE arena_t *
extent_node_arena_get(const extent_node_t * node)97 extent_node_arena_get(const extent_node_t *node)
98 {
99 
100 	return (node->en_arena);
101 }
102 
103 JEMALLOC_INLINE void *
extent_node_addr_get(const extent_node_t * node)104 extent_node_addr_get(const extent_node_t *node)
105 {
106 
107 	return (node->en_addr);
108 }
109 
110 JEMALLOC_INLINE size_t
extent_node_size_get(const extent_node_t * node)111 extent_node_size_get(const extent_node_t *node)
112 {
113 
114 	return (node->en_size);
115 }
116 
117 JEMALLOC_INLINE bool
extent_node_zeroed_get(const extent_node_t * node)118 extent_node_zeroed_get(const extent_node_t *node)
119 {
120 
121 	return (node->en_zeroed);
122 }
123 
124 JEMALLOC_INLINE bool
extent_node_committed_get(const extent_node_t * node)125 extent_node_committed_get(const extent_node_t *node)
126 {
127 
128 	assert(!node->en_achunk);
129 	return (node->en_committed);
130 }
131 
132 JEMALLOC_INLINE bool
extent_node_achunk_get(const extent_node_t * node)133 extent_node_achunk_get(const extent_node_t *node)
134 {
135 
136 	return (node->en_achunk);
137 }
138 
139 JEMALLOC_INLINE prof_tctx_t *
extent_node_prof_tctx_get(const extent_node_t * node)140 extent_node_prof_tctx_get(const extent_node_t *node)
141 {
142 
143 	return (node->en_prof_tctx);
144 }
145 
146 JEMALLOC_INLINE void
extent_node_arena_set(extent_node_t * node,arena_t * arena)147 extent_node_arena_set(extent_node_t *node, arena_t *arena)
148 {
149 
150 	node->en_arena = arena;
151 }
152 
153 JEMALLOC_INLINE void
extent_node_addr_set(extent_node_t * node,void * addr)154 extent_node_addr_set(extent_node_t *node, void *addr)
155 {
156 
157 	node->en_addr = addr;
158 }
159 
160 JEMALLOC_INLINE void
extent_node_size_set(extent_node_t * node,size_t size)161 extent_node_size_set(extent_node_t *node, size_t size)
162 {
163 
164 	node->en_size = size;
165 }
166 
167 JEMALLOC_INLINE void
extent_node_zeroed_set(extent_node_t * node,bool zeroed)168 extent_node_zeroed_set(extent_node_t *node, bool zeroed)
169 {
170 
171 	node->en_zeroed = zeroed;
172 }
173 
174 JEMALLOC_INLINE void
extent_node_committed_set(extent_node_t * node,bool committed)175 extent_node_committed_set(extent_node_t *node, bool committed)
176 {
177 
178 	node->en_committed = committed;
179 }
180 
181 JEMALLOC_INLINE void
extent_node_achunk_set(extent_node_t * node,bool achunk)182 extent_node_achunk_set(extent_node_t *node, bool achunk)
183 {
184 
185 	node->en_achunk = achunk;
186 }
187 
188 JEMALLOC_INLINE void
extent_node_prof_tctx_set(extent_node_t * node,prof_tctx_t * tctx)189 extent_node_prof_tctx_set(extent_node_t *node, prof_tctx_t *tctx)
190 {
191 
192 	node->en_prof_tctx = tctx;
193 }
194 
195 JEMALLOC_INLINE void
extent_node_init(extent_node_t * node,arena_t * arena,void * addr,size_t size,bool zeroed,bool committed)196 extent_node_init(extent_node_t *node, arena_t *arena, void *addr, size_t size,
197     bool zeroed, bool committed)
198 {
199 
200 	extent_node_arena_set(node, arena);
201 	extent_node_addr_set(node, addr);
202 	extent_node_size_set(node, size);
203 	extent_node_zeroed_set(node, zeroed);
204 	extent_node_committed_set(node, committed);
205 	extent_node_achunk_set(node, false);
206 	if (config_prof)
207 		extent_node_prof_tctx_set(node, NULL);
208 }
209 
210 JEMALLOC_INLINE void
extent_node_dirty_linkage_init(extent_node_t * node)211 extent_node_dirty_linkage_init(extent_node_t *node)
212 {
213 
214 	qr_new(&node->rd, rd_link);
215 	qr_new(node, cc_link);
216 }
217 
218 JEMALLOC_INLINE void
extent_node_dirty_insert(extent_node_t * node,arena_runs_dirty_link_t * runs_dirty,extent_node_t * chunks_dirty)219 extent_node_dirty_insert(extent_node_t *node,
220     arena_runs_dirty_link_t *runs_dirty, extent_node_t *chunks_dirty)
221 {
222 
223 	qr_meld(runs_dirty, &node->rd, rd_link);
224 	qr_meld(chunks_dirty, node, cc_link);
225 }
226 
227 JEMALLOC_INLINE void
extent_node_dirty_remove(extent_node_t * node)228 extent_node_dirty_remove(extent_node_t *node)
229 {
230 
231 	qr_remove(&node->rd, rd_link);
232 	qr_remove(node, cc_link);
233 }
234 
235 #endif
236 
237 #endif /* JEMALLOC_H_INLINES */
238 /******************************************************************************/
239 
240