Make dss operations lockless.

Rather than protecting dss operations with a mutex, use atomic
operations.  This has negligible impact on synchronization overhead
during typical dss allocation, but is a substantial improvement for
extent_in_dss() and the newly added extent_dss_mergeable(), which can be
called multiple times during extent deallocations.

This change also has the advantage of avoiding tsd in deallocation paths
associated with purging, which resolves potential deadlocks during
thread exit due to attempted tsd resurrection.

This resolves #425.
This commit is contained in:
Jason Evans
2016-10-13 12:18:38 -07:00
parent e5effef428
commit 577d4572b0
11 changed files with 139 additions and 155 deletions

View File

@@ -127,9 +127,6 @@ extent_t *extent_split_wrapper(tsdn_t *tsdn, arena_t *arena,
size_t usize_a, size_t size_b, size_t usize_b);
bool extent_merge_wrapper(tsdn_t *tsdn, arena_t *arena,
extent_hooks_t **r_extent_hooks, extent_t *a, extent_t *b);
void extent_prefork(tsdn_t *tsdn);
void extent_postfork_parent(tsdn_t *tsdn);
void extent_postfork_child(tsdn_t *tsdn);
bool extent_boot(void);

View File

@@ -23,15 +23,13 @@ extern const char *dss_prec_names[];
extern const char *opt_dss;
dss_prec_t extent_dss_prec_get(tsdn_t *tsdn);
bool extent_dss_prec_set(tsdn_t *tsdn, dss_prec_t dss_prec);
dss_prec_t extent_dss_prec_get(void);
bool extent_dss_prec_set(dss_prec_t dss_prec);
void *extent_alloc_dss(tsdn_t *tsdn, arena_t *arena, void *new_addr,
size_t size, size_t alignment, bool *zero, bool *commit);
bool extent_in_dss(tsdn_t *tsdn, void *addr);
bool extent_dss_boot(void);
void extent_dss_prefork(tsdn_t *tsdn);
void extent_dss_postfork_parent(tsdn_t *tsdn);
void extent_dss_postfork_child(tsdn_t *tsdn);
bool extent_in_dss(void *addr);
bool extent_dss_mergeable(void *addr_a, void *addr_b);
void extent_dss_boot(void);
#endif /* JEMALLOC_H_EXTERNS */
/******************************************************************************/

View File

@@ -19,11 +19,11 @@ void *large_ralloc(tsdn_t *tsdn, arena_t *arena, extent_t *extent,
#ifdef JEMALLOC_JET
typedef void (large_dalloc_junk_t)(void *, size_t);
extern large_dalloc_junk_t *large_dalloc_junk;
typedef void (large_dalloc_maybe_junk_t)(tsdn_t *, void *, size_t);
typedef void (large_dalloc_maybe_junk_t)(void *, size_t);
extern large_dalloc_maybe_junk_t *large_dalloc_maybe_junk;
#else
void large_dalloc_junk(void *ptr, size_t usize);
void large_dalloc_maybe_junk(tsdn_t *tsdn, void *ptr, size_t usize);
void large_dalloc_maybe_junk(void *ptr, size_t usize);
#endif
void large_dalloc_junked_locked(tsdn_t *tsdn, extent_t *extent);
void large_dalloc(tsdn_t *tsdn, extent_t *extent);

View File

@@ -156,11 +156,9 @@ extent_dalloc_mmap
extent_dalloc_wrapper
extent_decommit_wrapper
extent_dss_boot
extent_dss_postfork_child
extent_dss_postfork_parent
extent_dss_mergeable
extent_dss_prec_get
extent_dss_prec_set
extent_dss_prefork
extent_heap_empty
extent_heap_first
extent_heap_insert
@@ -176,9 +174,6 @@ extent_last_get
extent_lookup
extent_merge_wrapper
extent_past_get
extent_postfork_child
extent_postfork_parent
extent_prefork
extent_prof_tctx_get
extent_prof_tctx_set
extent_purge_wrapper