#define DECLARE_SEMAPHORE_WAITER(name, task) semaphore_waiter_t name = SEMAPHORE_WAITER_INITIALIZER(name, task)
-void __down(semaphore_t *s) {
+volatile void __down(semaphore_t *s) {
task_union *task = current;
DECLARE_SEMAPHORE_WAITER(waiter, task);
list_add_tail(&waiter.list, &s->wait_list);
while (true) {
task->state = TASK_WAIT;
- enable_irq();
-
schedule();
- disable_irq();
-
if (waiter.up) {
break;
}
}
}
-void down(semaphore_t *s) {
+volatile void down(semaphore_t *s) {
unsigned long iflags;
irq_save(iflags);
+
if (likely(s->cnt > 0)) {
s->cnt--;
} else {
irq_restore(iflags);
}
-void __up(semaphore_t *s) {
+volatile void __up(semaphore_t *s) {
semaphore_waiter_t *waiter = list_first_entry(&s->wait_list, semaphore_waiter_t, list);
list_del(&waiter->list);
waiter->up = 1;
waiter->task->state = TASK_READY;
}
-void up(semaphore_t *s) {
+volatile void up(semaphore_t *s) {
unsigned long iflags;
irq_save(iflags);
#include <sched.h>
#include <wait.h>
-void init_wait_queue_head(wait_queue_head_t *wqh) { INIT_LIST_HEAD(&wqh->task_list); }
+volatile void init_wait_queue_head(wait_queue_head_t *wqh) { INIT_LIST_HEAD(&wqh->task_list); }
-void add_wait_queue(wait_queue_head_t *head, wait_queue_t *wq) {
+volatile void add_wait_queue(wait_queue_head_t *head, wait_queue_t *wq) {
unsigned long flags;
irq_save(flags);
list_add_tail(&wq->task_list, &head->task_list);
irq_restore(flags);
}
-void del_wait_queue(wait_queue_head_t *head, wait_queue_t *wq) {
+volatile void del_wait_queue(wait_queue_head_t *head, wait_queue_t *wq) {
unsigned long flags;
irq_save(flags);
list_del(&wq->task_list);
irq_restore(flags);
}
-void prepare_to_wait(wait_queue_head_t *head, wait_queue_t *wq, unsigned int state) {
+volatile void prepare_to_wait(wait_queue_head_t *head, wait_queue_t *wq, unsigned int state) {
unsigned long flags;
irq_save(flags);
if (list_empty(&wq->task_list)) {
irq_restore(flags);
}
-void __end_wait(wait_queue_head_t *head, wait_queue_t *wq) {
+volatile void __end_wait(wait_queue_head_t *head, wait_queue_t *wq) {
set_current_state(TASK_READY);
unsigned long flags;
irq_save(flags);
irq_restore(flags);
}
-void sleep_on(wait_queue_head_t *head) {
+volatile void sleep_on(wait_queue_head_t *head) {
DECLARE_WAIT_QUEUE(wait, current);
unsigned long flags;
irq_restore(flags);
schedule();
+
+ // wake_up操作会把wait从heat链表上删除
+ // 所以这里就不用做什么了
}
-void __wake_up(wait_queue_head_t *head, int nr) {
+volatile void __wake_up(wait_queue_head_t *head, int nr) {
unsigned long flags;
wait_queue_t *p, *tmp;
irq_save(flags);
// no schedule() here.
}
-void wake_up(wait_queue_head_t *head) { __wake_up(head, 1); }
+volatile void wake_up(wait_queue_head_t *head) { __wake_up(head, 1); }
#include <irq.h>
DECLARE_WAIT_QUEUE_HEAD(debug_wq);