matos/core/synchro.c

82 lines
1.4 KiB
C
Raw Normal View History

2020-07-08 23:08:50 +02:00
#include "synchro.h"
#include "alloc.h"
2020-08-15 23:31:35 +02:00
#include "assert.h"
2020-07-08 23:08:50 +02:00
#include "irq.h"
#include "klibc.h"
#include "list.h"
#include "time.h"
int mutexInit(struct mutex *m)
{
m->owner = NULL;
m->wait = (struct wait_queue *)malloc(sizeof(struct wait_queue));
if (!m->wait)
return ENOMEM;
2020-08-19 14:31:16 +02:00
waitQueueInit(m->wait);
2020-07-08 23:08:50 +02:00
list_init(m->wait->thread);
return 0;
}
int mutexFree(struct mutex *m)
{
int ret = 0;
if (m) {
uint32_t flags;
disable_IRQs(flags);
if (list_is_empty(m->wait)) {
#ifdef DEBUG
if (m->owner) {
printf("Warning: freeing a owned mutex 0x%. owned by 0x%p 0x%p\n", m, m->owner,
2020-08-16 00:24:59 +02:00
getCurrentThread());
2020-07-08 23:08:50 +02:00
}
#endif
2020-08-19 14:31:16 +02:00
waitQueueFree(m->wait);
2020-07-08 23:08:50 +02:00
free(m->wait);
} else {
ret = EBUSY;
}
restore_IRQs(flags);
}
return ret;
}
int mutexLock(struct mutex *m)
{
uint32_t flags;
2021-10-30 14:08:12 +02:00
struct thread *current;
2020-07-08 23:08:50 +02:00
disable_IRQs(flags);
2020-08-16 00:24:59 +02:00
current = getCurrentThread();
2020-07-08 23:08:50 +02:00
assert(m->owner != current);
2020-08-15 23:31:35 +02:00
wait_event(m->wait, m->owner == NULL);
2020-07-08 23:08:50 +02:00
m->owner = current;
restore_IRQs(flags);
return 0;
}
int mutexUnlock(struct mutex *m)
{
uint32_t flags;
disable_IRQs(flags);
2020-08-16 00:24:59 +02:00
assert(m->owner == getCurrentThread());
2020-07-08 23:08:50 +02:00
m->owner = NULL;
2020-08-15 23:31:35 +02:00
2020-08-19 14:31:16 +02:00
wakeUp(m->wait);
2020-07-08 23:08:50 +02:00
restore_IRQs(flags);
return 0;
}