Add semaphore
This commit is contained in:
parent
e9e584149c
commit
c3b4d65a36
@ -6,7 +6,6 @@
|
|||||||
#include "list.h"
|
#include "list.h"
|
||||||
#include "time.h"
|
#include "time.h"
|
||||||
|
|
||||||
|
|
||||||
int mutexInit(struct mutex *m)
|
int mutexInit(struct mutex *m)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -16,8 +15,6 @@ int mutexInit(struct mutex *m)
|
|||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
|
|
||||||
waitQueueInit(m->wait);
|
waitQueueInit(m->wait);
|
||||||
list_init(m->wait->thread);
|
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -73,9 +70,64 @@ int mutexUnlock(struct mutex *m)
|
|||||||
|
|
||||||
m->owner = NULL;
|
m->owner = NULL;
|
||||||
|
|
||||||
wakeUp(m->wait);
|
waitUp(m->wait);
|
||||||
|
|
||||||
restore_IRQs(flags);
|
restore_IRQs(flags);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int semInit(struct semaphore *sem, int initVal)
|
||||||
|
{
|
||||||
|
sem->count = initVal;
|
||||||
|
waitQueueInit(&sem->wait);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int semFree(struct semaphore *sem)
|
||||||
|
{
|
||||||
|
return waitQueueFree(&sem->wait);
|
||||||
|
}
|
||||||
|
|
||||||
|
int semDown(struct semaphore *sem, unsigned long timeout)
|
||||||
|
{
|
||||||
|
uint32_t flags;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
disable_IRQs(flags);
|
||||||
|
sem->count--;
|
||||||
|
if (sem->count < 0) {
|
||||||
|
ret = waitTimeout(&sem->wait, timeout);
|
||||||
|
if (ret) {
|
||||||
|
sem->count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
restore_IRQs(flags);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int semTryDown(struct semaphore *sem)
|
||||||
|
{
|
||||||
|
uint32_t flags;
|
||||||
|
int ret = -EBUSY;
|
||||||
|
|
||||||
|
disable_IRQs(flags);
|
||||||
|
if (sem->count > 1) {
|
||||||
|
ret = 0;
|
||||||
|
sem->count--;
|
||||||
|
}
|
||||||
|
restore_IRQs(flags);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int semUp(struct semaphore *sem)
|
||||||
|
{
|
||||||
|
uint32_t flags;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
disable_IRQs(flags);
|
||||||
|
sem->count++;
|
||||||
|
ret = waitUpNb(&sem->wait, 1);
|
||||||
|
restore_IRQs(flags);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
@ -5,3 +5,9 @@ int mutexInit(struct mutex *);
|
|||||||
int mutexFree(struct mutex *);
|
int mutexFree(struct mutex *);
|
||||||
int mutexLock(struct mutex *);
|
int mutexLock(struct mutex *);
|
||||||
int mutexUnlock(struct mutex *);
|
int mutexUnlock(struct mutex *);
|
||||||
|
|
||||||
|
int semInit(struct semaphore *, int initVal);
|
||||||
|
int semFree(struct semaphore *);
|
||||||
|
int semDown(struct semaphore *, unsigned long timeout);
|
||||||
|
int semTryDown(struct semaphore *);
|
||||||
|
int semUp(struct semaphore *);
|
||||||
|
24
core/wait.c
24
core/wait.c
@ -8,6 +8,7 @@ static struct wait_queue *waitQueues = NULL;
|
|||||||
int waitQueueInit(struct wait_queue *wq)
|
int waitQueueInit(struct wait_queue *wq)
|
||||||
{
|
{
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
|
list_init(wq->thread);
|
||||||
disable_IRQs(flags);
|
disable_IRQs(flags);
|
||||||
list_add_tail(waitQueues, wq);
|
list_add_tail(waitQueues, wq);
|
||||||
restore_IRQs(flags);
|
restore_IRQs(flags);
|
||||||
@ -23,7 +24,7 @@ int waitQueueFree(struct wait_queue *wq)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int wakeUp(struct wait_queue *wq)
|
int waitUp(struct wait_queue *wq)
|
||||||
{
|
{
|
||||||
struct thread *th;
|
struct thread *th;
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
@ -39,6 +40,27 @@ int wakeUp(struct wait_queue *wq)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int waitUpNb(struct wait_queue *wq, unsigned int nbThread)
|
||||||
|
{
|
||||||
|
struct thread *th;
|
||||||
|
uint32_t flags;
|
||||||
|
|
||||||
|
disable_IRQs(flags);
|
||||||
|
list_collapse(wq->thread, th)
|
||||||
|
{
|
||||||
|
threadAddThread(th);
|
||||||
|
if(nbThread){
|
||||||
|
nbThread--;
|
||||||
|
if(!nbThread)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
restore_IRQs(flags);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int wait(struct wait_queue *wq)
|
int wait(struct wait_queue *wq)
|
||||||
{
|
{
|
||||||
return waitTimeout(wq, 0);
|
return waitTimeout(wq, 0);
|
||||||
|
@ -20,7 +20,8 @@ int waitQueueInit(struct wait_queue *);
|
|||||||
int waitQueueFree(struct wait_queue *);
|
int waitQueueFree(struct wait_queue *);
|
||||||
int wait(struct wait_queue *);
|
int wait(struct wait_queue *);
|
||||||
int waitTimeout(struct wait_queue *wq, unsigned long msec);
|
int waitTimeout(struct wait_queue *wq, unsigned long msec);
|
||||||
int wakeUp(struct wait_queue *);
|
int waitUp(struct wait_queue *);
|
||||||
|
int waitUpNb(struct wait_queue *wq, unsigned int nbThread);
|
||||||
|
|
||||||
#define wait_event(wq, condition) \
|
#define wait_event(wq, condition) \
|
||||||
do { \
|
do { \
|
||||||
@ -31,7 +32,7 @@ int wakeUp(struct wait_queue *);
|
|||||||
|
|
||||||
struct semaphore {
|
struct semaphore {
|
||||||
int count;
|
int count;
|
||||||
struct wait_queue *wait;
|
struct wait_queue wait;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mutex {
|
struct mutex {
|
||||||
|
Loading…
Reference in New Issue
Block a user