aboutsummaryrefslogtreecommitdiff
path: root/kernel/sched/sched.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sched/sched.c')
-rw-r--r--kernel/sched/sched.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/kernel/sched/sched.c b/kernel/sched/sched.c
index 609c81b..3f4d003 100644
--- a/kernel/sched/sched.c
+++ b/kernel/sched/sched.c
@@ -1,11 +1,13 @@
#include "sched/sched.h"
#include "sched/idle.h"
+#include "time/timer.h"
#include "mcu/sched/context.h"
struct tcb_t* volatile current = 0;
DECLARE_TASK(idle, IDLE_STACK_SIZE, idle_entry);
struct list_head ready = LIST_HEAD_INIT(ready);
+static struct list_head sleeping = LIST_HEAD_INIT(sleeping);
char* volatile kstack;
static void init_idle() {
@@ -24,6 +26,11 @@ void sched_init() {
void schedule() {
if(!list_empty(&ready)) {
+
+ if (current == &idle) {
+ debug_led(0,0);
+ }
+
current = list_entry(ready.next, struct tcb_t, q);
list_move_tail(ready.next, &ready);
} else {
@@ -31,6 +38,18 @@ void schedule() {
}
}
+void sched_tick() {
+ struct tcb_t* it;
+ struct tcb_t* tmp;
+ list_for_each_entry_safe(it, tmp, &sleeping, q) {
+ it->sleep_left -= 1000 / HZ;
+ if (it->sleep_left <= 0) {
+ list_move_tail(&it->q, &ready);
+ }
+ }
+ schedule(); //in a round-robin scheduler, scheduling is called after every tick
+}
+
void wake_all(struct list_head* queue) {
list_splice_init(queue, ready.prev);
if (current == &idle) {
@@ -51,4 +70,15 @@ void yield(void) {
RESTORE_CONTEXT();
sei();
RETURN();
+}
+
+void sleep(long ms) {
+ cli();
+ SAVE_CONTEXT();
+ current->sleep_left = ms;
+ sleep_on(&sleeping);
+ schedule();
+ RESTORE_CONTEXT();
+ sei();
+ RETURN();
} \ No newline at end of file