Home | History | Annotate | Download | only in internal
      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 *
    113 extent_node_arena_get(const extent_node_t *node)
    114 {
    115 
    116 	return (node->en_arena);
    117 }
    118 
    119 JEMALLOC_INLINE void *
    120 extent_node_addr_get(const extent_node_t *node)
    121 {
    122 
    123 	return (node->en_addr);
    124 }
    125 
    126 JEMALLOC_INLINE size_t
    127 extent_node_size_get(const extent_node_t *node)
    128 {
    129 
    130 	return (node->en_size);
    131 }
    132 
    133 JEMALLOC_INLINE size_t
    134 extent_node_sn_get(const extent_node_t *node)
    135 {
    136 
    137 	return (node->en_sn);
    138 }
    139 
    140 JEMALLOC_INLINE bool
    141 extent_node_zeroed_get(const extent_node_t *node)
    142 {
    143 
    144 	return (node->en_zeroed);
    145 }
    146 
    147 JEMALLOC_INLINE bool
    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
    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 *
    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
    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
    177 extent_node_addr_set(extent_node_t *node, void *addr)
    178 {
    179 
    180 	node->en_addr = addr;
    181 }
    182 
    183 JEMALLOC_INLINE void
    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
    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
    198 extent_node_zeroed_set(extent_node_t *node, bool zeroed)
    199 {
    200 
    201 	node->en_zeroed = zeroed;
    202 }
    203 
    204 JEMALLOC_INLINE void
    205 extent_node_committed_set(extent_node_t *node, bool committed)
    206 {
    207 
    208 	node->en_committed = committed;
    209 }
    210 
    211 JEMALLOC_INLINE void
    212 extent_node_achunk_set(extent_node_t *node, bool achunk)
    213 {
    214 
    215 	node->en_achunk = achunk;
    216 }
    217 
    218 JEMALLOC_INLINE void
    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
    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
    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
    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
    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