#pragma once
+#include <irq.h>
+#include <system.h>
#include <task.h>
-#include <wait.h>
#define FORK_USER 0
#define FORK_KRNL 1
extern void load_cr3(task_union *tsk);
extern list_head_t all_tasks;
-extern list_head_t delay_tasks;
\ No newline at end of file
+extern list_head_t delay_tasks;
+
+#define set_current_state(st) \
+ do { \
+ current->state = (st); \
+ mb(); \
+ } while (0)
#define cli() __asm__ __volatile__("cli")
#define sti() __asm__ __volatile__("sti")
#define nop() asm volatile("nop")
+#define mb() asm volatile("" ::: "memory")
#define disableIRQ() cli()
#define enableIRQ() sti()
#define DECLARE_WAIT_QUEUE(name, tsk) wait_queue_t name = WAIT_QUEUE_INITIALIZER(name, tsk)
void init_wait_queue_head(wait_queue_head_t *wqh);
-void add_wait_queue(wait_queue_head_t *wqh, wait_queue_t *wq);
-void del_wait_queue(wait_queue_head_t *wqh, wait_queue_t *wq);
+void add_wait_queue(wait_queue_head_t *head, wait_queue_t *wq);
+void del_wait_queue(wait_queue_head_t *head, wait_queue_t *wq);
+void __do_wait(wait_queue_head_t *head, wait_queue_t *wq, unsigned int state);
+void __end_wait(wait_queue_head_t *head, wait_queue_t *wq);
void sleep_on(wait_queue_head_t *head);
void wake_up(wait_queue_head_t *head);
+
+#define __wait_event(head, condition) \
+ do { \
+ DECLARE_WAIT_QUEUE(__wait, current); \
+ while (1) { \
+ __do_wait(head, wa, TASK_WAIT); \
+ if ((condition)) { \
+ break; \
+ } \
+ schedule(); \
+ } \
+ __end_wait(head, &__wait); \
+ } while (0)
+
+#define wait_event(head, condition) \
+ do { \
+ if (!(condition)) { \
+ __wait_event(head, (condition)); \
+ } \
+ } while (0)
irq_restore(flags);
}
+void __do_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)) {
+ list_add_tail(&wq->task_list, &head->task_list);
+ }
+ set_current_state(state);
+ irq_restore(flags);
+}
+
+void __end_wait(wait_queue_head_t *head, wait_queue_t *wq) {
+ set_current_state(TASK_RUNNING);
+ unsigned long flags;
+ irq_save(flags);
+ list_del_init(&wq->task_list);
+ irq_restore(flags);
+}
+
void sleep_on(wait_queue_head_t *head) {
DECLARE_WAIT_QUEUE(wait, current);