summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordormando <dormando@rydia.net>2012-07-24 00:07:31 -0700
committerdormando <dormando@rydia.net>2012-07-27 12:47:16 -0700
commit3b2dc737567f3ee30006be82bad004f193d83025 (patch)
treed68bec14547985ed9fcae1bc18bc8e4409408a18
parent63bf748a10d1e55c67783a517d2d4d28d2a14303 (diff)
downloadmemcached-3b2dc737567f3ee30006be82bad004f193d83025.tar.gz
remove rebalancer's race condition
slabs_reassign() calls now attempt to lock, return busy if thread is already moving something.
-rw-r--r--slabs.c20
1 files changed, 9 insertions, 11 deletions
diff --git a/slabs.c b/slabs.c
index 2503381..060fb25 100644
--- a/slabs.c
+++ b/slabs.c
@@ -52,6 +52,7 @@ static size_t mem_avail = 0;
* Access to the slab allocator is protected by this lock
*/
static pthread_mutex_t slabs_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t slabs_rebalance_lock = PTHREAD_MUTEX_INITIALIZER;
/*
* Forward Declarations
@@ -754,7 +755,7 @@ static void *slab_maintenance_thread(void *arg) {
*/
static void *slab_rebalance_thread(void *arg) {
int was_busy = 0;
-
+
while (do_run_slab_rebalance_thread) {
if (slab_rebalance_signal == 1) {
if (slab_rebalance_start() < 0) {
@@ -776,14 +777,8 @@ static void *slab_rebalance_thread(void *arg) {
}
if (slab_rebalance_signal == 0) {
- /* Wrap the conditional with slabs_lock so we can't accidentally miss
- * a signal */
- /* FIXME: Technically there's a race between
- * slab_rebalance_finish() and the wait here. move this around?
- */
- mutex_lock(&slabs_lock);
- pthread_cond_wait(&slab_rebalance_cond, &slabs_lock);
- pthread_mutex_unlock(&slabs_lock);
+ /* always hold this lock while we're running */
+ pthread_cond_wait(&slab_rebalance_cond, &slabs_rebalance_lock);
}
}
return NULL;
@@ -840,9 +835,11 @@ static enum reassign_result_type do_slabs_reassign(int src, int dst) {
enum reassign_result_type slabs_reassign(int src, int dst) {
enum reassign_result_type ret;
- mutex_lock(&slabs_lock);
+ if (pthread_mutex_trylock(&slabs_rebalance_lock) != 0) {
+ return REASSIGN_RUNNING;
+ }
ret = do_slabs_reassign(src, dst);
- pthread_mutex_unlock(&slabs_lock);
+ pthread_mutex_unlock(&slabs_rebalance_lock);
return ret;
}
@@ -865,6 +862,7 @@ int start_slab_maintenance_thread(void) {
fprintf(stderr, "Can't intiialize rebalance condition\n");
return -1;
}
+ pthread_mutex_init(&slabs_rebalance_lock, NULL);
if ((ret = pthread_create(&maintenance_tid, NULL,
slab_maintenance_thread, NULL)) != 0) {