Chapter 20
libCom OSI libraries

 20.1 Overview
  20.1.1 OSI source directory
  20.1.2 Rules for building OSI code
  20.1.3 Locating OSI header files.
 20.2 epicsAssert
  20.2.1 Runtime Assertion Checks
  20.2.2 Compile-time Assertion Checks
 20.3 epicsAtomic
  20.3.1 C Callable Interface
 20.4 epicsEndian
 20.5 epicsEvent
  20.5.1 C++ Interface
  20.5.2 C Interface
 20.6 epicsFindSymbol
 20.7 epicsGeneralTime
  20.7.1 Consumer interface
  20.7.2 Time Provider Interface
  20.7.3 Internal Interface
  20.7.4 Example
 20.8 epicsInterrupt
  20.8.1 C Interface
  20.8.2 Implementation notes
 20.9 epicsMath
 20.10 epicsMessageQueue
  20.10.1 C++ Interface
  20.10.2 C interface
 20.11 epicsMutex
  20.11.1 C++ Interface
  20.11.2 C Interface
  20.11.3 Implementation Notes
 20.12 epicsSpin
  20.12.1 C Interface
  20.12.2 Implementation Notes
 20.13 epicsStdlib
  20.13.1 Integer Parsing
  20.13.2 Floating-point Parsing
  20.13.3 Replacements for scanf()
 20.14 epicsStdio
 20.15 epicsTempFile
 20.16 epicsThread
  20.16.1 C Interface
  20.16.2 C++ Interface
 20.17 epicsTime
  20.17.1 Time Related Structures
  20.17.2 C++ Interface
  20.17.3 class epicsTimeEvent
  20.17.4 class epicsTime
  20.17.5 C Interface
 20.18 osiPoolStatus
 20.19 osiProcess
 20.20 Ignoring Posix Signals
 20.21 OS-Independent Socket API
 20.22 epicsMMIO
 20.23 Device Support Library
  20.23.1 Overview
  20.23.2 Location Probing
  20.23.3 Registering VME Addresses
  20.23.4 Interrupt Connection Routines
  20.23.5 Macros for Normalized Analog Values
  20.23.6 Deprecated Interrupt Routines
 20.24 vxWorks Specific routines and Headers
  20.24.1 veclist
  20.24.2 logMsgToErrlog
  20.24.3 camacLib.h
  20.24.4 epicsDynLink
  20.24.5 module_types.h
  20.24.6 task_params.h
  20.24.7 vxComLibrary

20.1 Overview

Most code in base is operating system independent, i.e. the code is exactly the same for all supported operating systems. This is accomplished by providing epics-specific APIs for facilities that are different on the various systems. These APIs are called Operating System Independent, or OSI, and are part of libCom. The OSI APIs have multiple implementations, which are Operating System Dependent or OSD. Some APIs are implemented using the features of a particular compiler that is supported on multiple operating systems. For example the GNU Compiler Collection (GCC) is used for compiling many targets and provides a common GCC-specific API for some features. Base now makes it possible to use compiler-specific as well as OS-specific code to implement the OSI APIs.

20.1.1 OSI source directory

Directory <base>/src/libCom/osi contains the code for the operating system independent libraries. The structure of this directory is:

  osi/
     ⋆.h
     ⋆.c
     ⋆.cpp
     compiler/
         borland/
         clang/
         default/
         gcc/
         msvc/
         solStudio/
     os/
         Linux/
         Darwin/
         RTEMS/
         WIN32/
         default/
         posix/
         solaris/
         vxWorks/

Code for additional compilers and operating systems may also be present.

20.1.2 Rules for building OSI code

The src/libCom/osi directory contains source and header files that provide common definitions for the OSI APIs. The directories under osi/compiler contain compiler-specific files that implement some of the OSI APIs. The directories under osi/os contain operating-system-specific files that implement the remaining OSI APIs.

Header files residing under src/libCom/osi are installed into include as follows:

The search order for locating OSD source files is:

  1. osi/compiler/<cmplr>
  2. osi/compiler/default
  3. osi/os/<os>
  4. osi/os/posix
  5. osi/os/default

20.1.3 Locating OSI header files.

When code is compiled, the search order for locating header files in base/include is:

  1. include/compiler/<cmplr>
  2. include/os/<os>
  3. include

20.2 epicsAssert

This is an enhanced version of ANSI C’s assert facility. To use this, replace:

#include <assert.h>

with

#include "epicsAssert.h"

20.2.1 Runtime Assertion Checks

The same assert(expression) macro is used as with the ANSI header to test a run-time assertion.

If a run-time assertion check finds the expression false, it calls errlog indicating the program’s author, file name, and line number. Each OS provides specialized instructions assisting the user to diagnose the problem and generate a good bug report. For instance, under vxWorks there are instructions on how to generate a stack trace; on posix there are instructions about saving the core file. After printing the message, the calling thread is suspended.

To provide the author’s name for the message, before including the epicsAssert.h file define a preprocessor macro named epicsAssertAuthor as a string containing the name and email address to be contacted.

20.2.2 Compile-time Assertion Checks

The C or C++ compiler can be used to evaluate and check a static expression at compile-time. Static assertions may only be placed where a variable declaration is valid, and can only test certain kinds of constant expressions. A static assertion looks like this:

STATIC_ASSERT(expression);

If the expression evaluates as false, the compiler will be presented with an illegal variable declaration using the name static_assert_failed_at_line_<n> and so should halt compilation at that point.

20.3 epicsAtomic

This is an operating system and compiler independent interface to an operating system and or compiler dependent implementation of several atomic primitives. Currently, only increment, decrement, add, subtract, compare-and-swap, and test-and-set primitives have been implemented as appropriate for the C primitive types of int, size_t, and void ⋆ pointer.

These primitives can be safely used in a multithreaded programs on symmetric multiprocessing (SMP) systems. Where possible the primitives are implemented with compiler intrinsic wrappers for archetecture specific instructions. Otherwise they are implemeted with OS specific functions and otherwise, when lacking a sufficently capable OS specific interface, then in some rare situations a mutual exclusion primitive is used for synchronization.

In operating systems environments which allow C code to run at interrupt level the implementation must use interrupt level invokable CPU instruction primitives.

All C++ functions are implemented in the namespace atomics which is nested inside of namespace epics.

#include <epicsAtomic.h>

20.3.1 C Callable Interface

void epicsAtomicReadMemoryBarrier (); 
void epicsAtomicWriteMemoryBarrier (); 
 
size_t epicsAtomicIncrSizeT ( size_t  pTarget ); 
int epicsAtomicIncrIntT ( int  pTarget ); 
 
size_t epicsAtomicDecrSizeT ( size_t  pTarget ); 
int epicsAtomicDecrIntT ( int  pTarget ); 
 
size_t epicsAtomicAddSizeT ( size_t  pTarget, size_t delta ); 
size_t epicsAtomicSubSizeT ( size_t  pTarget, size_t delta ); 
int epicsAtomicAddIntT ( int  pTarget, int delta ); 
 
void epicsAtomicSetSizeT  ( size_t  pTarget, size_t newValue ); 
void epicsAtomicSetIntT ( int  pTarget, int newValue ); 
void epicsAtomicSetPtrT ( EpicsAtomicPtrT  pTarget, EpicsAtomicPtrT newValue ); 
 
size_t epicsAtomicGetSizeT ( const size_t  pTarget ); 
int epicsAtomicGetIntT ( const int  pTarget ); 
EpicsAtomicPtrT epicsAtomicGetPtrT ( const EpicsAtomicPtrT  pTarget ); 
 
size_t epicsAtomicCmpAndSwapSizeT ( size_t  pTarget, 
                                            size_t oldVal, size_t newVal ); 
int epicsAtomicCmpAndSwapIntT ( int  pTarget, 
                                            int oldVal, int newVal ); 
EpicsAtomicPtrT epicsAtomicCmpAndSwapPtrT ( 
                                            EpicsAtomicPtrT  pTarget, 
                                            EpicsAtomicPtrT oldVal, 
                                            EpicsAtomicPtrT newVal ); 
 
int epicsAtomicTestAndSet ( int  pTarget );

C Function

C++ Function

Meaning




epicsAtomicReadMemoryBarrier

readMemoryBarrier

Load target into cache.

epicsAtomicWriteMemoryBarrier

writeMemoryBarrier

Push cache version of target into target.

epicsAtomicIncrXxxx

increment

Lock out other SMP processors from accessing the target, load the target into cache, add one to the target, flush cache to the target, allow other SMP processors to access the target, and return the new value of the target as modified by this operation.

epicsAtomicDecrXxxx

decrement

Lock out other smp processors from accessing the target, load the target into cache, subtract one from the target, flush cache to the target, allow other SMP processors to access the target, and return the new value of target as modified by this operation.

epicsAtomicAddXxxx

add

Lock out other SMP processors from accessing the target, load the target into cache, add delta to the target, flush the cache to the target, allow other SMP processors to access the target, return new value of target as modified by this operation.

epicsAtomicSubXxxx

subtract

Lock out other SMP processors from accessing the target, load the target into cache, subtract delta from the target, flush the cache to the target, allow other SMP processors to access the target, return new value of target as modified by this operation.

epicsAtomicSetXxxx

set

Set the cached version of target, and flush the cache to the target.

epicsAtomicGetXxxx

get

Fetch the target into cache, and return the cached value.

epicsAtomicCmpAndSwapXxxx

compareAndSwap

Lock out other SMP processors from accessing the target, load the target into cache, if the target is equal to oldVal set the target to newVal, flush cache to the target, allow other SMP processors to access the target, and return the original value stored in the target.

epicsAtomicTestAndSet

testAndSet

Lock out other SMP processors from accessing the target, load the target into cache, if the target value is logical false (zero) set the target to be logical true, flush cache to the target, allow other SMP processors to access the target, and return the original value stored in the target.

20.4 epicsEndian

epicsEndian.h provides an operating-system independent means of discovering the native byte order of the CPU which the compiler is targeting, and works in both C and C++ code. It defines the following preprocessor macros, the values of which are integers:

The latter two macros are defined to be one or other of the first two, and may be compared with them to determine conditional compilation or execution of code that performs byte or word swapping as necessary.

#if (EPICS_BYTE_ORDER == EPICS_ENDIAN_BIG) 
    /⋆ ... ⋆/ 
#else /⋆ EPICS_ENDIAN_LITTLE ⋆/ 
    /⋆ ... ⋆/ 
#endif /⋆ EPICS_BYTE_ORDER ⋆/

20.5 epicsEvent

epicsEvent.h defines the C++ and C APIs for a simple binary semaphore. If multiple threads are waiting on the same event, only one of them will be woken when the event is signalled.

20.5.1 C++ Interface

typedef enum { 
    epicsEventOK = 0, 
    epicsEventWaitTimeout, 
    epicsEventError 
} epicsEventStatus; 
 
/⋆ Backwards compatibility ⋆/ 
#define epicsEventWaitStatus epicsEventStatus 
#define epicsEventWaitOK epicsEventOK 
#define epicsEventWaitError epicsEventError 
 
typedef enum { 
    epicsEventEmpty, 
    epicsEventFull 
} epicsEventInitialState; 
 
class epicsEvent { 
public: 
    epicsEvent ( epicsEventInitialState initial = epicsEventEmpty ); 
    ~epicsEvent (); 
    void trigger (); 
    void signal () { this->trigger(); } 
    void wait ();                   /⋆ blocks until full ⋆/ 
    bool wait ( double timeOut );   /⋆ false if still empty at time out ⋆/ 
    bool tryWait ();                /⋆ false if empty ⋆/ 
    void show ( unsigned level ) const; 
 
    class invalidSemaphore;         /⋆ exception payload ⋆/ 
private: 
    ... 
};

Method

Meaning



epicsEvent

An epicsEvent can be created empty or full. If it is created empty then a wait issued before a trigger will block. If created full then the first wait will always succeed. Multiple triggers may be issued between waits but have the same effect as a single trigger.

~epicsEvent

Remove the event and any resources it uses. Any further use of the semaphore result in unknown (most certainly bad) behavior. No outstanding take can be active when this call is made.

trigger

Trigger the event i.e. ensures that the next or current call to wait completes. This method may be called from a vxWorks or RTEMS interrupt handler.

signal

A synonym for trigger, provided for backwards compatibility.

wait()

Wait for the event to be triggered.

wait(double timeOut)

Similar to wait except that if event does not happen the call completes after the specified time out. The return value is true) if the event was triggered, false if it timed out.

tryWait()

Similar to wait except that if event has not already been triggered the call completes immediately. The return value is true if an unused event has already been signalled, false if not.

show

Display information about the epicsEvent. The information displayed is architecture dependent.

The primary use of an event semaphore is for thread synchronization. An example of using an event semaphore is a consumer thread that processes requests from one or more producer threads. For example:

20.5.2 C Interface

epicsEventId epicsEventCreate(epicsEventInitialState initialState); 
epicsEventId epicsEventMustCreate(epicsEventInitialState initialState); 
void epicsEventDestroy(epicsEventId id); 
 
epicsEventStatus epicsEventTrigger(epicsEventId id); 
void epicsEventMustTrigger(epicsEventId id); 
#define epicsEventSignal(ID) epicsEventMustTrigger(ID) 
 
epicsEventStatus epicsEventWait(epicsEventId id); 
void epicsEventMustWait(epicsEventId id); 
epicsEventStatus epicsEventWaitWithTimeout(epicsEventId id, double timeOut); 
epicsEventStatus epicsEventTryWait(epicsEventId id); 
 
void epicsEventShow(epicsEventId id, unsigned int level);

The C routines shown above generally correspond to one of the C++ methods. The epicsEventSignal macro provides backwards compatibility. The routines epicsEventMustCreate, epicsEventMustTrigger and epicsEventMustWait do not return if they fail.

20.6 epicsFindSymbol

epicsFindSymbol.h contains the following definitions:

void  epicsFindSymbol(const char name); 
void  epicsLoadLibrary(const char name); 
const char epicsLoadError(void);

Function

Meaning



epicsFindSymbol

Return the address of the named variable

epicsLoadLibrary

Load named shared library

epicsLoadError

Returns an error string if a library load fails

The registry, described in another chapter, provides a way to find and return the address referred to by a registered symbol. Symbols that have not been explicitly registered may not be found. If the registry is asked for a name that has not been registered, it calls epicsFindSymbol. If epicsFindSymbol can locate the symbol, it returns the associated address, otherwise it returns null.

On vxWorks epicsFindSymbol calls symFindByName. On Linux, Darwin and Solaris it calls dlsym. The default version just returns null, i.e. it always fails.

The epicsLoadLibrary routine can be used to load a named library. Note that the library name may be different on different operating systems. This routine is implemented on vxWorks, Linux, Darwin, Windows and Solaris.

If epicsLoadLibrary fails, the routine epicsLoadError can be used to fetch a printable string that describes the reason for the failure. Note that this library loading API is not thread-safe and should not be used in circumstances where multiple threads might try to use it at the same time.

20.7 epicsGeneralTime

The generalTime framework provides a mechanism for several time providers to be present within the system. There are two types of provider, one type for the current time and one type for providing Time Event times. Each time provider has a priority, and installed providers are queried in priority order whenever a time is requested, until one returns successfully. Thus there is a fallback from higher priority providers (smaller value of priority) to lower priority providers (larger value of priority) if the higher priority ones fail. Each architecture has a “last resort” provider, installed at priority 999, usually based on the system clock, which is used in the absence of any other provider.

Targets running vxWorks and RTEMS have an NTP provider installed at priority 100.

Registered providers may also add an interrupt-safe routine to be called from the epicsTimeGetCurrentInt() or epicsTimeGetEventInt() API routines. These interfaces do not check the priority queue, and will only succeed if the last-used provider has registered a suitable routine.

There are two interfaces to this framework, epicsGeneralTime.h for consumers that wish to get a time and query the framework, and generalTimeSup.h for providers that supply timestamps.

20.7.1 Consumer interface

The epicsGeneralTime.h header contains the following:

void generalTime_Init(void); 
int installLastResortEventProvider(void); 
void generalTimeResetErrorCounts(void); 
int generalTimeGetErrorCounts(void); 
 
const char  generalTimeHighestCurrentName(void); 
const char  generalTimeCurrentProviderName(void); 
const char  generalTimeEventProviderName(void); 
 
/⋆ Original names, for compatibility ⋆/ 
#define generalTimeCurrentTpName generalTimeCurrentProviderName 
#define generalTimeEventTpName generalTimeEventProviderName 
 
long generalTimeReport(int interest);

Function

Meaning



generalTime_Init

Initialise the framework. This is called automatically by any function that requires the framework. It does not need to be called explicitly.

installLastResortEventProvider

Install a Time Event time provider that returns the current time for any Time Event number. This is optional as it is site policy whether the last resort for a Time Event time in the absence of any working provider should be a failure, or the current time.

generalTimeResetErrorCounts

Reset the internal counter of the number of times the time returned was earlier than when previously requested. Used by device support for bo record with DTYP = “General Time” and OUT = “@RSTERRCNT”

generalTimeGetErrorCounts

Return the internal counter of the number of times the time returned was earlier than when previously requested. Used by device support for longin record with DTYP = “General Time” and INP = “@GETERRCNT”

generalTimeCurrentProviderName

Return the name of the provider that last returned a valid current time, or NULL if none. Used by stringin device support with DTYP = “General Time” and INP = “@BESTTCP”

generalTimeEventProviderName

Return the name of the provider that last returned a valid Time Event time, or NULL if none. Used by stringin device support with DTYP = “General Time” and INP = “@BESTTEP”

generalTimeHighestCurrentName

Return the name of the registered current time provider that has the highest priority. Used by stringin device support with DTYP = “General Time” and INP = “@TOPTCP”

generalTimeReport

Provide information about the installed providers and their current best times.

20.7.2 Time Provider Interface

The generalTimeSup.h header for time providers contains the following:

typedef int (⋆TIMECURRENTFUN)(epicsTimeStamp pDest); 
typedef int (⋆TIMEEVENTFUN)(epicsTimeStamp pDest, int event); 
 
int generalTimeRegisterCurrentProvider(const char name, 
    int priority, TIMECURRENTFUN getTime); 
int generalTimeRegisterEventProvider(const char name, 
    int priority, TIMEEVENTFUN getEvent); 
 
/⋆ Original names, for compatibility ⋆/ 
#define generalTimeCurrentTpRegister generalTimeRegisterCurrentProvider 
#define generalTimeEventTpRegister generalTimeRegisterEventProvider 
 
int generalTimeAddIntCurrentProvider(const char name, 
    int priority, TIMECURRENTFUN getTime); 
int generalTimeAddIntEventProvider(const char name, 
    int priority, TIMEEVENTFUN getEvent); 
 
int generalTimeGetExceptPriority(epicsTimeStamp pDest, int pPrio, 
        int ignorePrio);

Function

Meaning



generalTimeRegisterCurrentProvider

Register a current time provider with the framework. The getTime routine must return epicsTimeOK if it provided a valid time, or epicsTimeERROR if it could not.

generalTimeRegisterEventProvider

Register a provider of Time Event times with the framework. The getEvent routine must return epicsTimeOK if it provided a valid time for the requested Time Event, or epicsTimeERROR if it could not. It is an implemetation decision by the provider whether a request for an Event that has never happened should return an error and/or a valid timestamp.

generalTimeAddIntCurrentProvider

Add or replace an interrupt-safe provider routine for an already-registered current time provider with the given name and priority.

generalTimeAddIntEventProvider

Add or replace an interrupt-safe provider routine for an already-registered event time provider with the given name and priority.

generalTimeGetExceptProirity

Request the current time from the framework, but exclude providers with priority ignorePrio. This allows a provider without an absolute time source to synchronise itself with other providers that do provide an absolute time. pPrio returns the priority of the provider that supplied the result, which may be higher or lower than ignorePrio.

If multiple providers are registered at the same priority, they will be queried in the order in which they were registered until one is able to provide the time when requested.

Some providers may start a task that periodically synchronizes themselves with a higher priority provider, using generalTimeGetExceptPriority() to ensure that they are themselves excluded from this time request.

Interrupt-safe providers are optional, but an IOC that needs to request the time from interrupt context must be using a current or event time source that supports the appropriate request because only the most recently successful provider will be used (the priority list cannot be traversed for requests made from interrupt context). The result returned by is not protected against backwards movement.

20.7.3 Internal Interface

The generalTime framework also now provides the implementations of the following routines that are declared in epicsTime.h:

int epicsTimeGetCurrent(epicsTimeStamp pDest); 
int epicsTimeGetEvent(epicsTimeStamp pDest, int eventNumber); 
int epicsTimeGetCurrentInt(epicsTimeStamp pDest); 
int epicsTimeGetEventInt(epicsTimeStamp pDest, int eventNumber);

If epicsTimeGetEvent() is called with an event number of 0 (epicsTimeEventCurrentTime) it will return the time from the best available current time provider. Thus providers do not need to provide event times if they do not implement an event system.

20.7.4 Example

Soft device support is provided for ai, bo, longin and stringin records. A typical example is:

  record(ai, "$(IOC):GTIM_CURTIME") {
    field(DESC, "Get Time")
    field(DTYP, "General Time")
    field(INP,  "@TIME")
  }
  
  record(bo, "$(IOC):GTIM_RSTERR") {
    field(DESC, "Reset ErrorCounts")
    field(DTYP, "General Time")
    field(OUT,  "@RSTERRCNT")
  }
  
  record(longin, "$(IOC):GTIM_ERRCNT") {
    field(DESC, "Get ErrorCounts")
    field(DTYP, "General Time")
    field(INP,  "@GETERRCNT")
  }
  
  record(stringin, "$(IOC):GTIM_BESTTCP") {
    field(DESC, "Best Time-Current-Provider")
    field(DTYP, "General Time")
    field(INP,  "@BESTTCP")
  }
  
  record(stringin, "$(IOC):GTIM_BESTTEP") {
    field(DESC, "Best Time-Event-Provider")
    field(DTYP, "General Time")
    field(INP,  "@BESTTEP")
  }

20.8 epicsInterrupt

epicsInterrupt.h contains the following:

20.8.1 C Interface

int epicsInterruptLock(); 
 
void epicsInterruptUnlock(int key); 
 
int epicsInterruptIsInterruptContext(); 
void epicsInterruptContextMessage(const char message);

Method

Meaning



epicsInterruptLock

Lock interrupts and return a key to be passed to epicsInterruptUnlock To lock the following is done. int key; ... key = epicsInterruptLock(); ... epicsInterruptUnlock(key);

epicsInterruptUnlock

Unlock interrupts.

epicsInterruptIsInterruptContext

Return (true, false) if current context is interrupt context.

epicsInterruptContextMessage

Generate a message while interrupt context is true.

20.8.2 Implementation notes

A vxWorks specific version is provided. It maps directly to intLib calls.

An RTEMS version is provided that maps to rtems_ calls.

A default version is provided that uses a global semaphore to lock. This version is intended for operating systems in which iocCore will run as a multi threaded process. The global semaphore is thus only global within the process. This version is intended for use on all except real time operating systems.

The vxWorks implementation will most likely not work on symmetric multiprocessing systems.

The reason epicsInterrupt is needed is:

20.9 epicsMath

epicsMath.h includes math.h and also ensures that isnan and isinf are defined.

20.10 epicsMessageQueue

epicsMessageQueue.h describes a C++ and a C facility for interlocked communication between threads.

20.10.1 C++ Interface

EpicsMessageQueue provides methods for sending messages between threads on a first in, first out basis. It is designed so that a single message queue can be used with multiple writer and reader threads.

class epicsMessageQueue { 
public: 
    epicsMessageQueue(unsigned int capacity, unsigned int maximumMessageSize); 
    ~epicsMessageQueue(); 
    int trySend(void message, unsigned int messageSize); 
    int send(void message, unsigned int messageSize); 
    int send(void message, unsigned int messageSize, double timeout); 
    int tryReceive(void message, unsigned int messageBufferSize); 
    int receive(void message, unsigned int messageBufferSize); 
    int receive(void message, unsigned int messageBufferSize, double timeout); 
    void show(int level) const; 
    int pending() const; 
 
private: // Prevent compiler-generated member functions 
    // default constructor, copy constructor, assignment operator 
    epicsMessageQueue(); 
    epicsMessageQueue(const epicsMessageQueue &); 
    epicsMessageQueue& operator=(const epicsMessageQueue &); 
 
private: // Data 
    ... 
};

An epicsMessageQueue cannot be assigned to, copy-constructed, or constructed without giving the capacity and maximumMessageSize arguments. The C++ compiler will object to some of the statements below:

epicsMessageQueue mq0();   // Error: default constructor is private 
epicsMessageQueue mq1(10, 20); // OK 
epicsMessageQueue mq2(t1); // Error: copy constructor is private 
epicsMessageQueue pmq;    // OK, pointer 
pmq = mq1;               // Error: assignment operator is private 
pmq = &mq1;               // OK, pointer assignment and address-of

Method

Meaning



epicsMessageQueue()

Constructor. The capacity is the maximum number of messages, each containing 0 to maximumMessageSize bytes, that can be stored in the message queue.

~epicsMessageQueue()

Destructor.

trySend()

Try to send a message. Return 0 if the message was sent to a receiver or queued for future delivery. Return -1 if no more messages can be queued or if the message is larger than the queue’s maximum message size. This method may be called from a vxWorks or RTEMS interrupt handler.

send()

Send a message. Return 0 if the message was sent to a receiver or queued for future delivery. Return -1 if the timeout, if any, was reached before the message could be sent or queued, or if the message is larger than the queue’s maximum message size.

tryReceive()

Try to receive a message. If the message queue is non-empty, the first message on the queue is copied to the specified location and the length of the message is returned. Returns -1 if the message queue is empty. If the pending message is larger than the specified messageBufferSize it may either return -1, or truncate the message. It is most efficient if the messageBufferSize is equal to the maximumMessageSize with which the message queue was created.

receive()

Wait until a message is sent and store it in the specified location. The number of bytes in the message is returned. Returns -1 if a message is not received within the timeout interval. If the received message is larger than the specified messageBufferSize it may either return -1, or truncate the message. It is most efficient if the messageBufferSize is equal to the maximumMessageSize with which the message queue was created.

show()

Displays some information about the message queue. The level argument controls the amount of information dispalyed.

pending()

Returns the number of messages presently in the queue.

20.10.2 C interface

typedef struct epicsMessageQueueOSD epicsMessageQueueId; 
 
epicsMessageQueueId epicsMessageQueueCreate(unsigned int capacity, 
    unsigned int maximumMessageSize); 
void epicsMessageQueueDestroy(epicsMessageQueueId id); 
int epicsMessageQueueTrySend(epicsMessageQueueId id, 
    void message, unsigned int size); 
int epicsMessageQueueSend(epicsMessageQueueId id, 
    void message, unsigned int size); 
int epicsMessageQueueSendWithTimeout(epicsMessageQueueId id, 
    void message, unsigned int size, double timeout); 
int epicsMessageQueueTryReceive(epicsMessageQueueId id, 
    void message, unsigned int size); 
int epicsMessageQueueReceive(epicsMessageQueueId id, 
    void message, unsigned int size); 
int epicsMessageQueueReceiveWithTimeout(epicsMessageQueueId id, 
    void message, unsigned int size, double timeout); 
void epicsMessageQueueShow(epicsMessageQueueId id); 
int epicsMessageQueuePending(epicsMessageQueueId id);

Each C function corresponds to one of the C++ methods.

20.11 epicsMutex

epicsMutex.h contains both C++ and C descriptions for a mutual exclusion semaphore.

20.11.1 C++ Interface

typedef enum { 
    epicsMutexLockOK, epicsMutexLockTimeout, epicsMutexLockError 
} epicsMutexLockStatus; 
 
#define newEpicsMutex new epicsMutex(__FILE__,__LINE__) 
 
class epicsMutex { 
public: 
    epicsMutex (); 
    epicsMutex ( const char pFileName, int lineno ); 
    ~epicsMutex (); 
    void lock (); /⋆ blocks until success ⋆/ 
    bool tryLock (); /⋆ true if successful ⋆/ 
    void unlock (); 
    void show ( unsigned level ) const; 
 
    class invalidSemaphore {}; /⋆ exception ⋆/ 
private: 
};

Method

Meaning



epicsMutex

Create a mutual exclusion semaphore.

~epicsMutex

Remove the semaphore and any resources it uses. Any further use of the semaphore result in unknown (most certainly bad) results.

lock()

Wait until the resource is free. After a successful lock additional, i.e. recursive, locks of any type can be issued but each must have an associated unlock.

tryLock()

Similar to lock except that, if the resource is owned by another thread, the call completes immediately. The return value is (false,true) if the resource (is not, is) owned by the caller.

unlock

Release the resource. If a thread issues recursive locks, there must be an unlock for each lock

show

Display information about the semaphore. The results are architecture dependent.

Mutual exclusion semaphores are for situations requiring mutually exclusive access to resources. A mutual exclusion semaphore may be taken recursively, i.e. can be taken more than once by the owner thread before releasing it. Recursive takes are useful for a set of routines that call each other while working on a mutually exclusive resource.

The newEpicsMutex macro simplifies debugging by letting the mutex store the source filename and line-number where it was created, using the second form of the constructor. The C interface also stores this information. The epicsMutex::show() routine can display that source location.

The typical use of a mutual exclusion semaphore is:

    epicsMutex plock = newEpicsMutex; 
    ... 
    ... 
    plock->lock(); 
    /⋆ process resource ⋆/ 
    plock->unlock();

20.11.2 C Interface

typedef struct epicsMutexOSD epicsMutexId; 
 
epicsMutexId epicsMutexCreate(void); 
epicsMutexId epicsMutexMustCreate (void); 
void epicsMutexDestroy(epicsMutexId id); 
void epicsMutexUnlock(epicsMutexId id); 
epicsMutexLockStatus epicsMutexLock(epicsMutexId id); 
 
void epicsMutexMustLock(epicsMutexId id); 
epicsMutexLockStatus epicsMutexTryLock(epicsMutexId id); 
void epicsMutexShow(epicsMutexId id,unsigned  int level); 
void epicsMutexShowAll(int onlyLocked,unsigned  int level);

Each C routine corresponds to one of the C++ methods. epicsMutexMustCreate and epicsMutexMustLock do not return if they fail.

20.11.3 Implementation Notes

The implementation:

A posix version is implemented via pthreads.

20.12 epicsSpin

epicsSpin.h contains definitions for a spin lock semaphore.

20.12.1 C Interface

typedef struct epicsSpin epicsSpinId; 
 
epicsSpinId epicsSpinCreate(); 
void epicsSpinDestroy(epicsSpinId); 
 
void epicsSpinLock(epicsSpinId); 
int epicsSpinTryLock(epicsSpinId); 
void epicsSpinUnlock(epicsSpinId);

Method

Meaning



epicsSpinCreate

Create a spin lock, allocate required resources, and initialize it to an unlocked state.

epicsSpinDestroy()

Remove the spin lock and any resources it uses. Any further use of the spin lock may result in unknown (most certainly bad) behavior. The results are also undefined if epicsSpinDestroy is used when a thread holds the lock.

epicsSpinLock()

Wait (by spinning, i.e. busy waiting) until the resource is free. After a successful lock, no additional, i.e. recursive, locking attempts may be issued.

epicsSpinTryLock()

Similar to lock except that, if the resource is owned by another thread, the call completes immediately. The return value is 0 if the resource is owned by the caller.

epicsSpinUnlock()

Release the spin lock resource which was locked by epicsSpinLock or epicsSpinTryLock. The results are undefined if the lock is not held by the calling thread, or if epicsSpinUnlock is used on an uninitialized spin lock.

20.12.2 Implementation Notes

The default implementation uses POSIX spin locks on POSIX compliant systems, and epicsMutex for non-POSIX environments.

20.13 epicsStdlib

epicsStdlib.h includes stdlib.h and epicsTypes.h and provides declarations for a series of string to number conversion functions and macros.

20.13.1 Integer Parsing

These routines convert a string into an integer of the indicated type and number base. The units pointer argument may be NULL, but if not it will be left pointing to the first non-whitespace character following the numeric string, or to the terminating zero byte.

int epicsParseLong(const char str, long to, int base, char ⋆⋆units); 
int epicsParseULong(const char str, unsigned long to, int base, 
    char ⋆⋆units); 
int epicsParseLLong(const char str, long long to, int base, char ⋆⋆units); 
int epicsParseULLong(const char str, unsigned long long to, int base, 
    char ⋆⋆units); 
 
int epicsParseInt8(const char str, epicsInt8 to, int base, char ⋆⋆units); 
int epicsParseUInt8(const char str, epicsUInt8 to, int base, char ⋆⋆units); 
 
int epicsParseInt16(const char str, epicsInt16 to, int base, char ⋆⋆units); 
int epicsParseUInt16(const char str, epicsUInt16 to, int base, char ⋆⋆units); 
 
int epicsParseInt32(const char str, epicsInt32 to, int base, char ⋆⋆units); 
int epicsParseUInt32(const char str, epicsUInt32 to, int base, char ⋆⋆units); 
 
int epicsParseInt64(const char str, epicsInt64 to, int base, char ⋆⋆units); 
int epicsParseUInt64(const char str, epicsUInt64 to, int base, char ⋆⋆units);

The return value from these routines is a status code, zero meaning OK.

20.13.2 Floating-point Parsing

These routines convert a string into a floating-point type.

double epicsStrtod(const char str, char ⋆⋆endp); 
 
int epicsParseDouble(const char str, double to, char ⋆⋆units); 
int epicsParseFloat(const char str, float to, char ⋆⋆units); 
 
#define epicsParseFloat32(str, to, units) epicsParseFloat(str, to, units) 
#define epicsParseFloat64(str, to, units) epicsParseDouble(str, to, units)

epicsStrtod() has the same semantics as the C99 function strtod() and is provided because some architectures do not fully conform to the standard. It is implemented as a simple macro on those architectures that do conform.

epicsParseDouble and epicsParseFloat convert a string into a variable of the indicated type. The units pointer argument may be NULL, but if not it will be left pointing to the first non-whitespace character following the numeric string, or to the terminating zero byte.

The return value from these routines is a status code, zero meaning OK.

20.13.3 Replacements for scanf()

The following routines are implemented as macros that call routines described above. They return 1 for a successful conversion, 0 on failure, and can be used to replace equivalent calls to sscanf().

#define epicsScanLong(str, to, base) !epicsParseLong(str, to, base, NULL) 
#define epicsScanULong(str, to, base) !epicsParseULong(str, to, base, NULL) 
#define epicsScanLLong(str, to, base) !epicsParseLLong(str, to, base, NULL) 
#define epicsScanULLong(str, to, base) !epicsParseULLong(str, to, base, NULL) 
#define epicsScanFloat(str, to) !epicsParseFloat(str, to, NULL) 
#define epicsScanDouble(str, to) !epicsParseDouble(str, to, NULL)

epicsScanFloat and epicsScanDouble behave like sscanf with a "%f" and "%lf" format string, respectively. They are provided because some architectures have implementations of scanf which do not accept NAN or INFINITY.

20.14 epicsStdio

The epicsStdio.h first includes the operating systems’s stdio.h header, then provides definitions for the following functions:

int epicsSnprintf(char str, size_t size, 
    const char format, ...); 
int epicsVsnprintf(char str, size_t size, 
    const char format, va_list ap); 
 
enum TF_RETURN {TF_OK = 0, TF_ERROR = 1}; 
enum TF_RETURN truncateFile(const char pFileName, unsigned size ); 
 
/⋆ Stream redirection of standard streams ⋆/ 
#define stdin epicsGetStdin() 
#define stdout epicsGetStdout() 
#define stderr epicsGetStderr() 
 
#define printf epicsStdoutPrintf 
#define puts epicsStdoutPuts 
#define putchar epicsStdoutPutchar 
 
FILE  epicsGetStdin(void); 
FILE  epicsGetStdout(void); 
FILE  epicsGetStderr(void); 
FILE  epicsGetThreadStdin(void); 
FILE  epicsGetThreadStdout(void); 
FILE  epicsGetThreadStderr(void); 
void epicsSetThreadStdin(FILE ⋆); 
void epicsSetThreadStdout(FILE ⋆); 
void epicsSetThreadStderr(FILE ⋆); 
 
int epicsStdoutPrintf(const char pformat, ...); 
int epicsStdoutPuts(const char str); 
int epicsStdoutPutchar(int c);

epicsSnprintf and epicsVsnprintf are meant to have the same semantics as the C99 functions snprintf and vsnprintf. They are provided because some architectures do not implement these functions, while others implement them incorrectly. Standardized as a C99 function, snprintf acts like sprintf except that the size argument gives the maximum number of characters (including the trailing zero byte) that may be placed in str. Similarly vsnprintf is a size-limited version of vsprintf. In both cases the return values are supposed to be the number characters (not counting the terminating zero byte) that would be written to str if it was large enough to hold them all; the output has been truncated if the return value is size or more.

On some operating systems though the implementations of these functions do not always return the correct value. If the OS implementation does not correctly return the number of characters that would have been written when the output gets truncated, it is not worth trying to fix this as long as they return size-1 instead; the resulting string must always be correctly terminated with a zero byte.

On operating systems such as Solaris which follow the Single Unix Specification V2, the epicsSnprintf and epicsVsnprintf implementations may not provide correct C99 semantics for the return value when size is given as zero. On these systems epicsSnprintf and epicsVsnprintf can return an error (a value less than zero) when a buffer length of zero is passed in, so callers should not use that technique to calculate the length of the buffer required.

truncateFile returns TF_OK if the file is less than size bytes or if it was successfully truncated. Returns TF_ERROR if the file could not be truncated.

The epicsSetThreadStdin/Stdout/Stderr routines allow the standard file steams to be redirected on a per thread basis, e.g. calling epicsSetThreadStdout will affect only the thread which calls it. To cancel a stream redirection, pass a NULL argument in another call to the same redirection routine that was used to set it.

The routines epicsGetStdin/Stdout/Stderr and epicsStdoutPrintf/Puts/Putchar are not normally named directly in user code. They are provided for the following macros that redefine the well-known C identifiers:

This is done so that any I/O through these standard streams can be redirected, usually to or from a file. The primary use of this facility is iocsh, which allows redirection of the input and/or output streams when running commands. In order for the redirection to work, all modules involved in I/O must include epicsStdio.h instead of the system header stdio.h.

20.15 epicsTempFile

epicsTempFile.h provides definitions for the following functions:

void epicsTempName(char pbuf, size_t buflen); 
FILE  epicsTempFile(void);

epicsTempName and epicsTempFile can be called to get unique filenames and open FILE ⋆ pointers. Note that epicsTempName cannot guarantee that the filenames it returns will not be created by some other thread or process after it has returned, although it does check that the filename it generates does not already exist. This security hole is why POSIX.1-2008 marked tempnam() as obsolete. The epicsTempName function will probably be deprecated in a future release of Base.

20.16 epicsThread

epicsThread.h contains C++ and C descriptions for a thread.

20.16.1 C Interface

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; 
 
unsigned int epicsThreadGetStackSize(epicsThreadStackSizeClass size); 
 
/⋆ (epicsThreadId)0 is guaranteed to be an invalid thread id ⋆/ 
typedef struct epicsThreadOSD epicsThreadId; 
 
typedef int epicsThreadOnceId; 
#define EPICS_THREAD_ONCE_INIT 0 
 
void epicsThreadOnce(epicsThreadOnceId id, EPICSTHREADFUNC, void arg); 
 
void epicsThreadExitMain(void); 
 
epicsThreadId epicsThreadCreate(const char name, 
    unsigned int priority, unsigned int stackSize, 
    EPICSTHREADFUNC funptr, void parm); 
void epicsThreadSuspendSelf(void); 
void epicsThreadResume(epicsThreadId id); 
unsigned int epicsThreadGetPriority(epicsThreadId id); 
unsigned int epicsThreadGetPrioritySelf(void); 
void epicsThreadSetPriority(epicsThreadId id, unsigned int priority); 
epicsThreadBooleanStatus epicsThreadHighestPriorityLevelBelow ( 
        unsigned int priority, unsigned pPriorityJustBelow); 
epicsThreadBooleanStatus epicsThreadLowestPriorityLevelAbove ( 
        unsigned int priority, unsigned pPriorityJustAbove); 
int epicsThreadIsEqual(epicsThreadId id1, epicsThreadId id2); 
int epicsThreadIsSuspended(epicsThreadId id); 
void epicsThreadSleep(double seconds); 
double epicsThreadSleepQuantum(void); 
epicsThreadId epicsThreadGetIdSelf(void); 
epicsThreadId epicsThreadGetId(const char name); 
int epicsThreadGetCPUs(void); 
 
const char  epicsThreadGetNameSelf(void); 
void epicsThreadGetName(epicsThreadId id, char name, size_t size); 
int epicsThreadIsOkToBlock(void); 
void epicsThreadSetOkToBlock(int isOkToBlock); 
 
void epicsThreadShowAll(unsigned int level); 
void epicsThreadShow(epicsThreadId id, unsigned int level); 
 
typedef void (⋆EPICS_THREAD_HOOK_ROUTINE)(epicsThreadId id); 
int epicsThreadHookAdd(EPICS_THREAD_HOOK_ROUTINE hook); 
int epicsThreadHookDelete(EPICS_THREAD_HOOK_ROUTINE hook); 
void epicsThreadHooksShow(void); 
void epicsThreadMap(EPICS_THREAD_HOOK_ROUTINE func); 
 
typedef void  epicsThreadPrivateId; 
epicsThreadPrivateId epicsThreadPrivateCreate(void); 
void epicsThreadPrivateDelete(epicsThreadPrivateId id); 
void epicsThreadPrivateSet(epicsThreadPrivateId,void ⋆); 
void  epicsThreadPrivateGet(epicsThreadPrivateId);

Routine

Meaning



epicsThreadGetStackSize

Get a stack size value that can be given to epicsThreadCreate. The size argument should be one of the values epicsThreadStackSmall, epicsThreadStackMedium or epicsThreadStackBig.

epicsThreadOnce

This is used as follows:

void myInitFunc(void  arg) { 
    ... 
} 
epicsThreadOnceId onceFlag = 
    EPICS_THREAD_ONCE_INIT; 
... 
epicsThreadOnce(&onceFlag, myInitFunc, 
    (void ⋆)myParm);

For each unique epicsThreadOnceId, epicsThreadOnce guarantees that 1) myInitFunc will only be called only once. 2) myInitFunc will have returned before any other epicsThreadOnce call returns. Note that myInitFunc must not call epicsThreadOnce with the same onceId.

epicsThreadExitMain

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.

epicsThreadCreate

Create a new thread. The use made of the priority, and stackSize arguments is implementation dependent. Some implementations may ignore one or other of these, but for portability appropriate values should be given for both. The value passed as the stackSize parameter should be obtained by calling epicsThreadGetStackSize. The funptr argument specifies a function that implements the thread, and parm is the single argument passed to funptr. A thread terminates when funptr returns.

epicsThreadSuspendSelf

This causes the calling thread to suspend. The only way it can resume is for another thread to call epicsThreadResume.

epicsThreadResume

Resume a suspended thread. Only do this if you know that it is safe to resume a suspended thread.

epicsThreadGetPriority

Get the priority of the specified thread.

epicsThreadGetPrioritySelf

Get the priority of this thread.

epicsThreadSetPriority

Set a new priority for the specified thread. The result is implementation dependent.

epicsThreadHighestPriorityLevelBelow

Get a priority that is just lower than the specified priority.

epicsThreadLowestPriorityLevelAbove

Get a priority that is just above the specified priority.

epicsThreadIsEqual

Compares two threadIds and returns (0,1) if they (are not, are) the same.

epicsThreadIsSuspended

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.

epicsThreadSleep

Sleep for the specified period of time, i.e. sleep without using the cpu. If delay is >0 then the thread will sleep at least until the next clock tick. The exact time is determined by the underlying architecture. If delay is <= 0 then a delay of 0 is requested of the underlying architecture. What happens is architecture dependent but often it allows other threads of the same priority to run.

epicsThreadSleepQuantum

This function returns the minimum slumber interval obtainable with epicsThreadSleep() in seconds. On most OS there is a system scheduler interrupt interval which determines the value of this parameter. Knowledge of this parameter is used by the various components of EPICS to improve scheduling of software tasks intime when the reduction of average time scheduling errors is important. If this parameter is unknown or is unpredictable for a particular OS then it is safe to return zero.

epicsThreadGetIdSelf

Get the threadId of the calling thread.

epicsThreadGetId

Get the threadId of the specified thread. A return value of 0 means that no thread was found with the specified name.

epicsThreadGetCPUs

Get the number of CPUs (logical cores) available to the IOC. On systems that provide Hyper-Threading, this may be more the number of physical CPU cores.

epicsThreadGetNameSelf

Get the name of the calling thread.

epicsThreadGetName

Get the name of the specified thread. The value is copied to a caller specified buffer so that if the thread terminates the caller is not left with a pointer to something that may no longer exist.

epicsThreadIsOkToBlock

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.

epicsThreadSetOkToBlock

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.

epicsThreadShowAll

Display info about all threads.

epicsThreadShow

Display info about the specified thread.

epicsThreadHookAdd

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.

epicsThreadHookDelete

Remove routine from the list of hooks run at thread creation time.

epicsThreadHooksShow

Print the current list of hook function pointers.

epicsThreadMap

Call func once for every known thread.

epicsThreadPrivateCreate

Thread private variables are intended for use by legacy libraries written for a single threaded environment and which used a global variable to store private data. The only code in base that currently needs this facility is channel access. A library that needs a private variable should make exactly one call to epicsThreadPrivateCreate and store the index returned. Each thread can later call epicsThreadPrivateGet and epicsThreadPrivateSet with that index to access a thread-specific pointer store.

epicsThreadPrivateDelete

Delete a thread private variable.

epicsThreadPrivateSet

Set the value for a thread private pointer.

epicsThreadPrivateGet

Get the value of a thread private pointer. The value returned is the last value given to epicsThreadPrivateSet by the same thread. If called before epicsThreadPrivateSet the pointer’s value is NULL.

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:

20.16.2 C++ Interface

class epicsThreadRunable { 
public: 
    virtual void run() = 0; 
    virtual void stop(); 
    virtual void show(unsigned int level) const; 
}; 
 
class epicsShareClass epicsThread { 
public: 
    epicsThread (epicsThreadRunable &,const char name, unsigned int stackSize, 
        unsigned int priority=epicsThreadPriorityLow); 
    virtual ~epicsThread (); 
    void start(); 
    void exitWait (); 
    bool exitWait (const double delay ); 
    void exitWaitRelease (); // noop if not called by managed thread 
    static void exit (); 
    void resume (); 
    void getName (char name, size_t size) const; 
    epicsThreadId getId () const; 
    unsigned int getPriority () const; 
    void setPriority (unsigned int); 
    bool priorityIsEqual (const epicsThread &otherThread) const; 
    bool isSuspended () const; 
    bool isCurrentThread () const; 
    bool operator == (const epicsThread &rhs) const; 
    /⋆ these operate on the current thread ⋆/ 
    static void suspendSelf (); 
    static void sleep (double seconds); 
    static epicsThread & getSelf (); 
    static const char  getNameSelf (); 
    static bool isOkToBlock (); 
    static void setOkToBlock(bool isOkToBlock) ; 
private: 
    ... 
}; 
template <class T> 
class epicsThreadPrivate { 
public: 
    epicsThreadPrivate (); 
    ~epicsThreadPrivate (); 
    T get () const; 
    void set (T ⋆); 
    class unableToCreateThreadPrivate {}; // exception 
private: 
    ... 
};

The C++ interface is a wrapper around the C interface. Two differences are the method start and the class epicsThreadRunable.

The start method must not be called until after the epicsThread constructor has returned. Calling the start method allows the run method of the epicsThreadRunable object to be executed in the context of the new thread.

Code using the C++ API must provide a class that derives from epicsThreadRunable. For example:

class myThread: public epicsThreadRunable { 
public: 
    myThread(int arg,const char name); 
    virtual ~myThread(); 
    virtual void run(); 
    epicsThread thread; 
} 
 
myThread::myThread(int arg,const char name) : 
    thread(⋆this,name,epicsThreadGetStackSize(epicsThreadStackSmall),50) 
{ 
    thread.start(); 
} 
 
myThread::~myThread() {} 
 
void myThread::run() 
{ 
    // ... 
}

20.17 epicsTime

epicsTime.h contains C++ and C descriptions for time.

20.17.1 Time Related Structures

/⋆ epics time stamp for C interface⋆/ 
typedef struct epicsTimeStamp { 
    epicsUInt32    secPastEpoch;   /⋆ seconds since 0000 Jan 1, 1990 ⋆/ 
    epicsUInt32    nsec;           /⋆ nanoseconds within second ⋆/ 
} epicsTimeStamp; 
 
/⋆TS_STAMP is deprecated ⋆/ 
#define TS_STAMP epicsTimeStamp 
 
struct timespec; /⋆ POSIX real time ⋆/ 
struct timeval; /⋆ BSD ⋆/ 
struct l_fp; /⋆ NTP timestamp ⋆/ 
 
// extend ANSI C RTL "struct tm" to include nano seconds within a second 
// and a struct tm that is adjusted for the local timezone 
struct local_tm_nano_sec { 
    struct tm ansi_tm; /⋆ ANSI C time details ⋆/ 
    unsigned long nSec; /⋆ nano seconds extension ⋆/ 
}; 
 
// extend ANSI C RTL "struct tm" to includes nano seconds within a second 
// and a struct tm that is adjusted for GMT (UTC) 
struct gm_tm_nano_sec { 
    struct tm ansi_tm; /⋆ ANSI C time details ⋆/ 
    unsigned long nSec; /⋆ nano seconds extension ⋆/ 
}; 
 
// wrapping this in a struct allows conversion to and 
// from ANSI time_t but does not allow unexpected 
// conversions to occur 
struct time_t_wrapper { 
    time_t ts; 
};

The above structures are for the various time formats.

NOTE on conversion. The epics implementation will properly convert between the various formats from the beginning of the EPICS epoch until at least 2038. Unless the underlying architecture support has defective POSIX, BSD/SRV5, or standard C time support the epics implementation should be valid until 2106.

20.17.2 C++ Interface

class epicsTime; 
 
class epicsTimeEvent { 
public: 
    epicsTimeEvent (const int &number); 
    operator int () const; 
private: 
    int eventNumber; 
}; 
 
class epicsTime { 
public: 
    // exceptions 
    class unableToFetchCurrentTime {}; 
    class formatProblemWithStructTM {}; 
 
    epicsTime (); 
    epicsTime (const epicsTime &t); 
 
    static epicsTime getEvent (const epicsTimeEvent &event); 
    static epicsTime getCurrent (); 
 
    // convert to and from EPICS epicsTimeStamp format 
    operator epicsTimeStamp () const; 
    epicsTime (const epicsTimeStamp &ts); 
    epicsTime & operator = (const epicsTimeStamp &rhs); 
 
    // convert to and from ANSI time_t 
    operator time_t_wrapper () const; 
    epicsTime (const time_t_wrapper &tv); 
    epicsTime & operator = (const time_t_wrapper &rhs); 
 
    // convert to and from ANSI Cs "struct tm" (with nano seconds) 
    // adjusted for the local time zone 
    operator local_tm_nano_sec () const; 
    epicsTime (const local_tm_nano_sec &ts); 
    epicsTime & operator = (const local_tm_nano_sec &rhs); 
 
    // convert to and from ANSI Cs "struct tm" (with nano seconds) 
    // adjusted for GM time (UTC) 
    operator gm_tm_nano_sec () const; 
    epicsTime ( const gm_tm_nano_sec & ); 
    epicsTime & operator = ( const gm_tm_nano_sec & ); 
 
    // convert to and from POSIX RT's "struct timespec" 
    operator struct timespec () const; 
    epicsTime (const struct timespec &ts); 
    epicsTime & operator = (const struct timespec &rhs); 
 
    // convert to and from BSD's "struct timeval" 
    operator struct timeval () const; 
    epicsTime (const struct timeval &ts); 
    epicsTime & operator = (const struct timeval &rhs); 
 
    // convert to and from NTP timestamp format 
    operator l_fp () const; 
    epicsTime (const l_fp &); 
    epicsTime & operator = (const l_fp &rhs); 
 
    // convert to and from WIN32s FILETIME (implemented only on WIN32) 
    operator struct _FILETIME () const; 
    epicsTime ( const struct _FILETIME & ); 
    epicsTime & operator = ( const struct _FILETIME & ); 
 
    // arithmetic operators 
    double operator- (const epicsTime &rhs) const; // returns seconds 
    epicsTime operator+ (const double &rhs) const; // add rhs seconds 
    epicsTime operator- (const double &rhs) const; // subtract rhs seconds 
    epicsTime operator+= (const double &rhs); // add rhs seconds 
    epicsTime operator-= (const double &rhs); // subtract rhs seconds 
 
    // comparison operators 
    bool operator == (const epicsTime &rhs) const; 
    bool operator != (const epicsTime &rhs) const; 
    bool operator <= (const epicsTime &rhs) const; 
    bool operator < (const epicsTime &rhs) const; 
    bool operator >= (const epicsTime &rhs) const; 
    bool operator > (const epicsTime &rhs) const; 
 
    // convert current state to user-specified string 
    size_t strftime (char pBuff, size_t bufLength, const char pFormat) const; 
 
    // dump current state to standard out 
    void show (unsigned interestLevel) const; 
 
private: 
    ... 
};

20.17.3 class epicsTimeEvent

class epicsShareClass epicsTimeEvent 
{ 
public: 
    epicsTimeEvent (const int &number); 
    operator int () const; 
private: 
    int eventNumber; 
};

Method

Meaning



Convert to/from integer

Does not currently check that the range of the integer is valid, although it might one day.

20.17.4 class epicsTime

epicsTime Method

Meaning



epicsTime()

The default constructor sets the time to the beginning of the epics epoch.

epicsTime(const epicsTime &t)

Copy constructor, copies the time from its argument.

static getEvent

Returns an epicsTime indicating when the associated event last occurred. See the description of the C routine epicsTimeGetEvent below for details.

static getCurrent

Returns an epicsTime containing the current time. For example:
    epicsTime now = epicsTime::getCurrent();

convert to/from epicsTimeStamp

Three epicsTime methods interface with epicsTimeStamp values: A constructor, an assignment operator, and a conversion operator. For example:
    epicsTimeStamp ts1 = {12345, 67890}, ts2;
    epicsTime t1(ts1), t2; // constructor
    t2 = ts1;              // assignment
    ts2 = t1;              // conversion operator

convert to/from time_t

The structure time_t_wrapper is used instead of time_t directly to avoid undesired conversions to integer types. Three methods are provided for ANSI time_t: A constructor, an assignment operator, and a conversion operator. Assume the following definitions:
    time_t tt;
    time_t_wrapper ttw;
    epicsTime time;
An example of the copy constructor is:
    ttw.ts = tt;
    epicsTime time1(ttw);
An example of the assignment operator is:
    time = ttw;
An example of the time_t_wrapper operator is:
    ttw = time;
    tt = ttw.ts;

convert to/from struct tm in local timezone

The structure local_tm_nano_sec is used instead of struct tm directly to add a nanoseconds field and indicate the time is expressed in the local timezone. Three methods are provided for local_tm_nano_sec: A constructor, an assignment operator, and a conversion operator. Assume the following definitions:
    local_tm_nano_sec ltn;
    epicsTime time;
An example of the copy constructor is:
    epicsTime time1(ltn);
An example of the assignment operator is:
    time = ltn;
An example of the local_tm_nano_sec operator is:
    ltn = time;

convert to/from struct tm in UTC

The structure local_tm_nano_sec is used instead of struct tm directly to add a nanoseconds field and indicate the time is expressed in UTC. Three methods are provided for gm_tm_nano_sec: A constructor, an assignment operator, and a conversion operator. Assume the following definitions:
    gm_tm_nano_sec gtn;
    epicsTime time;
An example of the copy constructor is:
    epicsTime time1(gtn);
An example of the assignment operator is:
    time = gtn;
An example of the gm_tm_nano_sec operator is:
    gtn = time;

convert to/from struct timespec

Three methods are provided for the POSIX struct timespec: A constructor, an assignment operator, and a conversion operator. Assume the following definitions:
    struct timespec tts;
    epicsTime time;
An example of the copy constructor is:
    epicsTime time1(tts);
An example of the assignment operator is:
    time = tts;
An example of the conversion operator is:
    tts = time;

convert to/from struct timeval

Three methods are provided for BSD’s struct timeval: A constructor, an assignment operator, and a conversion operator. Assume the following definitions:
    struct timeval ttv;
    epicsTime time;
An example of the copy constructor is:
    epicsTime time1(ttv);
An example of the assignment operator is:
    time = ttv;
An example of the conversion operator is:
    ttv = time;

convert to/from NTP timestamps

Three methods are provided for the NTP timestamp structure: A constructor, an assignment operator, and a conversion operator. Assume the following definitions:
    l_fp ntp;
    epicsTime time;
An example of the copy constructor is:
    epicsTime time1(ntp);
An example of the assignment operator is:
    time = ntp;
An example of the conversion operator is:
    ntp = time;

arithmetic operators -, +, +=, -=

The arithmetic operators allow the difference of two epicsTimes, with the result in seconds. It also allows -, +, +=, and -= where the left hand argument is an epicsTime and the right hand argument is a double. Examples are:
    epicsTime time, time1, time2;
    double t1,t2,t3;
    ...
    t1 = time2 - time1;
    time = time1 + 4.5;
    time = time2 - t3;
    time2 += 6.0;

Comparison operators ==, |=, <=, <, >=, >

Two epics times can be compared:
    epicsTime time1, time2;
    ...
    if (time1 <= time2)
        ...

strftime

This method is an extension of the standard C library routine strftime. See your OS documentation for details about the standard routine. The epicsTime method adds support for the printing the fractional portion of the time. It searches the format string for the sequence %0nf where n is the desired precision, and uses this format to convert the fractional seconds to the requested precision. For example:
    epicsTime time = epicsTime::getCurrent();
    char buf[30];
    time.strftime(buf, 30, "%Y-%m-%d %H:%M:%S.%06f");
    printf("%s\n", buf);
This will print the current time in the format:
    2001-01-26 20:50:29.813505

show

Shows the date/time.

20.17.5 C Interface

/⋆ All epicsTime routines return (-1,0) for (failure,success) ⋆/ 
#define epicsTimeOK 0 
#define epicsTimeERROR (-1) 
/⋆Some special values for eventNumber⋆/ 
#define epicsTimeEventCurrentTime 0 
#define epicsTimeEventBestTime -1 
#define epicsTimeEventDeviceTime -2 
 
/⋆ These are implemented in the "generalTime" framework ⋆/ 
int epicsTimeGetCurrent (epicsTimeStamp pDest); 
int epicsTimeGetEvent (epicsTimeStamp pDest, int eventNumber); 
 
/⋆ These are callable from an Interrupt Service Routine ⋆/ 
int epicsTimeGetCurrentInt(epicsTimeStamp pDest); 
int epicsTimeGetEventInt(epicsTimeStamp pDest, int eventNumber); 
 
/⋆ convert to and from ANSI C's "time_t" ⋆/ 
int epicsTimeToTime_t (time_t pDest, const epicsTimeStamp pSrc); 
int epicsTimeFromTime_t (epicsTimeStamp pDest, time_t src); 
 
/⋆convert to and from ANSI C's "struct tm" with nano seconds ⋆/ 
int epicsTimeToTM (struct tm pDest, unsigned long pNSecDest, 
    const epicsTimeStamp pSrc); 
int epicsTimeToGMTM (struct tm pDest, unsigned long pNSecDest, 
    const epicsTimeStamp pSrc); 
int epicsTimeFromTM (epicsTimeStamp pDest, const struct tm pSrc, 
    unsigned long nSecSrc); 
int epicsTimeFromGMTM (epicsTimeStamp pDest, const struct tm pSrc, 
    unsigned long nSecSrc); 
 
/⋆ convert to and from POSIX RT's "struct timespec" ⋆/ 
int epicsTimeToTimespec (struct timespec pDest, const epicsTimeStamp pSrc); 
int epicsTimeFromTimespec (epicsTimeStamp pDest, const struct timespec pSrc); 
 
/⋆ convert to and from BSD's "struct timeval" ⋆/ 
int epicsTimeToTimeval (struct timeval pDest, const epicsTimeStamp pSrc); 
int epicsTimeFromTimeval (epicsTimeStamp pDest, const struct timeval pSrc); 
/⋆arithmetic operations ⋆/ 
double epicsTimeDiffInSeconds ( 
    const epicsTimeStamp pLeft, const epicsTimeStamp pRight); 
void epicsTimeAddSeconds ( 
    epicsTimeStamp pDest, double secondsToAdd); /⋆ adds seconds to pDest ⋆/ 
 
/⋆comparison operations: returns (0,1) if (false,true) ⋆/ 
int epicsTimeEqual(const epicsTimeStamp pLeft, const epicsTimeStamp pRight); 
int epicsTimeNotEqual(const epicsTimeStamp pLeft,const epicsTimeStamp pRight); 
int epicsTimeLessThan(const epicsTimeStamp pLeft,const epicsTimeStamp pRight); 
int epicsTimeLessThanEqual( 
    const epicsTimeStamp pLeft, const epicsTimeStamp pRight); 
int epicsTimeGreaterThan ( 
    const epicsTimeStamp pLeft, const epicsTimeStamp pRight); 
int epicsTimeGreaterThanEqual ( 
    const epicsTimeStamp pLeft, const epicsTimeStamp pRight); 
/⋆convert to ASCII string ⋆/ 
size_t epicsTimeToStrftime ( 
    char pBuff, size_t bufLength, const char pFormat, const epicsTimeStamp 
pTS); 
 
/⋆ dump current state to standard out ⋆/ 
void epicsTimeShow (const epicsTimeStamp ⋆, unsigned interestLevel); 
/⋆ OS dependent reentrant versions of the ANSI C interface because ⋆/ 
/⋆ vxWorks gmtime_r interface does not match POSIX standards ⋆/ 
int epicsTime_localtime ( const time_t clock, struct tm result ); 
int epicsTime_gmtime ( const time_t clock, struct tm result );

The C interface provides most of the features as the C++ interface. The features of the C++ operators are provided as functions.

Note that the epicsTimeGetCurrent() and epicsTimeGetEvent() routines and their ISR-callable equivalents epicsTimeGetCurrentInt() and epicsTimeGetEventInt() are now implemented in epicsGeneralTime.c

20.18 osiPoolStatus

osiPoolStatus.h contains the following description:

int osiSufficentSpaceInPool(void);

Method

Meaning



osiSufficentSpaceInPool

Return (true,false) if there is sufficient free memory.

This determines if enough free memory exists to continue.

A vxWorks version returns (true,false) if memFindMax returns (>100000, <=100000) bytes.

The default version always returns true.

20.19 osiProcess

osiProcess.h contains the following:

typedef enum osiGetUserNameReturn { 
    osiGetUserNameFail, 
    osiGetUserNameSuccess 
}osiGetUserNameReturn; 
 
osiGetUserNameReturn osiGetUserName (char pBuf, unsigned bufSize); 
 
/⋆ 
  Spawn detached process with named executable, but return 
  osiSpawnDetachedProcessNoSupport if the local OS does not 
  support heavy weight processes. 
 ⋆/ 
typedef enum osiSpawnDetachedProcessReturn { 
    osiSpawnDetachedProcessFail, 
    osiSpawnDetachedProcessSuccess, 
    osiSpawnDetachedProcessNoSupport 
}osiSpawnDetachedProcessReturn; 
 
osiSpawnDetachedProcessReturn osiSpawnDetachedProcess( 
    const char pProcessName, const char pBaseExecutableName);

Not otherwise documented.

20.20 Ignoring Posix Signals

epicsSignal.h contains the following commented declarations:

/⋆ 
  Required to avoid problems with soft IOCs getting SIGHUPs 
  when a Channel Access client disconnects: 
 ⋆/ 
void epicsSignalInstallSigHupIgnore ( void ); 
 
/⋆ 
  Required to avoid terminating a process which is blocking 
  in a socket send() call when a SIGPIPE signal is generated 
  by the OS: 
 ⋆/ 
void epicsSignalInstallSigPipeIgnore ( void ); 
 
/⋆ 
  Required only if shutdown() and close() do not interrupt 
  a thread blocking in a socket system call: 
 ⋆/ 
void epicsSignalInstallSigAlarmIgnore ( void ); 
void epicsSignalRaiseSigAlarm ( struct epicsThreadOSD  );

Not otherwise documented.

20.21 OS-Independent Socket API

The header file osiSock.h provides wrappers around the different socket APIs provided by the supported operating systems. This API was designed to make it possible to write network applications that will compile and run on any OS. See the comments and declarations in the header file for details.

20.22 epicsMMIO

epicsMMIO.h provides a set of calls to perform safe access to Memory Mapped I/O regions. This is the typical means to access VME or PCI bus devices.

The following are the equivalant signatures of the MMIO read and write calls. The actual implementations may use macros.

epicsUInt8      ioread8 (void addr); 
epicsUInt16 nat_ioread16(void addr); 
epicsUInt16  be_ioread16(void addr); 
epicsUInt16  le_ioread16(void addr); 
epicsUInt32 nat_ioread32(void addr); 
epicsUInt32  be_ioread32(void addr); 
epicsUInt32  le_ioread32(void addr); 
 
void     iowrite8 (void addr, epicsUInt8  val); 
void nat_iowrite16(void addr, epicsUInt16 val); 
void  be_iowrite16(void addr, epicsUInt16 val); 
void  le_iowrite16(void addr, epicsUInt16 val); 
void nat_iowrite32(void addr, epicsUInt32 val); 
void  be_iowrite32(void addr, epicsUInt32 val); 
void  le_iowrite32(void addr, epicsUInt32 val);

The 16 and 32-bit calls have three variants: nat_, be_, and le_ which specify the byte ordering of the MMIO register being access as having: CPU Native, Big Endian, or Little Endian byte order. The specification will be used to re-order the bytes read/written into the CPU native integer format.

Determining which of these variants to use in a specific case requires knowledge of the underlying hardware (bus and/or device). This document can present only a general rule, which is that the nat_ variant will be used for VME devices as the common bus bridges do automatic byte lane swapping. PCI devices will generally use of one be_ or le_, although some devices have been known to have a mix of BE and LE registers.

These calls do not perform any checking of address alignment.

All of these calls have CPU, OS, and/or compiler specific definitions which try to preserve all MMIO operations by defeating instruction reordering and operation splitting/combining optimizations by the compiler and CPU.

20.23 Device Support Library

NOTE: EPICS Base only provides vxWorks and RTEMS back-end implementations of these routines. Versions of the back-end routines for other operating systems can be added in a support or IOC application.

20.23.1 Overview

devLib.h provides definitions for a library of routines useful for device and driver modules, which are primarily indended for accessing VME devices. If all VME drivers register with these routines then addressing conflicts caused by multiple device/drivers trying to use the same VME addresses will be detected.

20.23.2 Location Probing

20.23.2.1 Read Probe
long  devReadProbe( 
    unsigned wordSize, 
    volatile const void ptr, 
    void pValueRead);

Performs a bus-error-safe atomic read operation width wordSize bytes from the ptr location, placing the value read (if successful) at pValueRead. The routine returns a failure status (non-zero) if a bus error occurred during the read cycle.

20.23.2.2 Write Probe
long  devWriteProbe( 
    unsigned wordSize, 
    volatile void ptr, 
    const void pValueWritten);

Performs a bus-error-safe atomic write operation width wordSize which copies the value from pValueWritten to the ptr location. The routine returns a failure status (non-zero) if a bus error occurred during the write cycle.

20.23.2.3 No Response Probe
long devNoResponseProbe( 
    epicsAddressType addrType, 
    size_t base, 
    size_t size);

This routine performs a series of read probes for all word sizes from char to long at every naturally aligned location in the range [base, base+size) for the given bus address type. It returns an error if any location responds or if any such location cannot be mapped.

20.23.3 Registering VME Addresses

20.23.3.1 Definitions of Address Types
typedef enum { 
    atVMEA16, atVMEA24, atVMEA32, 
    atISA, 
    atVMECSR, 
    atLast /⋆ atLast is the last enum in this list ⋆/ 
} epicsAddressType; 
 
char  epicsAddressTypeName[] = { 
    "VMEA16", "VMEA24", "VMEA32", 
    "ISA", "VMECSR" 
};

20.23.3.2 Register Address
long  devRegisterAddress( 
    const char pOwnerName, 
    epicsAddressType addrType, 
    size_t logicalBaseAddress, 
    size_t size, /⋆ bytes ⋆/ 
    volatile void ⋆⋆pLocalAddress);

This routine is called to register a VME address. The routine keeps a list of all VME address ranges requested and returns an error message if an attempt is made to register any addresses that overlap a range that is already being used. ⋆pLocalAddress is set equal to the address as seen by the caller.

20.23.3.3 Print Address Map
long  devAddressMap(void)

This routine displays the table of registered VME address ranges, including the owner of each registered address.

20.23.3.4 Unregister Address
long  devUnregisterAddress( 
    epicsAddressType addrType, 
    size_t logicalBaseAddress, 
    const char pOwnerName);

This routine releases address ranges previously registered by a call to devRegisterAddress or devAllocAddress.

20.23.3.5 Allocate Address
long  devAllocAddress( 
    const char pOwnerName, 
    epicsAddressType addrType, 
    size_t size, 
    unsigned alignment, /⋆number of low zero bits needed in addr⋆/ 
    volatile void ⋆⋆pLocalAddress);

This routine is called to request the library to allocate an address block of a particular address type. This is useful for devices that appear in more than one address space and can program the base address of one window using registers found in another window.

20.23.4 Interrupt Connection Routines

20.23.4.1 Connect
long  devConnectInterruptVME( 
    unsigned vectorNumber, 
    void (⋆pFunction)(void ⋆), 
    void  parameter);

Connect ISR pFunction up to the VME interrupt vectorNumber.

20.23.4.2 Disconnect
long  devDisconnectInterruptVME( 
    unsigned vectorNumber, 
    void (⋆pFunction)(void ⋆));

Disconnects an ISR from its VME interrupt vector. The parameter pFunction should be set to the C function pointer that was connected. It is used as a key to prevent a driver from inadvertently removing an interrupt handler that it didn’t install.

20.23.4.3 Check If Used
int devInterruptInUseVME( 
    unsigned vectorNumber);

Determines if a VME interrupt vector is in use, returning a boolean value.

20.23.4.4 Enable
long devEnableInterruptLevelVME( 
    unsigned level);

Enable the given VME interrupt level onto the CPU.

20.23.4.5 Disable
long devDisableInterruptLevelVME( 
    unsigned level);

Disable VME interrupt level. This routine should generally never be used, since it is impossible for a driver to know whether any other active drivers are still making use of a particular interrupt level.

20.23.5 Macros for Normalized Analog Values

20.23.5.1 Convert Digital Value to a Normalized Double Value
#define devCreateMask(NBITS)((1<<(NBITS))-1) 
#define devDigToNml(DIGITAL,NBITS) \ 
    (((double)(DIGITAL))/devCreateMask(NBITS))

20.23.5.2 Convert Normalized Double Value to a Digital Value
#define devNmlToDig(NORMAL,NBITS) \ 
    (((long)(NORMAL))  devCreateMask(NBITS))

20.23.6 Deprecated Interrupt Routines

20.23.6.1 Definitions of Interrupt Types (deprecated)
typedef enum {intCPU, intVME, intVXI} epicsInterruptType;

The routines that use this typedef have all been deprecated, and currently only exist for backwards compatibility purposes. The typedef will be removed in a future release, along with those routines.

20.23.6.2 Connect (deprecated)
long  devConnectInterrupt( 
    epicsInterruptType  intType, 
    unsigned  vectorNumber, 
    void  (⋆pFunction)(), 
    void  parameter);

This routine has been deprecated, and currently only exists for backwards compatibility purposes. Uses of this routine should be converted to call devConnectInterruptVME or related routines instead. This routine will be removed in a future release.

20.23.6.3 Disconnect (deprecated)
long  devDisconnectInterrupt( 
    epicsInterruptType intType, 
    unsigned  vectorNumber);

This routine has been deprecated, and currently only exists for backwards compatibility purposes. Uses of this routine should be converted to call devDisconnectInterruptVME or related routines instead. This routine will be removed in a future release.

20.23.6.4 Enable Level (deprecated)
long  devEnableInterruptLevel( 
    epicsInterruptType  intType, 
    unsigned  level);

This routine has been deprecated, and currently only exists for backwards compatibility purposes. Uses of this routine should be converted to call devEnableInterruptLevelVME or related routines instead. This routine will be removed in a future release.

20.23.6.5 Disable Level (deprecated)
long  devDisableInterruptLevel( 
    epicsInterruptType  intType, 
    unsigned  level);

This routine has been deprecated, and currently only exists for backwards compatibility purposes. Uses of this routine should be converted to call devDisableInterruptLevelVME or related routines instead. This routine will be removed in a future release.

20.24 vxWorks Specific routines and Headers

The routines described in this section are included in a application by the Makfile command:

<appl>_OBJS_vxWorks += $(EPICS_BASE_BIN)/vxComLibrary

20.24.1 veclist

This routine shows the vxWorks interrupt vector table, but only works properly on 68K family CPUs.

20.24.2 logMsgToErrlog

This traps all calls to logMsg and sends them to errlogPrintf.

20.24.3 camacLib.h

This was included with 3.13.

20.24.4 epicsDynLink

This provides the routines symFindByNameEPICS and symFindByNameAndTypeEPICS. It is only provided for modules that have not been converted to use epicsFindSymbol. These routines are deprecated.

20.24.5 module_types.h

This is only provided for device/driver support that have not been converted to use OSI features of base. This header is deprecated. Instead of using this, drivers should register a configuration command to obtain the information originally provided by module_types.h

20.24.6 task_params.h

This is only provided for device/driver support that have not been converted to use OSI features of base. This header is deprecated.

20.24.7 vxComLibrary

This routine causes epicsDynLink, logMsgToErrlog and veclist to be loaded.