Implement proper mutex cleanup
All checks were successful
Build documentation / build-and-deploy (push) Successful in 23s
All checks were successful
Build documentation / build-and-deploy (push) Successful in 23s
This commit is contained in:
45
init/init.c
45
init/init.c
@@ -6,7 +6,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string/string.h>
|
#include <string/string.h>
|
||||||
|
|
||||||
#define EXAMPLE 2
|
#define EXAMPLE 3
|
||||||
|
|
||||||
#if EXAMPLE == 1
|
#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) {
|
void app_thread1 (void) {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
lock_mutex (MUTEX, RV_PRIVATE);
|
lock_mutex (MUTEX, RV_PRIVATE);
|
||||||
|
|||||||
@@ -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) {
|
void proc_cleanup_resource_mutex (struct proc* proc, struct proc_resource* resource) {
|
||||||
struct proc_mutex* mutex = &resource->u.mutex;
|
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) {
|
void proc_mutex_lock (struct proc* proc, struct proc_mutex* mutex) {
|
||||||
|
|||||||
Reference in New Issue
Block a user