Merged the epicsEvent-api branch.
Modified epicsEventTest.cpp to use the new names.
This commit is contained in:
@@ -15,6 +15,31 @@ EPICS Base 3.15.0.x releases are not intended for use in production systems.</p>
|
||||
<h2 align="center">Changes between 3.14.x and 3.15.0.x</h2>
|
||||
<!-- Insert new items immediately below here ... -->
|
||||
|
||||
<h3>
|
||||
Reworked the epicsEvent C & C++ APIs</h3>
|
||||
|
||||
<ul>
|
||||
<li>Renamed the enum epicsEventWaitStatus to epicsEventStatus</li>
|
||||
<li>Defined epicsEventWaitStatus as a macro for epicsEventStatus</li>
|
||||
<li>Renamed epicsEventWaitOk to epicsEventOk</li>
|
||||
<li>Renamed epicsEventWaitError to epicsEventError</li>
|
||||
<li>Defined epicsEventWaitOK and epicsEventWaitError as macros</li>
|
||||
<li>Added epicsEventTrigger(id) which triggers an event and returns OK or an
|
||||
error status if the underlying OS primitives report an error</li>
|
||||
<li>Added epicsEventMustTrigger(id) which halts on error</li>
|
||||
<li>Defined epicsEventSignal(id) as a macro for epicsEventMustTrigger(id)</li>
|
||||
<li>Added a new C++ method epicsEvent::trigger() which throws an
|
||||
epicsEvent::invalidSemaphore in the event of an error</li>
|
||||
<li>epicsEvent::signal() makes an inline call to epicsEvent::trigger()</li>
|
||||
<li>epicsEventWait() and epicsEventWaitWithTimeout() now return an error
|
||||
status if the underlying OS primitives report an error</li>
|
||||
<li>All the epicsEventMust...() routines are now implemented in the common
|
||||
libCom/osi/epicsEvent.cpp source file, and call cantProceed() instead of
|
||||
mis-using assert()</li>
|
||||
<li>Implemented epicsEventShow() on Posix</li>
|
||||
<li>Win32: Removed all epicsShareAPI decorations</li>
|
||||
</ul>
|
||||
|
||||
<h3>
|
||||
Enabled histogram record type</h3>
|
||||
|
||||
@@ -24,7 +49,8 @@ but has now been added along with its associated soft device support. The build
|
||||
system now generates the list of all the record.dbd files in base automatically
|
||||
in src/std/rec/Makefile.</p>
|
||||
|
||||
<h3>Reorganization of src/</h3>
|
||||
<h3>
|
||||
Reorganization of src/</h3>
|
||||
|
||||
<p>Reorganization of subdirectories of src/ to better represent the relation
|
||||
between different parts as described in the following table.</p>
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
@@ -17,6 +16,7 @@
|
||||
#define epicsExportSharedSymbols
|
||||
#include "epicsEvent.h"
|
||||
#include "epicsStdioRedirect.h"
|
||||
#include "cantProceed.h"
|
||||
|
||||
// vxWorks 5.4 gcc fails during compile when I use std::exception
|
||||
using namespace std;
|
||||
@@ -52,49 +52,81 @@ epicsEvent::~epicsEvent ()
|
||||
epicsEventDestroy ( this->id );
|
||||
}
|
||||
|
||||
void epicsEvent::signal ()
|
||||
void epicsEvent::trigger ()
|
||||
{
|
||||
epicsEventSignal ( this->id );
|
||||
epicsEventStatus status = epicsEventTrigger (this->id);
|
||||
|
||||
if (status != epicsEventOK) {
|
||||
throw invalidSemaphore ();
|
||||
}
|
||||
}
|
||||
|
||||
void epicsEvent::wait ()
|
||||
{
|
||||
epicsEventWaitStatus status;
|
||||
status = epicsEventWait (this->id);
|
||||
if (status!=epicsEventWaitOK) {
|
||||
epicsEventStatus status = epicsEventWait (this->id);
|
||||
|
||||
if (status != epicsEventOK) {
|
||||
throw invalidSemaphore ();
|
||||
}
|
||||
}
|
||||
|
||||
bool epicsEvent::wait (double timeOut)
|
||||
{
|
||||
epicsEventWaitStatus status;
|
||||
status = epicsEventWaitWithTimeout (this->id, timeOut);
|
||||
if (status==epicsEventWaitOK) {
|
||||
epicsEventStatus status = epicsEventWaitWithTimeout (this->id, timeOut);
|
||||
|
||||
if (status == epicsEventOK) {
|
||||
return true;
|
||||
} else if (status==epicsEventWaitTimeout) {
|
||||
} else if (status == epicsEventWaitTimeout) {
|
||||
return false;
|
||||
} else {
|
||||
throw invalidSemaphore ();
|
||||
}
|
||||
return false;
|
||||
throw invalidSemaphore ();
|
||||
}
|
||||
|
||||
bool epicsEvent::tryWait ()
|
||||
{
|
||||
epicsEventWaitStatus status;
|
||||
status = epicsEventTryWait (this->id);
|
||||
if (status==epicsEventWaitOK) {
|
||||
epicsEventStatus status = epicsEventTryWait (this->id);
|
||||
|
||||
if (status == epicsEventOK) {
|
||||
return true;
|
||||
} else if (status==epicsEventWaitTimeout) {
|
||||
} else if (status == epicsEventWaitTimeout) {
|
||||
return false;
|
||||
} else {
|
||||
throw invalidSemaphore ();
|
||||
}
|
||||
return false;
|
||||
throw invalidSemaphore ();
|
||||
}
|
||||
|
||||
void epicsEvent::show ( unsigned level ) const
|
||||
{
|
||||
epicsEventShow ( this->id, level );
|
||||
}
|
||||
|
||||
|
||||
// epicsEventMust... convenience routines for C code
|
||||
|
||||
extern "C" {
|
||||
|
||||
epicsShareFunc epicsEventId epicsEventMustCreate (
|
||||
epicsEventInitialState initialState)
|
||||
{
|
||||
epicsEventId id = epicsEventCreate (initialState);
|
||||
|
||||
if (!id)
|
||||
cantProceed ("epicsEventMustCreate");
|
||||
return id;
|
||||
}
|
||||
|
||||
epicsShareFunc void epicsEventMustTrigger (epicsEventId id) {
|
||||
epicsEventStatus status = epicsEventTrigger (id);
|
||||
|
||||
if (status != epicsEventOK)
|
||||
cantProceed ("epicsEventMustTrigger");
|
||||
}
|
||||
|
||||
epicsShareFunc void epicsEventMustWait (epicsEventId id) {
|
||||
epicsEventStatus status = epicsEventWait (id);
|
||||
|
||||
if (status != epicsEventOK)
|
||||
cantProceed ("epicsEventMustWait");
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
|
||||
@@ -1,25 +1,33 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
#ifndef epicsEventh
|
||||
#define epicsEventh
|
||||
|
||||
#include "epicsAssert.h"
|
||||
#include "shareLib.h"
|
||||
|
||||
typedef struct epicsEventOSD *epicsEventId;
|
||||
|
||||
typedef enum {
|
||||
epicsEventWaitOK,epicsEventWaitTimeout,epicsEventWaitError
|
||||
} epicsEventWaitStatus;
|
||||
epicsEventOK = 0,
|
||||
epicsEventWaitTimeout,
|
||||
epicsEventError
|
||||
} epicsEventStatus;
|
||||
|
||||
typedef enum {epicsEventEmpty,epicsEventFull} epicsEventInitialState;
|
||||
/* Backwards compatibility */
|
||||
#define epicsEventWaitStatus epicsEventStatus
|
||||
#define epicsEventWaitOK epicsEventOK
|
||||
#define epicsEventWaitError epicsEventError
|
||||
|
||||
typedef enum {
|
||||
epicsEventEmpty,
|
||||
epicsEventFull
|
||||
} epicsEventInitialState;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -27,42 +35,40 @@ class epicsShareClass epicsEvent {
|
||||
public:
|
||||
epicsEvent ( epicsEventInitialState initial = epicsEventEmpty );
|
||||
~epicsEvent ();
|
||||
void signal ();
|
||||
void wait (); /* blocks until full */
|
||||
bool wait ( double timeOut ); /* false if empty at time out */
|
||||
bool tryWait (); /* false if empty */
|
||||
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 */
|
||||
class invalidSemaphore; /* exception payload */
|
||||
private:
|
||||
epicsEvent ( const epicsEvent & );
|
||||
epicsEvent & operator = ( const epicsEvent & );
|
||||
epicsEventId id;
|
||||
};
|
||||
|
||||
#endif /*__cplusplus */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /*__cplusplus */
|
||||
|
||||
epicsShareFunc epicsEventId epicsShareAPI epicsEventCreate(
|
||||
epicsShareFunc epicsEventId epicsEventCreate(
|
||||
epicsEventInitialState initialState);
|
||||
epicsShareFunc epicsEventId epicsShareAPI epicsEventMustCreate (
|
||||
epicsShareFunc epicsEventId epicsEventMustCreate (
|
||||
epicsEventInitialState initialState);
|
||||
epicsShareFunc void epicsShareAPI epicsEventDestroy(epicsEventId id);
|
||||
epicsShareFunc void epicsShareAPI epicsEventSignal(epicsEventId id);
|
||||
epicsShareFunc epicsEventWaitStatus epicsShareAPI epicsEventWait(
|
||||
epicsShareFunc void epicsEventDestroy(epicsEventId id);
|
||||
epicsShareFunc epicsEventStatus epicsEventTrigger(
|
||||
epicsEventId id);
|
||||
#define epicsEventMustWait(ID) { \
|
||||
epicsEventWaitStatus status = epicsEventWait(ID); \
|
||||
assert(status == epicsEventWaitOK); \
|
||||
}
|
||||
epicsShareFunc epicsEventWaitStatus epicsShareAPI epicsEventWaitWithTimeout(
|
||||
epicsShareFunc void epicsEventMustTrigger(epicsEventId id);
|
||||
#define epicsEventSignal(ID) epicsEventMustTrigger(ID)
|
||||
epicsShareFunc epicsEventStatus epicsEventWait(
|
||||
epicsEventId id);
|
||||
epicsShareFunc void epicsEventMustWait(epicsEventId id);
|
||||
epicsShareFunc epicsEventStatus epicsEventWaitWithTimeout(
|
||||
epicsEventId id, double timeOut);
|
||||
epicsShareFunc epicsEventWaitStatus epicsShareAPI epicsEventTryWait(
|
||||
epicsShareFunc epicsEventStatus epicsEventTryWait(
|
||||
epicsEventId id);
|
||||
epicsShareFunc void epicsShareAPI epicsEventShow(
|
||||
epicsShareFunc void epicsEventShow(
|
||||
epicsEventId id, unsigned int level);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Saskatchewan
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/*
|
||||
@@ -18,7 +19,6 @@
|
||||
*/
|
||||
#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__ 1
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <rtems.h>
|
||||
#include <rtems/error.h>
|
||||
@@ -84,13 +84,6 @@ epicsEventCreate(epicsEventInitialState initialState)
|
||||
return (epicsEventId)sid;
|
||||
}
|
||||
|
||||
epicsEventId epicsEventMustCreate(epicsEventInitialState initialState)
|
||||
{
|
||||
epicsEventId id = epicsEventCreate (initialState);
|
||||
assert (id);
|
||||
return id;
|
||||
}
|
||||
|
||||
void
|
||||
epicsEventDestroy(epicsEventId id)
|
||||
{
|
||||
@@ -102,18 +95,20 @@ epicsEventDestroy(epicsEventId id)
|
||||
errlogPrintf ("Can't destroy semaphore: %s\n", rtems_status_text (sc));
|
||||
}
|
||||
|
||||
void
|
||||
epicsEventSignal(epicsEventId id)
|
||||
epicsEventStatus
|
||||
epicsEventTrigger(epicsEventId id)
|
||||
{
|
||||
rtems_id sid = (rtems_id)id;
|
||||
rtems_status_code sc;
|
||||
|
||||
sc = rtems_semaphore_release (sid);
|
||||
if (sc != RTEMS_SUCCESSFUL)
|
||||
errlogPrintf ("Can't release semaphore: %s\n", rtems_status_text (sc));
|
||||
if (sc == RTEMS_SUCCESSFUL)
|
||||
return epicsEventOK;
|
||||
errlogPrintf ("Can't release semaphore: %s\n", rtems_status_text (sc));
|
||||
return epicsEventError;
|
||||
}
|
||||
|
||||
epicsEventWaitStatus
|
||||
epicsEventStatus
|
||||
epicsEventWait(epicsEventId id)
|
||||
{
|
||||
rtems_id sid = (rtems_id)id;
|
||||
@@ -122,11 +117,11 @@ epicsEventWait(epicsEventId id)
|
||||
SEMSTAT(0)
|
||||
sc = rtems_semaphore_obtain (sid, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
|
||||
if (sc != RTEMS_SUCCESSFUL)
|
||||
return epicsEventWaitError;
|
||||
return epicsEventWaitOK;
|
||||
return epicsEventError;
|
||||
return epicsEventOK;
|
||||
}
|
||||
|
||||
epicsEventWaitStatus
|
||||
epicsEventStatus
|
||||
epicsEventWaitWithTimeout(epicsEventId id, double timeOut)
|
||||
{
|
||||
rtems_id sid = (rtems_id)id;
|
||||
@@ -142,14 +137,14 @@ epicsEventWaitWithTimeout(epicsEventId id, double timeOut)
|
||||
delay++;
|
||||
sc = rtems_semaphore_obtain (sid, RTEMS_WAIT, delay);
|
||||
if (sc == RTEMS_SUCCESSFUL)
|
||||
return epicsEventWaitOK;
|
||||
return epicsEventOK;
|
||||
else if (sc == RTEMS_TIMEOUT)
|
||||
return epicsEventWaitTimeout;
|
||||
else
|
||||
return epicsEventWaitError;
|
||||
return epicsEventError;
|
||||
}
|
||||
|
||||
epicsEventWaitStatus
|
||||
epicsEventStatus
|
||||
epicsEventTryWait(epicsEventId id)
|
||||
{
|
||||
rtems_id sid = (rtems_id)id;
|
||||
@@ -158,11 +153,11 @@ epicsEventTryWait(epicsEventId id)
|
||||
SEMSTAT(2)
|
||||
sc = rtems_semaphore_obtain (sid, RTEMS_NO_WAIT, RTEMS_NO_TIMEOUT);
|
||||
if (sc == RTEMS_SUCCESSFUL)
|
||||
return epicsEventWaitOK;
|
||||
return epicsEventOK;
|
||||
else if (sc == RTEMS_UNSATISFIED)
|
||||
return epicsEventWaitTimeout;
|
||||
else
|
||||
return epicsEventWaitError;
|
||||
return epicsEventError;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* osdEvent.c */
|
||||
@@ -27,7 +26,6 @@
|
||||
#define epicsExportSharedSymbols
|
||||
#include "shareLib.h"
|
||||
#include "epicsEvent.h"
|
||||
#include "epicsAssert.h"
|
||||
|
||||
typedef struct epicsEventOSD {
|
||||
HANDLE handle;
|
||||
@@ -36,7 +34,7 @@ typedef struct epicsEventOSD {
|
||||
/*
|
||||
* epicsEventCreate ()
|
||||
*/
|
||||
epicsShareFunc epicsEventId epicsShareAPI epicsEventCreate (
|
||||
epicsShareFunc epicsEventId epicsEventCreate (
|
||||
epicsEventInitialState initialState )
|
||||
{
|
||||
epicsEventOSD *pSem;
|
||||
@@ -53,55 +51,44 @@ epicsShareFunc epicsEventId epicsShareAPI epicsEventCreate (
|
||||
return pSem;
|
||||
}
|
||||
|
||||
/*
|
||||
* epicsEventMustCreate ()
|
||||
*/
|
||||
epicsShareFunc epicsEventId epicsShareAPI epicsEventMustCreate (
|
||||
epicsEventInitialState initialState )
|
||||
{
|
||||
epicsEventId id = epicsEventCreate ( initialState );
|
||||
assert ( id );
|
||||
return id;
|
||||
}
|
||||
|
||||
/*
|
||||
* epicsEventDestroy ()
|
||||
*/
|
||||
epicsShareFunc void epicsShareAPI epicsEventDestroy ( epicsEventId pSem )
|
||||
epicsShareFunc void epicsEventDestroy ( epicsEventId pSem )
|
||||
{
|
||||
CloseHandle ( pSem->handle );
|
||||
free ( pSem );
|
||||
}
|
||||
|
||||
/*
|
||||
* epicsEventSignal ()
|
||||
* epicsEventTrigger ()
|
||||
*/
|
||||
epicsShareFunc void epicsShareAPI epicsEventSignal ( epicsEventId pSem )
|
||||
epicsShareFunc epicsEventStatus epicsEventTrigger ( epicsEventId pSem )
|
||||
{
|
||||
BOOL status;
|
||||
status = SetEvent ( pSem->handle );
|
||||
assert ( status );
|
||||
return status ? epicsEventOK : epicsEventError;
|
||||
}
|
||||
|
||||
/*
|
||||
* epicsEventWait ()
|
||||
*/
|
||||
epicsShareFunc epicsEventWaitStatus epicsShareAPI epicsEventWait ( epicsEventId pSem )
|
||||
epicsShareFunc epicsEventStatus epicsEventWait ( epicsEventId pSem )
|
||||
{
|
||||
DWORD status;
|
||||
status = WaitForSingleObject (pSem->handle, INFINITE);
|
||||
if ( status == WAIT_OBJECT_0 ) {
|
||||
return epicsEventWaitOK;
|
||||
return epicsEventOK;
|
||||
}
|
||||
else {
|
||||
return epicsEventWaitError;
|
||||
return epicsEventError;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* epicsEventWaitWithTimeout ()
|
||||
*/
|
||||
epicsShareFunc epicsEventWaitStatus epicsShareAPI epicsEventWaitWithTimeout (
|
||||
epicsShareFunc epicsEventStatus epicsEventWaitWithTimeout (
|
||||
epicsEventId pSem, double timeOut )
|
||||
{
|
||||
static const unsigned mSecPerSec = 1000;
|
||||
@@ -122,38 +109,38 @@ epicsShareFunc epicsEventWaitStatus epicsShareAPI epicsEventWaitWithTimeout (
|
||||
}
|
||||
status = WaitForSingleObject ( pSem->handle, tmo );
|
||||
if ( status == WAIT_OBJECT_0 ) {
|
||||
return epicsEventWaitOK;
|
||||
return epicsEventOK;
|
||||
}
|
||||
else if ( status == WAIT_TIMEOUT ) {
|
||||
return epicsEventWaitTimeout;
|
||||
}
|
||||
else {
|
||||
return epicsEventWaitError;
|
||||
return epicsEventError;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* epicsEventTryWait ()
|
||||
*/
|
||||
epicsShareFunc epicsEventWaitStatus epicsShareAPI epicsEventTryWait ( epicsEventId pSem )
|
||||
epicsShareFunc epicsEventStatus epicsEventTryWait ( epicsEventId pSem )
|
||||
{
|
||||
DWORD status;
|
||||
|
||||
status = WaitForSingleObject ( pSem->handle, 0 );
|
||||
if ( status == WAIT_OBJECT_0 ) {
|
||||
return epicsEventWaitOK;
|
||||
return epicsEventOK;
|
||||
}
|
||||
else if ( status == WAIT_TIMEOUT ) {
|
||||
return epicsEventWaitTimeout;
|
||||
}
|
||||
else {
|
||||
return epicsEventWaitError;
|
||||
return epicsEventError;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* epicsEventShow ()
|
||||
*/
|
||||
epicsShareFunc void epicsShareAPI epicsEventShow ( epicsEventId id, unsigned level )
|
||||
epicsShareFunc void epicsEventShow ( epicsEventId id, unsigned level )
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne
|
||||
* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
@@ -21,155 +21,142 @@
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include "epicsEvent.h"
|
||||
#include "cantProceed.h"
|
||||
#include "epicsTime.h"
|
||||
#include "errlog.h"
|
||||
#include "epicsAssert.h"
|
||||
|
||||
/* Until these can be demonstrated to work leave them undefined*/
|
||||
#undef _POSIX_THREAD_PROCESS_SHARED
|
||||
#undef _POSIX_THREAD_PRIO_INHERIT
|
||||
|
||||
typedef struct epicsEventOSD {
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t cond;
|
||||
int isFull;
|
||||
}epicsEventOSD;
|
||||
|
||||
#define checkStatus(status,message) \
|
||||
if((status)) { \
|
||||
errlogPrintf("epicsEvent %s failed: error %s\n",(message),strerror((status)));}
|
||||
struct epicsEventOSD {
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t cond;
|
||||
int isFull;
|
||||
};
|
||||
|
||||
#define checkStatusQuit(status,message,method) \
|
||||
if(status) { \
|
||||
errlogPrintf("epicsEvent %s failed: error %s\n",(message),strerror((status))); \
|
||||
cantProceed((method)); \
|
||||
}
|
||||
#define printStatus(status, routine, func) \
|
||||
errlogPrintf("%s: %s failed: %s\n", (func), (routine), strerror(status))
|
||||
|
||||
static int mutexLock(pthread_mutex_t *id)
|
||||
{
|
||||
int status;
|
||||
|
||||
while(1) {
|
||||
status = pthread_mutex_lock(id);
|
||||
if(status!=EINTR) return status;
|
||||
errlogPrintf("pthread_mutex_lock returned EINTR. Violates SUSv3\n");
|
||||
#define checkStatus(status, routine, func) \
|
||||
if (status) { \
|
||||
printStatus(status, routine, func); \
|
||||
}
|
||||
}
|
||||
|
||||
static int condTimedwait(pthread_cond_t *condId, pthread_mutex_t *mutexId,
|
||||
struct timespec *time)
|
||||
{
|
||||
int status;
|
||||
while(1) {
|
||||
status = pthread_cond_timedwait(condId,mutexId,time);
|
||||
if(status!=EINTR) return status;
|
||||
errlogPrintf("pthread_cond_timedwait returned EINTR. Violates SUSv3\n");
|
||||
#define checkStatusReturn(status, routine, func) \
|
||||
if (status) { \
|
||||
printStatus(status, routine, func); \
|
||||
return epicsEventError; \
|
||||
}
|
||||
}
|
||||
|
||||
static int condWait(pthread_cond_t *condId, pthread_mutex_t *mutexId)
|
||||
|
||||
epicsShareFunc epicsEventId epicsEventCreate(epicsEventInitialState init)
|
||||
{
|
||||
int status;
|
||||
while(1) {
|
||||
status = pthread_cond_wait(condId,mutexId);
|
||||
if(status!=EINTR) return status;
|
||||
errlogPrintf("pthread_cond_wait returned EINTR. Violates SUSv3\n");
|
||||
epicsEventId pevent = malloc(sizeof(*pevent));
|
||||
|
||||
if (pevent) {
|
||||
int status = pthread_mutex_init(&pevent->mutex, 0);
|
||||
|
||||
pevent->isFull = (init == epicsEventFull);
|
||||
if (status) {
|
||||
printStatus(status, "pthread_mutex_init", "epicsEventCreate");
|
||||
} else {
|
||||
status = pthread_cond_init(&pevent->cond, 0);
|
||||
if (!status)
|
||||
return pevent;
|
||||
printStatus(status, "pthread_cond_init", "epicsEventCreate");
|
||||
status = pthread_mutex_destroy(&pevent->mutex);
|
||||
checkStatus(status, "pthread_mutex_destroy", "epicsEventCreate");
|
||||
}
|
||||
free(pevent);
|
||||
}
|
||||
}
|
||||
|
||||
epicsShareFunc epicsEventId epicsShareAPI epicsEventCreate(epicsEventInitialState initialState)
|
||||
{
|
||||
epicsEventOSD *pevent;
|
||||
int status;
|
||||
|
||||
pevent = callocMustSucceed(1,sizeof(*pevent),"epicsEventCreate");
|
||||
status = pthread_mutex_init(&pevent->mutex,0);
|
||||
checkStatusQuit(status,"pthread_mutex_init","epicsEventCreate");
|
||||
status = pthread_cond_init(&pevent->cond,0);
|
||||
checkStatusQuit(status,"pthread_cond_init","epicsEventCreate");
|
||||
if(initialState==epicsEventFull) pevent->isFull = 1;
|
||||
return((epicsEventId)pevent);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
epicsShareFunc epicsEventId epicsShareAPI epicsEventMustCreate(epicsEventInitialState initialState)
|
||||
epicsShareFunc void epicsEventDestroy(epicsEventId pevent)
|
||||
{
|
||||
epicsEventId id = epicsEventCreate (initialState);
|
||||
assert (id);
|
||||
return id;
|
||||
}
|
||||
int status = pthread_mutex_destroy(&pevent->mutex);
|
||||
|
||||
epicsShareFunc void epicsShareAPI epicsEventDestroy(epicsEventId pevent)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = pthread_mutex_destroy(&pevent->mutex);
|
||||
checkStatus(status,"pthread_mutex_destroy");
|
||||
checkStatus(status, "pthread_mutex_destroy", "epicsEventDestroy");
|
||||
status = pthread_cond_destroy(&pevent->cond);
|
||||
checkStatus(status,"pthread_cond_destroy");
|
||||
checkStatus(status, "pthread_cond_destroy", "epicsEventDestroy");
|
||||
free(pevent);
|
||||
}
|
||||
|
||||
epicsShareFunc void epicsShareAPI epicsEventSignal(epicsEventId pevent)
|
||||
epicsShareFunc epicsEventStatus epicsEventTrigger(epicsEventId pevent)
|
||||
{
|
||||
int status;
|
||||
int status = pthread_mutex_lock(&pevent->mutex);
|
||||
|
||||
status = mutexLock(&pevent->mutex);
|
||||
checkStatusQuit(status,"pthread_mutex_lock","epicsEventSignal");
|
||||
if(!pevent->isFull) {
|
||||
checkStatusReturn(status, "pthread_mutex_lock", "epicsEventTrigger");
|
||||
if (!pevent->isFull) {
|
||||
pevent->isFull = 1;
|
||||
status = pthread_cond_signal(&pevent->cond);
|
||||
checkStatus(status,"pthread_cond_signal");
|
||||
checkStatus(status, "pthread_cond_signal", "epicsEventTrigger");
|
||||
}
|
||||
status = pthread_mutex_unlock(&pevent->mutex);
|
||||
checkStatusQuit(status,"pthread_mutex_unlock","epicsEventSignal");
|
||||
checkStatusReturn(status, "pthread_mutex_unlock", "epicsEventTrigger");
|
||||
return epicsEventOK;
|
||||
}
|
||||
|
||||
epicsShareFunc epicsEventWaitStatus epicsShareAPI epicsEventWait(epicsEventId pevent)
|
||||
{
|
||||
int status;
|
||||
|
||||
if(!pevent) return(epicsEventWaitError);
|
||||
status = mutexLock(&pevent->mutex);
|
||||
checkStatusQuit(status,"pthread_mutex_lock","epicsEventWait");
|
||||
/*no need for while since caller must be prepared for no work*/
|
||||
if(!pevent->isFull) {
|
||||
status = condWait(&pevent->cond,&pevent->mutex);
|
||||
checkStatusQuit(status,"pthread_cond_wait","epicsEventWait");
|
||||
epicsShareFunc epicsEventStatus epicsEventWait(epicsEventId pevent)
|
||||
{
|
||||
epicsEventStatus result = epicsEventOK;
|
||||
int status = pthread_mutex_lock(&pevent->mutex);
|
||||
|
||||
checkStatusReturn(status, "pthread_mutex_lock", "epicsEventWait");
|
||||
while (!pevent->isFull) {
|
||||
status = pthread_cond_wait(&pevent->cond, &pevent->mutex);
|
||||
if (status) {
|
||||
printStatus(status, "pthread_cond_wait", "epicsEventWait");
|
||||
result = epicsEventError;
|
||||
goto release;
|
||||
}
|
||||
}
|
||||
pevent->isFull = 0;
|
||||
result = epicsEventOK;
|
||||
release:
|
||||
status = pthread_mutex_unlock(&pevent->mutex);
|
||||
checkStatusQuit(status,"pthread_mutex_unlock","epicsEventWait");
|
||||
return(epicsEventWaitOK);
|
||||
checkStatusReturn(status, "pthread_mutex_unlock", "epicsEventWait");
|
||||
return result;
|
||||
}
|
||||
|
||||
epicsShareFunc epicsEventWaitStatus epicsShareAPI epicsEventWaitWithTimeout(epicsEventId pevent, double timeout)
|
||||
epicsShareFunc epicsEventStatus epicsEventWaitWithTimeout(epicsEventId pevent,
|
||||
double timeout)
|
||||
{
|
||||
struct timespec wakeTime;
|
||||
int status = 0;
|
||||
int unlockStatus;
|
||||
epicsEventStatus result = epicsEventOK;
|
||||
int status = pthread_mutex_lock(&pevent->mutex);
|
||||
|
||||
status = mutexLock(&pevent->mutex);
|
||||
checkStatusQuit(status,"pthread_mutex_lock","epicsEventWaitWithTimeout");
|
||||
if(!pevent->isFull) {
|
||||
convertDoubleToWakeTime(timeout,&wakeTime);
|
||||
status = condTimedwait(
|
||||
&pevent->cond,&pevent->mutex,&wakeTime);
|
||||
checkStatusReturn(status, "pthread_mutex_lock", "epicsEventWaitWithTimeout");
|
||||
if (!pevent->isFull) {
|
||||
struct timespec wakeTime;
|
||||
|
||||
convertDoubleToWakeTime(timeout, &wakeTime);
|
||||
while (!status && !pevent->isFull) {
|
||||
status = pthread_cond_timedwait(&pevent->cond, &pevent->mutex,
|
||||
&wakeTime);
|
||||
}
|
||||
if (status) {
|
||||
result = (status == ETIMEDOUT) ?
|
||||
epicsEventWaitTimeout : epicsEventError;
|
||||
goto release;
|
||||
}
|
||||
}
|
||||
if(status==0) pevent->isFull = 0;
|
||||
unlockStatus = pthread_mutex_unlock(&pevent->mutex);
|
||||
checkStatusQuit(unlockStatus,"pthread_mutex_unlock","epicsEventWaitWithTimeout");
|
||||
if(status==0) return(epicsEventWaitOK);
|
||||
if(status==ETIMEDOUT) return(epicsEventWaitTimeout);
|
||||
checkStatus(status,"pthread_cond_timedwait");
|
||||
return(epicsEventWaitError);
|
||||
pevent->isFull = 0;
|
||||
release:
|
||||
status = pthread_mutex_unlock(&pevent->mutex);
|
||||
checkStatusReturn(status, "pthread_mutex_unlock", "epicsEventWaitWithTimeout");
|
||||
return result;
|
||||
}
|
||||
|
||||
epicsShareFunc epicsEventWaitStatus epicsShareAPI epicsEventTryWait(epicsEventId id)
|
||||
epicsShareFunc epicsEventStatus epicsEventTryWait(epicsEventId id)
|
||||
{
|
||||
return(epicsEventWaitWithTimeout(id,0.0));
|
||||
return epicsEventWaitWithTimeout(id, 0.0);
|
||||
}
|
||||
|
||||
epicsShareFunc void epicsShareAPI epicsEventShow(epicsEventId id,unsigned int level)
|
||||
epicsShareFunc void epicsEventShow(epicsEventId pevent, unsigned int level)
|
||||
{
|
||||
printf("epicsEvent %p: %s\n", pevent,
|
||||
pevent->isFull ? "full" : "empty");
|
||||
if (level > 0)
|
||||
printf(" pthread_mutex = %p, pthread_cond = %p\n",
|
||||
&pevent->mutex, &pevent->cond);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* os/vxWorks/osdEvent.c */
|
||||
@@ -29,19 +28,12 @@ epicsEventId epicsEventCreate(epicsEventInitialState initialState)
|
||||
(initialState == epicsEventEmpty) ? SEM_EMPTY : SEM_FULL);
|
||||
}
|
||||
|
||||
epicsEventId epicsEventMustCreate(epicsEventInitialState initialState)
|
||||
{
|
||||
epicsEventId id = epicsEventCreate(initialState);
|
||||
assert(id);
|
||||
return id;
|
||||
}
|
||||
|
||||
void epicsEventDestroy(epicsEventId id)
|
||||
{
|
||||
semDelete((SEM_ID)id);
|
||||
}
|
||||
|
||||
epicsEventWaitStatus epicsEventWaitWithTimeout(epicsEventId id, double timeOut)
|
||||
epicsEventStatus epicsEventWaitWithTimeout(epicsEventId id, double timeOut)
|
||||
{
|
||||
int rate = sysClkRateGet();
|
||||
int status;
|
||||
@@ -58,22 +50,22 @@ epicsEventWaitStatus epicsEventWaitWithTimeout(epicsEventId id, double timeOut)
|
||||
}
|
||||
status = semTake((SEM_ID)id, ticks);
|
||||
if (status == OK)
|
||||
return epicsEventWaitOK;
|
||||
return epicsEventOK;
|
||||
if (errno == S_objLib_OBJ_TIMEOUT ||
|
||||
(errno == S_objLib_OBJ_UNAVAILABLE && ticks == 0))
|
||||
return epicsEventWaitTimeout;
|
||||
return epicsEventWaitError;
|
||||
return epicsEventError;
|
||||
}
|
||||
|
||||
epicsEventWaitStatus epicsEventTryWait(epicsEventId id)
|
||||
epicsEventStatus epicsEventTryWait(epicsEventId id)
|
||||
{
|
||||
int status = semTake((SEM_ID)id, NO_WAIT);
|
||||
|
||||
if (status == OK)
|
||||
return epicsEventWaitOK;
|
||||
return epicsEventOK;
|
||||
if (errno == S_objLib_OBJ_UNAVAILABLE)
|
||||
return epicsEventWaitTimeout;
|
||||
return epicsEventWaitError;
|
||||
return epicsEventError;
|
||||
}
|
||||
|
||||
void epicsEventShow(epicsEventId id, unsigned int level)
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* os/vxWorks/osdEvent.h */
|
||||
@@ -14,12 +13,8 @@
|
||||
#include <vxWorks.h>
|
||||
#include <semLib.h>
|
||||
|
||||
/* If the macro is replaced by inline it is necessary to say
|
||||
static __inline__
|
||||
but then a warning message appears everywhere osdEvent.h is included
|
||||
*/
|
||||
|
||||
#define epicsEventSignal(ID) semGive((SEM_ID)(ID))
|
||||
#define epicsEventTrigger(ID) \
|
||||
(semGive((SEM_ID)(ID)) == OK ? epicsEventOK : epicsEventError)
|
||||
|
||||
#define epicsEventWait(ID) \
|
||||
(semTake((SEM_ID)(ID),WAIT_FOREVER)==OK ? epicsEventWaitOK : epicsEventWaitError)
|
||||
(semTake((SEM_ID)(ID), WAIT_FOREVER) == OK ? epicsEventOK : epicsEventError)
|
||||
|
||||
@@ -47,8 +47,8 @@ static void consumer(void *arg)
|
||||
|
||||
testDiag("consumer: starting");
|
||||
while (!pinfo->quit) {
|
||||
epicsEventWaitStatus status = epicsEventWait(pinfo->event);
|
||||
if (status != epicsEventWaitOK) {
|
||||
epicsEventStatus status = epicsEventWait(pinfo->event);
|
||||
if (status != epicsEventOK) {
|
||||
testDiag("consumer: epicsEventWait returned %d", status);
|
||||
errors++;
|
||||
}
|
||||
@@ -101,7 +101,7 @@ static void producer(void *arg)
|
||||
}
|
||||
epicsMutexUnlock(pinfo->lockRing);
|
||||
epicsThreadSleep(1.0);
|
||||
epicsEventSignal(pinfo->event);
|
||||
epicsEventMustTrigger(pinfo->event);
|
||||
}
|
||||
testOk(errors == 0, "%s: errors = %d", name, errors);
|
||||
}
|
||||
@@ -140,7 +140,7 @@ static void eventWakeupTest(void)
|
||||
epicsMutexUnlock(wp->countMutex);
|
||||
testOk(c == 0, "all threads still sleeping");
|
||||
for (i = 1 ; i <= SLEEPERCOUNT ; i++) {
|
||||
epicsEventSignal(wp->event);
|
||||
epicsEventMustTrigger(wp->event);
|
||||
epicsThreadSleep(0.5);
|
||||
epicsMutexLock(wp->countMutex);
|
||||
c = wp->count;
|
||||
@@ -190,7 +190,7 @@ MAIN(epicsEventTest)
|
||||
epicsEventId event;
|
||||
int status;
|
||||
|
||||
testPlan(12+SLEEPERCOUNT);
|
||||
testPlan(13+SLEEPERCOUNT);
|
||||
|
||||
event = epicsEventMustCreate(epicsEventEmpty);
|
||||
|
||||
@@ -206,19 +206,21 @@ MAIN(epicsEventTest)
|
||||
testOk(status == epicsEventWaitTimeout,
|
||||
"epicsEventTryWait(event) = %d", status);
|
||||
|
||||
epicsEventSignal(event);
|
||||
status = epicsEventTrigger(event);
|
||||
testOk(status == epicsEventOK,
|
||||
"epicsEventTrigger(event) = %d", status);
|
||||
status = epicsEventWaitWithTimeout(event, 1.0);
|
||||
testOk(status == epicsEventWaitOK,
|
||||
testOk(status == epicsEventOK,
|
||||
"epicsEventWaitWithTimeout(event, 1.0) = %d", status);
|
||||
|
||||
epicsEventSignal(event);
|
||||
epicsEventMustTrigger(event);
|
||||
status = epicsEventWaitWithTimeout(event,DBL_MAX);
|
||||
testOk(status == epicsEventWaitOK,
|
||||
testOk(status == epicsEventOK,
|
||||
"epicsEventWaitWithTimeout(event, DBL_MAX) = %d", status);
|
||||
|
||||
epicsEventSignal(event);
|
||||
epicsEventMustTrigger(event);
|
||||
status = epicsEventTryWait(event);
|
||||
testOk(status == epicsEventWaitOK,
|
||||
testOk(status == epicsEventOK,
|
||||
"epicsEventTryWait(event) = %d", status);
|
||||
|
||||
info *pinfo = (info *)calloc(1,sizeof(info));
|
||||
@@ -242,7 +244,7 @@ MAIN(epicsEventTest)
|
||||
pinfo->quit = 1;
|
||||
epicsThreadSleep(2.0);
|
||||
|
||||
epicsEventSignal(pinfo->event);
|
||||
epicsEventMustTrigger(pinfo->event);
|
||||
epicsThreadSleep(1.0);
|
||||
|
||||
eventWaitTest();
|
||||
|
||||
Reference in New Issue
Block a user