/*----------------------------------------------------------+ | SHARE Multi-tasking Example - 1998 Winter conference | | session 5957 | +----------------------------------------------------------*/ #define ULONG unsigned long #define UCHAR unsigned char #define PSZ unsigned char * #define PUCHAR unsigned char * #define PULONG unsigned long * #define UINT unsigned int #define PUINT unsigned int * #define ECB unsigned long #define PECB unsigned long * #define WAITING 0x80000000 #define POSTED 0x40000000 /*-------------------------------------------------------------------+ | STRUCTURE NAME: MSG | USE: Maps the common messages +-------------------------------------------------------------------*/ typedef struct _MSG { UINT uiMsg; /* Message ID */ #define SHUTDOWN 0 #define TIMERREQ 1 #define TIMERPOP 2 UCHAR ucData[236]; /* Variable data */ } MSG, *PMSG; /*-------------------------------------------------------------------+ | STRUCTURE NAME: TREQUEST | USE: Maps the Timer request message +-------------------------------------------------------------------*/ typedef struct _TREQUEST { time_t dWakeUpTime; /* When to send the timer message*/ struct _TASK *pTask; /* What task to send it to */ } TREQUEST, *PTREQUEST; /*-------------------------------------------------------------------+ | STRUCTURE NAME: MSGBLOCK | USE: Maps the message block +-------------------------------------------------------------------*/ typedef struct _MSGBLOCK { UCHAR abID(|4|); /* eye-catcher - 'MSG ' */ struct _MSGBLOCK *pMsgPrev;/* address of prev message block on the */ /* free chain or queue chain */ struct _MSGBLOCK *pMsgNext;/* address of next msg in fifo list */ ULONG ulMsgSize; /* message size */ MSG stMsg; /* msg data (set so max size = 256)*/ } MSGBLOCK, *PMSGBLOCK; /*-------------------------------------------------------------------+ | STRUCTURE NAME: QUEUE | USE: Maps the message queue headers +-------------------------------------------------------------------*/ typedef struct _QUEUE { UCHAR abID(|4|); /* eye catcher - 'QUE ' */ PMSGBLOCK pMsgFirst; /* address of first message for fifo */ union { double dCDSAlign; /* used to force doubleword alignment */ struct { ECB ulQECB; /* getmsg/putmsg ecb */ ULONG ulCount; /* queue message counter */ } stCDS; } uCDS; PMSGBLOCK pMsgLast; /* address of last message on the queue */ } QUEUE, *PQUEUE; /*-------------------------------------------------------------------+ | STRUCTURE NAME: LOCK | USE: Semaphore lock element +-------------------------------------------------------------------*/ typedef struct _LOCK { ECB ulLockECB; /* ECB to post when element is unlocked */ struct _LOCK *pNext; /* address of next element on LIFO queue*/ } LOCK, *PLOCK; /*-------------------------------------------------------------------+ | STRUCTURE NAME: TASK | USE: Maps the data associated with a task instance +-------------------------------------------------------------------*/ typedef struct _TASK { struct _TASKARG *pstTaskArg; /* points to &stTaskArg. This pointer is used as the ATTACH parm */ struct _ANCHOR *pAnchor; /* global anchor address */ QUEUE stQueue; /* message queue hdr */ ECB ulTaskEndECB; /* end of task ecb */ void *pTaskTCB; /* pointer to TCB (used in DETACH) */ int iTaskNum; /* Task number */ struct _TASK *pNextTask; /* pointer to next task */ struct _TASK *pNextTimeTask; /* pointer to next task on the timer queue */ time_t dWakeUpTime; /* When to send the timer message*/ struct _TASKARG { short sLen; /* length of main() parms */ char ucParm(|100|); /* parm passed to main(). Arg(|1|) will contain a character string of the address of this TASK structure */ } stTaskArg; } TASK, *PTASK; /*-------------------------------------------------------------------+ | STRUCTURE NAME: ANCHOR | USE: Global area | NOTE: This area should be considered 'read-only' except for those | members explicitly serialized. +-------------------------------------------------------------------*/ typedef struct _ANCHOR { UCHAR ucEye(|8|); /* eyecatcher - "ANCHOR " */ PTASK pSubTaskChain;/* points to first subtask cb on chain*/ QUEUE stMainQueue; /* message queue hdr for main task */ TASK stTimerTask; /* Timer subtask info */ ULONG ulSemLog; /* print log mutex semaphore */ union { double dCDSAlign; /* used to force doubleword alignment */ struct { PMSGBLOCK pMsgFirst; /* addr of first message in free pool*/ ULONG ulRefNum; /* number of references to the pool */ } stCDS; } uCDS; PMSGBLOCK pFreePool; /* points to the start of free pool*/ ULONG ulFree; /* free messages in the pool */ } ANCHOR, *PANCHOR;