Files
riscv-operating-system-mooc/code/os/04-multitask/sched.c
Wang Chen 744226d09e improved comments
Signed-off-by: ablechen <17895010372@163.com>
Signed-off-by: Wang Chen <wangchen20@iscas.ac.cn>
2022-11-23 10:06:37 +08:00

82 lines
1.4 KiB
C

#include "os.h"
/* defined in entry.S */
extern void switch_to(struct context *next);
#define MAX_TASKS 10
#define STACK_SIZE 1024
uint8_t task_stack[MAX_TASKS][STACK_SIZE];
struct context ctx_tasks[MAX_TASKS];
/*
* _top is used to mark the max available position of ctx_tasks
* _current is used to point to the context of current task
*/
static int _top = 0;
static int _current = -1;
static void w_mscratch(reg_t x)
{
asm volatile("csrw mscratch, %0" : : "r" (x));
}
void sched_init()
{
w_mscratch(0);
}
/*
* implment a simple cycle FIFO schedular
*/
void schedule()
{
if (_top <= 0) {
panic("Num of task should be greater than zero!");
return;
}
_current = (_current + 1) % _top;
struct context *next = &(ctx_tasks[_current]);
switch_to(next);
}
/*
* DESCRIPTION
* Create a task.
* - start_routin: task routine entry
* RETURN VALUE
* 0: success
* -1: if error occured
*/
int task_create(void (*start_routin)(void))
{
if (_top < MAX_TASKS) {
ctx_tasks[_top].sp = (reg_t) &task_stack[_top][STACK_SIZE - 1];
ctx_tasks[_top].ra = (reg_t) start_routin;
_top++;
return 0;
} else {
return -1;
}
}
/*
* DESCRIPTION
* task_yield() causes the calling task to relinquish the CPU and a new
* task gets to run.
*/
void task_yield()
{
schedule();
}
/*
* a very rough implementaion, just to consume the cpu
*/
void task_delay(volatile int count)
{
count *= 50000;
while (count--);
}