ejes consulting

Techincal Consulting Design and Automation

timeshare.c

leave a comment »

#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

Written by ejes

August 5, 2010 at 9:40 am

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: