mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-01 23:18:21 +00:00
semaphore: haswaiters and redo how threads are attached
This commit is contained in:
@@ -21,9 +21,11 @@ typedef struct semaphore_t{
|
|||||||
(x)->head = NULL; \
|
(x)->head = NULL; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int semaphore_wait(semaphore_t *sem, bool interruptible);
|
int semaphore_wait(semaphore_t *sem, bool interruptible);
|
||||||
void semaphore_signal(semaphore_t *sem);
|
void semaphore_signal(semaphore_t *sem);
|
||||||
bool semaphore_test(semaphore_t *sem);
|
bool semaphore_test(semaphore_t *sem);
|
||||||
|
bool semaphore_haswaiters(semaphore_t *sem);
|
||||||
|
|
||||||
#include <kernel/scheduler.h>
|
#include <kernel/scheduler.h>
|
||||||
|
|
||||||
|
|||||||
+29
-16
@@ -3,27 +3,27 @@
|
|||||||
#include <logging.h>
|
#include <logging.h>
|
||||||
|
|
||||||
static void insert(semaphore_t *sem, thread_t *thread) {
|
static void insert(semaphore_t *sem, thread_t *thread) {
|
||||||
if (sem->head == NULL) {
|
thread->sleepnext = sem->head;
|
||||||
sem->head = thread;
|
thread->sleepprev = NULL;
|
||||||
sem->tail = thread;
|
sem->head = thread;
|
||||||
thread->sleepnext = NULL;
|
|
||||||
thread->sleepprev = NULL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
sem->tail->sleepnext = _cpu()->thread;
|
if (sem->tail == NULL)
|
||||||
_cpu()->thread->sleepprev = sem->tail;
|
sem->tail = thread;
|
||||||
|
|
||||||
|
if (thread->sleepnext)
|
||||||
|
thread->sleepnext->sleepprev = thread;
|
||||||
}
|
}
|
||||||
|
|
||||||
static thread_t *get(semaphore_t *sem) {
|
static thread_t *get(semaphore_t *sem) {
|
||||||
thread_t *thread = sem->head;
|
thread_t *thread = sem->tail;
|
||||||
__assert(thread);
|
__assert(thread);
|
||||||
|
|
||||||
sem->head = sem->head->sleepnext;
|
sem->tail = thread->sleepprev;
|
||||||
if (sem->head == NULL)
|
|
||||||
sem->tail = NULL;
|
if (sem->tail == NULL)
|
||||||
else
|
sem->head = NULL;
|
||||||
sem->head->sleepprev = NULL;
|
else
|
||||||
|
sem->tail->sleepnext = NULL;
|
||||||
|
|
||||||
return thread;
|
return thread;
|
||||||
}
|
}
|
||||||
@@ -37,10 +37,12 @@ int semaphore_wait(semaphore_t *sem, bool interruptible) {
|
|||||||
insert(sem, _cpu()->thread);
|
insert(sem, _cpu()->thread);
|
||||||
sched_preparesleep(interruptible);
|
sched_preparesleep(interruptible);
|
||||||
spinlock_release(&sem->lock);
|
spinlock_release(&sem->lock);
|
||||||
return sched_yield();
|
ret = sched_yield();
|
||||||
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
spinlock_release(&sem->lock);
|
spinlock_release(&sem->lock);
|
||||||
|
leave:
|
||||||
interrupt_set(intstate);
|
interrupt_set(intstate);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -57,6 +59,17 @@ void semaphore_signal(semaphore_t *sem) {
|
|||||||
interrupt_set(intstate);
|
interrupt_set(intstate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool semaphore_haswaiters(semaphore_t *sem) {
|
||||||
|
bool intstate = interrupt_set(false);
|
||||||
|
spinlock_acquire(&sem->lock);
|
||||||
|
|
||||||
|
bool v = sem->head != NULL;
|
||||||
|
|
||||||
|
spinlock_release(&sem->lock);
|
||||||
|
interrupt_set(intstate);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
bool semaphore_test(semaphore_t *sem) {
|
bool semaphore_test(semaphore_t *sem) {
|
||||||
bool intstate = interrupt_set(false);
|
bool intstate = interrupt_set(false);
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user