Compare commits

...

5 Commits

Author SHA1 Message Date
bb89d5d24e add EPICS_MUTEX_USE_PRIORITY_INHERITANCE environment variable to make inversion-safe mutiexes configurable
Some checks failed
Base / Ub-20 clang-10 C++11 (push) Has been cancelled
Base / Ub-16 clang-9 (push) Has been cancelled
Base / Ub-20 clang-10 (push) Has been cancelled
Base / Ub-20 gcc-9 + MinGW (push) Has been cancelled
Base / Ub-20 gcc-9 + RT-4.10 (push) Has been cancelled
Base / Win2019 MSC-19, debug (push) Has been cancelled
Base / Win2019 MSC-19 (push) Has been cancelled
Base / Win2019 MSC-19, static (push) Has been cancelled
Base / MacOS clang-12 (push) Has been cancelled
Base / Ub-20 gcc-9 + RT-4.9 (push) Has been cancelled
Base / Win2019 mingw (push) Has been cancelled
Base / Ub-20 gcc-9 C++11, static (push) Has been cancelled
Base / Ub-20 gcc-9 + MinGW, static (push) Has been cancelled
Base / Ub-16 gcc-4.8 (push) Has been cancelled
Base / Ub-16 gcc-4.9 (push) Has been cancelled
Base / Ub-20 gcc-8 (push) Has been cancelled
Base / Ub-20 gcc-9 (push) Has been cancelled
2021-06-10 15:24:59 +02:00
ad7a2ddf65 remove buggy vxWorks implementation of epicsAtomicCmpAndSwap* using vxCas 2021-06-10 15:23:09 +02:00
19031a7d11 make callbackRequest safer in case initialization fails 2021-06-10 15:20:54 +02:00
1c9887bd45 move -whole-archive flags to central config 2021-06-10 15:20:19 +02:00
209b979e56 fix warning missing no newline at end of file 2021-06-02 14:52:04 +02:00
7 changed files with 61 additions and 64 deletions

View File

@@ -59,6 +59,10 @@ OP_SYS_INCLUDE_CPPFLAGS_6 += -include $(VX_DIR)/target/h/vxWorks.h
OP_SYS_INCLUDE_CPPFLAGS_7 += -include vxWorks.h
OP_SYS_INCLUDE_CPPFLAGS = $(OP_SYS_INCLUDE_CPPFLAGS_$(VXWORKS_MAJOR_VERSION))
OP_SYS_LDFLAGS += $(OP_SYS_LDFLAGS_$@)
OP_SYS_LDFLAGS_softIoc = -whole-archive
OP_SYS_LDFLAGS_softIocPVA = -whole-archive
# WIND_BASE is where you installed the Wind River software.
WIND_BASE = /afs/psi.ch/project/vxworks/VxWorks$(VXWORKS_VERSION)
@@ -70,4 +74,3 @@ SKIP_BUILDS_5 = $(PV_MODULES)
SKIP_BUILDS_OLD = $(PV_MODULES)
SKIP_BUILDS_6 = $(SKIP_BUILDS_$(VX_OLD_GCC))
SKIP_BUILDS = $(SKIP_BUILDS_$(VXWORKS_MAJOR_VERSION))

View File

@@ -263,7 +263,9 @@ void callbackCleanup(void)
assert(epicsAtomicGetIntT(&mySet->threadsRunning)==0);
epicsEventDestroy(mySet->semWakeUp);
mySet->semWakeUp = NULL;
epicsRingPointerDelete(mySet->queue);
mySet->queue = NULL;
}
epicsTimerQueueRelease(timerQueue);
@@ -333,6 +335,10 @@ int callbackRequest(epicsCallback *pcallback)
return S_db_badChoice;
}
mySet = &callbackQueue[priority];
if (!mySet->queue) {
epicsInterruptContextMessage("callbackRequest: Callbacks not initialized\n");
return S_db_notInit;
}
if (mySet->queueOverflow) return S_db_bufFull;
pushOK = epicsRingPointerPush(mySet->queue, pcallback);

View File

@@ -12,8 +12,6 @@ SRC_DIRS += $(STDDIR)/softIoc
PROD_IOC_DEFAULT = softIoc
PROD_IOC_iOS = -nil-
PROD_LDFLAGS_vxWorks = --whole-archive
DBD += base.dbd
DBD += asSub.dbd
DBD += softIoc.dbd

View File

@@ -76,6 +76,7 @@ LIBCOM_API extern const ENV_PARAM EPICS_IOC_LOG_FILE_COMMAND;
LIBCOM_API extern const ENV_PARAM IOCSH_PS1;
LIBCOM_API extern const ENV_PARAM IOCSH_HISTSIZE;
LIBCOM_API extern const ENV_PARAM IOCSH_HISTEDIT_DISABLE;
LIBCOM_API extern const ENV_PARAM EPICS_MUTEX_USE_PRIORITY_INHERITANCE;
LIBCOM_API extern const ENV_PARAM *env_param_list[];
struct in_addr;

View File

@@ -41,4 +41,3 @@ LIBCOM_API size_t epicsStdCall freeListItemsAvail(void *pvt);
#endif
#endif /*INCfreeListh*/

View File

@@ -23,6 +23,7 @@
#include <errno.h>
#include <unistd.h>
#include <pthread.h>
#include <ctype.h>
#define EPICS_PRIVATE_API
@@ -34,6 +35,7 @@
#include "errlog.h"
#include "epicsStdio.h"
#include "epicsAssert.h"
#include "envDefs.h"
#define checkStatus(status,message) \
if((status)) { \
@@ -69,21 +71,27 @@ static void globalAttrInit()
status = pthread_mutexattr_settype(&globalAttrRecursive, PTHREAD_MUTEX_RECURSIVE);
checkStatusQuit(status, "pthread_mutexattr_settype(&globalAttrRecursive, PTHREAD_MUTEX_RECURSIVE)", "globalAttrInit");
#if defined _POSIX_THREAD_PRIO_INHERIT
status = pthread_mutexattr_setprotocol(&globalAttrDefault, PTHREAD_PRIO_INHERIT);
if (errVerbose) checkStatus(status, "pthread_mutexattr_setprotocol(&globalAttrDefault, PTHREAD_PRIO_INHERIT)");
status = pthread_mutexattr_setprotocol(&globalAttrRecursive, PTHREAD_PRIO_INHERIT);
if (errVerbose) checkStatus(status, "pthread_mutexattr_setprotocol(&globalAttrRecursive, PTHREAD_PRIO_INHERIT)");
if (status == 0) {
/* Can we really use PTHREAD_PRIO_INHERIT? */
pthread_mutex_t temp;
status = pthread_mutex_init(&temp, &globalAttrRecursive);
if (errVerbose) checkStatus(status, "pthread_mutex_init(&temp, &globalAttrRecursive)");
if (status != 0) {
/* No, PTHREAD_PRIO_INHERIT does not work, fall back to PTHREAD_PRIO_NONE */;
pthread_mutexattr_setprotocol(&globalAttrDefault, PTHREAD_PRIO_NONE);
pthread_mutexattr_setprotocol(&globalAttrRecursive, PTHREAD_PRIO_NONE);
} else {
pthread_mutex_destroy(&temp);
{
const char *p = envGetConfigParamPtr(&EPICS_MUTEX_USE_PRIORITY_INHERITANCE);
char c = p ? toupper(p[0]) : 'N';
if ( 'T' == c || 'Y' == c || '1' == c ) {
status = pthread_mutexattr_setprotocol(&globalAttrDefault, PTHREAD_PRIO_INHERIT);
if (errVerbose) checkStatus(status, "pthread_mutexattr_setprotocol(&globalAttrDefault, PTHREAD_PRIO_INHERIT)");
status = pthread_mutexattr_setprotocol(&globalAttrRecursive, PTHREAD_PRIO_INHERIT);
if (errVerbose) checkStatus(status, "pthread_mutexattr_setprotocol(&globalAttrRecursive, PTHREAD_PRIO_INHERIT)");
if (status == 0) {
/* Can we really use PTHREAD_PRIO_INHERIT? */
pthread_mutex_t temp;
status = pthread_mutex_init(&temp, &globalAttrRecursive);
if (errVerbose) checkStatus(status, "pthread_mutex_init(&temp, &globalAttrRecursive)");
if (status != 0) {
/* No, PTHREAD_PRIO_INHERIT does not work, fall back to PTHREAD_PRIO_NONE */;
pthread_mutexattr_setprotocol(&globalAttrDefault, PTHREAD_PRIO_NONE);
pthread_mutexattr_setprotocol(&globalAttrRecursive, PTHREAD_PRIO_NONE);
} else {
pthread_mutex_destroy(&temp);
}
}
}
}
#endif

View File

@@ -24,6 +24,33 @@
#include "vxWorks.h" /* obtain the version of vxWorks */
#include "epicsAssert.h"
#include "vxLib.h"
#include "intLib.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#ifndef EPICS_ATOMIC_LOCK
#define EPICS_ATOMIC_LOCK
typedef struct EpicsAtomicLockKey { int m_key; } EpicsAtomicLockKey;
EPICS_ATOMIC_INLINE void epicsAtomicLock ( EpicsAtomicLockKey * pKey )
{
pKey->m_key = intLock ();
}
EPICS_ATOMIC_INLINE void epicsAtomicUnlock ( EpicsAtomicLockKey * pKey )
{
intUnlock ( pKey->m_key );
}
#endif
#ifdef __cplusplus
} /* end of extern "C" */
#endif /* __cplusplus */
/*
* With vxWorks 6.6 and later we need to use vxAtomicLib
* to implement this functionality correctly on SMP systems
@@ -123,26 +150,6 @@ EPICS_ATOMIC_INLINE size_t epicsAtomicSubSizeT ( size_t * pTarget, size_t delta
}
#endif
#ifndef EPICS_ATOMIC_CAS_SIZET
#define EPICS_ATOMIC_CAS_SIZET
EPICS_ATOMIC_INLINE size_t epicsAtomicCmpAndSwapSizeT ( size_t * pTarget,
size_t oldVal, size_t newVal )
{
atomic_t * const pTarg = ( atomic_t * ) ( pTarget );
return ( size_t ) vxCas ( pTarg, (atomic_t) oldVal, (atomic_t) newVal );
}
#endif
#ifndef EPICS_ATOMIC_CAS_PTRT
#define EPICS_ATOMIC_CAS_PTRT
EPICS_ATOMIC_INLINE EpicsAtomicPtrT epicsAtomicCmpAndSwapPtrT ( EpicsAtomicPtrT * pTarget,
EpicsAtomicPtrT oldVal, EpicsAtomicPtrT newVal )
{
atomic_t * const pTarg = ( atomic_t * ) ( pTarget );
return (EpicsAtomicPtrT) vxCas ( pTarg, (atomic_t) oldVal, (atomic_t) newVal );
}
#endif
#else /* ULONG_MAX == UINT_MAX */
/*
@@ -190,15 +197,6 @@ EPICS_ATOMIC_INLINE int epicsAtomicAddIntT ( int * pTarget, int delta )
}
#endif
#ifndef EPICS_ATOMIC_CAS_INTT
#define EPICS_ATOMIC_CAS_INTT
EPICS_ATOMIC_INLINE int epicsAtomicCmpAndSwapIntT ( int * pTarget,
int oldVal, int newVal )
{
atomic_t * const pTarg = ( atomic_t * ) ( pTarget );
return ( int ) vxCas ( pTarg, (atomic_t) oldVal, (atomic_t) newVal );
}
#endif
#ifdef __cplusplus
} /* end of extern "C" */
@@ -215,22 +213,6 @@ EPICS_ATOMIC_INLINE int epicsAtomicCmpAndSwapIntT ( int * pTarget,
extern "C" {
#endif /* __cplusplus */
#ifndef EPICS_ATOMIC_LOCK
#define EPICS_ATOMIC_LOCK
typedef struct EpicsAtomicLockKey { int m_key; } EpicsAtomicLockKey;
EPICS_ATOMIC_INLINE void epicsAtomicLock ( EpicsAtomicLockKey * pKey )
{
pKey->m_key = intLock ();
}
EPICS_ATOMIC_INLINE void epicsAtomicUnlock ( EpicsAtomicLockKey * pKey )
{
intUnlock ( pKey->m_key );
}
#endif
#ifndef EPICS_ATOMIC_READ_MEMORY_BARRIER
#define EPICS_ATOMIC_READ_MEMORY_BARRIER
/*