diff --git a/init/init.c b/init/init.c index b77df85..003980c 100644 --- a/init/init.c +++ b/init/init.c @@ -6,7 +6,7 @@ #include #include -#define EXAMPLE 2 +#define EXAMPLE 3 #if EXAMPLE == 1 @@ -57,6 +57,49 @@ void app_main (void) { } } +void app_thread1 (void) { + for (;;) { + lock_mutex (MUTEX, RV_PRIVATE); + + for (int i = 0; i < 3; i++) + test ('b'); + + unlock_mutex (MUTEX, RV_PRIVATE); + } + + quit (); +} +#elif EXAMPLE == 3 + +#define MUTEX 2000 + +void app_thread1 (void); + +int spawn (void (*fn) (void)) { + size_t stack_size = 256 * PAGE_SIZE; + void* stack = malloc (stack_size); + if (stack == NULL) + return -ST_OOM_ERROR; + + uintptr_t stack_top = (uintptr_t)stack + stack_size; + return clone (stack_top, stack_size, fn); +} + +void app_main (void) { + create_mutex (MUTEX, RV_PRIVATE); + + spawn (&app_thread1); + + for (;;) { + lock_mutex (MUTEX, RV_PRIVATE); + + for (int i = 0; i < 3; i++) + test ('a'); + + quit (); + } +} + void app_thread1 (void) { for (;;) { lock_mutex (MUTEX, RV_PRIVATE); diff --git a/kernel/proc/mutex.c b/kernel/proc/mutex.c index a4246c9..47ffe5a 100644 --- a/kernel/proc/mutex.c +++ b/kernel/proc/mutex.c @@ -93,6 +93,32 @@ bool proc_create_resource_mutex (struct proc_mutex* mutex) { void proc_cleanup_resource_mutex (struct proc* proc, struct proc_resource* resource) { struct proc_mutex* mutex = &resource->u.mutex; + spin_lock_ctx_t ctxmt, ctxsq; + + spin_lock (&mutex->resource->lock, &ctxmt); + spin_lock (&mutex->suspension_q.lock, &ctxsq); + + while (mutex->suspension_q.proc_list != NULL) { + struct list_node_link* node = mutex->suspension_q.proc_list; + struct proc_sq_entry* sq_entry = list_entry (node, struct proc_sq_entry, sq_link); + struct proc* suspended_proc = sq_entry->proc; + + /* we will relock during resume */ + spin_unlock (&mutex->suspension_q.lock, &ctxsq); + spin_unlock (&mutex->resource->lock, &ctxmt); + + proc_mutex_resume (suspended_proc, sq_entry); + + /* reacquire */ + spin_lock (&mutex->resource->lock, &ctxmt); + spin_lock (&mutex->suspension_q.lock, &ctxsq); + } + + mutex->locked = false; + mutex->owner = NULL; + + spin_unlock (&mutex->suspension_q.lock, &ctxsq); + spin_unlock (&mutex->resource->lock, &ctxmt); } void proc_mutex_lock (struct proc* proc, struct proc_mutex* mutex) {