epicsThread.h
C++ and C descriptions for a thread.
The epicsThread API is meant as a somewhat minimal interface for multithreaded applications. It can be implemented on a wide variety of systems with the restriction that the system MUST support a multithreaded environment. A POSIX pthreads version is provided.
The interface provides the following thread facilities, with restrictions as noted:
Life cycle: a thread starts life as a result of a call to epicsThreadCreate. It terminates when the thread function returns. It should not return until it has released all resources it uses. If a thread is expected to terminate as a natural part of its life cycle then the thread function must return.
epicsThreadOnce: this provides the ability to have an initialization function that is guaranteed to be called exactly once.
main: if a main routine finishes its work but wants to leave other threads running it can call epicsThreadExitMain, which should be the last statement in main.
Priorities: ranges between 0 and 99 with a higher number meaning higher priority. A number of constants are defined for iocCore specific threads. The underlying implementation may collapse the range 0 to 99 into a smaller range; even a single priority. User code should never rely on the existence of multiple thread priorities to guarantee correct behavior.
Stack Size: epicsThreadCreate accepts a stack size parameter. Three generic sizes are available: small, medium,and large. Portable code should always use one of the generic sizes. Some implementation may ignore the stack size request and use a system default instead. Virtual memory systems providing generous stack sizes can be expected to use the system default.
epicsThreadId: every epicsThread has an Id which gets returned by epicsThreadCreate and is valid as long as that thread still exists. A value of 0 always means no thread. If a threadId is used after the thread has terminated,the results are not defined (but will normally lead to bad things happening). Thus code that looks after other threads MUST be aware of threads terminating.
Some Named Thread Priorities
-
epicsThreadPriorityMax
-
epicsThreadPriorityMin
-
epicsThreadPriorityLow
-
epicsThreadPriorityMedium
-
epicsThreadPriorityHigh
-
epicsThreadPriorityCAServerLow
-
epicsThreadPriorityCAServerHigh
-
epicsThreadPriorityScanLow
-
epicsThreadPriorityScanHigh
-
epicsThreadPriorityIocsh
-
epicsThreadPriorityBaseMax
Defines
-
EPICS_THREAD_ONCE_INIT
-
EPICS_THREAD_OPTS_INIT
Default initial values for epicsThreadOpts Applications should always use this macro to initialize an epicsThreadOpts structure. Additional fields may be added in the future, and the order of the fields might also change, thus code that assumes the above definition might break if these rules are not followed.
-
EPICS_THREAD_CAN_JOIN
Typedefs
-
typedef void (*EPICSTHREADFUNC)(void *parm)
-
typedef epicsThreadId epicsThreadOnceId
-
typedef void (*EPICS_THREAD_HOOK_ROUTINE)(epicsThreadId id)
Hooks called when a thread starts, map function called once for every thread.
-
typedef struct epicsThreadPrivateOSD *epicsThreadPrivateId
Thread local storage
Enums
Functions
-
unsigned int epicsThreadGetStackSize(epicsThreadStackSizeClass size)
Get a stack size value that can be given to epicsThreadCreate().
- Parameters:
size – one of the values epicsThreadStackSmall, epicsThreadStackMedium or epicsThreadStackBig.
-
void epicsThreadOnce(epicsThreadOnceId *id, EPICSTHREADFUNC, void *arg)
Perform one-time initialization.
Run the provided function if it has not run, and is not running in some other thread.
For each unique epicsThreadOnceId, epicsThreadOnce guarantees that
myInitFunc will only be called only once.
myInitFunc will have returned before any other epicsThreadOnce call using the same epicsThreadOnceId returns.
static epicsThreadOnceId onceId = EPICS_THREAD_ONCE_INIT; static void myInitFunc(void *arg) { ... } static void some Function(void) { epicsThreadOnce(&onceId, &myInitFunc, NULL); }
-
void epicsThreadRealtimeLock(void)
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.
-
void epicsThreadExitMain(void)
If the main routine is done but wants to let other threads run it can call this routine. This should be the last call in main, except the final return. On most systems epicsThreadExitMain never returns.This must only be called by the main thread.
- Deprecated:
Deprecated for lack of use. Please report any usage. Recommended replacement is loop + epicsThreadSleep(), epicsEventMustWait(), or similar.
-
epicsThreadId epicsThreadCreateOpt(const char *name, EPICSTHREADFUNC funptr, void *parm, const epicsThreadOpts *opts)
Allocate and start a new OS thread.
- Parameters:
name – A name describing this thread. Appears in various log and error message.
funptr – The thread main function.
parm – Passed to thread main function.
opts – Modifiers for the new thread, or NULL to use target specific defaults.
- Returns:
NULL on error
-
epicsThreadId epicsThreadCreate(const char *name, unsigned int priority, unsigned int stackSize, EPICSTHREADFUNC funptr, void *parm)
Short-hand for epicsThreadCreateOpt() to create an un-joinable thread.
-
epicsThreadId epicsThreadMustCreate(const char *name, unsigned int priority, unsigned int stackSize, EPICSTHREADFUNC funptr, void *parm)
Short-hand for epicsThreadCreateOpt() to create an un-joinable thread. On error calls cantProceed()
-
void epicsThreadMustJoin(epicsThreadId id)
Wait for a joinable thread to exit (return from its main function)
-
void epicsThreadSuspendSelf(void)
Block the current thread until epicsThreadResume().
-
void epicsThreadResume(epicsThreadId id)
Resume a thread suspended with epicsThreadSuspendSelf()
-
unsigned int epicsThreadGetPriority(epicsThreadId id)
Return thread OSI priority
-
unsigned int epicsThreadGetPrioritySelf(void)
Return thread OSI priority
-
void epicsThreadSetPriority(epicsThreadId id, unsigned int priority)
Change OSI priority of target thread.
-
epicsThreadBooleanStatus epicsThreadHighestPriorityLevelBelow(unsigned int priority, unsigned *pPriorityJustBelow)
Lookup the next usage OSI priority such that priority > *pPriorityJustBelow if this is possible with the current target configuration and privlages.
-
epicsThreadBooleanStatus epicsThreadLowestPriorityLevelAbove(unsigned int priority, unsigned *pPriorityJustAbove)
Lookup the next usage OSI priority such that priority < *pPriorityJustBelow if this is possible with the current target configuration and privlages.
-
int epicsThreadIsEqual(epicsThreadId id1, epicsThreadId id2)
Test if two thread IDs actually refer to the same OS thread
-
int epicsThreadIsSuspended(epicsThreadId id)
How and why a thread can be suspended is implementation dependent. A thread calling epicsThreadSuspendSelf() should result in this routine returning true for that thread, but a thread may also be suspended for other reasons.
-
void epicsThreadSleep(double seconds)
Block the calling thread for at least the specified time.
- Parameters:
seconds – Time to wait in seconds. Values <=0 blocks for the shortest possible time.
-
double epicsThreadSleepQuantum(void)
Query a value approximating the OS timer/scheduler resolution.
Warning
On targets other than vxWorks and RTEMS, the quantum value often isn’t meaningful. Use of this function is discouraged in portable code.
- Returns:
A value in seconds >=0
-
epicsThreadId epicsThreadGetIdSelf(void)
Find an epicsThreadId associated with the current thread. For non-EPICS threads, a new epicsThreadId may be allocated.
-
epicsThreadId epicsThreadGetId(const char *name)
Attempt to find the first instance of a thread by name.
Warning
Safe use of this function requires external knowledge that this thread will not return.
- Returns:
An epicsThreadId, or NULL if no such thread is currently running. Note that a non-NULL ID may still be invalid if this call races with thread exit.
-
int epicsThreadGetCPUs(void)
Return a value approximating the number of threads which this target can run in parallel. This value is advisory.
- Returns:
>=1
-
const char *epicsThreadGetNameSelf(void)
Return the name of the current thread.
This is either a copy of the string passed to epicsThread*Create*(), or an arbitrary unique string for non-EPICS threads.
- Returns:
Never NULL. Storage lifetime tied to epicsThreadId.
-
void epicsThreadGetName(epicsThreadId id, char *name, size_t size)
Copy out the thread name into the provided buffer.
Guaranteed to be null terminated. size is number of bytes in buffer to hold name (including terminator). Failure results in an empty string stored in name.
-
int epicsThreadIsOkToBlock(void)
Is it OK for a thread to block? This can be called by support code that does not know if it is called in a thread that should not block. For example the errlog system calls this to decide when messages should be displayed on the console.
-
void epicsThreadSetOkToBlock(int isOkToBlock)
When a thread is started the default is that it is not allowed to block. This method can be called to change the state. For example iocsh calls this to specify that it is OK to block.
-
void epicsThreadShowAll(unsigned int level)
Print to stdout information about all running EPICS threads.
- Parameters:
level – 0 prints minimal output. Higher values print more details.
-
void epicsThreadShow(epicsThreadId id, unsigned int level)
Print info about a single EPICS thread.
-
int epicsThreadHookAdd(EPICS_THREAD_HOOK_ROUTINE hook)
Register a routine to be called by every new thread before the thread function gets run. Hook routines will often register a thread exit routine with epicsAtThreadExit() to release thread-specific resources they have allocated.
-
int epicsThreadHookDelete(EPICS_THREAD_HOOK_ROUTINE hook)
Remove routine from the list of hooks run at thread creation time.
-
void epicsThreadHooksShow(void)
Print the current list of hook function pointers.
-
void epicsThreadMap(EPICS_THREAD_HOOK_ROUTINE func)
Call func once for every known thread.
-
epicsThreadPrivateId epicsThreadPrivateCreate(void)
Allocate a new thread local variable. This variable will initially hold NULL for each thread.
-
void epicsThreadPrivateDelete(epicsThreadPrivateId id)
Free a thread local variable
-
void epicsThreadPrivateSet(epicsThreadPrivateId, void*)
Update thread local variable
-
void *epicsThreadPrivateGet(epicsThreadPrivateId)
Fetch the current value of a thread local variable
-
void epicsThreadCallEntryPoint(void*)
-
struct epicsThreadOpts
- #include <epicsThread.h>
For use with epicsThreadCreateOpt()
Public Members
-
unsigned int priority
Thread priority in OSI range (cf. epicsThreadPriority*)
-
unsigned int stackSize
Thread stack size, either in bytes for this architecture or an enum epicsThreadStackSizeClass value.
-
unsigned int joinable
Should thread be joinable? (default (0) is not joinable). If joinable=1, then epicsThreadMustJoin() must be called for cleanup thread resources.
-
unsigned int priority
-
class epicsThreadRunable
- #include <epicsThread.h>
Interface used with class epicsThread.
Public Functions
-
virtual ~epicsThreadRunable() = 0
-
virtual void run() = 0
Thread main function. C++ exceptions which propagate from this method will be caught and a warning printed. No other action is taken.
-
virtual void show(unsigned int level) const
Optional. Called via epicsThread::show()
-
virtual ~epicsThreadRunable() = 0
-
class epicsThread
- #include <epicsThread.h>
An OS thread.
A wrapper around the epicsThread* C API.
Note
Threads must be start() ed.
Public Functions
-
epicsThread(epicsThreadRunable&, const char *name, unsigned int stackSize, unsigned int priority = 10)
Create a new thread with the provided information.
cf. epicsThreadOpts
Note
Threads must be start() ed.
- Throws:
epicsThread::unableToCreateThread – on error.
-
~epicsThread()
-
void start()
Actually start the thread.
-
void exitWait()
Wait for the thread epicsRunnable::run() to return.
-
bool exitWait(const double delay)
Wait for the thread epicsRunnable::run() to return.
- Parameters:
delay – Wait up to this many seconds.
- Returns:
true if run() returned. false on timeout.
-
void resume()
-
void getName(char *name, size_t size) const
cf. epicsThreadGetName();
-
epicsThreadId getId() const
cf. epicsThreadGetIdSelf()()
-
unsigned int getPriority() const
-
void setPriority(unsigned int)
-
bool priorityIsEqual(const epicsThread&) const
-
bool isSuspended() const
-
bool isCurrentThread() const
- Returns:
true if call through this thread’s epicsRunnable::run()
-
bool operator==(const epicsThread&) const
-
void show(unsigned level) const
Say something interesting about this thread to stdout.
Public Static Functions
-
static void exit()
Note
This exitException doesn’t not derive from std::exception
- Throws:
A – special exitException which will be caught and ignored.
-
static void suspendSelf()
-
static void sleep(double seconds)
-
static const char *getNameSelf()
-
static bool isOkToBlock()
-
static void setOkToBlock(bool isOkToBlock)
Private Functions
-
bool beginWait()
-
epicsThread(const epicsThread&)
-
epicsThread &operator=(const epicsThread&)
-
void printLastChanceExceptionMessage(const char *pExceptionTypeName, const char *pExceptionContext)
Private Members
-
epicsThreadRunable &runable
-
epicsThreadId id
-
epicsMutex mutex
-
epicsEvent event
-
epicsEvent exitEvent
-
bool *pThreadDestroyed
-
bool begin
-
bool cancel
-
bool terminated
-
bool joined
Friends
-
friend void epicsThreadCallEntryPoint(void*)
-
class exitException
-
epicsThread(epicsThreadRunable&, const char *name, unsigned int stackSize, unsigned int priority = 10)
-
class epicsThreadPrivateBase
Subclassed by epicsThreadPrivate< T >
Protected Static Functions
-
static void throwUnableToCreateThreadPrivate()
-
class unableToCreateThreadPrivate
-
static void throwUnableToCreateThreadPrivate()
-
template<class T>
class epicsThreadPrivate : private epicsThreadPrivateBase -
Private Members