Files
sics/task.h
2015-07-29 17:47:46 +10:00

418 lines
15 KiB
C

/*---------------------------------------------------------------------------
T A S K
This is a portable task switching module. Tasks are maintained in a
circular list and switched in between. Waiting for some task to end,
a yield and a primitive form of inter task communication is implemented.
Mark Koennecke, September 1997
extended to support task groups
Mark Koennecke, December 2012
copyright: see implementation file
-----------------------------------------------------------------------------*/
#ifndef TASKOMAT
#define TASKOMAT
typedef long TaskTaskID;
typedef long TaskGroupID;
extern TaskTaskID TaskUnknownTaskID, TaskBadTaskID;
extern TaskGroupID TaskUnknownGroupID, TaskBadGroupID;
/*---------------------------------------------------------------------------*/
typedef enum eTaskLogLevel {
eTaskLogNone = 0,
eTaskLogDebug = 1,
eTaskLogInfo = 2,
eTaskLogWarning = 3,
eTaskLogError = 4,
eTaskLogFatal = 5
} eTaskLogLevel;
typedef void (*TaskLogFunc) (eTaskLogLevel, const char *buf);
/*
A TaskLogFunc can be registered for logging activity within the task module.
*/
/*
* Use these values for the Task Priority
*/
#define TASK_PRIO_LOW 10
#define TASK_PRIO_MED 30
#define TASK_PRIO_HIGH 50
/*--------------------------------------------------------------------------*/
typedef struct __TaskHead *pTaskHead;
typedef struct __TaskMan *pTaskMan;
typedef struct __TaskQueue *pTaskQueue;
typedef struct __TaskMessage *pTaskMessage;
/*
two data structure used internally and defined in task.c
*/
/*---------------------------------------------------------------------------*/
typedef int (*TaskFunc) (void *pData);
/*
a task function must be implemented by each task. This function will be
called when it is the tasks turn to execute. This function obtains a
pointer to a user defined data structure as parameter. If the task is going
to end, it has to return 0. It's data structure will be removed by a
KillFunction of the type defined below. If the task is
going to run again in its next turn the task function has to return a
1.
*/
/*--------------------------------------------------------------------------*/
typedef int (*TaskMsgFunc) (void *pData, pTaskMessage pMsg);
/*
* Like the TaskFunc but with a message extracted from the task queue
*/
/*--------------------------------------------------------------------------*/
typedef void (*TaskKillFunc) (void *pData);
/*
Each task using private data structures must define this functions. It's
task is to clear the private data structure of the task and free all memory
associated with it. This function will be called automatically by the
Tasker when a task finishes or when the whole Tasker is shut down.
*/
/*---------------------------------------------------------------------------*/
typedef void (*SignalFunc) (void *pUser, int iSignal, void *pSigData);
/*
A SignalFunction can be implemented by each task. It is the means of
inter task communication. The first parameter is a pointer to the
tasks private datastructure. Further parameters are an integer signal ID
and a pointer to a datastructure for this signal. The meaning of signal
ID's and signal data structures is up to the client of this code.
*/
/*===========================================================================
ALL FUNTIONS RETURN 0 on FAILURE, 1 ON SUCCESS WHEN NOT MENTIONED
OTHERWISE
============================================================================*/
int TaskerInit(pTaskMan * self);
/*
Initalises a Task Manager.
*/
int TaskerDelete(pTaskMan * self);
/*
Stops all running tasks and clears all data structures associated with
tasks and the TaskManager.
*/
/*--------------------------------------------------------------------------*/
TaskTaskID TaskRegister(pTaskMan self, TaskFunc pTaskRun,
SignalFunc pSignalFunc,
TaskKillFunc pKillFunc, void *pData, int iPriority);
/*
This call enter a new task into the system. The caller has to
specify:
a TaskFunction [Required]
a SignalFunction [Optional, can be NULL]
a KillFunction for task private data.
[Optional, can be NULL]
a pointer to task private data
[Optional, can be NULL]
a priority for this task. This is currently unused.
On Success a positive value denoting the ID of the task is returned.
On error a negative value is returned.
*/
/*--------------------------------------------------------------------------*/
TaskTaskID TaskRegisterN(pTaskMan self, char *name, TaskFunc pTaskRun,
SignalFunc pSignalFunc, TaskKillFunc pKillFunc,
void *pData, int iPriority);
/*
This call enter a new task into the system. The caller has to
specify:
a TaskFunction [Required]
a SignalFunction [Optional, can be NULL]
a KillFunction for task private data.
[Optional, can be NULL]
a pointer to task private data
[Optional, can be NULL]
a priority for this task. This is currently unused.
On Success a positive value denoting the ID of the task is returned.
On error a negative value is returned.
*/
/*--------------------------------------------------------------------------*/
TaskTaskID TaskRegisterD(pTaskMan self, char *name, TaskFunc pTaskRun,
SignalFunc pSignalFunc, TaskKillFunc pKillFunc,
void *pData, int iPriority, double delay);
/*
This call enters a new task into the system.
The task will start running after the given delay in seconds.
*/
/*--------------------------------------------------------------------------*/
TaskTaskID TaskRegisterP(pTaskMan self, char *name, TaskFunc pTaskRun,
SignalFunc pSignalFunc, TaskKillFunc pKillFunc,
void *pData, int iPriority, double delay, double period);
/*
This call enters a new task into the system.
The task will run after delay seconds and then every period seconds.
*/
/*--------------------------------------------------------------------------*/
TaskTaskID TaskRegisterQ(pTaskMan self, char *name, TaskMsgFunc pTaskRun,
SignalFunc pSignalFunc, TaskKillFunc pKillFunc,
void *pData, int iPriority);
/*
This call enters a new task with queue into the system.
As for TaskRegisterN except the task function signature has
a message pointer.
*/
/*-------------------------------------------------------------------------*/
int TaskSchedule(pTaskMan self);
/*
Starts task switching.
*/
/*-----------------------------------------------------------------------*/
int TaskStop(pTaskMan self);
/*
Interrupts task switching all together
*/
/*------------------------------------------------------------------------*/
int TaskContinue(pTaskMan self);
/*
Continues an task switching session interrupted by TaskStop. After this
the apopriate TaskYield, TaskSchedule or wahtever has to be called.
*/
/*-------------------------------------------------------------------------*/
int TaskWait(pTaskMan self, TaskTaskID taskID);
/*
Waits until the task specified by taskID has finished. taskID is obtained
from a call to TaskRegister.
*/
/*-------------------------------------------------------------------------*/
int TaskYield(pTaskMan self);
/*
does one cycle of the task loop and returns to the caller.This call allows
other tasks to execute while a task executes a lengthy calculation.
*/
/*--------------------------------------------------------------------------*/
int TaskSignal(pTaskMan self, int iSignal, void *pSigData);
/*
Invokes each Task's signal function with parameters iSignal and
pSigData.
*/
/*-------------------------------------------------------------------------*/
void TaskRemove(pTaskMan self, TaskFunc pTaskRun, void *pData);
/*
remove the task with the given task function and the given data pointer
*/
/*-------------------------------------------------------------------------*/
int StopTask(pTaskMan self, char *name);
/*
stop the task with the given name. Returns 0 on failure, 1 on success
*/
/*--------------------------------------------------------------------------*/
int isTaskRunning(pTaskMan self, char *name);
/*
returns 1 when task name is running, 0 else
*/
/*--------------------------------------------------------------------------*/
int isTaskIDRunning(pTaskMan self, TaskTaskID taskID);
/*
returns 1 when task name is running, 0 else
*/
/*===========================================================================
Iterating the task list. This works like:
pTaskHead it;
char *des;
for(it = TaskIteratorStart(self); it != NULL; it = TaskIteratorNext(it)){
des = TaskDescription(it);
}
There are two limitations of the implementation here:
- Never, ever delete the Iterator it
- Do your iteration in one go or abandon it mid iteration. If another task
gets in between and registers new tasks or removes one, then the whole
iterator may be messed up.
=============================================================================*/
pTaskHead TaskIteratorStart(pTaskMan self);
/*
starts iterating on the TaskList. Do NOT delete the returned pointer!
*/
pTaskHead TaskIteratorNext(pTaskHead it);
/*
Steps to the next element in the task list. Returns NULL when node.
Do NOT delete the returned pointer!
*/
pTaskHead TaskIteratorCurrent(pTaskMan self);
pTaskHead TaskIteratorByName(pTaskMan self, const char* name);
pTaskHead TaskIteratorByID(pTaskMan self, TaskTaskID taskID);
/*
Gets the task iterator for either the current, named or numbered task
Do NOT delete the returned pointer!
*/
char *TaskDescription(pTaskHead it);
/*
get a description of the task at the current iterator
You are responsible for deleting the returned character array.
*/
char *TaskDetail(pTaskHead it);
/*
get a detailed description of the task at the current iterator
You are responsible for deleting the returned character array.
*/
TaskTaskID GetTaskID(pTaskHead it);
/*
get the ID of the current task
*/
TaskGroupID GetGroupID(pTaskHead it);
/*
get the group ID of the current task
*/
const char *GetTaskName(pTaskHead it);
/*
get the name of the current task. Do not delete the returned pointer.
*/
const void *GetTaskData(pTaskHead it);
/*
Get the user data for the current task. Do not free the returned pointer!
*/
/*=============================================================================
Task Groups. The implementation has the limit that any given task can
only be member of one task group
===============================================================================*/
TaskGroupID GetTaskGroupID(pTaskMan self);
/*
get the ID for a task group
*/
void AddTaskToGroup(pTaskMan self, TaskTaskID taskID, TaskGroupID groupID);
/*
Add taskID to the task group groupID
*/
int isTaskGroupRunning(pTaskMan self, TaskGroupID groupID);
/*
Returns 1 when the task group is still running, 0 else
*/
int TaskGroupTask(void *data);
/*
This is a task function which implements the common task of waiting
for a group of tasks to finish. It expects as data a TaskGroupData
structure.
*/
/*--------------------------------------------------------------------------*/
int TaskSignalGroup(pTaskMan self, int iSignal, void *pSigData, TaskGroupID groupID);
/*
signal only tasks in the group groupID
*/
/*--------------------------------------------------------------------------*/
void TaskSetLogFunc(TaskLogFunc);
TaskLogFunc TaskGetLogFunc(void);
eTaskLogLevel TaskSetLogLevel(eTaskLogLevel thresh);
eTaskLogLevel TaskGetLogLevel(void);
/*--------------------------------------------------------------------------*/
int TaskGetStack(pTaskMan self, pTaskHead it[]);
/*
* Returns the current stack depth of tasks and, if provided, fills the array
* of iterators. The iterators start at it[0] and can be used to get
* information about each task.
*/
/*--------------------------------------------------------------------------*/
void TaskRunMeAfter(pTaskMan self, double delay);
/*
* Run this task once in <delay> seconds
*/
/*--------------------------------------------------------------------------*/
void TaskRunMeEvery(pTaskMan self, double delay);
/*
* Run this task every <delay> seconds from now on
*/
/*--------------------------------------------------------------------------*/
double TaskRunMyPeriod(pTaskMan self);
/*
* Return this task run period in seconds
*/
/*--------------------------------------------------------------------------*/
pTaskQueue TaskQueueAlloc(void);
/*
* Task Queue constructor
*/
/*--------------------------------------------------------------------------*/
int TaskQueueFree(pTaskQueue);
/*
* Task Queue destructor
*/
/*--------------------------------------------------------------------------*/
int TaskQueueCount(pTaskQueue);
/*
* Returns the message count on the Task Queue
*/
/*--------------------------------------------------------------------------*/
int TaskQueueSend(pTaskQueue, pTaskMessage);
/*
* Pushes a Task Message onto the tail of the Task Queue
*/
/*--------------------------------------------------------------------------*/
int TaskQueueSendID(pTaskMan self, TaskTaskID taskID, pTaskMessage);
/*
* Pushes a Task Message onto the tail of the Task Queue
*/
/*--------------------------------------------------------------------------*/
pTaskMessage TaskQueueRecv(pTaskQueue);
/*
* Pops a Task Message off the head of the given Task Queue
*/
/*--------------------------------------------------------------------------*/
pTaskMessage TaskQueueRecvMine(pTaskMan self);
/*
* Pops a Task Message off the head of the owner's Task Queue
*/
/*--------------------------------------------------------------------------*/
int TaskQueueSet(pTaskMan self, TaskTaskID taskID, pTaskQueue);
/*
* Sets the Task Queue of the task
*/
/*--------------------------------------------------------------------------*/
int TaskQueueRem(pTaskMan self, TaskTaskID taskID);
/*
* Clears the Task Queue of the task
*/
/*--------------------------------------------------------------------------*/
pTaskQueue TaskQueueGet(pTaskMan self, TaskTaskID taskID);
/*
* Gets the Task Queue of the specified task
*/
/*--------------------------------------------------------------------------*/
pTaskQueue TaskQueueGetMine(pTaskMan self);
/*
* Gets the Task Queue of the current task
*/
/*--------------------------------------------------------------------------*/
pTaskMessage TaskMessageAlloc(size_t mSize, int mType);
/*
* Constructor for a Task Message of the requested size and type
*/
/*--------------------------------------------------------------------------*/
int TaskMessageFree(pTaskMessage);
/*
* Destructor for the Task Message
* returne 0=success, -1=fail
*/
/*--------------------------------------------------------------------------*/
int TaskMessageGetType(pTaskMessage self);
/*
* Get the type of the Task Message
*/
/*--------------------------------------------------------------------------*/
void TaskMessageSetType(pTaskMessage self, int mType);
/*
* Set the type of the Task Message
*/
/*--------------------------------------------------------------------------*/
void * TaskMessageGetData(pTaskMessage self);
/*
* Get the data pointer from the message
*/
/*--------------------------------------------------------------------------*/
void TaskMessageSetData(pTaskMessage self, void *mData);
/*
* Set the data pointer in the message
*/
/*--------------------------------------------------------------------------*/
#endif