[ltt-dev] [PATCH 3/7] urcu, defer_rcu: Avoid thread exit unexpected

Lai Jiangshan laijs at cn.fujitsu.com
Wed Sep 28 04:34:29 EDT 2011


When a cancellation was requested, the target thread will exit
when it find any cancellation points.

Pthread cancellation is useful when further operations of one or
more threads are undesirable or unnecessary.
But thr_defer() need to release all lock before exit, unexpected
exiting will break such semantic.

pthread_testcancel() is not the only function who can creates
a cancellation points. Some other functions may also have
cancellation points. Example: poll() which in synchronize_rcu().

Signed-off-by: Lai Jiangshan <laijs at cn.fujitsu.com>
---
 urcu-defer-impl.h |   18 +++++++++++++++---
 1 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/urcu-defer-impl.h b/urcu-defer-impl.h
index 6339747..49570ff 100644
--- a/urcu-defer-impl.h
+++ b/urcu-defer-impl.h
@@ -122,6 +122,7 @@ static pthread_mutex_t rcu_defer_mutex = PTHREAD_MUTEX_INITIALIZER;
 static pthread_mutex_t defer_thread_mutex = PTHREAD_MUTEX_INITIALIZER;
 
 static int32_t defer_thread_futex;
+static int32_t defer_thread_stop;
 
 /*
  * Written to only by each individual deferer. Read by both the deferer and
@@ -148,7 +149,6 @@ static void mutex_lock_defer(pthread_mutex_t *mutex)
 			perror("Error in pthread mutex lock");
 			exit(-1);
 		}
-		pthread_testcancel();
 		poll(NULL,0,10);
 	}
 #endif /* #else #ifndef DISTRUST_SIGNALS_EXTREME */
@@ -187,7 +187,8 @@ static void wait_defer(void)
 {
 	uatomic_dec(&defer_thread_futex);
 	cmm_smp_mb();	/* Write futex before read queue */
-	pthread_testcancel();
+	if (defer_thread_stop)
+		pthread_exit(0);
 	if (rcu_defer_num_callbacks()) {
 		cmm_smp_mb();	/* Read queue before write futex */
 		/* Callbacks are queued, don't wait. */
@@ -397,10 +398,21 @@ static void stop_defer_thread(void)
 	int ret;
 	void *tret;
 
-	pthread_cancel(tid_defer);
+	/*
+	 * stop_defer_thread():		tid_defer():
+	 *
+	 * set defer_thread_stop	set futex
+	 * mb()				mb()
+	 * test futex and wake		test defer_thread_stop and exit
+	 */
+	defer_thread_stop = 1;
+	cmm_smp_mb();
 	wake_up_defer();
+
 	ret = pthread_join(tid_defer, &tret);
 	assert(!ret);
+
+	defer_thread_stop = 0;
 }
 
 int rcu_defer_register_thread(void)
-- 
1.7.4.4





More information about the lttng-dev mailing list