diff --git a/configure/os/CONFIG.Common.vxWorks-mpc8540 b/configure/os/CONFIG.Common.vxWorks-mpc8540
index 057fd4c67..2b684417b 100644
--- a/configure/os/CONFIG.Common.vxWorks-mpc8540
+++ b/configure/os/CONFIG.Common.vxWorks-mpc8540
@@ -1,9 +1,10 @@
+# CONFIG.Common.vxWorks-mpc8540
+#
# $Revision-Id$
+# This file is maintained by the build community.
#
-# Definitions for vxWorks-mpc8540 targets: MPC8540 CPU with >32MB RAM.
-# Site-specific overrides go in CONFIG_SITE.Common.vxWorks-mpc8540
-#
-# This file is maintained by the EPICS build community.
+# Definitions for vxWorks-mpc8540 target archs
+# Sites may override these definitions in CONFIG_SITE.Common.vxWorks-mpc8540
#-------------------------------------------------------
# Include definitions common to all vxWorks target archs
diff --git a/configure/os/CONFIG.Common.vxWorks-mpc8548 b/configure/os/CONFIG.Common.vxWorks-mpc8548
new file mode 100644
index 000000000..1dd6a1c3b
--- /dev/null
+++ b/configure/os/CONFIG.Common.vxWorks-mpc8548
@@ -0,0 +1,26 @@
+# CONFIG.Common.vxWorks-mpc8548
+#
+# $Revision-Id$
+# This file is maintained by the build community.
+#
+# Definitions for vxWorks-mpc8548 target archs
+# Sites may override these definitions in CONFIG_SITE.Common.vxWorks-mpc8548
+#-------------------------------------------------------
+
+# Include definitions common to all vxWorks target archs
+include $(CONFIG)/os/CONFIG.Common.vxWorksCommon
+
+# Vx GNU cross compiler suffix
+CMPLR_SUFFIX = ppc
+
+ARCH_CLASS = ppc
+
+# Architecture specific build flags
+ARCH_DEP_CPPFLAGS = -DCPU=PPC32
+ARCH_DEP_CFLAGS = -DCPU_VARIANT=_ppc85XX_e500v2
+ARCH_DEP_CFLAGS += -mlongcall
+
+# This flag isn't present in early vxWorks 6.x versions
+#ARCH_DEP_CFLAGS += -te500v2
+
+GNU_TARGET = powerpc-wrs-vxworks
diff --git a/configure/os/CONFIG.Common.vxWorks-mpc8548-debug b/configure/os/CONFIG.Common.vxWorks-mpc8548-debug
new file mode 100644
index 000000000..d258a16e8
--- /dev/null
+++ b/configure/os/CONFIG.Common.vxWorks-mpc8548-debug
@@ -0,0 +1,14 @@
+# CONFIG.Common.vxWorks-mpc8548-debug
+#
+# $Revision-Id$
+# This file is maintained by the build community.
+#
+# Definitions for vxWorks-mpc8548-debug targets.
+# Sites may override these definitions in CONFIG_SITE.Common.vxWorks-mpc8548-debug
+#-------------------------------------------------------
+
+# Include definitions common to all vxWorks archs
+include $(CONFIG)/os/CONFIG.Common.vxWorks-mpc8548
+
+CROSS_OPT = NO
+
diff --git a/configure/os/CONFIG_SITE.Common.vxWorks-mpc8548 b/configure/os/CONFIG_SITE.Common.vxWorks-mpc8548
new file mode 100644
index 000000000..da8671436
--- /dev/null
+++ b/configure/os/CONFIG_SITE.Common.vxWorks-mpc8548
@@ -0,0 +1,6 @@
+# $Revision-Id$
+#
+# Site Specific definitions for the vxWorks-mpc8548 target
+#
+# Only the local epics system manager should modify this file
+#-------------------------------------------------------
diff --git a/documentation/KnownProblems.html b/documentation/KnownProblems.html
index 9a15e68c8..1f730dc1d 100644
--- a/documentation/KnownProblems.html
+++ b/documentation/KnownProblems.html
@@ -4,11 +4,21 @@
- Known Problems in R3.14.12
+ Known Problems in R3.15.0
-EPICS Base R3.14.12: Known Problems
+EPICS Base R3.15.0: Known Problems
+
+Any patch files linked below should be applied at the root of the
+base-3.15.0 tree. Download them, then use the GNU Patch program as
+follows:
+
+% cd /path/to/base-3.15.0
+% patch -p0 < /path/to/file.patch
+
+The following significant problems have been reported with this
+version of EPICS Base:
diff --git a/src/ca/tcpiiu.cpp b/src/ca/tcpiiu.cpp
index a38ee7ff3..9cf9f6f4d 100644
--- a/src/ca/tcpiiu.cpp
+++ b/src/ca/tcpiiu.cpp
@@ -1866,10 +1866,14 @@ void tcpiiu::unlinkAllChannels (
guard.assertIdenticalMutex ( this->mutex );
while ( nciu * pChan = this->createReqPend.get () ) {
+ pChan->channelNode::listMember =
+ channelNode::cs_none;
pChan->serviceShutdownNotify ( cbGuard, guard );
}
while ( nciu * pChan = this->createRespPend.get () ) {
+ pChan->channelNode::listMember =
+ channelNode::cs_none;
// we dont yet know the server's id so we cant
// send a channel delete request and will instead
// trust that the server can do the proper cleanup
@@ -1878,12 +1882,16 @@ void tcpiiu::unlinkAllChannels (
}
while ( nciu * pChan = this->v42ConnCallbackPend.get () ) {
+ pChan->channelNode::listMember =
+ channelNode::cs_none;
this->clearChannelRequest ( guard,
pChan->getSID(guard), pChan->getCID(guard) );
pChan->serviceShutdownNotify ( cbGuard, guard );
}
while ( nciu * pChan = this->subscripReqPend.get () ) {
+ pChan->channelNode::listMember =
+ channelNode::cs_none;
pChan->disconnectAllIO ( cbGuard, guard );
this->clearChannelRequest ( guard,
pChan->getSID(guard), pChan->getCID(guard) );
@@ -1891,6 +1899,8 @@ void tcpiiu::unlinkAllChannels (
}
while ( nciu * pChan = this->connectedList.get () ) {
+ pChan->channelNode::listMember =
+ channelNode::cs_none;
pChan->disconnectAllIO ( cbGuard, guard );
this->clearChannelRequest ( guard,
pChan->getSID(guard), pChan->getCID(guard) );
@@ -1898,6 +1908,8 @@ void tcpiiu::unlinkAllChannels (
}
while ( nciu * pChan = this->unrespCircuit.get () ) {
+ pChan->channelNode::listMember =
+ channelNode::cs_none;
pChan->disconnectAllIO ( cbGuard, guard );
// if we know that the circuit is unresponsive
// then we dont send a channel delete request and
@@ -1907,6 +1919,8 @@ void tcpiiu::unlinkAllChannels (
}
while ( nciu * pChan = this->subscripUpdateReqPend.get () ) {
+ pChan->channelNode::listMember =
+ channelNode::cs_none;
pChan->disconnectAllIO ( cbGuard, guard );
this->clearChannelRequest ( guard,
pChan->getSID(guard), pChan->getCID(guard) );
diff --git a/src/libCom/error/errlog.c b/src/libCom/error/errlog.c
index 36399a119..322eb9c4f 100644
--- a/src/libCom/error/errlog.c
+++ b/src/libCom/error/errlog.c
@@ -534,8 +534,10 @@ static msgNode *msgbufGetNode(void)
char *plimit = pbuffer + pvtData.buffersize;
pnextFree = plast->message + adjustToWorstCaseAlignment(plast->length);
- if (pfirst <= plast &&
- pnextFree + pvtData.msgNeeded > plimit) {
+ if (pfirst > plast) {
+ plimit = (char *)pfirst;
+ }
+ else if (pnextFree + pvtData.msgNeeded > plimit) {
pnextFree = pbuffer; /* Hit end, wrap to start */
plimit = (char *)pfirst;
}
diff --git a/src/libCom/osi/epicsThread.cpp b/src/libCom/osi/epicsThread.cpp
index 55f9e5872..ed016f47e 100644
--- a/src/libCom/osi/epicsThread.cpp
+++ b/src/libCom/osi/epicsThread.cpp
@@ -169,6 +169,8 @@ bool epicsThread::exitWait ( const double delay ) throw ()
"epicsThread::exitWait()\n" );
epicsThreadSleep ( epicsMin ( delay, 5.0 ) );
}
+ // the event mechanism is used for other purposes
+ this->event.signal ();
return this->terminated;
}
diff --git a/src/libCom/osi/os/WIN32/osdThread.c b/src/libCom/osi/os/WIN32/osdThread.c
index 8c3b54792..b7d63a787 100644
--- a/src/libCom/osi/os/WIN32/osdThread.c
+++ b/src/libCom/osi/os/WIN32/osdThread.c
@@ -124,7 +124,7 @@ BOOL WINAPI DllMain (
#if _WIN32_WINNT >= 0x0501
/*
* Only in WXP
- * Thats a shame becaus ethis is probably much faster
+ * Thats a shame because this is probably much faster
*/
success = GetModuleHandleEx (
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
@@ -268,7 +268,8 @@ static void threadCleanupWIN32 ( void )
return;
}
- while ( ( pParm = ( win32ThreadParam * ) ellFirst ( & pGbl->threadList ) ) ) {
+ while ( ( pParm = ( win32ThreadParam * )
+ ellFirst ( & pGbl->threadList ) ) ) {
epicsParmCleanupWIN32 ( pParm );
}
@@ -446,7 +447,8 @@ epicsShareFunc epicsThreadBooleanStatus epicsShareAPI epicsThreadHighestPriority
/*
* epicsThreadGetStackSize ()
*/
-epicsShareFunc unsigned int epicsShareAPI epicsThreadGetStackSize ( epicsThreadStackSizeClass stackSizeClass )
+epicsShareFunc unsigned int epicsShareAPI
+ epicsThreadGetStackSize ( epicsThreadStackSizeClass stackSizeClass )
{
static const unsigned stackSizeTable[epicsThreadStackBig+1] = {4000, 6000, 11000};
@@ -628,18 +630,21 @@ epicsShareFunc epicsThreadId epicsShareAPI epicsThreadCreate (const char *pName,
free ( pParmWIN32 );
return NULL;
}
+
+ EnterCriticalSection ( & pGbl->mutex );
+ ellAdd ( & pGbl->threadList, & pParmWIN32->node );
+ LeaveCriticalSection ( & pGbl->mutex );
wstat = ResumeThread ( pParmWIN32->handle );
if (wstat==0xFFFFFFFF) {
+ EnterCriticalSection ( & pGbl->mutex );
+ ellDelete ( & pGbl->threadList, & pParmWIN32->node );
+ LeaveCriticalSection ( & pGbl->mutex );
CloseHandle ( pParmWIN32->handle );
free ( pParmWIN32 );
return NULL;
}
- EnterCriticalSection ( & pGbl->mutex );
- ellAdd ( & pGbl->threadList, & pParmWIN32->node );
- LeaveCriticalSection ( & pGbl->mutex );
-
return ( epicsThreadId ) pParmWIN32;
}
@@ -955,10 +960,17 @@ static void epicsThreadShowPrivate ( epicsThreadId id, unsigned level )
(void *) pParm, idForFormat, pParm->epicsPriority,
epics_GetThreadPriorityAsString ( pParm->handle ),
epicsThreadIsSuspended ( id ) ? "suspend" : "ok" );
+ if ( level ) {
+ fprintf (epicsGetStdout(), " %-8p %-8p ",
+ (void *) pParm->handle, (void *) pParm->parm );
+ }
}
else {
fprintf (epicsGetStdout(),
"NAME EPICS-ID WIN32-ID EPICS-PRI WIN32-PRI STATE " );
+ if ( level ) {
+ fprintf (epicsGetStdout(), " HANDLE FUNCTION PARAMETER" );
+ }
}
fprintf (epicsGetStdout(),"\n" );
}
diff --git a/src/libCom/osi/os/WIN32/osdTime.cpp b/src/libCom/osi/os/WIN32/osdTime.cpp
index 5efdb2cbc..035c7308c 100644
--- a/src/libCom/osi/os/WIN32/osdTime.cpp
+++ b/src/libCom/osi/os/WIN32/osdTime.cpp
@@ -409,8 +409,8 @@ epicsTimerNotify::expireStatus currentTime::expire ( const epicsTime & )
EnterCriticalSection ( & this->mutex );
- LONGLONG perfCounterDiff = curPerfCounter.QuadPart - this->lastPerfCounterPLL;
- if ( curPerfCounter.QuadPart >= this->lastPerfCounter ) {
+ LONGLONG perfCounterDiff;
+ if ( curPerfCounter.QuadPart >= this->lastPerfCounterPLL ) {
perfCounterDiff = curPerfCounter.QuadPart - this->lastPerfCounterPLL;
}
else {
diff --git a/src/libCom/test/epicsErrlogTest.c b/src/libCom/test/epicsErrlogTest.c
index c96013313..08389e438 100644
--- a/src/libCom/test/epicsErrlogTest.c
+++ b/src/libCom/test/epicsErrlogTest.c
@@ -260,29 +260,31 @@ MAIN(epicsErrlogTest)
for (i = 0; i < N; i++) {
errlogPrintfNoConsole(msg);
}
+ epicsThreadSleep(0.1); /* should really be a second Event */
testOk1(pvt.count == 0);
- epicsThreadSleep(0.1); /* should really be a second Event */
-
- pvt.jam = -2; /* Block before #th message */
+ /* Extract the first 2 messages, 2*(sizeof(msgNode) + 128) bytes */
+ pvt.jam = -2;
epicsEventSignal(pvt.jammer);
epicsThreadSleep(0.1);
- testDiag("Drain %u messages", pvt.count);
+ testDiag("Drained %u messages", pvt.count);
testOk1(pvt.count == 2);
- testDiag("Add two more (%d total)", (int) N+2);
- errlogPrintfNoConsole(msg);
+ /* The buffer has space for 1 more message: sizeof(msgNode) + 256 bytes */
+ errlogPrintfNoConsole(msg); /* Use up that space */
+
+ testDiag("Overflow the buffer");
errlogPrintfNoConsole(msg);
testOk1(pvt.count == 2);
- epicsEventSignal(pvt.jammer);
+ epicsEventSignal(pvt.jammer); /* Empty */
errlogFlush();
- testDiag("Logged %u messages", pvt.count);
- testOk1(pvt.count == N+2);
+ testDiag("Logged %u messages", pvt.count);
+ testOk1(pvt.count == N+1);
/* Clean up */
errlogRemoveListener(&logClient);