#include
#include
#include
#define RUNNING 1
#define SLEEPING 2
struct task_struct {
int status;
int parent;
int return_code;
time_t alarm;
int argc;
char **argv;
jmp_buf c;
};
#define MAX_TASKS 3
static struct task_struct task[MAX_TASKS];
static jmp_buf _tasker_;
#define kernel 0
/* swis is 1 to tell the kernel to call swi for all kernel calls */
static int swis=1;
static int pid=kernel;
/* newpid: get next pid on stack */
int newpid(void) {
register int p;
for(p=0;p<MAX_TASKS;p++) {
if(task[p].status==0) return(p);
}
return(-1);
}
/* getpid: return pid */
int getpid(void) {
return(pid);
}
/* become: become new task */
void become(int p) {
pid=p;
}
/* cli: clear interrupt */
void cli(void) {
swis=0;
}
/* sti: set interrupt */
void sti(void) {
swis=1;
}
/* swi: software interrupt, yield cpu */
void swi(void) {
int save=pid;
printf("swi()\n");
if(!setjmp(task[pid].c)) {
longjmp(_tasker_,1); /* return to tasker */
}
become(save);
}
/* isswi: returns the value of swis for the kernel */
int kswi(void) {
if(swis) swi();
}
/* fork: become new process, and fork back here */
int fork(void) {
int save=pid;
if(!setjmp(task[pid].c)) {
/* child */
become(newpid());
task[pid].status=RUNNING;
if(!setjmp(task[pid].c)) {
longjmp(_tasker_,1); /* return to tasker */
}
return(pid);
}
become(save);
return(0);
}
/* sleep: set the alarm */
void sleep(int seconds) {
task[pid].alarm=time(NULL)+seconds;
task[pid].status=SLEEPING;
swi();
return;
}
#define ever ;;
void tasker(int (*primo)()) {
int p;
become(kernel);
for(p=0;p<MAX_TASKS;p++) {
task[p].status=-1;
task[p].alarm=0;
}
if(!setjmp(_tasker_)) {
task[pid].status=RUNNING;
task[pid].parent=0;
(*primo)();
}
for(ever) {
for(p=0;p<MAX_TASKS;p++) {
if(task[p].status==RUNNING) {
if(!setjmp(_tasker_)) {
become(p);
longjmp(task[p].c,1);
}
}
}
}
}
/* _exit: end task */
void _exit(int status) {
task[pid].status=0;
task[pid].return_code=status;
longjmp(_tasker_,1);
return;
}
#if DEBUGGING_TIMESHARE_C
/* init.c */
int init_main() {
int k;
if(fork()) {
sleep(10);
printf("pid %d\n",pid);
for(k=0;k<100;k++) {
printf("forked task %d %d\n",pid,k);
swi();
}
_exit(0);
}
for(;;) {
printf("init(%d)\n",pid);
swi();
printf("/init(%d)\n",pid);
}
}
/* kernel.c */
/* idle: is "alarm" function ;) */
int idle() {
time_t now;
int i;
if(fork()) {
init_main();
}
for(;;) {
printf("kernel(idle) %d\n",pid);
now=time(NULL);
printf("gottime\n");
for(i=0;i=task[i].alarm)) {
printf("woke up %d\n",i);
task[i].status=RUNNING;
}
}
swi();
printf("/kernel(idle) %d\n",pid);
}
}
int main(void) {
tasker(idle);
return(0);
}
#endif
Like this:
Like Loading...