Merged the epicsEvent-api branch.

Modified epicsEventTest.cpp to use the new names.
This commit is contained in:
Andrew Johnson
2011-08-23 18:19:55 -05:00
9 changed files with 270 additions and 248 deletions

View File

@@ -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 &amp; 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>

View File

@@ -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"

View File

@@ -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

View File

@@ -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

View File

@@ -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 )
{
}

View File

@@ -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);
}

View File

@@ -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)

View File

@@ -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)

View File

@@ -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();