home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / lxapi32.zip / Lib32 / lxsched.c < prev    next >
C/C++ Source or Header  |  2002-04-26  |  5KB  |  214 lines

  1. /* $Id: lxsched.c,v 1.2 2002/04/26 23:09:24 smilcke Exp $ */
  2.  
  3. /*
  4.  * sched.c
  5.  * Autor:               Stefan Milcke
  6.  * Erstellt am:         23.11.2001
  7.  * Letzte Aenderung am: 20.01.2002
  8.  *
  9. */
  10.  
  11. #include <linux/kernel.h>
  12. #include <linux/slab.h>
  13. #include <linux/mm.h>
  14. #include <linux/version.h>
  15. #include <linux/module.h>
  16. #include <linux/delay.h>
  17. #include <linux/types.h>
  18. #include <linux/timer.h>
  19. #include <linux/sched.h>
  20.  
  21. struct kthread
  22. {
  23.  int active;
  24.  int initCalled;
  25.  int (*initFn)(void *);
  26.  int (*fn)(void *);
  27.  int (*exitFn)(void *);
  28.  wait_queue_head_t *wq;
  29.  signed long wq_timeout;
  30.  void *data;
  31.  struct task_struct task;
  32. };
  33.  
  34. #define MAX_THREADS        10
  35.  
  36. spinlock_t threadlist_lock=SPIN_LOCK_UNLOCKED;
  37.  
  38. struct kthread kthread_array[MAX_THREADS]={0};
  39. int thread_list_initialized=0;
  40.  
  41. //------------------------------- kernel_thread --------------------------------
  42. // Because i don't know how to implement kernel threads in OS2 device driver
  43. // we emulate this via timer calls.
  44. // So this function differs from original kernel_thread in linux
  45. // initFn is called first (one time) and then fn is called periodically until
  46. // it returns nonzero. Then exitFn is called and the thread is removed from
  47. // the list
  48. int kernel_thread(int (*initFn)(void *)
  49.                   ,int (*fn)(void *)
  50.                   ,int (*exitFn)(void *)
  51.                   ,void *arg,unsigned long flags)
  52. {
  53.  int i,ret=0;
  54.  unsigned long f;
  55.  spin_lock_irqsave(&threadlist_lock,f);
  56.  for(i=0;i<MAX_THREADS;i++)
  57.  {
  58.   if(0==kthread_array[i].active)
  59.   {
  60.    struct kthread *p=&(kthread_array[i]);
  61.    p->initCalled=0;
  62.    p->data=arg;
  63.    p->initFn=initFn;
  64.    p->fn=fn;
  65.    p->exitFn=exitFn;
  66.    p->wq=NULL;
  67.    p->wq_timeout=-1;
  68.    p->active=1;
  69.    p->task.state=0;
  70.    p->task.flags=TASK_RUNNING;
  71.    p->task.sigpending=0;
  72.    p->task.files=NULL;
  73.    p->task.need_resched=0;
  74.    break;
  75.   }
  76.  }
  77.  if(i==MAX_THREADS)
  78.   ret=-1;
  79.  spin_unlock_irqrestore(&threadlist_lock,f);
  80.  return ret;
  81. }
  82.  
  83. struct kthread *pCurrent=NULL;
  84.  
  85. //--------------------------------- run_thread ---------------------------------
  86. int run_thread(struct kthread *p)
  87. {
  88.  if(0==p->initCalled)
  89.  {
  90.   pCurrent=p;
  91.   if(0!=p->initFn(p->data))
  92.   {
  93.    p->exitFn(p->data);
  94.    p->active=0;
  95.   }
  96.   p->initCalled=1;
  97.   pCurrent=NULL;
  98.  }
  99.  if(p->wq)
  100.  { // waitqueue exists, so check, if a timeout was given
  101.   if(-1!=p->wq_timeout)
  102.   { // timeout is running, decrement and check if we've reached
  103.    p->wq_timeout--;
  104.    if(-1==p->wq_timeout)
  105.    { // O.K, so let's run the thread
  106.     p->wq=NULL;
  107.     pCurrent=p;
  108.     if(p->fn(p->data))
  109.     {
  110.      p->exitFn(p->data);
  111.      p->active=0;
  112.     }
  113.     pCurrent=NULL;
  114.     return 1;
  115.    }
  116.    else // timeout still busy
  117.     return 0;
  118.   }
  119.   else // No timeout, so don't run
  120.    return 0;
  121.  }
  122.  else
  123.  { // No waitqueue
  124.   pCurrent=p;
  125.   if(0!=p->fn(p->data))
  126.   {
  127.    p->exitFn(p->data);
  128.    p->active=0;
  129.   }
  130.   pCurrent=NULL;
  131.   return 1;
  132.  }
  133. }
  134.  
  135. //------------------------------ run_thread_list -------------------------------
  136. void run_thread_list(void)
  137. {
  138.  int i;
  139.  for(i=0;i<MAX_THREADS;i++)
  140.  {
  141.   if(0!=kthread_array[i].active)
  142.   {
  143.    struct task_struct *prev_current=current;
  144.    current=&(kthread_array[i].task);
  145.    run_thread(&(kthread_array[i]));
  146.    current=prev_current;
  147.   }
  148.  }
  149. }
  150.  
  151. //--------------------------------- __wake_up ----------------------------------
  152. void __wake_up(wait_queue_head_t *q,unsigned int mode)
  153. {
  154.  int i;
  155.  unsigned long f;
  156.  spin_lock_irqsave(&threadlist_lock,f);
  157.  for(i=0;i<MAX_THREADS;i++)
  158.  {
  159.   if(kthread_array[i].wq==q)
  160.   {
  161.    kthread_array[i].wq=NULL;
  162.    kthread_array[i].wq_timeout=-1;
  163.   }
  164.  }
  165.  spin_unlock_irqrestore(&threadlist_lock,f);
  166. }
  167.  
  168. //---------------------------------- sleep_on ----------------------------------
  169. void sleep_on(wait_queue_head_t *q)
  170. {
  171.  int i;
  172.  unsigned long f;
  173.  spin_lock_irqsave(&threadlist_lock,f);
  174.  if(pCurrent)
  175.  {
  176.   pCurrent->wq=q;
  177.   pCurrent->wq_timeout=-1;
  178.  }
  179.  spin_unlock_irqrestore(&threadlist_lock,f);
  180. }
  181.  
  182. //------------------------------ sleep_on_timeout ------------------------------
  183. long sleep_on_timeout(wait_queue_head_t *q,signed long timeout)
  184. {
  185.  int i;
  186.  unsigned long f;
  187.  spin_lock_irqsave(&threadlist_lock,f);
  188.  if(pCurrent)
  189.  {
  190.   pCurrent->wq=q;
  191.   pCurrent->wq_timeout=timeout;
  192.  }
  193.  spin_unlock_irqrestore(&threadlist_lock,f);
  194.  return 0;
  195. }
  196.  
  197. //--------------------------- interruptible_sleep_on ---------------------------
  198. void interruptible_sleep_on(wait_queue_head_t *q)
  199. {
  200.  sleep_on(q);
  201. }
  202.  
  203. //----------------------- interruptible_sleep_on_timeout -----------------------
  204. long interruptible_sleep_on_timeout(wait_queue_head_t *q,signed long timeout)
  205. {
  206.  sleep_on_timeout(q,timeout);
  207.  return 0;
  208. }
  209.  
  210. //------------------------------ wake_up_process -------------------------------
  211. void wake_up_process(struct task_struct *tsk)
  212. {
  213. }
  214.