9os

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit a169e5e8b958395249861cc6d64b191ea3164ef9
parent 9f6fbda00aec1be7d746dc8d118d693eecd6cec5
Author: Roberto E. Vargas Caballero <roberto.vargas@midokura.com>
Date:   Fri, 25 Nov 2022 09:47:46 +0100

os9: Add sleep() and wakeup()

Diffstat:
Minclude/bits/amd64/arch/types.h | 1+
Minclude/bits/arm64/arch/types.h | 1+
Minclude/os9/os9.h | 10++++++++++
Msrc/os9/hosted/lock.c | 12++++++++++++
Msrc/os9/proc.c | 39+++++++++++++++++++++++++++++++++++++++
5 files changed, 63 insertions(+), 0 deletions(-)

diff --git a/include/bits/amd64/arch/types.h b/include/bits/amd64/arch/types.h @@ -11,6 +11,7 @@ typedef int atomic_t; typedef unsigned long mutex_t; +typedef unsigned long spinlock_t; typedef unsigned long long phyaddr_t; typedef struct context Context; diff --git a/include/bits/arm64/arch/types.h b/include/bits/arm64/arch/types.h @@ -61,6 +61,7 @@ enum regidx { typedef int atomic_t; typedef unsigned long mutex_t; +typedef unsigned long splinlock_t; typedef unsigned long long pte_t; typedef unsigned long long phyaddr_t; typedef struct context Context; diff --git a/include/os9/os9.h b/include/os9/os9.h @@ -52,6 +52,7 @@ typedef struct mpoint Mpoint; typedef struct nspace Nspace; typedef struct fdset Fdset; typedef struct ref Ref; +typedef struct rendez Rendez; enum rforkflags { RFPROC = 1 << 0, @@ -187,6 +188,11 @@ struct fdset { Fdset *next; }; +struct rendez { + spinlock_t s; + Task *task; +}; + /** * @entry: Entry point for the task. * @prio: @@ -266,6 +272,8 @@ extern Map *newstack(Task *); extern void sched(void); extern void locktask(Task *); extern void unlocktask(Task *); +extern void sleep(Rendez *, int (*cond)(void *), void *); +extern void wakeup(Rendez *); /* alloc.c */ extern void *alloc(size_t); @@ -316,6 +324,8 @@ extern uint32_t outm32(uint32_t, void *addr); extern void lock(mutex_t *m); extern void unlock(mutex_t *m); extern int trylock(mutex_t *m); +extern void lockspin(spinlock_t *); +extern void unlockspin(spinlock_t *); extern void barrier(int); extern noreturn void halt(void); extern noreturn void panic(const char *msg); diff --git a/src/os9/hosted/lock.c b/src/os9/hosted/lock.c @@ -1,6 +1,18 @@ #include <os9/os9.h> void +unlockspin(spinlock_t *s) +{ + unlock(s); +} + +void +lockspin(spinlock_t *s) +{ + lock(s); +} + +void lock(mutex_t *mutex) { if (!mutex) diff --git a/src/os9/proc.c b/src/os9/proc.c @@ -404,6 +404,45 @@ inittask(void) return tp; } +/* + * sleep() and wakeup() are highly inspired in + * the paper 'Process Sleep and Wakeup on a + * Shared-memory Multiprocessor' + */ +void +sleep(Rendez *r, int (*cond)(void *), void *arg) +{ + lockspin(&r->s); + + if (!(*cond)(arg)) { + unlockspin(&r->s); + return; + } + + proc->state = TWAITING; + proc->next = r->task; + r->task = proc; + unlockspin(&r->s); + sched(); +} + +void +wakeup(Rendez *r) +{ + Task *tp, *next; + + lockspin(&r->s); + for (tp = r->task; tp; tp = next) { + if (tp->state != TWAITING) + panic("wakeup: not sleeping"); + next = tp->next; + tp->next = NULL; + tp->state = TREADY; + } + r->task = NULL; + unlockspin(&r->s); +} + void iproc(void) {