summaryrefslogtreecommitdiff
path: root/kernel/task.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/task.c')
-rw-r--r--kernel/task.c77
1 files changed, 57 insertions, 20 deletions
diff --git a/kernel/task.c b/kernel/task.c
index 6ea9b79..ac54dbe 100644
--- a/kernel/task.c
+++ b/kernel/task.c
@@ -17,7 +17,7 @@
#define MAX_TASKS 10
-static volatile int current_task=-2;
+static volatile int current_task=-1;
static volatile struct task_list_struct
{
@@ -25,6 +25,8 @@ static volatile struct task_list_struct
bool active;
uint32_t esp; // stack pointer of the task;
uint32_t vmem; // number of virtual memory table to switch to
+ bool waiting;
+ bool skipwait;
}volatile task_list[MAX_TASKS];
@@ -40,6 +42,8 @@ int add_task(uint32_t esp, uint32_t vmem)
task_list[i].vmem=vmem;
task_list[i].esp=esp;
task_list[i].active=true;
+ task_list[i].waiting=false;
+ task_list[i].skipwait=false;
return i;
}
@@ -48,22 +52,19 @@ int add_task(uint32_t esp, uint32_t vmem)
panic(FOOLOS_MODULE_NAME,"out of task slots!");
}
-// this gets called by our clock interrupt regularly!
-uint32_t task_switch_next(uint32_t oldesp)
+uint32_t my_scheduler(uint32_t oldesp)
{
- timer_tick();
-
- if(current_task==-2)return oldesp;
-
task_list[current_task].esp=oldesp;
-
+
for(int i=0;i<MAX_TASKS;i++)
{
int pid=(current_task+1+i)%MAX_TASKS; // schedule round robin style
- if(task_list[pid].active)
+ if(task_list[pid].active && !task_list[pid].waiting)
{
- // log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"switch from %d to pid: %d (0x%08X) vmem: %d ", current_task,pid,task_list[pid].esp,task_list[pid].vmem);
+ // if(current_task!=pid)
+ // log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"switch from %d to %d", current_task, pid);
+
current_task=pid;
vmem_set_dir(task_list[pid].vmem);
@@ -72,34 +73,68 @@ uint32_t task_switch_next(uint32_t oldesp)
}
- return oldesp;
+ panic(FOOLOS_MODULE_NAME,"nothing to schedule!");
+}
+
+// this gets called by our clock interrupt regularly!
+uint32_t task_switch_next(uint32_t oldesp)
+{
+ timer_tick();
+
+ // check if multitasking has been started
+ if(current_task<0)return oldesp;
+
+ return my_scheduler(oldesp);
}
+
//TODO: free vmem too!
+//TODO: notify waiting parent when child finished;
uint32_t task_exit(uint32_t oldesp)
{
task_list[current_task].active=false;
+ int parent_pid=task_list[current_task].parent;
- for(int i=0;i<MAX_TASKS;i++)
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"[%d] exit ", current_task);
+ if(task_list[parent_pid].active)
{
- int pid=(current_task+1+i)%MAX_TASKS; // schedule round robin style
-
- if(task_list[pid].active)
+ if(task_list[parent_pid].waiting)
{
- // log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"switch from %d to pid: %d (0x%08X) vmem: %d ", current_task,pid,task_list[pid].esp,task_list[pid].vmem);
- current_task=pid;
-
- vmem_set_dir(task_list[pid].vmem);
- return task_list[pid].esp;
+
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"wakeing up %d ", parent_pid);
+ task_list[parent_pid].waiting=false;
+ }
+ else
+ {
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"set skipwait on %d ", parent_pid);
+ task_list[parent_pid].skipwait=true;
}
+
+ }
+
+ return my_scheduler(oldesp);
+
+}
+uint32_t task_wait(uint32_t oldesp)
+{
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"[%d] wait", current_task);
+ if(task_list[current_task].skipwait)
+ {
+ task_list[current_task].skipwait=false;
+ }
+ else
+ {
+ task_list[current_task].waiting=true;
}
+ return my_scheduler(oldesp);
}
uint32_t task_fork(uint32_t oldesp)
{
int pid=add_task(oldesp,vmem_new_space_dir(task_list[current_task].vmem));
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"[%d] forked -> [%d]", current_task, pid);
return pid;
}
@@ -107,7 +142,9 @@ uint32_t task_fork(uint32_t oldesp)
void task_init()
{
// this is our main task on slot 0
+ task_list[0].parent=0;
task_list[0].active=true;
+ task_list[0].waiting=false;
task_list[0].vmem=0;
task_list[0].esp = 0; // will be set by next task_switch_next() call.
current_task=0;