mirror of
https://github.com/jemalloc/jemalloc.git
synced 2026-04-22 02:42:12 +03:00
[EASY] Encapsulate better, do not pass hpa_shard when hooks are enough, move shard independent actions to hpa_utils
This commit is contained in:
parent
76d6771770
commit
0507f6dacc
14 changed files with 198 additions and 175 deletions
|
|
@ -2,8 +2,20 @@
|
|||
#define JEMALLOC_INTERNAL_HPA_UTILS_H
|
||||
|
||||
#include "jemalloc/internal/hpa.h"
|
||||
#include "jemalloc/internal/extent.h"
|
||||
|
||||
#define HPA_MIN_VAR_VEC_SIZE 8
|
||||
/*
|
||||
* This is used for jemalloc internal tuning and may change in the future based
|
||||
* on production traffic.
|
||||
*
|
||||
* This value protects two things:
|
||||
* 1. Stack size
|
||||
* 2. Number of huge pages that are being purged in a batch as we do not
|
||||
* allow allocations while making madvise syscall.
|
||||
*/
|
||||
#define HPA_PURGE_BATCH_MAX 16
|
||||
|
||||
#ifdef JEMALLOC_HAVE_PROCESS_MADVISE
|
||||
typedef struct iovec hpa_io_vector_t;
|
||||
#else
|
||||
|
|
@ -13,27 +25,35 @@ typedef struct {
|
|||
} hpa_io_vector_t;
|
||||
#endif
|
||||
|
||||
static inline size_t
|
||||
hpa_process_madvise_max_iovec_len(void) {
|
||||
assert(
|
||||
opt_process_madvise_max_batch <= PROCESS_MADVISE_MAX_BATCH_LIMIT);
|
||||
return opt_process_madvise_max_batch == 0
|
||||
? HPA_MIN_VAR_VEC_SIZE
|
||||
: opt_process_madvise_max_batch;
|
||||
}
|
||||
|
||||
/* Actually invoke hooks. If we fail vectorized, use single purges */
|
||||
static void
|
||||
hpa_try_vectorized_purge(
|
||||
hpa_shard_t *shard, hpa_io_vector_t *vec, size_t vlen, size_t nbytes) {
|
||||
hpa_hooks_t *hooks, hpa_io_vector_t *vec, size_t vlen, size_t nbytes) {
|
||||
bool success = opt_process_madvise_max_batch > 0
|
||||
&& !shard->central->hooks.vectorized_purge(vec, vlen, nbytes);
|
||||
&& !hooks->vectorized_purge(vec, vlen, nbytes);
|
||||
if (!success) {
|
||||
/* On failure, it is safe to purge again (potential perf
|
||||
* penalty) If kernel can tell exactly which regions
|
||||
* failed, we could avoid that penalty.
|
||||
*/
|
||||
* penalty) If kernel can tell exactly which regions
|
||||
* failed, we could avoid that penalty.
|
||||
*/
|
||||
for (size_t i = 0; i < vlen; ++i) {
|
||||
shard->central->hooks.purge(
|
||||
vec[i].iov_base, vec[i].iov_len);
|
||||
hooks->purge(vec[i].iov_base, vec[i].iov_len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This struct accumulates the regions for process_madvise.
|
||||
* It invokes the hook when batch limit is reached
|
||||
* This structure accumulates the regions for process_madvise. It invokes the
|
||||
* hook when batch limit is reached.
|
||||
*/
|
||||
typedef struct {
|
||||
hpa_io_vector_t *vp;
|
||||
|
|
@ -51,16 +71,16 @@ hpa_range_accum_init(hpa_range_accum_t *ra, hpa_io_vector_t *v, size_t sz) {
|
|||
}
|
||||
|
||||
static inline void
|
||||
hpa_range_accum_flush(hpa_range_accum_t *ra, hpa_shard_t *shard) {
|
||||
hpa_range_accum_flush(hpa_range_accum_t *ra, hpa_hooks_t *hooks) {
|
||||
assert(ra->total_bytes > 0 && ra->cur > 0);
|
||||
hpa_try_vectorized_purge(shard, ra->vp, ra->cur, ra->total_bytes);
|
||||
hpa_try_vectorized_purge(hooks, ra->vp, ra->cur, ra->total_bytes);
|
||||
ra->cur = 0;
|
||||
ra->total_bytes = 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
hpa_range_accum_add(
|
||||
hpa_range_accum_t *ra, void *addr, size_t sz, hpa_shard_t *shard) {
|
||||
hpa_range_accum_t *ra, void *addr, size_t sz, hpa_hooks_t *hooks) {
|
||||
assert(ra->cur < ra->capacity);
|
||||
|
||||
ra->vp[ra->cur].iov_base = addr;
|
||||
|
|
@ -69,14 +89,14 @@ hpa_range_accum_add(
|
|||
ra->cur++;
|
||||
|
||||
if (ra->cur == ra->capacity) {
|
||||
hpa_range_accum_flush(ra, shard);
|
||||
hpa_range_accum_flush(ra, hooks);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
hpa_range_accum_finish(hpa_range_accum_t *ra, hpa_shard_t *shard) {
|
||||
hpa_range_accum_finish(hpa_range_accum_t *ra, hpa_hooks_t *hooks) {
|
||||
if (ra->cur > 0) {
|
||||
hpa_range_accum_flush(ra, shard);
|
||||
hpa_range_accum_flush(ra, hooks);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -114,4 +134,28 @@ struct hpa_purge_batch_s {
|
|||
size_t npurged_hp_total;
|
||||
};
|
||||
|
||||
static inline bool
|
||||
hpa_batch_full(hpa_purge_batch_t *b) {
|
||||
/* It's okay for ranges to go above */
|
||||
return b->npurged_hp_total == b->max_hp
|
||||
|| b->item_cnt == b->items_capacity
|
||||
|| b->nranges >= b->range_watermark;
|
||||
}
|
||||
|
||||
static inline void
|
||||
hpa_batch_pass_start(hpa_purge_batch_t *b) {
|
||||
b->item_cnt = 0;
|
||||
b->nranges = 0;
|
||||
b->ndirty_in_batch = 0;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
hpa_batch_empty(hpa_purge_batch_t *b) {
|
||||
return b->item_cnt == 0;
|
||||
}
|
||||
|
||||
/* Purge pages in a batch using given hooks */
|
||||
void hpa_purge_batch(
|
||||
hpa_hooks_t *hooks, hpa_purge_item_t *batch, size_t batch_sz);
|
||||
|
||||
#endif /* JEMALLOC_INTERNAL_HPA_UTILS_H */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue