Initial revision

This commit is contained in:
cvs
2000-02-07 10:38:55 +00:00
commit fdc6b051c9
846 changed files with 230218 additions and 0 deletions

348
task.c Normal file
View File

@ -0,0 +1,348 @@
/*------------------------------------------------------------------------
T A S K E R
Implementation of a portable task switcher.
Mark Koennecke, September 1997
copyleft, 1997.
NO WARRANTIES OF ANY KIND WHATSOEVER TAKEN BY ME OR MY EMPLOYER.
YOU ARE AT YOUR OWN!
----------------------------------------------------------------------------*/
#include <stdlib.h>
#include <assert.h>
#include "../fortify.h"
#include "task.h"
#define READY 1
#define WAITING 2
#define YIELDING 3
/*--------------------------------------------------------------------------*/
typedef struct __TaskHead {
long lID;
int iStatus;
long lWait;
TaskFunc pRun;
SignalFunc pSignal;
void *pData;
TaskKillFunc pKill;
pTaskHead pNext;
pTaskHead pPrevious;
} TaskHead;
typedef struct __TaskMan {
int iID;
int iStop;
pTaskHead pCurrent;
pTaskHead pHead;
} TaskMan;
/*---------------------------------------------------------------------------*/
static long lIDMama = 0L;
#define TASKERID 123399
/*---------------------------------------------------------------------------*/
static pTaskHead MakeTaskHead(TaskFunc pTask, SignalFunc pSignal,
void *pData, TaskKillFunc pKill)
{
pTaskHead pNew = NULL;
pNew = (pTaskHead)malloc(sizeof(TaskHead));
if(!pNew)
{
return NULL;
}
memset(pNew,0,sizeof(TaskHead));
pNew->pRun = pTask;
pNew->pSignal = pSignal;
pNew->pData = pData;
pNew->pKill = pKill;
pNew->lID = lIDMama++;
pNew->iStatus = READY;
return pNew;
}
/*--------------------------------------------------------------------------*/
static void DeleteTaskHead(pTaskHead self)
{
assert(self);
if(self->pKill)
{
self->pKill(self->pData);
}
/* unlink */
if(self->pPrevious != NULL)
{
self->pPrevious->pNext = self->pNext;
}
if(self->pNext != NULL)
{
self->pNext->pPrevious = self->pPrevious;
}
free(self);
}
/*--------------------------------------------------------------------------*/
static int DummyTask(void *pData)
{
return 1;
}
/*--------------------------------------------------------------------------*/
int TaskerInit(pTaskMan *self)
{
pTaskMan pNew = NULL;
pTaskHead pDummyTask = NULL;
*self = NULL;
/* a new Task manager */
pNew = (pTaskMan)malloc(sizeof(TaskMan));
if(!pNew)
{
return 0;
}
memset(pNew, 0, sizeof(TaskMan));
pNew->iID = TASKERID;
/* create a dummy task as start point */
pDummyTask = MakeTaskHead(DummyTask,NULL,NULL,NULL);
if(!pDummyTask)
{
free(pNew);
return 0;
}
/* link */
pDummyTask->pNext = NULL;
pDummyTask->pPrevious = NULL;
pNew->pCurrent = pDummyTask;
pNew->pHead = pDummyTask;
*self = pNew;
return 1;
}
/*---------------------------------------------------------------------------*/
int TaskerDelete(pTaskMan *pData)
{
pTaskMan self = *pData;
pTaskHead pCurrent, pKill;
assert(self);
assert(self->iID == TASKERID);
pCurrent = self->pHead;
while(pCurrent != NULL)
{
pKill = pCurrent;
pCurrent = pCurrent->pNext;
DeleteTaskHead(pKill);
}
free(self);
*pData = NULL;
return 1;
}
/*---------------------------------------------------------------------------*/
long TaskRegister(pTaskMan self, TaskFunc pTask, SignalFunc pSignal,
TaskKillFunc pKill, void *pData, int iPriority)
{
pTaskHead pNew = NULL;
assert(self);
assert(self->iID == TASKERID);
assert(pTask);
pNew = MakeTaskHead(pTask,pSignal, pData, pKill);
if(!pNew)
{
return -1;
}
/* link it in */
if(self->pCurrent->pNext)
{
self->pCurrent->pNext->pPrevious = pNew;
}
pNew->pPrevious = self->pCurrent;
pNew->pNext = self->pCurrent->pNext;
self->pCurrent->pNext = pNew;
return pNew->lID;
}
/*-------------------------------------------------------------------------*/
static void IncrTaskPointer(pTaskMan self)
{
self->pCurrent = self->pCurrent->pNext;
if(self->pCurrent == NULL)
{
self->pCurrent = self->pHead;
}
}
/*--------------------------------------------------------------------------*/
int TaskSchedule(pTaskMan self)
{
int iRet;
pTaskHead pTemp;
assert(self);
assert(self->iID == TASKERID);
/* forever, until stop is called somehow */
while(self->iStop == 0)
{
if(self->pCurrent->iStatus == READY)
{
iRet = self->pCurrent->pRun(self->pCurrent->pData);
if(iRet != 1)
{
pTemp = self->pCurrent;
IncrTaskPointer(self);
DeleteTaskHead(pTemp);
}
else
{
IncrTaskPointer(self);
}
}
else
{
IncrTaskPointer(self);
}
}
return 1;
}
/*-----------------------------------------------------------------*/
int TaskWait(pTaskMan self, long lID)
{
int iRet;
long lTest;
pTaskHead pTemp, pEnd;
assert(self);
assert(self->iID == TASKERID);
/* Cycle until lID is killed. Stop is obeyed as well */
pEnd = self->pCurrent;
pEnd->iStatus = WAITING;
IncrTaskPointer(self);
while(self->iStop == 0)
{
if((self->pCurrent != pEnd) && (self->pCurrent->iStatus == READY))
/* omit ourselves! */
{
iRet = self->pCurrent->pRun(self->pCurrent->pData);
if(iRet != 1)
{
pTemp = self->pCurrent;
lTest = pTemp->lID;
IncrTaskPointer(self);
DeleteTaskHead(pTemp);
if(lTest == lID)
{
goto ente;
}
}
else
{
IncrTaskPointer(self);
}
}
else
{
IncrTaskPointer(self);
}
}
ente:
/* task ended, we need to continue to pEnd before we are done */
while(self->pCurrent != pEnd)
{
IncrTaskPointer(self);
}
pEnd->iStatus = READY;
return 1;
}
/*----------------------------------------------------------------*/
int TaskYield(pTaskMan self)
{
int iRet;
long lTest;
pTaskHead pTemp, pEnd;
assert(self);
assert(self->iID == TASKERID);
/* Cycle until back at our selves killed. */
pEnd = self->pCurrent;
pEnd->iStatus = WAITING;
IncrTaskPointer(self);
while((self->iStop == 0) && (self->pCurrent != pEnd))
{
if((self->pCurrent != pEnd) && (self->pCurrent->iStatus == READY))
/* omit ourselves! */
{
iRet = self->pCurrent->pRun(self->pCurrent->pData);
if(iRet != 1)
{
pTemp = self->pCurrent;
lTest = pTemp->lID;
IncrTaskPointer(self);
DeleteTaskHead(pTemp);
}
else
{
IncrTaskPointer(self);
}
}
else
{
IncrTaskPointer(self);
}
}
pEnd->iStatus = READY;
return 1;
}
/*---------------------------------------------------------------------------*/
int TaskSignal(pTaskMan self, int iSignal, void *pSigData)
{
pTaskHead pTemp, pEnd;
assert(self);
assert(self->iID == TASKERID);
/* Do one cycle until we are at the caller, then return to him*/
pEnd = self->pCurrent;
IncrTaskPointer(self);
while(self->pCurrent != pEnd)
{
if(self->pCurrent->pSignal)
{
self->pCurrent->pSignal(self->pCurrent->pData, iSignal, pSigData);
}
IncrTaskPointer(self);
}
/* finally, tell me about the thingie as well */
if(pEnd->pSignal)
{
pEnd->pSignal(pEnd->pData, iSignal, pSigData);
}
return 1;
}
/*--------------------------------------------------------------------------*/
int TaskStop(pTaskMan self)
{
assert(self);
assert(self->iID == TASKERID);
self->iStop = 1;
return 1;
}
/*--------------------------------------------------------------------------*/
int TaskContinue(pTaskMan self)
{
assert(self);
assert(self->iID == TASKERID);
self->iStop = 0;
return 1;
}