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