home *** CD-ROM | disk | FTP | other *** search
- /* $Id: lxsched.c,v 1.2 2002/04/26 23:09:24 smilcke Exp $ */
-
- /*
- * sched.c
- * Autor: Stefan Milcke
- * Erstellt am: 23.11.2001
- * Letzte Aenderung am: 20.01.2002
- *
- */
-
- #include <linux/kernel.h>
- #include <linux/slab.h>
- #include <linux/mm.h>
- #include <linux/version.h>
- #include <linux/module.h>
- #include <linux/delay.h>
- #include <linux/types.h>
- #include <linux/timer.h>
- #include <linux/sched.h>
-
- struct kthread
- {
- int active;
- int initCalled;
- int (*initFn)(void *);
- int (*fn)(void *);
- int (*exitFn)(void *);
- wait_queue_head_t *wq;
- signed long wq_timeout;
- void *data;
- struct task_struct task;
- };
-
- #define MAX_THREADS 10
-
- spinlock_t threadlist_lock=SPIN_LOCK_UNLOCKED;
-
- struct kthread kthread_array[MAX_THREADS]={0};
- int thread_list_initialized=0;
-
- //------------------------------- kernel_thread --------------------------------
- // Because i don't know how to implement kernel threads in OS2 device driver
- // we emulate this via timer calls.
- // So this function differs from original kernel_thread in linux
- // initFn is called first (one time) and then fn is called periodically until
- // it returns nonzero. Then exitFn is called and the thread is removed from
- // the list
- int kernel_thread(int (*initFn)(void *)
- ,int (*fn)(void *)
- ,int (*exitFn)(void *)
- ,void *arg,unsigned long flags)
- {
- int i,ret=0;
- unsigned long f;
- spin_lock_irqsave(&threadlist_lock,f);
- for(i=0;i<MAX_THREADS;i++)
- {
- if(0==kthread_array[i].active)
- {
- struct kthread *p=&(kthread_array[i]);
- p->initCalled=0;
- p->data=arg;
- p->initFn=initFn;
- p->fn=fn;
- p->exitFn=exitFn;
- p->wq=NULL;
- p->wq_timeout=-1;
- p->active=1;
- p->task.state=0;
- p->task.flags=TASK_RUNNING;
- p->task.sigpending=0;
- p->task.files=NULL;
- p->task.need_resched=0;
- break;
- }
- }
- if(i==MAX_THREADS)
- ret=-1;
- spin_unlock_irqrestore(&threadlist_lock,f);
- return ret;
- }
-
- struct kthread *pCurrent=NULL;
-
- //--------------------------------- run_thread ---------------------------------
- int run_thread(struct kthread *p)
- {
- if(0==p->initCalled)
- {
- pCurrent=p;
- if(0!=p->initFn(p->data))
- {
- p->exitFn(p->data);
- p->active=0;
- }
- p->initCalled=1;
- pCurrent=NULL;
- }
- if(p->wq)
- { // waitqueue exists, so check, if a timeout was given
- if(-1!=p->wq_timeout)
- { // timeout is running, decrement and check if we've reached
- p->wq_timeout--;
- if(-1==p->wq_timeout)
- { // O.K, so let's run the thread
- p->wq=NULL;
- pCurrent=p;
- if(p->fn(p->data))
- {
- p->exitFn(p->data);
- p->active=0;
- }
- pCurrent=NULL;
- return 1;
- }
- else // timeout still busy
- return 0;
- }
- else // No timeout, so don't run
- return 0;
- }
- else
- { // No waitqueue
- pCurrent=p;
- if(0!=p->fn(p->data))
- {
- p->exitFn(p->data);
- p->active=0;
- }
- pCurrent=NULL;
- return 1;
- }
- }
-
- //------------------------------ run_thread_list -------------------------------
- void run_thread_list(void)
- {
- int i;
- for(i=0;i<MAX_THREADS;i++)
- {
- if(0!=kthread_array[i].active)
- {
- struct task_struct *prev_current=current;
- current=&(kthread_array[i].task);
- run_thread(&(kthread_array[i]));
- current=prev_current;
- }
- }
- }
-
- //--------------------------------- __wake_up ----------------------------------
- void __wake_up(wait_queue_head_t *q,unsigned int mode)
- {
- int i;
- unsigned long f;
- spin_lock_irqsave(&threadlist_lock,f);
- for(i=0;i<MAX_THREADS;i++)
- {
- if(kthread_array[i].wq==q)
- {
- kthread_array[i].wq=NULL;
- kthread_array[i].wq_timeout=-1;
- }
- }
- spin_unlock_irqrestore(&threadlist_lock,f);
- }
-
- //---------------------------------- sleep_on ----------------------------------
- void sleep_on(wait_queue_head_t *q)
- {
- int i;
- unsigned long f;
- spin_lock_irqsave(&threadlist_lock,f);
- if(pCurrent)
- {
- pCurrent->wq=q;
- pCurrent->wq_timeout=-1;
- }
- spin_unlock_irqrestore(&threadlist_lock,f);
- }
-
- //------------------------------ sleep_on_timeout ------------------------------
- long sleep_on_timeout(wait_queue_head_t *q,signed long timeout)
- {
- int i;
- unsigned long f;
- spin_lock_irqsave(&threadlist_lock,f);
- if(pCurrent)
- {
- pCurrent->wq=q;
- pCurrent->wq_timeout=timeout;
- }
- spin_unlock_irqrestore(&threadlist_lock,f);
- return 0;
- }
-
- //--------------------------- interruptible_sleep_on ---------------------------
- void interruptible_sleep_on(wait_queue_head_t *q)
- {
- sleep_on(q);
- }
-
- //----------------------- interruptible_sleep_on_timeout -----------------------
- long interruptible_sleep_on_timeout(wait_queue_head_t *q,signed long timeout)
- {
- sleep_on_timeout(q,timeout);
- return 0;
- }
-
- //------------------------------ wake_up_process -------------------------------
- void wake_up_process(struct task_struct *tsk)
- {
- }
-