Files
pcas/src/libCom/osi/epicsThread.h
2016-02-23 15:43:26 -06:00

248 lines
8.5 KiB
C++

/*************************************************************************\
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* Copyright (c) 2013 ITER Organization.
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
#ifndef epicsThreadh
#define epicsThreadh
#include <stddef.h>
#include "shareLib.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef void (*EPICSTHREADFUNC)(void *parm);
#define epicsThreadPriorityMax 99
#define epicsThreadPriorityMin 0
/* some generic values */
#define epicsThreadPriorityLow 10
#define epicsThreadPriorityMedium 50
#define epicsThreadPriorityHigh 90
/* some iocCore specific values */
#define epicsThreadPriorityCAServerLow 20
#define epicsThreadPriorityCAServerHigh 40
#define epicsThreadPriorityScanLow 60
#define epicsThreadPriorityScanHigh 70
#define epicsThreadPriorityIocsh 91
#define epicsThreadPriorityBaseMax 91
/* stack sizes for each stackSizeClass are implementation and CPU dependent */
typedef enum {
epicsThreadStackSmall, epicsThreadStackMedium, epicsThreadStackBig
} epicsThreadStackSizeClass;
typedef enum {
epicsThreadBooleanStatusFail, epicsThreadBooleanStatusSuccess
} epicsThreadBooleanStatus;
epicsShareFunc unsigned int epicsShareAPI epicsThreadGetStackSize(
epicsThreadStackSizeClass size);
/* (epicsThreadId)0 is guaranteed to be an invalid thread id */
typedef struct epicsThreadOSD *epicsThreadId;
typedef epicsThreadId epicsThreadOnceId;
#define EPICS_THREAD_ONCE_INIT 0
epicsShareFunc void epicsShareAPI epicsThreadOnce(
epicsThreadOnceId *id, EPICSTHREADFUNC, void *arg);
/* When real-time scheduling is active, attempt any post-init operations
* that preserve real-time performance. For POSIX targets this locks the
* process into RAM, preventing swap-related VM faults.
*/
epicsShareFunc void epicsThreadRealtimeLock(void);
epicsShareFunc void epicsShareAPI epicsThreadExitMain(void);
epicsShareFunc epicsThreadId epicsShareAPI epicsThreadCreate (
const char * name, unsigned int priority, unsigned int stackSize,
EPICSTHREADFUNC funptr,void * parm );
epicsShareFunc epicsThreadId epicsShareAPI epicsThreadMustCreate (
const char * name, unsigned int priority, unsigned int stackSize,
EPICSTHREADFUNC funptr,void * parm );
epicsShareFunc void epicsShareAPI epicsThreadSuspendSelf(void);
epicsShareFunc void epicsShareAPI epicsThreadResume(epicsThreadId id);
epicsShareFunc unsigned int epicsShareAPI epicsThreadGetPriority(
epicsThreadId id);
epicsShareFunc unsigned int epicsShareAPI epicsThreadGetPrioritySelf(void);
epicsShareFunc void epicsShareAPI epicsThreadSetPriority(
epicsThreadId id,unsigned int priority);
epicsShareFunc epicsThreadBooleanStatus epicsShareAPI
epicsThreadHighestPriorityLevelBelow (
unsigned int priority, unsigned *pPriorityJustBelow);
epicsShareFunc epicsThreadBooleanStatus epicsShareAPI
epicsThreadLowestPriorityLevelAbove (
unsigned int priority, unsigned *pPriorityJustAbove);
epicsShareFunc int epicsShareAPI epicsThreadIsEqual(
epicsThreadId id1, epicsThreadId id2);
epicsShareFunc int epicsShareAPI epicsThreadIsSuspended(epicsThreadId id);
epicsShareFunc void epicsShareAPI epicsThreadSleep(double seconds);
epicsShareFunc double epicsShareAPI epicsThreadSleepQuantum(void);
epicsShareFunc epicsThreadId epicsShareAPI epicsThreadGetIdSelf(void);
epicsShareFunc epicsThreadId epicsShareAPI epicsThreadGetId(const char *name);
epicsShareFunc int epicsThreadGetCPUs(void);
epicsShareFunc const char * epicsShareAPI epicsThreadGetNameSelf(void);
/* For epicsThreadGetName name is guaranteed to be null terminated */
/* size is size of buffer to hold name (including terminator) */
/* Failure results in an empty string stored in name */
epicsShareFunc void epicsShareAPI epicsThreadGetName(
epicsThreadId id, char *name, size_t size);
epicsShareFunc int epicsShareAPI epicsThreadIsOkToBlock(void);
epicsShareFunc void epicsShareAPI epicsThreadSetOkToBlock(int isOkToBlock);
epicsShareFunc void epicsShareAPI epicsThreadShowAll(unsigned int level);
epicsShareFunc void epicsShareAPI epicsThreadShow(
epicsThreadId id,unsigned int level);
/* Hooks called when a thread starts, map function called once for every thread */
typedef void (*EPICS_THREAD_HOOK_ROUTINE)(epicsThreadId id);
epicsShareFunc int epicsThreadHookAdd(EPICS_THREAD_HOOK_ROUTINE hook);
epicsShareFunc int epicsThreadHookDelete(EPICS_THREAD_HOOK_ROUTINE hook);
epicsShareFunc void epicsThreadHooksShow(void);
epicsShareFunc void epicsThreadMap(EPICS_THREAD_HOOK_ROUTINE func);
typedef struct epicsThreadPrivateOSD * epicsThreadPrivateId;
epicsShareFunc epicsThreadPrivateId epicsShareAPI epicsThreadPrivateCreate(void);
epicsShareFunc void epicsShareAPI epicsThreadPrivateDelete(epicsThreadPrivateId id);
epicsShareFunc void epicsShareAPI epicsThreadPrivateSet(epicsThreadPrivateId,void *);
epicsShareFunc void * epicsShareAPI epicsThreadPrivateGet(epicsThreadPrivateId);
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
#include "epicsEvent.h"
#include "epicsMutex.h"
class epicsShareClass epicsThreadRunable {
public:
virtual ~epicsThreadRunable () = 0;
virtual void run () = 0;
virtual void show ( unsigned int level ) const;
};
extern "C" void epicsThreadCallEntryPoint ( void * );
class epicsShareClass epicsThread {
public:
epicsThread ( epicsThreadRunable &,const char *name, unsigned int stackSize,
unsigned int priority=epicsThreadPriorityLow );
~epicsThread () throw ();
void start () throw ();
void exitWait () throw ();
bool exitWait ( const double delay ) throw ();
static void exit ();
void resume () throw ();
void getName ( char * name, size_t size ) const throw ();
epicsThreadId getId () const throw ();
unsigned int getPriority () const throw ();
void setPriority ( unsigned int ) throw ();
bool priorityIsEqual ( const epicsThread & ) const throw ();
bool isSuspended () const throw ();
bool isCurrentThread () const throw ();
bool operator == ( const epicsThread & ) const throw ();
void show ( unsigned level ) const throw ();
/* these operate on the current thread */
static void suspendSelf () throw ();
static void sleep (double seconds) throw ();
/* static epicsThread & getSelf (); */
static const char * getNameSelf () throw ();
static bool isOkToBlock () throw ();
static void setOkToBlock ( bool isOkToBlock ) throw ();
/* exceptions */
class unableToCreateThread;
private:
epicsThreadRunable & runable;
epicsThreadId id;
epicsMutex mutex;
epicsEvent event;
epicsEvent exitEvent;
bool * pWaitReleaseFlag;
bool begin;
bool cancel;
bool terminated;
bool beginWait () throw ();
epicsThread ( const epicsThread & );
epicsThread & operator = ( const epicsThread & );
friend void epicsThreadCallEntryPoint ( void * );
void printLastChanceExceptionMessage (
const char * pExceptionTypeName,
const char * pExceptionContext );
/* exceptions */
class exitException {};
};
class epicsShareClass epicsThreadPrivateBase {
public:
class unableToCreateThreadPrivate {}; /* exception */
protected:
static void throwUnableToCreateThreadPrivate ();
};
template < class T >
class epicsThreadPrivate :
private epicsThreadPrivateBase {
public:
epicsThreadPrivate ();
~epicsThreadPrivate () throw ();
T * get () const throw ();
void set (T *) throw ();
private:
epicsThreadPrivateId id;
};
#endif /* __cplusplus */
#include "osdThread.h"
#ifdef __cplusplus
template <class T>
inline epicsThreadPrivate<T>::epicsThreadPrivate ()
{
this->id = epicsThreadPrivateCreate ();
if ( this->id == 0 ) {
epicsThreadPrivateBase::throwUnableToCreateThreadPrivate ();
}
}
template <class T>
inline epicsThreadPrivate<T>::~epicsThreadPrivate () throw ()
{
epicsThreadPrivateDelete ( this->id );
}
template <class T>
inline T *epicsThreadPrivate<T>::get () const throw ()
{
return static_cast<T *> ( epicsThreadPrivateGet (this->id) );
}
template <class T>
inline void epicsThreadPrivate<T>::set (T *pIn) throw ()
{
epicsThreadPrivateSet ( this->id, static_cast<void *> (pIn) );
}
#endif /* ifdef __cplusplus */
#endif /* epicsThreadh */