diff options
Diffstat (limited to 'kern')
-rw-r--r-- | kern/semaphore.c | 37 | ||||
-rw-r--r-- | kern/semaphore.h | 15 | ||||
-rw-r--r-- | kern/semaphore_i.h | 3 |
3 files changed, 52 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 diff --git a/kern/semaphore.h b/kern/semaphore.h index e08927ec..e1acbf21 100644 --- a/kern/semaphore.h +++ b/kern/semaphore.h @@ -33,6 +33,7 @@ #define _KERN_SEMAPHORE_H #include <assert.h> +#include <stdint.h> #include <kern/atomic.h> #include <kern/error.h> @@ -93,6 +94,20 @@ semaphore_wait(struct semaphore *semaphore) } } +static inline int +semaphore_timedwait(struct semaphore *semaphore, uint64_t ticks) +{ + unsigned int prev; + + prev = semaphore_dec(semaphore); + + if (unlikely(prev == 0)) { + return semaphore_timedwait_slow(semaphore, ticks); + } + + return 0; +} + /* * Unlock a semaphore. * diff --git a/kern/semaphore_i.h b/kern/semaphore_i.h index acd7cd48..6e79b137 100644 --- a/kern/semaphore_i.h +++ b/kern/semaphore_i.h @@ -19,6 +19,7 @@ #define _KERN_SEMAPHORE_I_H #include <assert.h> +#include <stdint.h> #include <kern/atomic.h> @@ -56,6 +57,8 @@ semaphore_inc(struct semaphore *semaphore) void semaphore_wait_slow(struct semaphore *semaphore); +int semaphore_timedwait_slow(struct semaphore *semaphore, uint64_t ticks); + void semaphore_post_slow(struct semaphore *semaphore); #endif /* _KERN_SEMAPHORE_I_H */ |