Module Name:    src
Committed By:   riastradh
Date:           Tue Apr  1 14:55:20 UTC 2014

Modified Files:
        src/sys/external/bsd/drm2/include/linux: completion.h

Log Message:
Add some more Linux completion operations.

Adapted from a patch by nick@.


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/sys/external/bsd/drm2/include/linux/completion.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/external/bsd/drm2/include/linux/completion.h
diff -u src/sys/external/bsd/drm2/include/linux/completion.h:1.2 src/sys/external/bsd/drm2/include/linux/completion.h:1.3
--- src/sys/external/bsd/drm2/include/linux/completion.h:1.2	Tue Mar 18 18:20:43 2014
+++ src/sys/external/bsd/drm2/include/linux/completion.h	Tue Apr  1 14:55:20 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: completion.h,v 1.2 2014/03/18 18:20:43 riastradh Exp $	*/
+/*	$NetBSD: completion.h,v 1.3 2014/04/01 14:55:20 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -146,6 +146,17 @@ INIT_COMPLETION_blorp(struct completion 
 	mutex_exit(&completion->c_lock);
 }
 
+static inline void
+_completion_claim(struct completion *completion)
+{
+
+	KASSERT(mutex_owned(&completion->c_lock));
+	if (completion->c_done > 0)
+		completion->c_done--;
+	else
+		KASSERT(completion->c_done == -1);
+}
+
 /*
  * Wait interruptibly with a timeout for someone to call complete or
  * complete_all.
@@ -175,13 +186,8 @@ wait_for_completion_interruptible_timeou
 		start = now;
 	}
 
-	/* Claim a completion if it's not open season.  */
-	if (completion->c_done > 0)
-		completion->c_done--;
-	else
-		KASSERT(completion->c_done == -1);
-
 	/* Success!  */
+	_completion_claim(completion);
 	error = 0;
 
 out:	mutex_exit(&completion->c_lock);
@@ -195,4 +201,66 @@ out:	mutex_exit(&completion->c_lock);
 	}
 }
 
+/*
+ * Wait interruptibly for someone to call complete or complete_all.
+ */
+static inline int
+wait_for_completion_interruptible(struct completion *completion)
+{
+	int error;
+
+	mutex_enter(&completion->c_lock);
+
+	/* Wait until c_done is nonzero.  */
+	while (completion->c_done == 0) {
+		error = cv_wait_sig(&completion->c_cv, &completion->c_lock);
+		if (error)
+			goto out;
+	}
+
+	/* Success!  */
+	_completion_claim(completion);
+	error = 0;
+
+out:	mutex_exit(&completion->c_lock);
+	if ((error == EINTR) || (error == ERESTART))
+		error = -ERESTARTSYS;
+	return error;
+}
+
+/*
+ * Wait uninterruptibly, except by SIGKILL, for someone to call
+ * complete or complete_all.
+ *
+ * XXX In this implementation, any signal will actually wake us, not
+ * just SIGKILL.
+ */
+static inline int
+wait_for_completion_killable(struct completion *completion)
+{
+
+	return wait_for_completion_interruptible(completion);
+}
+
+/*
+ * Try to claim a completion immediately.  Return true on success, false
+ * if it would block.
+ */
+static inline bool
+try_wait_for_completion(struct completion *completion)
+{
+	bool ok;
+
+	mutex_enter(&completion->c_lock);
+	if (completion->c_done == 0) {
+		ok = false;
+	} else {
+		_completion_claim(completion);
+		ok = true;
+	}
+	mutex_exit(&completion->c_lock);
+
+	return ok;
+}
+
 #endif	/* _LINUX_COMPLETION_H_ */

Reply via email to