Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 3 Jan 2005 02:02:06 GMT
From:      David Xu <davidxu@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 68182 for review
Message-ID:  <200501030202.j0322548058581@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=68182

Change 68182 by davidxu@davidxu_celeron on 2005/01/03 02:01:16

	simplify code.

Affected files ...

.. //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_cancel.c#6 edit

Differences ...

==== //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_cancel.c#6 (text+ko) ====

@@ -39,17 +39,19 @@
 _pthread_cancel(pthread_t pthread)
 {
 	struct pthread *curthread = _get_curthread();
-	int oldval, newval, ret;
+	int oldval, newval = 0;
+	int ret;
 
 	if ((ret = _thr_ref_add(curthread, pthread, 0)) != 0)
 		return (ret);
+
 	do {
 		oldval = pthread->cancelflags;
 		if (oldval & THR_CANCEL_NEEDED)
 			break;
 		newval = oldval | THR_CANCEL_NEEDED;
 	} while (!atomic_cmpset_acq_int(&pthread->cancelflags, oldval, newval));
-	
+
 	if (!(oldval & THR_CANCEL_NEEDED) && SHOULD_ASYNC_CANCEL(newval))
 		thr_kill(pthread->tid, SIGCANCEL);
 
@@ -57,78 +59,75 @@
 	return (0);
 }
 
+static inline void
+testcancel(struct pthread *curthread)
+{
+	int newval;
+
+	newval = curthread->cancelflags;
+	if (SHOULD_CANCEL(newval))
+		pthread_exit(PTHREAD_CANCELED);
+}
+
 int
 _pthread_setcancelstate(int state, int *oldstate)
 {
 	struct pthread *curthread = _get_curthread();
-	int oldval, newval;
+	int oldval, ret;
 
-	if (state != PTHREAD_CANCEL_ENABLE && state != PTHREAD_CANCEL_DISABLE)
-		return (EINVAL);
+	oldval = curthread->cancelflags;
+	if (oldstate != NULL)
+		*oldstate = ((oldval & THR_CANCEL_DISABLE) ?
+		    PTHREAD_CANCEL_DISABLE : PTHREAD_CANCEL_ENABLE);
+	switch (state) {
+	case PTHREAD_CANCEL_DISABLE:
+		atomic_set_int(&curthread->cancelflags, THR_CANCEL_DISABLE);
+		ret = 0;
+		break;
+	case PTHREAD_CANCEL_ENABLE:
+		atomic_clear_int(&curthread->cancelflags, THR_CANCEL_DISABLE);
+		testcancel(curthread);
+		ret = 0;
+		break;
+	default:
+		ret = EINVAL;
+	}
 
-	for (;;) {
-		oldval = curthread->cancelflags;
-		newval = (state == PTHREAD_CANCEL_DISABLE ?
-			oldval | THR_CANCEL_DISABLE :
-			oldval & ~THR_CANCEL_DISABLE);
-
-		if (oldstate != NULL)
-			*oldstate = ((oldval & THR_CANCEL_DISABLE) ?
-			    PTHREAD_CANCEL_DISABLE : PTHREAD_CANCEL_ENABLE);
-
-		if (oldval == newval)
-			break;
-
-		if (atomic_cmpset_acq_int(&curthread->cancelflags, oldval,
-		    newval)) {
-			if (SHOULD_CANCEL(newval))
-				pthread_exit(PTHREAD_CANCELED);
-			break;
-		}
-	}
-	
-	return (0);
+	return (ret);
 }
 
 int
 _pthread_setcanceltype(int type, int *oldtype)
 {
 	struct pthread	*curthread = _get_curthread();
-	int oldval, newval;
+	int oldval, ret;
 
-	if (type != PTHREAD_CANCEL_DEFERRED &&
-	    type != PTHREAD_CANCEL_ASYNCHRONOUS)
-		return (EINVAL);
-
-	for (;;) {
-		oldval = curthread->cancelflags;
-		if (oldtype != NULL)
-			*oldtype = ((oldval & THR_CANCEL_AT_POINT) ?
+	oldval = curthread->cancelflags;
+	if (oldtype != NULL)
+		*oldtype = ((oldval & THR_CANCEL_AT_POINT) ?
 				 PTHREAD_CANCEL_ASYNCHRONOUS :
 				 PTHREAD_CANCEL_DEFERRED);
-		newval = (type == PTHREAD_CANCEL_ASYNCHRONOUS ?
-			oldval | THR_CANCEL_AT_POINT :
-			oldval & ~THR_CANCEL_AT_POINT);
-		if (oldval == newval)
-			break;
-		if (atomic_cmpset_acq_int(&curthread->cancelflags, oldval,
-		    newval)) {
-			if (SHOULD_CANCEL(newval))
-				pthread_exit(PTHREAD_CANCELED);
-			break;
-		}
+	switch (type) {
+	case PTHREAD_CANCEL_ASYNCHRONOUS:
+		atomic_set_int(&curthread->cancelflags, THR_CANCEL_AT_POINT);
+		testcancel(curthread);
+		ret = 0;
+		break;
+	case PTHREAD_CANCEL_DEFERRED:
+		atomic_clear_int(&curthread->cancelflags, THR_CANCEL_AT_POINT);
+		ret = 0;
+		break;
+	default:
+		ret = EINVAL;
 	}
-	
-	return (0);
+
+	return (ret);
 }
 
 void
 _pthread_testcancel(void)
 {
-	struct pthread *curthread = _get_curthread();
-	
-	if (SHOULD_CANCEL(curthread->cancelflags))
-		pthread_exit(PTHREAD_CANCELED);
+	testcancel(_get_curthread());
 }
 
 int
@@ -136,16 +135,10 @@
 {
 	int oldval;
 
-	for (;;) {
-		oldval = curthread->cancelflags;
-		if (oldval & THR_CANCEL_AT_POINT)
-			break;
-		int newval = oldval | THR_CANCEL_AT_POINT;
-		if (atomic_cmpset_acq_int(&curthread->cancelflags, oldval,
-		    newval)) {
-			if (SHOULD_CANCEL(newval))
-				pthread_exit(PTHREAD_CANCELED);
-		}
+	oldval = curthread->cancelflags;
+	if (!(oldval & THR_CANCEL_AT_POINT)) {
+		atomic_set_int(&curthread->cancelflags, THR_CANCEL_AT_POINT);
+		testcancel(curthread);
 	}
 	return (oldval);
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200501030202.j0322548058581>