Edata: add an "age" field.
This commit is contained in:
parent
6599651aee
commit
634ec6f50a
@ -71,6 +71,7 @@ struct edata_map_info_s {
|
|||||||
typedef struct edata_s edata_t;
|
typedef struct edata_s edata_t;
|
||||||
typedef ph(edata_t) edata_tree_t;
|
typedef ph(edata_t) edata_tree_t;
|
||||||
typedef ph(edata_t) edata_heap_t;
|
typedef ph(edata_t) edata_heap_t;
|
||||||
|
typedef ph(edata_t) edata_age_heap_t;
|
||||||
struct edata_s {
|
struct edata_s {
|
||||||
/*
|
/*
|
||||||
* Bitfield containing several fields:
|
* Bitfield containing several fields:
|
||||||
@ -193,16 +194,11 @@ struct edata_s {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reserved for hugepages -- once that allocator is more settled, we
|
* In some context-specific sense, the age of an active extent. Each
|
||||||
* might be able to claw some of this back. Until then, don't get any
|
* context can pick a specific meaning, and share the definition of the
|
||||||
* funny ideas about using the space we just freed up to keep some other
|
* edata_age_heap_t below.
|
||||||
* bit of metadata around. That kind of thinking can be hazardous to
|
|
||||||
* your health.
|
|
||||||
*
|
|
||||||
* This keeps the size of an edata_t at exactly 128 bytes on
|
|
||||||
* architectures with 8-byte pointers and 4k pages.
|
|
||||||
*/
|
*/
|
||||||
void *reserved1;
|
uint64_t age;
|
||||||
union {
|
union {
|
||||||
/*
|
/*
|
||||||
* We could steal a low bit from these fields to indicate what
|
* We could steal a low bit from these fields to indicate what
|
||||||
@ -374,6 +370,11 @@ edata_bsize_get(const edata_t *edata) {
|
|||||||
return edata->e_bsize;
|
return edata->e_bsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline uint64_t
|
||||||
|
edata_age_get(const edata_t *edata) {
|
||||||
|
return edata->age;
|
||||||
|
}
|
||||||
|
|
||||||
static inline edata_t *
|
static inline edata_t *
|
||||||
edata_ps_get(const edata_t *edata) {
|
edata_ps_get(const edata_t *edata) {
|
||||||
assert(edata_pai_get(edata) == EXTENT_PAI_HPA);
|
assert(edata_pai_get(edata) == EXTENT_PAI_HPA);
|
||||||
@ -468,6 +469,11 @@ edata_bsize_set(edata_t *edata, size_t bsize) {
|
|||||||
edata->e_bsize = bsize;
|
edata->e_bsize = bsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
edata_age_set(edata_t *edata, uint64_t age) {
|
||||||
|
edata->age = age;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
edata_ps_set(edata_t *edata, edata_t *ps) {
|
edata_ps_set(edata_t *edata, edata_t *ps) {
|
||||||
assert(edata_pai_get(edata) == EXTENT_PAI_HPA || ps == NULL);
|
assert(edata_pai_get(edata) == EXTENT_PAI_HPA || ps == NULL);
|
||||||
@ -615,6 +621,7 @@ edata_init(edata_t *edata, unsigned arena_ind, void *addr, size_t size,
|
|||||||
if (config_prof) {
|
if (config_prof) {
|
||||||
edata_prof_tctx_set(edata, NULL);
|
edata_prof_tctx_set(edata, NULL);
|
||||||
}
|
}
|
||||||
|
edata_age_set(edata, 0);
|
||||||
edata_ps_set(edata, NULL);
|
edata_ps_set(edata, NULL);
|
||||||
edata_longest_free_range_set(edata, 0);
|
edata_longest_free_range_set(edata, 0);
|
||||||
}
|
}
|
||||||
@ -630,6 +637,7 @@ edata_binit(edata_t *edata, void *addr, size_t bsize, size_t sn) {
|
|||||||
edata_state_set(edata, extent_state_active);
|
edata_state_set(edata, extent_state_active);
|
||||||
edata_zeroed_set(edata, true);
|
edata_zeroed_set(edata, true);
|
||||||
edata_committed_set(edata, true);
|
edata_committed_set(edata, true);
|
||||||
|
edata_age_set(edata, 0);
|
||||||
/*
|
/*
|
||||||
* This isn't strictly true, but base allocated extents never get
|
* This isn't strictly true, but base allocated extents never get
|
||||||
* deallocated and can't be looked up in the emap, but no sense in
|
* deallocated and can't be looked up in the emap, but no sense in
|
||||||
@ -698,7 +706,25 @@ edata_esnead_comp(const edata_t *a, const edata_t *b) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
edata_age_comp(const edata_t *a, const edata_t *b) {
|
||||||
|
uint64_t a_age = edata_age_get(a);
|
||||||
|
uint64_t b_age = edata_age_get(b);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Equal ages are possible in certain race conditions, like two distinct
|
||||||
|
* threads simultaneously allocating a new fresh slab without holding a
|
||||||
|
* bin lock.
|
||||||
|
*/
|
||||||
|
int ret = (a_age > b_age) - (a_age < b_age);
|
||||||
|
if (ret != 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return edata_snad_comp(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
ph_proto(, edata_avail_, edata_tree_t, edata_t)
|
ph_proto(, edata_avail_, edata_tree_t, edata_t)
|
||||||
ph_proto(, edata_heap_, edata_heap_t, edata_t)
|
ph_proto(, edata_heap_, edata_heap_t, edata_t)
|
||||||
|
ph_proto(, edata_age_heap_, edata_age_heap_t, edata_t);
|
||||||
|
|
||||||
#endif /* JEMALLOC_INTERNAL_EDATA_H */
|
#endif /* JEMALLOC_INTERNAL_EDATA_H */
|
||||||
|
@ -4,3 +4,4 @@
|
|||||||
ph_gen(, edata_avail_, edata_tree_t, edata_t, ph_link,
|
ph_gen(, edata_avail_, edata_tree_t, edata_t, ph_link,
|
||||||
edata_esnead_comp)
|
edata_esnead_comp)
|
||||||
ph_gen(, edata_heap_, edata_heap_t, edata_t, ph_link, edata_snad_comp)
|
ph_gen(, edata_heap_, edata_heap_t, edata_t, ph_link, edata_snad_comp)
|
||||||
|
ph_gen(, edata_age_heap_, edata_age_heap_t, edata_t, ph_link, edata_age_comp)
|
||||||
|
Loading…
Reference in New Issue
Block a user