summaryrefslogtreecommitdiff
path: root/kern/semaphore.c
diff options
context:
space:
mode:
authorRichard Braun <rbraun@sceen.net>2017-08-27 16:55:36 +0200
committerRichard Braun <rbraun@sceen.net>2017-08-27 16:55:36 +0200
commit50c583b698c4d1d13d1c0537c350691b18dd7033 (patch)
tree2745b01aea67d3559712b19a4376b2bad2232137 /kern/semaphore.c
parenta509d86280d14b435640c446d81d85e53fd866e9 (diff)
kern/semaphore: implement timed waits
Diffstat (limited to 'kern/semaphore.c')
-rw-r--r--kern/semaphore.c37
1 files changed, 34 insertions, 3 deletions
diff --git a/kern/semaphore.c b/kern/semaphore.c
index 7e94dafd..72e843a9 100644
--- a/kern/semaphore.c
+++ b/kern/semaphore.c
@@ -15,19 +15,25 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <assert.h>
#include <stdbool.h>
#include <stddef.h>
+#include <stdint.h>
#include <kern/semaphore.h>
#include <kern/semaphore_i.h>
#include <kern/sleepq.h>
-void
-semaphore_wait_slow(struct semaphore *semaphore)
+static int
+semaphore_wait_slow_common(struct semaphore *semaphore,
+ bool timed, uint64_t ticks)
{
struct sleepq *sleepq;
unsigned long flags;
unsigned int prev;
+ int error;
+
+ error = 0;
sleepq = sleepq_lend(semaphore, false, &flags);
@@ -38,10 +44,35 @@ semaphore_wait_slow(struct semaphore *semaphore)
break;
}
- sleepq_wait(sleepq, "sem");
+ if (!timed) {
+ sleepq_wait(sleepq, "sem");
+ } else {
+ error = sleepq_timedwait(sleepq, "sem", ticks);
+
+ if (error) {
+ break;
+ }
+ }
}
sleepq_return(sleepq, flags);
+
+ return error;
+}
+
+void
+semaphore_wait_slow(struct semaphore *semaphore)
+{
+ int error;
+
+ error = semaphore_wait_slow_common(semaphore, false, 0);
+ assert(!error);
+}
+
+int
+semaphore_timedwait_slow(struct semaphore *semaphore, uint64_t ticks)
+{
+ return semaphore_wait_slow_common(semaphore, true, ticks);
}
void