void poweroff();
void ide_debug();
void ide_status();
-void debug_sched();
void kbd_debug(uint8_t scan_code);
extern list_head_t all_tasks;
extern list_head_t delay_tasks;
-
-#define set_current_state(st) \
- do { \
- current->state = (st); \
- mb(); \
- } while (0)
list_head_t list; // 所有进程串成一个链表
+ list_head_t ready_list; // 就绪队列
+
list_head_t pend; // 某些条件串成一个链表
// list_head_t wait;
return current->pid;
}
-task_t* find_task(pid_t pid);
-
#define ROOT_TSK_PID (0)
// #define TASK_INIT_WEIGHT 0
#define get_tsk_from_list(p) list_entry((p), Task, list)
#define del_tsk_from_list(tsk) list_del((&tsk->list))
-#endif
+
+void task_set_run(task_t* t);
+void task_set_ready(task_t* t);
+void task_set_wait(task_t* t);
+
+#endif // ASM
#endif //_TASK_H
// 以下wait_event被定义成宏,而不是函数是因为condition
// condition可能是一个表达式,如果定义成函数,往下传递就直接变成了一个值
// 如果在某一步这个值变了,并不会反应在这些逻辑判断上
-#define __wait_event(head, condition) \
- do { \
- DECLARE_WAIT_QUEUE_ENTRY(__wait, current); \
- unsigned long flags; \
- while (1) { \
- irq_save(flags); \
- prepare_to_wait(head, &__wait, TASK_WAIT); \
- if ((condition)) { \
- __end_wait(&__wait); \
- irq_restore(flags); \
- break; \
- } else { \
- irq_restore(flags); \
- void schedule(); \
- schedule(); \
- irq_save(flags); \
- __end_wait(&__wait); \
- irq_restore(flags); \
- } \
- } \
+#define __wait_event(head, condition) \
+ do { \
+ DECLARE_WAIT_QUEUE_ENTRY(__wait, current); \
+ unsigned long flags; \
+ while (1) { \
+ irq_save(flags); \
+ __prepare_to_wait(head, &__wait, TASK_WAIT); \
+ if ((condition)) { \
+ __end_wait(&__wait); \
+ irq_restore(flags); \
+ break; \
+ } else { \
+ irq_restore(flags); \
+ void schedule(); \
+ schedule(); \
+ irq_save(flags); \
+ __end_wait(&__wait); \
+ irq_restore(flags); \
+ } \
+ } \
} while (0)
#define wait_event(head, condition) \
assert(p->state == TASK_WAIT);
assert(p->delay_jiffies != 0);
if (p->delay_jiffies > 0 && jiffies > p->delay_jiffies) {
- list_del(&p->pend);
+ list_del_init(&p->pend);
p->delay_jiffies = 0;
- p->state = TASK_READY;
+ // p->state = TASK_READY;
+ task_set_ready(p);
p->reason = "clk_bh";
}
}
console_list[i]->write(buf, size);
}
return 0;
-}
-
-#if 0
-
-cnsl_t cnsl;
-
-static bool empty(const cnsl_queue_t* q) {
- return q->head == q->tail;
-}
-
-static bool full(const cnsl_queue_t* q) {
- return (q->head + 1) % CNSL_QUEUE_SIZE == q->tail;
-}
-
-static void put(cnsl_queue_t* q, char c) {
- if (!full(q)) {
- q->data[q->head] = c;
- q->head = (q->head + 1) % CNSL_QUEUE_SIZE;
- }
-}
-
-static bool get(cnsl_queue_t* q, char* c) {
- if (!empty(q)) {
- *c = q->data[q->tail];
- q->tail = (q->tail + 1) % CNSL_QUEUE_SIZE;
- return true;
- }
-
- return false;
-}
-
-static void clear(cnsl_queue_t* q) {
- q->head = q->tail = 0;
-}
-
-static void erase(cnsl_queue_t* q) {
- if (empty(q))
- return;
-
- if (q->head == 0)
- q->head = CNSL_QUEUE_SIZE - 1;
- else
- q->head--;
-}
-
-static void cnsl_queue_init(cnsl_queue_t* cq) {
- memset((void*)cq, 0, sizeof(*cq));
- cq->head = 0;
- cq->tail = 0;
- init_wait_queue_head(&cq->wait);
-}
-
-// wait_queue_head_t rdwq;
-semaphore_t sem;
-void cnsl_init() {
- cnsl_queue_init(&cnsl.rd_q);
- cnsl_queue_init(&cnsl.wr_q);
- cnsl_queue_init(&cnsl.sc_q);
- // init_wait_queue_head(&rdwq);
- semaphore_init(&sem, 0);
-}
-
-int cnsl_kbd_write(char ch) {
- if (ch == 0) {
- return 0;
- }
- extern tty_t* const default_tty;
- if (ch == '\b') {
- if (!empty(&cnsl.wr_q)) {
- tty_color_putc(default_tty, '\b', TTY_FG_HIGHLIGHT | TTY_WHITE, TTY_BLACK);
- }
- // tty_color_putc(default_tty, '\b', TTY_WHITE, TTY_BLACK);
- erase(&cnsl.wr_q);
- erase(&cnsl.sc_q);
- } else {
- put(&cnsl.wr_q, ch);
- put(&cnsl.sc_q, ch);
- tty_color_putc(default_tty, ch, TTY_FG_HIGHLIGHT | TTY_WHITE, TTY_BLACK);
- }
-
- if (ch == '\n') {
- clear(&cnsl.wr_q);
- return 0; // TODO FIX
- while (get(&cnsl.sc_q, &ch))
- put(&cnsl.rd_q, ch);
- // wake_up(&rdwq);
- up(&sem);
- }
-
- return 0;
-}
-
-int cnsl_read(char* buf, size_t count) {
- // unsigned long flags;
-
- assert(count > 0);
- int cnt = 0;
- for (cnt = 0; cnt < count;) {
- char ch;
-#if 1
- while (true) {
- down(&sem);
-
- bool r = get(&cnsl.rd_q, &ch);
- if (r) {
- buf[cnt++] = ch;
- if (ch == '\n') {
- goto end;
- }
- } else {
- break;
- }
- }
-#else
- task_union* task = current;
- DECLARE_WAIT_QUEUE(wait, task);
- add_wait_queue(&rdwq, &wait);
-
- while (true) {
- task->state = TASK_WAIT;
- irq_save(flags);
- bool r = get(&cnsl.rd_q, &ch);
- irq_restore(flags);
-
- if (r) {
- buf[cnt++] = ch;
-
- task->state = TASK_READY;
- del_wait_queue(&rdwq, &wait);
-
- if (ch == '\n')
- goto end;
-
- break;
- }
-
- schedule();
- }
-#endif
- }
-
-end:
- buf[cnt] = 0;
- return cnt;
-}
-
-chrdev_t cnsl_chrdev = {.read = cnsl_read};
-#endif
+}
\ No newline at end of file
tsk->state = TASK_INITING;
INIT_LIST_HEAD(&tsk->list);
+ INIT_LIST_HEAD(&tsk->ready_list);
+ INIT_LIST_HEAD(&tsk->pend);
unsigned long iflags;
irq_save(iflags);
list_add(&tsk->list, &all_tasks);
printd("task %08x child_regs esp %08x esp0 %08x\n", tsk, tsk->esp, tsk->esp0);
- tsk->state = TASK_READY;
+ task_set_ready(tsk);
void add_task_for_monitor(task_t * tsk);
add_task_for_monitor(tsk);
extern pde_t __initdata init_pgd[PDECNT_PER_PAGE] __attribute__((__aligned__(PAGE_SIZE)));
-// list_head_t all_tasks;
-// list_head_t delay_tasks;
LIST_HEAD(all_tasks);
-
+LIST_HEAD(ready_tasks);
LIST_HEAD(delay_tasks);
void init_root_task() {
root_task.pid = get_next_pid();
root_task.ppid = 0;
- root_task.state = TASK_READY;
+ root_task.state = TASK_RUN;
root_task.reason = "root";
root_task.priority = 7;
root_task.ticks = root_task.priority;
root_task.magic = TASK_MAGIC;
strcpy(root_task.name, "root");
- list_add(&root_task.list, &all_tasks);
+ INIT_LIST_HEAD(&root_task.list);
+ INIT_LIST_HEAD(&root_task.ready_list);
+ INIT_LIST_HEAD(&root_task.pend);
// INIT_LIST_HEAD(&root_task.next);
+ list_add(&root_task.list, &all_tasks);
+
// TODO
// for(i=0; i<NR_OPENS; i++)
// root_task.fps[i] = 0;
void setup_tasks() {
INIT_LIST_HEAD(&all_tasks);
+ INIT_LIST_HEAD(&ready_tasks);
INIT_LIST_HEAD(&delay_tasks);
init_root_task();
: "memory");
}
-task_t* find_task(pid_t pid) {
- task_t* p = 0;
- list_head_t *pos = 0, *tmp = 0;
-
- unsigned long iflags;
- irq_save(iflags);
- list_for_each_safe(pos, tmp, &all_tasks) {
- p = list_entry(pos, task_t, list);
- if (p->pid == pid) {
- break;
- }
- }
- irq_restore(iflags);
-
- return p;
-}
-
void schedule() {
- // task_t* root = &root_task;
- task_t* sel = 0;
- task_t* p = 0;
- list_head_t *pos = 0, *t = 0;
-
- assert(current->priority <= TASK_MAX_PRIORITY);
+ task_t* prev = current;
+ task_t* next = NULL;
- unsigned long iflags;
- irq_save(iflags);
+ unsigned long eflags;
+ irq_save(eflags);
- if (current->state == TASK_RUN) {
- current->state = TASK_READY;
+ if (prev->state == TASK_READY || prev->state == TASK_RUN) {
+ task_set_ready(prev);
}
- // task_t *head = current;
- list_for_each_safe(pos, t, ¤t->list) {
- p = list_entry(pos, task_t, list);
- if (TASK_READY != p->state) {
- continue;
- }
- if (&root_task == p) {
- continue;
- }
-
- sel = p;
- break;
+ if (list_empty(&ready_tasks)) {
+ next = &root_task;
+ goto end;
}
- if (sel == 0) {
- if (current->state != TASK_READY) {
- sel = &root_task;
- root_task.ticks = root_task.priority;
- root_task.state = TASK_READY;
- } else {
- sel = current;
- }
- }
+ // 从ready_tasks中选择第一个
+ next = list_entry(ready_tasks.next, task_t, ready_list);
- task_t* prev = current;
- task_t* next = sel;
+ assert(next->state == TASK_READY);
+ assert(next != &root_task);
- next->state = TASK_RUN;
- next->reason = "";
+end:
+ task_set_run(next);
+
+ if (prev->ticks <= 0) {
+ prev->ticks = prev->priority;
+ }
if (prev != next) {
- if (prev->ticks <= 0) {
- prev->ticks = prev->priority;
- }
next->sched_cnt++;
context_switch(prev, next);
} else {
- // 这里可能是的情况是任务把时间片ticks用完了
- // 被设置成READY
- // 重新高度,还是选中了该任务
next->sched_keep_cnt++;
}
- assert(current->state == TASK_RUN);
-
- irq_restore(iflags);
-}
-
-void debug_sched() {
- task_t* p = list_entry(current->list.next, task_t, list);
- p->state = (p->state == TASK_READY) ? TASK_WAIT : TASK_READY;
+ irq_restore(eflags);
}
task_t* monitor_tasks[1024] = {&root_task, 0};
int id = tsk->pid;
monitor_tasks[id] = tsk;
}
+
+void task_set_run(task_t* t) {
+ assert(t != NULL);
+
+ if (t == &root_task) {
+ t->state = TASK_RUN;
+ return;
+ }
+
+ assert(t->state == TASK_READY);
+
+ unsigned long eflags;
+ irq_save(eflags);
+
+ list_del_init(&t->ready_list);
+ t->state = TASK_RUN;
+
+ irq_restore(eflags);
+}
+
+void task_set_ready(task_t* t) {
+ assert(t != NULL);
+ if (t == &root_task) {
+ t->state = TASK_READY;
+ return;
+ }
+
+ unsigned long eflags;
+ irq_save(eflags);
+ if (!list_empty(&t->ready_list)) {
+ list_del_init(&t->ready_list);
+ }
+ list_add_tail(&t->ready_list, &ready_tasks);
+ t->state = TASK_READY;
+ irq_restore(eflags);
+}
+
+void task_set_wait(task_t* t) {
+ assert(t != NULL);
+ // printk("task_set_wait %s %d\n", t->name, t->state);
+ assert(t != &root_task);
+
+ unsigned long eflags;
+ irq_save(eflags);
+
+ list_del_init(&t->ready_list);
+ t->state = TASK_WAIT;
+
+ irq_restore(eflags);
+}
\ No newline at end of file
INIT_LIST_HEAD(&waiter.list);
list_add(&waiter.list, &s->wait_list);
- task->state = TASK_WAIT;
+ // task->state = TASK_WAIT;
+ task_set_wait(task);
task->reason = "down";
irq_restore(iflags);
list_del(&waiter->list);
task_t* task = waiter->task;
- task->state = TASK_READY;
+ // task->state = TASK_READY;
+ task_set_ready(task);
task->reason = "up";
irq_restore(iflags);
} else {
unsigned long flags;
irq_save(flags);
- current->state = TASK_WAIT;
+ // current->state = TASK_WAIT;
+ assert(current->state != TASK_WAIT);
+ assert(list_empty(¤t->pend));
+ task_set_wait(current);
current->reason = "sysc_wait";
current->delay_jiffies = jiffies + ticks;
list_add(¤t->pend, &delay_tasks);
irq_restore(eflags);
- // 目前先总是回显
- tty_write(tty, (const char*)&c, 1);
-
// 唤醒读进程
wake_up(&tty->ib_wait);
+ // 目前先总是回显
+ tty_write(tty, (const char*)&c, 1);
+
return 1;
}
\ No newline at end of file
// list_add_tail(&wqe->entry, &head->task_list);
list_add(&wqe->entry, &head->task_list);
}
- set_current_state(state);
+
+ assert(state == TASK_WAIT);
+ task_set_wait(current);
current->reason = "p_wait";
}
volatile void __end_wait(wait_queue_entry_t* wqe) {
- set_current_state(TASK_READY);
+ task_set_ready(current);
current->reason = "e_wait";
// unsigned long flags;
// irq_save(flags);
list_for_each_entry_safe(p, tmp, &head->task_list, entry) {
assert(p->task != NULL);
// printk("wakeup %s\n", p->task->name);
- p->task->state = TASK_READY;
+ // p->task->state = TASK_READY;
+ task_set_ready(p->task);
p->task->reason = "wake_up";
list_del_init(&p->entry);