update to 3.14.12.2
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
# CONFIG_SITE.Common.ios-arm
|
||||
#
|
||||
# Revision-Id: anj@aps.anl.gov-20111202164243-clxybuefflizbyvr
|
||||
# This file is maintained by the build community.
|
||||
#
|
||||
# Site-specific settings for ios-arm target builds
|
||||
#-------------------------------------------------------
|
||||
|
||||
# Which ARM instruction set(s) to generate code for:
|
||||
# Most iOS devices can run programs compiled for both the
|
||||
# ARMv6 and ARMv7 instruction sets. ARMv7 code is usually
|
||||
# more efficient, but the older devices listed below can only
|
||||
# use the ARMv6 instruction set. Including both architectures
|
||||
# generates a Universal binary, which is larger and takes
|
||||
# longer to compile but runs efficiently on all devices.
|
||||
#
|
||||
# ARMv6-only devices: iPhone 1 or 3G, iPod Touch Gen 1 or 2
|
||||
#
|
||||
ARCH_CLASS = armv7
|
||||
#ARCH_CLASS = armv6 armv7
|
||||
#ARCH_CLASS = armv6
|
||||
|
||||
|
||||
# Uncomment these two definitions to use g++ instead of clang++
|
||||
# which may be needed in some circumstances:
|
||||
#
|
||||
#CCC = $(GNU_BIN)/c++
|
||||
#GNU_LDLIBS_YES = -lgcc
|
||||
@@ -1,6 +1,6 @@
|
||||
# CONFIG_SITE.Common.linux-x86
|
||||
#
|
||||
# Revision-Id: anj@aps.anl.gov-20101122164049-brpnm0uwvpptmw80
|
||||
# Revision-Id: anj@aps.anl.gov-20111207195604-heciohzgvyhhpgrb
|
||||
#
|
||||
# Site Specific definitions for linux-x86 target
|
||||
# Only the local epics system manager should modify this file
|
||||
@@ -33,4 +33,8 @@ COMMANDLINE_LIBRARY = READLINE
|
||||
#COMMANDLINE_LIBRARY = READLINE_CURSES
|
||||
|
||||
|
||||
OP_SYS_CFLAGS += -g
|
||||
# It makes sense to include debugging symbols even in optimized builds
|
||||
# in case you want to attach gdb to the process or examine a core-dump.
|
||||
# This does cost disk space, but not memory as debug symbols are not
|
||||
# loaded into RAM when the binary is loaded.
|
||||
OPT_CFLAGS_YES += -g
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# CONFIG_SITE.Common.linux-x86_64
|
||||
#
|
||||
# Revision-Id: anj@aps.anl.gov-20101122164049-brpnm0uwvpptmw80
|
||||
# Revision-Id: anj@aps.anl.gov-20111207195604-heciohzgvyhhpgrb
|
||||
#
|
||||
# Site Specific definitions for linux-x86_64 target
|
||||
# Only the local epics system manager should modify this file
|
||||
@@ -33,4 +33,8 @@ COMMANDLINE_LIBRARY = READLINE
|
||||
#COMMANDLINE_LIBRARY = READLINE_CURSES
|
||||
|
||||
|
||||
OP_SYS_CFLAGS += -g
|
||||
# It makes sense to include debugging symbols even in optimized builds
|
||||
# in case you want to attach gdb to the process or examine a core-dump.
|
||||
# This does cost disk space, but not memory as debug symbols are not
|
||||
# loaded into RAM when the binary is loaded.
|
||||
OPT_CFLAGS_YES += -g
|
||||
|
||||
@@ -12,15 +12,14 @@ include $(TOP)/configure/CONFIG
|
||||
|
||||
INC += epicsRtemsInitHooks.h
|
||||
|
||||
SRCS += rtems_init.c
|
||||
SRCS += rtems_config.c
|
||||
SRCS += rtems_netconfig.c
|
||||
SRCS += rtems_util.c
|
||||
SRCS += setBootConfigFromNVRAM.c
|
||||
SRCS += epicsRtemsInitHookPre.c
|
||||
SRCS += epicsRtemsInitHookPost.c
|
||||
rtemsCom_SRCS += rtems_init.c
|
||||
rtemsCom_SRCS += rtems_config.c
|
||||
rtemsCom_SRCS += rtems_netconfig.c
|
||||
rtemsCom_SRCS += rtems_util.c
|
||||
rtemsCom_SRCS += setBootConfigFromNVRAM.c
|
||||
rtemsCom_SRCS += epicsRtemsInitHookPre.c
|
||||
rtemsCom_SRCS += epicsRtemsInitHookPost.c
|
||||
|
||||
LIBRARY_RTEMS = rtemsCom
|
||||
LIBRARY_SRCS = $(SRCS) $(BUILD_ARCHS)
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
|
||||
+2
-1
@@ -22,7 +22,8 @@ DBD += bptTypeKdegF.dbd
|
||||
|
||||
PROD_LIBS = Com
|
||||
PROD_HOST += makeBpt
|
||||
makeBpt_SRCS=makeBpt
|
||||
|
||||
makeBpt_SRCS = makeBpt
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
|
||||
|
||||
+3
-3
@@ -52,7 +52,7 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" height="31"
|
||||
width="88"></a></p>
|
||||
|
||||
<p><small><span style="font-size: smaller; font-weight:lighter;">Modified on
|
||||
Date: Wed 2010-11-24 13:31:47 -0500</span></small></p>
|
||||
Date: Tue 2011-07-26 10:40:37 -0600</span></small></p>
|
||||
<hr>
|
||||
|
||||
<h2>Table of Contents</h2>
|
||||
@@ -246,7 +246,7 @@ Date: Wed 2010-11-24 13:31:47 -0500</span></small></p>
|
||||
|
||||
<h3>Why Reconfigure Channel Access</h3>
|
||||
|
||||
<p>Typically reasons to reconfigure EPICS Channel Access:</p>
|
||||
<p>Typical reasons to reconfigure EPICS Channel Access:</p>
|
||||
<ul>
|
||||
<li>Two independent control systems must share a network without fear of
|
||||
interaction</li>
|
||||
@@ -4359,7 +4359,7 @@ that use ca_context_destroy).</p>
|
||||
<p><a href="#ca_context_destroy">ca_context_destroy</a>()</p>
|
||||
|
||||
<h3><code><a name="ca_dump_dbr">ca_dump_dbr()</a></code></h3>
|
||||
<pre>void ca_dump_dbr (chtype TYPE, unsigned COUNT, const void * PDBR);</pre>
|
||||
<code><pre>void ca_dump_dbr (chtype TYPE, unsigned COUNT, const void * PDBR);</pre></code>
|
||||
|
||||
<h4>Description</h4>
|
||||
|
||||
|
||||
+1
-1
@@ -92,7 +92,7 @@ PROD_LIBS = ca Com
|
||||
PROD_SYS_LIBS_WIN32 = ws2_32 advapi32 user32
|
||||
|
||||
PROD_HOST += caRepeater catime acctst caConnTest casw caEventRate
|
||||
OBJS_IOC_vxWorks += catime acctst caConnTest casw caEventRate
|
||||
OBJS_IOC += catime acctst caConnTest casw caEventRate acctstRegister
|
||||
caRepeater_SRCS = caRepeater.cpp
|
||||
catime_SRCS = catimeMain.c catime.c
|
||||
acctst_SRCS = acctstMain.c acctst.c
|
||||
|
||||
+230
-27
@@ -10,6 +10,10 @@
|
||||
|
||||
/*
|
||||
* CA regression test
|
||||
* Authors:
|
||||
* Jeff Hill
|
||||
* Murali Shankar - initial versions of verifyMultithreadSubscr
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -26,6 +30,8 @@
|
||||
*/
|
||||
#define epicsAssertAuthor "Jeff Hill johill@lanl.gov"
|
||||
#include "epicsAssert.h"
|
||||
#include "epicsMutex.h"
|
||||
#include "epicsEvent.h"
|
||||
#include "epicsTime.h"
|
||||
#include "dbDefs.h"
|
||||
#include "envDefs.h"
|
||||
@@ -2719,6 +2725,186 @@ void fdRegCB ( void * parg, int fd, int opened )
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
char m_chanName[100u];
|
||||
struct ca_client_context * m_pCtx;
|
||||
chid m_chan;
|
||||
epicsMutexId m_mutex;
|
||||
epicsEventId m_testCompleteEvent;
|
||||
epicsEventId m_threadExitEvent;
|
||||
size_t m_nUpdatesReceived;
|
||||
size_t m_nUpdatesRequired;
|
||||
int m_testInitiated;
|
||||
int m_testComplete;
|
||||
unsigned m_interestLevel;
|
||||
} MultiThreadSubscrTest;
|
||||
|
||||
static void testMultithreadSubscrSubscrCallback
|
||||
( struct event_handler_args eha )
|
||||
{
|
||||
const epicsEventId firstUpdateEvent = ( epicsEventId ) eha.usr;
|
||||
epicsEventSignal ( firstUpdateEvent );
|
||||
}
|
||||
|
||||
static void testMultithreadSubscrCreateSubscr ( void * pParm )
|
||||
{
|
||||
static unsigned nElem = 0;
|
||||
int testComplete = FALSE;
|
||||
evid id;
|
||||
epicsEventId firstUpdateEvent;
|
||||
epicsEventWaitStatus eventWaitStatus;
|
||||
MultiThreadSubscrTest * const pMultiThreadSubscrTest =
|
||||
( MultiThreadSubscrTest * ) pParm;
|
||||
|
||||
/* this is required for the ca_flush below to work correctly */
|
||||
int status = ca_attach_context ( pMultiThreadSubscrTest->m_pCtx );
|
||||
verify ( status == ECA_NORMAL );
|
||||
firstUpdateEvent = epicsEventMustCreate ( epicsEventEmpty );
|
||||
verify ( firstUpdateEvent );
|
||||
status = ca_create_subscription (
|
||||
DBR_TIME_LONG,
|
||||
nElem,
|
||||
pMultiThreadSubscrTest->m_chan,
|
||||
DBE_VALUE,
|
||||
testMultithreadSubscrSubscrCallback,
|
||||
firstUpdateEvent,
|
||||
& id );
|
||||
verify ( status == ECA_NORMAL );
|
||||
status = ca_flush_io ();
|
||||
verify ( status == ECA_NORMAL );
|
||||
/* wait for first update */
|
||||
eventWaitStatus = epicsEventWaitWithTimeout (
|
||||
firstUpdateEvent, 60.0 * 10 );
|
||||
verify ( eventWaitStatus == epicsEventWaitOK );
|
||||
epicsEventDestroy ( firstUpdateEvent );
|
||||
status = ca_clear_subscription ( id );
|
||||
verify ( status == ECA_NORMAL );
|
||||
epicsMutexMustLock ( pMultiThreadSubscrTest->m_mutex );
|
||||
pMultiThreadSubscrTest->m_nUpdatesReceived++;
|
||||
testComplete = ( pMultiThreadSubscrTest->m_nUpdatesReceived ==
|
||||
pMultiThreadSubscrTest->m_nUpdatesRequired );
|
||||
pMultiThreadSubscrTest->m_testComplete = testComplete;
|
||||
epicsMutexUnlock ( pMultiThreadSubscrTest->m_mutex );
|
||||
if ( testComplete ) {
|
||||
epicsEventSignal ( pMultiThreadSubscrTest->m_testCompleteEvent );
|
||||
}
|
||||
}
|
||||
|
||||
void testMultithreadSubscrConnHandler ( struct connection_handler_args args )
|
||||
{
|
||||
MultiThreadSubscrTest * const pMultiThreadSubscrTest =
|
||||
( MultiThreadSubscrTest * ) ca_puser ( args.chid );
|
||||
epicsMutexMustLock ( pMultiThreadSubscrTest->m_mutex );
|
||||
if ( !pMultiThreadSubscrTest->m_testInitiated &&
|
||||
args.op == CA_OP_CONN_UP ) {
|
||||
int i;
|
||||
pMultiThreadSubscrTest->m_testInitiated = TRUE;
|
||||
for ( i = 0; i < pMultiThreadSubscrTest->m_nUpdatesRequired; i++ ) {
|
||||
char threadname[64];
|
||||
epicsThreadId threadId;
|
||||
sprintf(threadname, "testSubscr%06u", i);
|
||||
threadId = epicsThreadCreate ( threadname,
|
||||
epicsThreadPriorityMedium,
|
||||
epicsThreadGetStackSize(epicsThreadStackSmall),
|
||||
testMultithreadSubscrCreateSubscr,
|
||||
pMultiThreadSubscrTest );
|
||||
verify ( threadId );
|
||||
}
|
||||
}
|
||||
epicsMutexUnlock ( pMultiThreadSubscrTest->m_mutex );
|
||||
}
|
||||
|
||||
void testMultithreadSubscr ( void * pParm )
|
||||
{
|
||||
MultiThreadSubscrTest * const pMultiThreadSubscrTest =
|
||||
( MultiThreadSubscrTest * ) pParm;
|
||||
int status;
|
||||
unsigned i;
|
||||
|
||||
status = ca_context_create ( ca_enable_preemptive_callback );
|
||||
verify ( status == ECA_NORMAL );
|
||||
pMultiThreadSubscrTest->m_pCtx = ca_current_context ();
|
||||
verify ( pMultiThreadSubscrTest->m_pCtx );
|
||||
status = ca_create_channel (
|
||||
pMultiThreadSubscrTest->m_chanName,
|
||||
testMultithreadSubscrConnHandler,
|
||||
pMultiThreadSubscrTest,
|
||||
CA_PRIORITY_MIN,
|
||||
& pMultiThreadSubscrTest->m_chan );
|
||||
verify ( status == ECA_NORMAL );
|
||||
|
||||
showProgressBegin ( "verifyMultithreadSubscr",
|
||||
pMultiThreadSubscrTest->m_interestLevel );
|
||||
i = 0;
|
||||
while ( TRUE ) {
|
||||
int success = FALSE;
|
||||
epicsEventWaitStatus eventWaitStatus;
|
||||
epicsMutexMustLock ( pMultiThreadSubscrTest->m_mutex );
|
||||
success = pMultiThreadSubscrTest->m_testComplete;
|
||||
epicsMutexUnlock ( pMultiThreadSubscrTest->m_mutex );
|
||||
if ( success ) {
|
||||
break;
|
||||
}
|
||||
eventWaitStatus = epicsEventWaitWithTimeout (
|
||||
pMultiThreadSubscrTest->m_testCompleteEvent, 0.1 );
|
||||
verify ( eventWaitStatus == epicsEventWaitOK ||
|
||||
eventWaitStatus == epicsEventWaitTimeout );
|
||||
if ( i++ % 100 == 0u )
|
||||
showProgress ( pMultiThreadSubscrTest->m_interestLevel );
|
||||
verify ( i < 1000 );
|
||||
}
|
||||
showProgressEnd ( pMultiThreadSubscrTest->m_interestLevel );
|
||||
|
||||
status = ca_clear_channel ( pMultiThreadSubscrTest->m_chan );
|
||||
verify ( status == ECA_NORMAL );
|
||||
ca_context_destroy ();
|
||||
epicsEventSignal ( pMultiThreadSubscrTest->m_threadExitEvent );
|
||||
}
|
||||
|
||||
/*
|
||||
* test installation of subscriptions similar to usage paterns
|
||||
* employed by modern versions of the sequencer
|
||||
*/
|
||||
void verifyMultithreadSubscr ( const char * pName, unsigned interestLevel )
|
||||
{
|
||||
static unsigned nSubscr = 3000;
|
||||
epicsThreadId threadId;
|
||||
MultiThreadSubscrTest * const pMultiThreadSubscrTest =
|
||||
(MultiThreadSubscrTest*) calloc ( 1,
|
||||
sizeof ( MultiThreadSubscrTest ) );
|
||||
verify ( pMultiThreadSubscrTest);
|
||||
pMultiThreadSubscrTest->m_mutex = epicsMutexMustCreate ();
|
||||
verify ( pMultiThreadSubscrTest->m_mutex );
|
||||
pMultiThreadSubscrTest->m_testCompleteEvent =
|
||||
epicsEventMustCreate ( epicsEventEmpty );
|
||||
verify ( pMultiThreadSubscrTest->m_testCompleteEvent );
|
||||
pMultiThreadSubscrTest->m_threadExitEvent =
|
||||
epicsEventMustCreate ( epicsEventEmpty );
|
||||
verify ( pMultiThreadSubscrTest->m_threadExitEvent );
|
||||
strncpy ( pMultiThreadSubscrTest->m_chanName, pName,
|
||||
sizeof ( pMultiThreadSubscrTest->m_chanName ) );
|
||||
pMultiThreadSubscrTest->m_chanName
|
||||
[ sizeof ( pMultiThreadSubscrTest->m_chanName ) - 1u ] = '\0';
|
||||
pMultiThreadSubscrTest->m_nUpdatesRequired = nSubscr;
|
||||
pMultiThreadSubscrTest->m_interestLevel = interestLevel;
|
||||
threadId = epicsThreadCreate (
|
||||
"testMultithreadSubscr",
|
||||
epicsThreadPriorityMedium,
|
||||
epicsThreadGetStackSize(epicsThreadStackSmall),
|
||||
testMultithreadSubscr, pMultiThreadSubscrTest );
|
||||
verify ( threadId );
|
||||
{
|
||||
epicsEventWaitStatus eventWaitStatus;
|
||||
eventWaitStatus = epicsEventWaitWithTimeout (
|
||||
pMultiThreadSubscrTest->m_threadExitEvent, 1000.0 );
|
||||
verify ( eventWaitStatus == epicsEventWaitOK );
|
||||
}
|
||||
epicsEventDestroy ( pMultiThreadSubscrTest->m_testCompleteEvent );
|
||||
epicsEventDestroy ( pMultiThreadSubscrTest->m_threadExitEvent );
|
||||
epicsMutexDestroy ( pMultiThreadSubscrTest->m_mutex );
|
||||
free ( pMultiThreadSubscrTest );
|
||||
}
|
||||
|
||||
void fdManagerVerify ( const char * pName, unsigned interestLevel )
|
||||
{
|
||||
int status;
|
||||
@@ -2965,17 +3151,22 @@ void verifyContextRundownFlush ( const char * pName, unsigned interestLevel )
|
||||
SEVCHK ( status, "context create failed" );
|
||||
|
||||
status = ca_create_channel ( pName, 0, 0, 0, & chan );
|
||||
SEVCHK ( status, NULL );
|
||||
|
||||
status = ca_pend_io( timeoutToPendIO );
|
||||
SEVCHK ( status, "channel connect failed" );
|
||||
|
||||
status = ca_put ( DBR_DOUBLE, chan, & stim );
|
||||
SEVCHK ( status, "channel put failed" );
|
||||
|
||||
status = ca_clear_channel ( chan );
|
||||
SEVCHK ( status, NULL );
|
||||
|
||||
/*
|
||||
* currently in-memory channels cant be used with this test
|
||||
* !!!! FIX ME, FIX ME, FIX ME, FIX ME !!!!
|
||||
*/
|
||||
if ( status != ECA_UNAVAILINSERV ) {
|
||||
SEVCHK ( status, NULL );
|
||||
|
||||
status = ca_pend_io( timeoutToPendIO );
|
||||
SEVCHK ( status, "channel connect failed" );
|
||||
|
||||
status = ca_put ( DBR_DOUBLE, chan, & stim );
|
||||
SEVCHK ( status, "channel put failed" );
|
||||
|
||||
status = ca_clear_channel ( chan );
|
||||
SEVCHK ( status, NULL );
|
||||
}
|
||||
ca_context_destroy ();
|
||||
}
|
||||
|
||||
@@ -2985,24 +3176,28 @@ void verifyContextRundownFlush ( const char * pName, unsigned interestLevel )
|
||||
dbr_double_t resp;
|
||||
status = ca_context_create ( ca_disable_preemptive_callback );
|
||||
SEVCHK ( status, "context create failed" );
|
||||
|
||||
|
||||
status = ca_create_channel ( pName, 0, 0, 0, & chan );
|
||||
SEVCHK ( status, NULL );
|
||||
|
||||
status = ca_pend_io( timeoutToPendIO );
|
||||
SEVCHK ( status, "channel connect failed" );
|
||||
|
||||
status = ca_get ( DBR_DOUBLE, chan, & resp );
|
||||
SEVCHK ( status, "channel get failed" );
|
||||
|
||||
status = ca_pend_io ( timeoutToPendIO );
|
||||
SEVCHK ( status, "get, pend io failed" );
|
||||
|
||||
verify ( stim == resp );
|
||||
|
||||
status = ca_clear_channel ( chan );
|
||||
SEVCHK ( status, NULL );
|
||||
|
||||
/*
|
||||
* currently in-memory channels cant be used with this test
|
||||
* !!!! FIX ME, FIX ME, FIX ME, FIX ME !!!!
|
||||
*/
|
||||
if ( status != ECA_UNAVAILINSERV ) {
|
||||
status = ca_pend_io( timeoutToPendIO );
|
||||
SEVCHK ( status, "channel connect failed" );
|
||||
|
||||
status = ca_get ( DBR_DOUBLE, chan, & resp );
|
||||
SEVCHK ( status, "channel get failed" );
|
||||
|
||||
status = ca_pend_io ( timeoutToPendIO );
|
||||
SEVCHK ( status, "get, pend io failed" );
|
||||
|
||||
verify ( stim == resp );
|
||||
|
||||
status = ca_clear_channel ( chan );
|
||||
SEVCHK ( status, NULL );
|
||||
}
|
||||
ca_context_destroy ();
|
||||
}
|
||||
|
||||
@@ -3028,6 +3223,13 @@ void verifyContextRundownChanStillExist (
|
||||
|
||||
for ( i = 0; i < NELEMENTS ( chan ); i++ ) {
|
||||
status = ca_create_channel ( pName, 0, 0, 0, & chan[i] );
|
||||
/*
|
||||
* currently in-memory channels cant be used with this test
|
||||
* !!!! FIX ME, FIX ME, FIX ME, FIX ME !!!!
|
||||
*/
|
||||
if ( status == ECA_UNAVAILINSERV ) {
|
||||
break;
|
||||
}
|
||||
SEVCHK ( status, NULL );
|
||||
}
|
||||
|
||||
@@ -3123,6 +3325,7 @@ int acctst ( const char * pName, unsigned interestLevel, unsigned channelCount,
|
||||
verifyHighThroughputReadCallback ( chan, interestLevel );
|
||||
verifyHighThroughputWriteCallback ( chan, interestLevel );
|
||||
verifyBadString ( chan, interestLevel );
|
||||
verifyMultithreadSubscr ( pName, interestLevel );
|
||||
if ( select != ca_enable_preemptive_callback ) {
|
||||
fdManagerVerify ( pName, interestLevel );
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, 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 is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
* CA client library diagnostics IOC shell registration
|
||||
* Authors:
|
||||
* Jeff Hill
|
||||
*/
|
||||
|
||||
#include <iocsh.h>
|
||||
#include "caDiagnostics.h"
|
||||
|
||||
/* Information needed by iocsh */
|
||||
static const iocshArg acctstArg0 = { "channel name", iocshArgString };
|
||||
static const iocshArg acctstArg1 = { "interest level", iocshArgInt };
|
||||
static const iocshArg acctstArg2 = { "channel count", iocshArgInt };
|
||||
static const iocshArg acctstArg3 = { "repetition count", iocshArgInt };
|
||||
static const iocshArg acctstArg4 = { "preemptive callback select", iocshArgInt };
|
||||
|
||||
static const iocshArg *acctstArgs[] =
|
||||
{
|
||||
&acctstArg0,
|
||||
&acctstArg1,
|
||||
&acctstArg2,
|
||||
&acctstArg3,
|
||||
&acctstArg4
|
||||
};
|
||||
static const iocshFuncDef acctstFuncDef = {"acctst", 5, acctstArgs};
|
||||
|
||||
|
||||
/* Wrapper called by iocsh, selects the argument types that print needs */
|
||||
static void acctstCallFunc(const iocshArgBuf *args) {
|
||||
if ( args[1].ival < 0 ) {
|
||||
printf ( "negative interest level not allowed\n" );
|
||||
return;
|
||||
}
|
||||
if ( args[2].ival < 0 ) {
|
||||
printf ( "negative channel count not allowed\n" );
|
||||
return;
|
||||
}
|
||||
if ( args[3].ival < 0 ) {
|
||||
printf ( "negative repetition count not allowed\n" );
|
||||
return;
|
||||
}
|
||||
acctst (
|
||||
args[0].sval, /* channel name */
|
||||
( unsigned ) args[1].ival, /* interest level */
|
||||
( unsigned ) args[2].ival, /* channel count */
|
||||
( unsigned ) args[3].ival, /* repetition count */
|
||||
( ca_preemptive_callback_select ) args[4].ival ); /* preemptive callback select */
|
||||
}
|
||||
|
||||
struct AutoInit {
|
||||
AutoInit ();
|
||||
};
|
||||
|
||||
AutoInit :: AutoInit ()
|
||||
{
|
||||
iocshRegister ( &acctstFuncDef, acctstCallFunc );
|
||||
}
|
||||
|
||||
AutoInit autoInit;
|
||||
|
||||
+2
-2
@@ -266,8 +266,8 @@ private:
|
||||
// **** lock hierarchy ****
|
||||
// 1) callback lock must always be acquired before
|
||||
// the primary mutex if both locks are needed
|
||||
mutable epicsMutex & mutex;
|
||||
mutable epicsMutex & cbMutex;
|
||||
epicsMutex & mutex;
|
||||
epicsMutex & cbMutex;
|
||||
epicsEvent iiuUninstall;
|
||||
ipAddrToAsciiEngine & ipToAEngine;
|
||||
epicsTimerQueueActive & timerQueue;
|
||||
|
||||
+2
-1
@@ -185,7 +185,8 @@ epicsShareFunc enum channel_state epicsShareAPI ca_state (chid chan);
|
||||
epicsShareFunc int epicsShareAPI ca_task_initialize (void);
|
||||
enum ca_preemptive_callback_select
|
||||
{ ca_disable_preemptive_callback, ca_enable_preemptive_callback };
|
||||
epicsShareFunc int epicsShareAPI ca_context_create (enum ca_preemptive_callback_select select);
|
||||
epicsShareFunc int epicsShareAPI
|
||||
ca_context_create (enum ca_preemptive_callback_select select);
|
||||
epicsShareFunc void epicsShareAPI ca_detach_context ();
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
+10
-9
@@ -81,8 +81,9 @@ udpiiu::udpiiu (
|
||||
cac::lowestPriorityLevelAbove (
|
||||
cac::lowestPriorityLevelAbove (
|
||||
cac.getInitializingThreadsPriority () ) ) ),
|
||||
m_repeaterTimerNotify ( *this ),
|
||||
repeaterSubscribeTmr (
|
||||
*this, timerQueue, cbMutexIn, ctxNotifyIn ),
|
||||
m_repeaterTimerNotify, timerQueue, cbMutexIn, ctxNotifyIn ),
|
||||
govTmr ( *this, timerQueue, cacMutexIn ),
|
||||
maxPeriod ( maxSearchPeriodDefault ),
|
||||
rtteMean ( minRoundTripEstimate ),
|
||||
@@ -397,14 +398,14 @@ void udpRecvThread::run ()
|
||||
}
|
||||
|
||||
/*
|
||||
* udpiiu::repeaterRegistrationMessage ()
|
||||
* udpiiu::M_repeaterTimerNotify::repeaterRegistrationMessage ()
|
||||
*
|
||||
* register with the repeater
|
||||
*/
|
||||
void udpiiu::repeaterRegistrationMessage ( unsigned attemptNumber )
|
||||
void udpiiu :: M_repeaterTimerNotify :: repeaterRegistrationMessage ( unsigned attemptNumber )
|
||||
{
|
||||
epicsGuard < epicsMutex > cbGuard ( this->cacMutex );
|
||||
caRepeaterRegistrationMessage ( this->sock, this->repeaterPort, attemptNumber );
|
||||
epicsGuard < epicsMutex > cbGuard ( m_udpiiu.cacMutex );
|
||||
caRepeaterRegistrationMessage ( m_udpiiu.sock, m_udpiiu.repeaterPort, attemptNumber );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1233,16 +1234,16 @@ void udpiiu::govExpireNotify (
|
||||
this->ppSearchTmr[0]->installChannel ( guard, chan );
|
||||
}
|
||||
|
||||
int udpiiu :: printFormated (
|
||||
epicsGuard < epicsMutex > & cbGuard,
|
||||
const char * pformat, ... )
|
||||
int udpiiu :: M_repeaterTimerNotify :: printFormated (
|
||||
epicsGuard < epicsMutex > & cbGuard,
|
||||
const char * pformat, ... )
|
||||
{
|
||||
va_list theArgs;
|
||||
int status;
|
||||
|
||||
va_start ( theArgs, pformat );
|
||||
|
||||
status = this->cacRef.varArgsPrintFormated ( cbGuard, pformat, theArgs );
|
||||
status = m_udpiiu.cacRef.varArgsPrintFormated ( cbGuard, pformat, theArgs );
|
||||
|
||||
va_end ( theArgs );
|
||||
|
||||
|
||||
+19
-12
@@ -88,8 +88,7 @@ static const double beaconAnomalySearchPeriod = 5.0; // seconds
|
||||
class udpiiu :
|
||||
private netiiu,
|
||||
private searchTimerNotify,
|
||||
private disconnectGovernorNotify,
|
||||
private repeaterTimerNotify {
|
||||
private disconnectGovernorNotify {
|
||||
public:
|
||||
udpiiu (
|
||||
epicsGuard < epicsMutex > & cacGuard,
|
||||
@@ -139,9 +138,24 @@ private:
|
||||
private:
|
||||
udpiiu & _udpiiu;
|
||||
};
|
||||
class M_repeaterTimerNotify :
|
||||
public repeaterTimerNotify {
|
||||
public:
|
||||
M_repeaterTimerNotify ( udpiiu & iiu ) :
|
||||
m_udpiiu ( iiu ) {}
|
||||
// repeaterTimerNotify
|
||||
void repeaterRegistrationMessage (
|
||||
unsigned attemptNumber );
|
||||
int printFormated (
|
||||
epicsGuard < epicsMutex > & callbackControl,
|
||||
const char * pformat, ... );
|
||||
private:
|
||||
udpiiu & m_udpiiu;
|
||||
};
|
||||
char xmitBuf [MAX_UDP_SEND];
|
||||
char recvBuf [MAX_UDP_RECV];
|
||||
udpRecvThread recvThread;
|
||||
M_repeaterTimerNotify m_repeaterTimerNotify;
|
||||
repeaterSubscribeTimer repeaterSubscribeTmr;
|
||||
disconnectGovernorTimer govTmr;
|
||||
tsDLList < SearchDest > _searchDestList;
|
||||
@@ -149,8 +163,8 @@ private:
|
||||
double rtteMean;
|
||||
double rtteMeanDev;
|
||||
cac & cacRef;
|
||||
mutable epicsMutex & cbMutex;
|
||||
mutable epicsMutex & cacMutex;
|
||||
epicsMutex & cbMutex;
|
||||
epicsMutex & cacMutex;
|
||||
epics_auto_ptr < epics_auto_ptr < class searchTimer >, eapt_array > ppSearchTmr;
|
||||
unsigned nBytesInXmitBuf;
|
||||
unsigned nTimers;
|
||||
@@ -278,14 +292,6 @@ private:
|
||||
void govExpireNotify (
|
||||
epicsGuard < epicsMutex > &, nciu & );
|
||||
|
||||
// repeaterTimerNotify
|
||||
void repeaterRegistrationMessage (
|
||||
unsigned attemptNumber );
|
||||
|
||||
int printFormated (
|
||||
epicsGuard < epicsMutex > & callbackControl,
|
||||
const char * pformat, ... );
|
||||
|
||||
udpiiu ( const udpiiu & );
|
||||
udpiiu & operator = ( const udpiiu & );
|
||||
|
||||
@@ -294,6 +300,7 @@ private:
|
||||
// These are needed for the vxWorks 5.5 compiler:
|
||||
friend class udpiiu::SearchDestUDP;
|
||||
friend class udpiiu::SearchRespCallback;
|
||||
friend class udpiiu::M_repeaterTimerNotify;
|
||||
};
|
||||
|
||||
#endif // udpiiuh
|
||||
|
||||
+6
-4
@@ -6,9 +6,6 @@ use warnings;
|
||||
|
||||
my $version = '0.4';
|
||||
|
||||
exists $ENV{EPICS_HOST_ARCH}
|
||||
or die "EPICS_HOST_ARCH environment variable not set";
|
||||
|
||||
|
||||
package CA;
|
||||
|
||||
@@ -26,12 +23,17 @@ package Cap5;
|
||||
our $VERSION = $version;
|
||||
our @ISA = qw(DynaLoader);
|
||||
|
||||
# Library is specific to the Perl version and archname
|
||||
use Config;
|
||||
my $perl_version = $Config::Config{version};
|
||||
my $perl_archname = $Config::Config{archname};
|
||||
|
||||
require DynaLoader;
|
||||
|
||||
# Add our lib/<arch> directory to the shared library search path
|
||||
use File::Basename;
|
||||
my $Lib = dirname(__FILE__);
|
||||
push @DynaLoader::dl_library_path, "$Lib/../$ENV{EPICS_HOST_ARCH}";
|
||||
push @DynaLoader::dl_library_path, "$Lib/$perl_version/$perl_archname";
|
||||
|
||||
bootstrap Cap5 $VERSION;
|
||||
|
||||
|
||||
+14
-8
@@ -22,8 +22,12 @@ ifneq ($(findstring darwin,$(T_A)),)
|
||||
LOADABLE_SHRLIB_SUFFIX = .bundle
|
||||
endif
|
||||
|
||||
ifeq ($(T_A),$(EPICS_HOST_ARCH))
|
||||
ifeq ($(findstring $(OS_CLASS),WIN32 cygwin32 solaris-sparc),)
|
||||
PERL_VERSION = $(shell $(PERL) ../perlConfig.pl version)
|
||||
PERL_ARCHNAME = $(shell $(PERL) ../perlConfig.pl archname)
|
||||
PERL_ARCHPATH = $(PERL_VERSION)/$(PERL_ARCHNAME)
|
||||
|
||||
ifeq ($(findstring Host,$(VALID_BUILDS)),Host)
|
||||
ifeq ($(findstring $(OS_CLASS),WIN32 cygwin32),)
|
||||
# Doesn't build on WIN32
|
||||
LOADABLE_LIBRARY_HOST = Cap5
|
||||
|
||||
@@ -34,6 +38,10 @@ ifeq ($(findstring $(OS_CLASS),WIN32 cygwin32 solaris-sparc),)
|
||||
PERL_SCRIPTS += camonitor.pl
|
||||
|
||||
PERL_MODULES += CA.pm
|
||||
PERL_MODULES += $(PERL_ARCHPATH)/$(LOADABLE_SHRLIB_PREFIX)Cap5$(LOADABLE_SHRLIB_SUFFIX)
|
||||
|
||||
HTMLS_DIR = .
|
||||
HTMLS = CA.html
|
||||
endif
|
||||
endif
|
||||
|
||||
@@ -42,12 +50,6 @@ Cap5_LIBS = ca Com
|
||||
Cap5_INCLUDES = -I$(shell $(PERL) ../perlConfig.pl archlib)/CORE
|
||||
Cap5_CFLAGS = $(shell $(PERL) ../perlConfig.pl ccflags)
|
||||
|
||||
ifeq ($(findstring Host,$(VALID_BUILDS)),Host)
|
||||
# Can only create docs in Host build
|
||||
HTMLS_DIR = .
|
||||
HTMLS = CA.html
|
||||
endif
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
|
||||
ifdef T_A
|
||||
@@ -61,6 +63,10 @@ ifdef T_A
|
||||
$(RM) $@
|
||||
podchecker $< && pod2html --infile=$< --outfile=$@
|
||||
|
||||
$(INSTALL_PERL_MODULES)/$(PERL_ARCHPATH)/%: %
|
||||
$(ECHO) "Installing loadable shared library $@"
|
||||
@$(INSTALL_LIBRARY) -d -m $(LIB_PERMISSIONS) $< $(INSTALL_PERL_MODULES)/$(PERL_ARCHPATH)
|
||||
|
||||
clean::
|
||||
$(RM) Cap5.c
|
||||
endif
|
||||
|
||||
@@ -23,8 +23,8 @@ PROD_LIBS := cas ca gdd Com
|
||||
#
|
||||
PROD_SYS_LIBS_WIN32 := ws2_32 advapi32 user32
|
||||
|
||||
SRCS += main.cc
|
||||
SRCS += directoryServer.cc
|
||||
caDirServ_SRCS += main.cc
|
||||
caDirServ_SRCS += directoryServer.cc
|
||||
|
||||
PROD_HOST = caDirServ
|
||||
|
||||
|
||||
@@ -64,18 +64,6 @@ private:
|
||||
casStreamReadReg & operator = ( const casStreamReadReg & );
|
||||
};
|
||||
|
||||
//
|
||||
// casStreamOS::armRecv ()
|
||||
//
|
||||
inline void casStreamOS::armRecv()
|
||||
{
|
||||
if ( ! this->pRdReg ) {
|
||||
if ( ! this->inBufFull() ) {
|
||||
this->pRdReg = new casStreamReadReg ( *this );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// casStreamReadReg::casStreamReadReg()
|
||||
//
|
||||
@@ -309,6 +297,18 @@ void casStreamIOWakeup::start ( casStreamOS &os )
|
||||
this->pOS->printStatus ( "casStreamIOWakeup tmr start" );
|
||||
}
|
||||
|
||||
//
|
||||
// casStreamOS::armRecv ()
|
||||
//
|
||||
inline void casStreamOS::armRecv()
|
||||
{
|
||||
if ( ! this->pRdReg ) {
|
||||
if ( ! this->inBufFull() ) {
|
||||
this->pRdReg = new casStreamReadReg ( *this );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// casStreamOS::disarmRecv ()
|
||||
//
|
||||
|
||||
+12
-16
@@ -126,7 +126,6 @@ static void event_handler (evargs args)
|
||||
ppv->dbrType = args.type;
|
||||
ppv->value = calloc(1, dbr_size_n(args.type, args.count));
|
||||
memcpy(ppv->value, args.dbr, dbr_size_n(args.type, args.count));
|
||||
ppv->onceConnected = 1;
|
||||
ppv->nElems = args.count;
|
||||
nRead++;
|
||||
}
|
||||
@@ -159,12 +158,13 @@ static int caget (pv *pvs, int nPvs, RequestT request, OutputT format,
|
||||
int n, result;
|
||||
|
||||
for (n = 0; n < nPvs; n++) {
|
||||
unsigned long nElems;
|
||||
|
||||
/* Set up pvs structure */
|
||||
/* -------------------- */
|
||||
|
||||
/* Get natural type and array count */
|
||||
pvs[n].nElems = ca_element_count(pvs[n].chid);
|
||||
nElems = ca_element_count(pvs[n].chid);
|
||||
pvs[n].dbfType = ca_field_type(pvs[n].chid);
|
||||
pvs[n].dbrType = dbrType;
|
||||
|
||||
@@ -183,10 +183,6 @@ static int caget (pv *pvs, int nPvs, RequestT request, OutputT format,
|
||||
pvs[n].dbrType = DBR_TIME_STRING;
|
||||
}
|
||||
}
|
||||
/* Adjust array count */
|
||||
if (reqElems > pvs[n].nElems)
|
||||
reqElems = pvs[n].nElems;
|
||||
pvs[n].reqElems = reqElems;
|
||||
|
||||
/* Issue CA request */
|
||||
/* ---------------- */
|
||||
@@ -196,17 +192,20 @@ static int caget (pv *pvs, int nPvs, RequestT request, OutputT format,
|
||||
nConn++;
|
||||
pvs[n].onceConnected = 1;
|
||||
if (request == callback)
|
||||
{ /* Event handler will allocate value */
|
||||
{
|
||||
/* Event handler will allocate value and set nElems */
|
||||
pvs[n].reqElems = reqElems > nElems ? nElems : reqElems;
|
||||
result = ca_array_get_callback(pvs[n].dbrType,
|
||||
pvs[n].reqElems,
|
||||
pvs[n].chid,
|
||||
event_handler,
|
||||
(void*)&pvs[n]);
|
||||
} else {
|
||||
/* Allocate value structure */
|
||||
/* We allocate value structure and set nElems */
|
||||
pvs[n].nElems = reqElems && reqElems < nElems ? reqElems : nElems;
|
||||
pvs[n].value = calloc(1, dbr_size_n(pvs[n].dbrType, pvs[n].nElems));
|
||||
if(!pvs[n].value) {
|
||||
fprintf(stderr,"Allocation failed\n");
|
||||
if (!pvs[n].value) {
|
||||
fprintf(stderr,"Memory allocation failed\n");
|
||||
return 1;
|
||||
}
|
||||
result = ca_array_get(pvs[n].dbrType,
|
||||
@@ -252,9 +251,6 @@ static int caget (pv *pvs, int nPvs, RequestT request, OutputT format,
|
||||
/* -------------- */
|
||||
|
||||
for (n = 0; n < nPvs; n++) {
|
||||
/* Truncate the data printed to what was requested. */
|
||||
if (pvs[n].reqElems != 0 && pvs[n].nElems > pvs[n].reqElems)
|
||||
pvs[n].nElems = pvs[n].reqElems;
|
||||
|
||||
switch (format) {
|
||||
case plain: /* Emulate old caget behaviour */
|
||||
@@ -377,7 +373,7 @@ static void complainIfNotPlainAndSet (OutputT *current, const OutputT requested)
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
int n = 0;
|
||||
int n;
|
||||
int result; /* CA result */
|
||||
OutputT format = plain; /* User specified format */
|
||||
RequestT request = get; /* User specified request type */
|
||||
@@ -389,7 +385,7 @@ int main (int argc, char *argv[])
|
||||
int digits = 0; /* getopt() no. of float digits */
|
||||
|
||||
int nPvs; /* Number of PVs */
|
||||
pv* pvs = 0; /* Array of PV structures */
|
||||
pv* pvs; /* Array of PV structures */
|
||||
|
||||
LINE_BUFFER(stdout); /* Configure stdout buffering */
|
||||
|
||||
@@ -529,7 +525,7 @@ int main (int argc, char *argv[])
|
||||
result = ca_context_create(ca_disable_preemptive_callback);
|
||||
if (result != ECA_NORMAL) {
|
||||
fprintf(stderr, "CA error %s occurred while trying "
|
||||
"to start channel access '%s'.\n", ca_message(result), pvs[n].name);
|
||||
"to start channel access.\n", ca_message(result));
|
||||
return 1;
|
||||
}
|
||||
/* Allocate PV structure array */
|
||||
|
||||
@@ -127,13 +127,13 @@ int cainfo (pv *pvs, int nPvs)
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
int n = 0;
|
||||
int n;
|
||||
int result; /* CA result */
|
||||
|
||||
int opt; /* getopt() current option */
|
||||
|
||||
int nPvs; /* Number of PVs */
|
||||
pv* pvs = 0; /* Array of PV structures */
|
||||
pv* pvs; /* Array of PV structures */
|
||||
|
||||
LINE_BUFFER(stdout); /* Configure stdout buffering */
|
||||
|
||||
@@ -195,7 +195,7 @@ int main (int argc, char *argv[])
|
||||
result = ca_context_create(ca_disable_preemptive_callback);
|
||||
if (result != ECA_NORMAL) {
|
||||
fprintf(stderr, "CA error %s occurred while trying "
|
||||
"to start channel access '%s'.\n", ca_message(result), pvs[n].name);
|
||||
"to start channel access.\n", ca_message(result));
|
||||
return 1;
|
||||
}
|
||||
/* Allocate PV structure array */
|
||||
|
||||
+65
-71
@@ -42,45 +42,49 @@ static int nConn = 0; /* Number of connected
|
||||
|
||||
void usage (void)
|
||||
{
|
||||
fprintf (stderr, "\nUsage: camonitor [options] <PV name> ...\n\n"
|
||||
" -h: Help: Print this message\n"
|
||||
fprintf (stderr, "\nUsage: camonitor [options] <PV name> ...\n"
|
||||
"\n"
|
||||
" -h: Help; Print this message\n"
|
||||
"Channel Access options:\n"
|
||||
" -w <sec>: Wait time, specifies CA timeout, default is %f second(s)\n"
|
||||
" -m <mask>: Specify CA event mask to use, with <mask> being any combination of\n"
|
||||
" 'v' (value), 'a' (alarm), 'l' (log/archive), 'p' (property). Default: va\n"
|
||||
" -p <prio>: CA priority (0-%u, default 0=lowest)\n"
|
||||
" -w <sec>: Wait time, specifies CA timeout, default is %f second(s)\n"
|
||||
" -m <msk>: Specify CA event mask to use. <msk> is any combination of\n"
|
||||
" 'v' (value), 'a' (alarm), 'l' (log/archive), 'p' (property).\n"
|
||||
" Default event mask is 'va'\n"
|
||||
" -p <pri>: CA priority (0-%u, default 0=lowest)\n"
|
||||
"Timestamps:\n"
|
||||
" Default: Print absolute timestamps (as reported by CA server)\n"
|
||||
" -t <key>: Specify timestamp source(s) and type, with <key> containing\n"
|
||||
" 's' = CA server (remote) timestamps\n"
|
||||
" 'c' = CA client (local) timestamps (shown in '()'s)\n"
|
||||
" 'n' = no timestamps\n"
|
||||
" 'r' = relative timestamps (time elapsed since start of program)\n"
|
||||
" 'i' = incremental timestamps (time elapsed since last update)\n"
|
||||
" 'I' = incremental timestamps (time elapsed since last update, by channel)\n"
|
||||
" Default: Print absolute timestamps (as reported by CA server)\n"
|
||||
" -t <key>: Specify timestamp source(s) and type, with <key> containing\n"
|
||||
" 's' = CA server (remote) timestamps\n"
|
||||
" 'c' = CA client (local) timestamps (shown in '()'s)\n"
|
||||
" 'n' = no timestamps\n"
|
||||
" 'r' = relative timestamps (time elapsed since start of program)\n"
|
||||
" 'i' = incremental timestamps (time elapsed since last update)\n"
|
||||
" 'I' = incremental timestamps (time since last update, by channel)\n"
|
||||
" 'r', 'i' or 'I' require 's' or 'c' to select the time source\n"
|
||||
"Enum format:\n"
|
||||
" -n: Print DBF_ENUM values as number (default are enum string values)\n"
|
||||
"Arrays: Value format: print number of requested values, then list of values\n"
|
||||
" Default: Print all values\n"
|
||||
" -# <count>: Print first <count> elements of an array\n"
|
||||
" -S: Print array of char as a string (long string)\n"
|
||||
"Floating point type format:\n"
|
||||
" Default: Use %%g format\n"
|
||||
" -e <nr>: Use %%e format, with a precision of <nr> digits\n"
|
||||
" -f <nr>: Use %%f format, with a precision of <nr> digits\n"
|
||||
" -g <nr>: Use %%g format, with a precision of <nr> digits\n"
|
||||
" -s: Get value as string (honors server-side precision)\n"
|
||||
" -lx: Round to long integer and print as hex number\n"
|
||||
" -lo: Round to long integer and print as octal number\n"
|
||||
" -lb: Round to long integer and print as binary number\n"
|
||||
" -n: Print DBF_ENUM values as number (default is enum string)\n"
|
||||
"Array values: Print number of elements, then list of values\n"
|
||||
" Default: Request and print all elements (dynamic arrays supported)\n"
|
||||
" -# <num>: Request and print up to <num> elements\n"
|
||||
" -S: Print arrays of char as a string (long string)\n"
|
||||
"Floating point format:\n"
|
||||
" Default: Use %%g format\n"
|
||||
" -e <num>: Use %%e format, with a precision of <num> digits\n"
|
||||
" -f <num>: Use %%f format, with a precision of <num> digits\n"
|
||||
" -g <num>: Use %%g format, with a precision of <num> digits\n"
|
||||
" -s: Get value as string (honors server-side precision)\n"
|
||||
" -lx: Round to long integer and print as hex number\n"
|
||||
" -lo: Round to long integer and print as octal number\n"
|
||||
" -lb: Round to long integer and print as binary number\n"
|
||||
"Integer number format:\n"
|
||||
" Default: Print as decimal number\n"
|
||||
" -0x: Print as hex number\n"
|
||||
" -0o: Print as octal number\n"
|
||||
" -0b: Print as binary number\n"
|
||||
" Default: Print as decimal number\n"
|
||||
" -0x: Print as hex number\n"
|
||||
" -0o: Print as octal number\n"
|
||||
" -0b: Print as binary number\n"
|
||||
"Alternate output field separator:\n"
|
||||
" -F <ofs>: Use <ofs> as an alternate output field separator\n"
|
||||
"\nExample: camonitor -f8 my_channel another_channel\n"
|
||||
" -F <ofs>: Use <ofs> to separate fields in output\n"
|
||||
"\n"
|
||||
"Example: camonitor -f8 my_channel another_channel\n"
|
||||
" (doubles are printed as %%f with precision of 8)\n\n"
|
||||
, DEFAULT_TIMEOUT, CA_PRIORITY_MAX);
|
||||
}
|
||||
@@ -92,7 +96,7 @@ void usage (void)
|
||||
* Function: event_handler
|
||||
*
|
||||
* Description: CA event_handler for request type callback
|
||||
* Allocates the dbr structure and copies the data
|
||||
* Prints the event data
|
||||
*
|
||||
* Arg(s) In: args - event handler args (see CA manual)
|
||||
*
|
||||
@@ -107,10 +111,12 @@ static void event_handler (evargs args)
|
||||
{
|
||||
pv->dbrType = args.type;
|
||||
pv->nElems = args.count;
|
||||
memcpy(pv->value, args.dbr, dbr_size_n(args.type, args.count));
|
||||
pv->value = (void *) args.dbr; /* casting away const */
|
||||
|
||||
print_time_val_sts(pv, reqElems);
|
||||
fflush(stdout);
|
||||
|
||||
pv->value = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,51 +135,39 @@ static void connection_handler ( struct connection_handler_args args )
|
||||
{
|
||||
pv *ppv = ( pv * ) ca_puser ( args.chid );
|
||||
if ( args.op == CA_OP_CONN_UP ) {
|
||||
nConn++;
|
||||
if (!ppv->onceConnected) {
|
||||
ppv->onceConnected = 1;
|
||||
/* Set up pv structure */
|
||||
/* ------------------- */
|
||||
|
||||
/* Get natural type and array count */
|
||||
ppv->nElems = ca_element_count(ppv->chid);
|
||||
ppv->dbfType = ca_field_type(ppv->chid);
|
||||
ppv->dbfType = ca_field_type(ppv->chid);
|
||||
ppv->dbrType = dbf_type_to_DBR_TIME(ppv->dbfType); /* Use native type */
|
||||
if (dbr_type_is_ENUM(ppv->dbrType)) /* Enums honour -n option */
|
||||
{
|
||||
if (enumAsNr) ppv->dbrType = DBR_TIME_INT;
|
||||
else ppv->dbrType = DBR_TIME_STRING;
|
||||
}
|
||||
else if (floatAsString &&
|
||||
(dbr_type_is_FLOAT(ppv->dbrType) || dbr_type_is_DOUBLE(ppv->dbrType)))
|
||||
{
|
||||
ppv->dbrType = DBR_TIME_STRING;
|
||||
}
|
||||
/* Set request count */
|
||||
ppv->nElems = ca_element_count(ppv->chid);
|
||||
ppv->reqElems = reqElems > ppv->nElems ? ppv->nElems : reqElems;
|
||||
|
||||
/* Set up value structures */
|
||||
ppv->dbrType = dbf_type_to_DBR_TIME(ppv->dbfType); /* Use native type */
|
||||
if (dbr_type_is_ENUM(ppv->dbrType)) /* Enums honour -n option */
|
||||
{
|
||||
if (enumAsNr) ppv->dbrType = DBR_TIME_INT;
|
||||
else ppv->dbrType = DBR_TIME_STRING;
|
||||
}
|
||||
|
||||
else if (floatAsString &&
|
||||
(dbr_type_is_FLOAT(ppv->dbrType) || dbr_type_is_DOUBLE(ppv->dbrType)))
|
||||
{
|
||||
ppv->dbrType = DBR_TIME_STRING;
|
||||
}
|
||||
/* Adjust array count */
|
||||
if (reqElems > ppv->nElems)
|
||||
reqElems = ppv->nElems;
|
||||
ppv->reqElems = reqElems;
|
||||
|
||||
ppv->onceConnected = 1;
|
||||
nConn++;
|
||||
/* Issue CA request */
|
||||
/* ---------------- */
|
||||
/* install monitor once with first connect */
|
||||
if ( ! ppv->value ) {
|
||||
/* Allocate value structure */
|
||||
ppv->value = calloc(1, dbr_size_n(ppv->dbrType, ppv->nElems));
|
||||
if ( ppv->value ) {
|
||||
ppv->status = ca_create_subscription(ppv->dbrType,
|
||||
/* install monitor once with first connect */
|
||||
ppv->status = ca_create_subscription(ppv->dbrType,
|
||||
ppv->reqElems,
|
||||
ppv->chid,
|
||||
eventMask,
|
||||
event_handler,
|
||||
(void*)ppv,
|
||||
NULL);
|
||||
if ( ppv->status != ECA_NORMAL ) {
|
||||
free ( ppv->value );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( args.op == CA_OP_CONN_DOWN ) {
|
||||
@@ -203,7 +197,7 @@ static void connection_handler ( struct connection_handler_args args )
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
int returncode = 0;
|
||||
int n = 0;
|
||||
int n;
|
||||
int result; /* CA result */
|
||||
IntFormatT outType; /* Output type */
|
||||
|
||||
@@ -211,7 +205,7 @@ int main (int argc, char *argv[])
|
||||
int digits = 0; /* getopt() no. of float digits */
|
||||
|
||||
int nPvs; /* Number of PVs */
|
||||
pv* pvs = 0; /* Array of PV structures */
|
||||
pv* pvs; /* Array of PV structures */
|
||||
|
||||
LINE_BUFFER(stdout); /* Configure stdout buffering */
|
||||
|
||||
@@ -356,7 +350,7 @@ int main (int argc, char *argv[])
|
||||
result = ca_context_create(ca_disable_preemptive_callback);
|
||||
if (result != ECA_NORMAL) {
|
||||
fprintf(stderr, "CA error %s occurred while trying "
|
||||
"to start channel access '%s'.\n", ca_message(result), pvs[n].name);
|
||||
"to start channel access.\n", ca_message(result));
|
||||
return 1;
|
||||
}
|
||||
/* Allocate PV structure array */
|
||||
|
||||
+2
-3
@@ -251,7 +251,6 @@ int caget (pv *pvs, int nPvs, OutputT format,
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
int n = 0;
|
||||
int i;
|
||||
int result; /* CA result */
|
||||
OutputT format = plain; /* User specified format */
|
||||
@@ -273,7 +272,7 @@ int main (int argc, char *argv[])
|
||||
struct dbr_gr_enum bufGrEnum;
|
||||
|
||||
int nPvs; /* Number of PVs */
|
||||
pv* pvs = 0; /* Array of PV structures */
|
||||
pv* pvs; /* Array of PV structures */
|
||||
|
||||
LINE_BUFFER(stdout); /* Configure stdout buffering */
|
||||
putenv("POSIXLY_CORRECT="); /* Behave correct on GNU getopt systems */
|
||||
@@ -372,7 +371,7 @@ int main (int argc, char *argv[])
|
||||
result = ca_context_create(ca_enable_preemptive_callback);
|
||||
if (result != ECA_NORMAL) {
|
||||
fprintf(stderr, "CA error %s occurred while trying "
|
||||
"to start channel access '%s'.\n", ca_message(result), pvs[n].name);
|
||||
"to start channel access.\n", ca_message(result));
|
||||
return 1;
|
||||
}
|
||||
/* Allocate PV structure array */
|
||||
|
||||
@@ -33,8 +33,6 @@ INC += dbIocRegister.h
|
||||
# The following go away what old database access goes away
|
||||
INC += db_access_routines.h
|
||||
INC += db_convert.h
|
||||
# The following is used by iocmon
|
||||
INC += dbCaPvt.h
|
||||
|
||||
DBDINC += menuAlarmSevr
|
||||
DBDINC += menuAlarmStat
|
||||
|
||||
+3
-3
@@ -8,7 +8,7 @@
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/*
|
||||
* Revision-Id: anj@aps.anl.gov-20101005192737-disfz3vs0f3fiixd
|
||||
* Revision-Id: anj@aps.anl.gov-20110601222212-z1p7qoplm5mw0eho
|
||||
*
|
||||
*
|
||||
* L O S A L A M O S
|
||||
@@ -196,8 +196,8 @@ private:
|
||||
dbContextReadNotifyCache readNotifyCache;
|
||||
dbEventCtx ctx;
|
||||
unsigned long stateNotifyCacheSize;
|
||||
mutable epicsMutex & mutex;
|
||||
mutable epicsMutex & cbMutex;
|
||||
epicsMutex & mutex;
|
||||
epicsMutex & cbMutex;
|
||||
cacContextNotify & notify;
|
||||
epics_auto_ptr < cacContext > pNetContext;
|
||||
char * pStateNotifyCache;
|
||||
|
||||
+2
-3
@@ -43,11 +43,10 @@
|
||||
special(SPC_SCAN)
|
||||
interest(1)
|
||||
}
|
||||
field(EVNT,DBF_STRING) {
|
||||
prompt("Event Name")
|
||||
field(EVNT,DBF_SHORT) {
|
||||
prompt("Event Number")
|
||||
promptgroup(GUI_SCAN)
|
||||
special(SPC_SCAN)
|
||||
size(40)
|
||||
interest(1)
|
||||
}
|
||||
field(TSE,DBF_SHORT) {
|
||||
|
||||
+110
-86
@@ -8,7 +8,7 @@
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* dbEvent.c */
|
||||
/* Revision-Id: anj@aps.anl.gov-20101005192737-disfz3vs0f3fiixd */
|
||||
/* Revision-Id: johill@lanl.gov-20111019180700-7u25j7zwo2w1894n */
|
||||
/* routines for scheduling events to lower priority tasks via the RT kernel */
|
||||
/*
|
||||
* Author: Jeffrey O. Hill
|
||||
@@ -203,35 +203,44 @@ int epicsShareAPI dbel ( const char *pname, unsigned level )
|
||||
}
|
||||
|
||||
if ( level > 1 ) {
|
||||
unsigned nEntriesFree = ringSpace ( pevent->ev_que );
|
||||
unsigned nEntriesFree;
|
||||
const void * taskId;
|
||||
LOCKEVQUE(pevent->ev_que);
|
||||
nEntriesFree = ringSpace ( pevent->ev_que );
|
||||
taskId = ( void * ) pevent->ev_que->evUser->taskid;
|
||||
UNLOCKEVQUE(pevent->ev_que);
|
||||
if ( nEntriesFree == 0u ) {
|
||||
printf ( ", thread=%p, queue full",
|
||||
(void *) pevent->ev_que->evUser->taskid );
|
||||
(void *) taskId );
|
||||
}
|
||||
else if ( nEntriesFree == EVENTQUESIZE ) {
|
||||
printf ( ", thread=%p, queue empty",
|
||||
(void *) pevent->ev_que->evUser->taskid );
|
||||
(void *) taskId );
|
||||
}
|
||||
else {
|
||||
printf ( ", thread=%p, unused entries=%u",
|
||||
(void *) pevent->ev_que->evUser->taskid, nEntriesFree );
|
||||
(void *) taskId, nEntriesFree );
|
||||
}
|
||||
}
|
||||
|
||||
if ( level > 2 ) {
|
||||
unsigned nDuplicates;
|
||||
unsigned nCanceled;
|
||||
if ( pevent->nreplace ) {
|
||||
printf (", discarded by replacement=%ld", pevent->nreplace);
|
||||
}
|
||||
if ( ! pevent->valque ) {
|
||||
printf (", queueing disabled" );
|
||||
}
|
||||
if ( pevent->ev_que->nDuplicates ) {
|
||||
printf (", duplicate count =%u\n",
|
||||
pevent->ev_que->nDuplicates );
|
||||
LOCKEVQUE(pevent->ev_que);
|
||||
nDuplicates = pevent->ev_que->nDuplicates;
|
||||
nCanceled = pevent->ev_que->nCanceled;
|
||||
UNLOCKEVQUE(pevent->ev_que);
|
||||
if ( nDuplicates ) {
|
||||
printf (", duplicate count =%u\n", nDuplicates );
|
||||
}
|
||||
if ( pevent->ev_que->nCanceled ) {
|
||||
printf (", canceled count =%u\n",
|
||||
pevent->ev_que->nCanceled );
|
||||
if ( nCanceled ) {
|
||||
printf (", canceled count =%u\n", nCanceled );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -264,7 +273,7 @@ int epicsShareAPI dbel ( const char *pname, unsigned level )
|
||||
*/
|
||||
dbEventCtx epicsShareAPI db_init_events (void)
|
||||
{
|
||||
struct event_user *evUser;
|
||||
struct event_user * evUser;
|
||||
|
||||
if (!dbevEventUserFreeList) {
|
||||
freeListInitPvt(&dbevEventUserFreeList,
|
||||
@@ -326,7 +335,7 @@ dbEventCtx epicsShareAPI db_init_events (void)
|
||||
*/
|
||||
void epicsShareAPI db_close_events (dbEventCtx ctx)
|
||||
{
|
||||
struct event_user *evUser = (struct event_user *) ctx;
|
||||
struct event_user * const evUser = (struct event_user *) ctx;
|
||||
|
||||
/*
|
||||
* Exit not forced on event blocks for now - this is left to channel
|
||||
@@ -336,13 +345,32 @@ void epicsShareAPI db_close_events (dbEventCtx ctx)
|
||||
* NOTE: not deleting events before calling this routine could be
|
||||
* hazardous to the system's health.
|
||||
*/
|
||||
|
||||
epicsMutexMustLock ( evUser->lock );
|
||||
evUser->pendexit = TRUE;
|
||||
|
||||
epicsMutexUnlock ( evUser->lock );
|
||||
/* notify the waiting task */
|
||||
epicsEventSignal(evUser->ppendsem);
|
||||
}
|
||||
|
||||
/*
|
||||
* create_ev_que()
|
||||
*/
|
||||
static struct event_que * create_ev_que ( struct event_user * const evUser )
|
||||
{
|
||||
struct event_que * const ev_que = (struct event_que *)
|
||||
freeListCalloc ( dbevEventQueueFreeList );
|
||||
if ( ! ev_que ) {
|
||||
return NULL;
|
||||
}
|
||||
ev_que->writelock = epicsMutexCreate();
|
||||
if ( ! ev_que->writelock ) {
|
||||
freeListFree ( dbevEventQueueFreeList, ev_que );
|
||||
return NULL;
|
||||
}
|
||||
ev_que->evUser = evUser;
|
||||
return ev_que;
|
||||
}
|
||||
|
||||
/*
|
||||
* DB_ADD_EVENT()
|
||||
*/
|
||||
@@ -350,13 +378,9 @@ dbEventSubscription epicsShareAPI db_add_event (
|
||||
dbEventCtx ctx, struct dbAddr *paddr,
|
||||
EVENTFUNC *user_sub, void *user_arg, unsigned select)
|
||||
{
|
||||
struct event_user *evUser = (struct event_user *) ctx;
|
||||
struct dbCommon *precord;
|
||||
struct event_que *ev_que;
|
||||
struct event_que *tmp_que;
|
||||
struct evSubscrip *pevent;
|
||||
|
||||
precord = paddr->precord;
|
||||
struct event_user * const evUser = (struct event_user *) ctx;
|
||||
struct event_que * ev_que;
|
||||
struct evSubscrip * pevent;
|
||||
|
||||
/*
|
||||
* Don't add events which will not be triggered
|
||||
@@ -365,38 +389,42 @@ dbEventSubscription epicsShareAPI db_add_event (
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pevent = freeListCalloc (dbevEventBlockFreeList);
|
||||
if (!pevent) {
|
||||
pevent = freeListCalloc ( dbevEventBlockFreeList );
|
||||
if ( ! pevent ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* find an event que block with enough quota */
|
||||
/* otherwise add a new one to the list */
|
||||
ev_que = &evUser->firstque;
|
||||
while (TRUE) {
|
||||
if (ev_que->quota + ev_que->nCanceled < EVENTQUESIZE - EVENTENTRIES) {
|
||||
epicsMutexMustLock ( evUser->lock );
|
||||
ev_que = & evUser->firstque;
|
||||
while ( TRUE ) {
|
||||
int success = 0;
|
||||
LOCKEVQUE ( ev_que );
|
||||
success = ( ev_que->quota + ev_que->nCanceled <
|
||||
EVENTQUESIZE - EVENTENTRIES );
|
||||
if ( success ) {
|
||||
ev_que->quota += EVENTENTRIES;
|
||||
}
|
||||
UNLOCKEVQUE ( ev_que );
|
||||
if ( success ) {
|
||||
break;
|
||||
}
|
||||
if (!ev_que->nextque) {
|
||||
tmp_que = (struct event_que *)
|
||||
freeListCalloc(dbevEventQueueFreeList);
|
||||
if (!tmp_que) {
|
||||
freeListFree (dbevEventBlockFreeList, pevent);
|
||||
return NULL;
|
||||
if ( ! ev_que->nextque ) {
|
||||
ev_que->nextque = create_ev_que ( evUser );
|
||||
if ( ! ev_que->nextque ) {
|
||||
ev_que = NULL;
|
||||
break;
|
||||
}
|
||||
tmp_que->evUser = evUser;
|
||||
tmp_que->writelock = epicsMutexCreate();
|
||||
if (!tmp_que->writelock) {
|
||||
freeListFree (dbevEventBlockFreeList, pevent);
|
||||
freeListFree (dbevEventQueueFreeList, tmp_que);
|
||||
return NULL;
|
||||
}
|
||||
ev_que->nextque = tmp_que;
|
||||
ev_que = tmp_que;
|
||||
break;
|
||||
}
|
||||
ev_que = ev_que->nextque;
|
||||
}
|
||||
epicsMutexUnlock ( evUser->lock );
|
||||
|
||||
if ( ! ev_que ) {
|
||||
freeListFree ( dbevEventBlockFreeList, pevent );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pevent->npend = 0ul;
|
||||
pevent->nreplace = 0ul;
|
||||
@@ -409,10 +437,6 @@ dbEventSubscription epicsShareAPI db_add_event (
|
||||
pevent->enabled = FALSE;
|
||||
pevent->ev_que = ev_que;
|
||||
|
||||
LOCKEVQUE(ev_que);
|
||||
ev_que->quota += EVENTENTRIES;
|
||||
UNLOCKEVQUE(ev_que);
|
||||
|
||||
/*
|
||||
* Simple types values queued up for reliable interprocess
|
||||
* communication (for other types they get whatever happens to be
|
||||
@@ -434,10 +458,9 @@ dbEventSubscription epicsShareAPI db_add_event (
|
||||
*/
|
||||
void epicsShareAPI db_event_enable (dbEventSubscription es)
|
||||
{
|
||||
struct evSubscrip *pevent = (struct evSubscrip *) es;
|
||||
struct dbCommon *precord;
|
||||
|
||||
precord = (struct dbCommon *) pevent->paddr->precord;
|
||||
struct evSubscrip * const pevent = (struct evSubscrip *) es;
|
||||
struct dbCommon * const precord =
|
||||
(struct dbCommon *) pevent->paddr->precord;
|
||||
|
||||
LOCKREC(precord);
|
||||
if ( ! pevent->enabled ) {
|
||||
@@ -452,10 +475,9 @@ void epicsShareAPI db_event_enable (dbEventSubscription es)
|
||||
*/
|
||||
void epicsShareAPI db_event_disable (dbEventSubscription es)
|
||||
{
|
||||
struct evSubscrip *pevent = (struct evSubscrip *) es;
|
||||
struct dbCommon *precord;
|
||||
|
||||
precord = (struct dbCommon *) pevent->paddr->precord;
|
||||
struct evSubscrip * const pevent = (struct evSubscrip *) es;
|
||||
struct dbCommon * const precord =
|
||||
(struct dbCommon *) pevent->paddr->precord;
|
||||
|
||||
LOCKREC(precord);
|
||||
if ( pevent->enabled ) {
|
||||
@@ -472,7 +494,7 @@ void epicsShareAPI db_event_disable (dbEventSubscription es)
|
||||
static void event_remove ( struct event_que *ev_que,
|
||||
unsigned short index, struct evSubscrip *placeHolder )
|
||||
{
|
||||
struct evSubscrip *pEvent = ev_que->evque[index];
|
||||
struct evSubscrip * const pEvent = ev_que->evque[index];
|
||||
|
||||
ev_que->evque[index] = placeHolder;
|
||||
if ( pEvent->npend == 1u ) {
|
||||
@@ -495,12 +517,9 @@ static void event_remove ( struct event_que *ev_que,
|
||||
*/
|
||||
void epicsShareAPI db_cancel_event (dbEventSubscription es)
|
||||
{
|
||||
struct evSubscrip * pevent = ( struct evSubscrip * ) es;
|
||||
struct dbCommon * precord;
|
||||
struct evSubscrip * const pevent = ( struct evSubscrip * ) es;
|
||||
unsigned short getix;
|
||||
|
||||
precord = ( struct dbCommon * ) pevent->paddr->precord;
|
||||
|
||||
db_event_disable ( es );
|
||||
|
||||
/*
|
||||
@@ -564,12 +583,12 @@ void epicsShareAPI db_cancel_event (dbEventSubscription es)
|
||||
*/
|
||||
void epicsShareAPI db_flush_extra_labor_event (dbEventCtx ctx)
|
||||
{
|
||||
struct event_user *evUser = (struct event_user *) ctx;
|
||||
struct event_user * const evUser = (struct event_user *) ctx;
|
||||
|
||||
epicsMutexMustLock ( evUser->lock );
|
||||
while ( evUser->extraLaborBusy ) {
|
||||
epicsMutexUnlock ( evUser->lock );
|
||||
epicsThreadSleep(1.0);
|
||||
epicsThreadSleep(0.1);
|
||||
epicsMutexMustLock ( evUser->lock );
|
||||
}
|
||||
epicsMutexUnlock ( evUser->lock );
|
||||
@@ -585,7 +604,7 @@ void epicsShareAPI db_flush_extra_labor_event (dbEventCtx ctx)
|
||||
int epicsShareAPI db_add_extra_labor_event (
|
||||
dbEventCtx ctx, EXTRALABORFUNC *func, void *arg)
|
||||
{
|
||||
struct event_user *evUser = (struct event_user *) ctx;
|
||||
struct event_user * const evUser = (struct event_user *) ctx;
|
||||
|
||||
epicsMutexMustLock ( evUser->lock );
|
||||
evUser->extralabor_sub = func;
|
||||
@@ -600,7 +619,7 @@ int epicsShareAPI db_add_extra_labor_event (
|
||||
*/
|
||||
int epicsShareAPI db_post_extra_labor (dbEventCtx ctx)
|
||||
{
|
||||
struct event_user *evUser = (struct event_user *) ctx;
|
||||
struct event_user * const evUser = (struct event_user *) ctx;
|
||||
int doit;
|
||||
|
||||
epicsMutexMustLock ( evUser->lock );
|
||||
@@ -627,12 +646,10 @@ int epicsShareAPI db_post_extra_labor (dbEventCtx ctx)
|
||||
*/
|
||||
static void db_post_single_event_private (struct evSubscrip *event)
|
||||
{
|
||||
struct event_que *ev_que;
|
||||
db_field_log *pLog;
|
||||
int firstEventFlag;
|
||||
unsigned rngSpace;
|
||||
|
||||
ev_que = event->ev_que;
|
||||
struct event_que * const ev_que = event->ev_que;
|
||||
db_field_log * pLog;
|
||||
int firstEventFlag;
|
||||
unsigned rngSpace;
|
||||
|
||||
/*
|
||||
* evUser ring buffer must be locked for the multiple
|
||||
@@ -747,10 +764,10 @@ void *pField,
|
||||
unsigned int caEventMask
|
||||
)
|
||||
{
|
||||
struct dbCommon *pdbc = (struct dbCommon *)pRecord;
|
||||
struct evSubscrip *event;
|
||||
struct dbCommon * const pdbc = (struct dbCommon *)pRecord;
|
||||
struct evSubscrip * event;
|
||||
|
||||
if (pdbc->mlis.count == 0) return DB_EVENT_OK; /* no monitors set */
|
||||
if (pdbc->mlis.count == 0) return DB_EVENT_OK; /* no monitors set */
|
||||
|
||||
LOCKREC(pdbc);
|
||||
|
||||
@@ -762,8 +779,7 @@ unsigned int caEventMask
|
||||
* changed or pval==NULL and waiting on alarms and alarms changed
|
||||
*/
|
||||
if ( (event->paddr->pfield == (void *)pField || pField==NULL) &&
|
||||
(caEventMask & event->select)) {
|
||||
|
||||
(caEventMask & event->select) ) {
|
||||
db_post_single_event_private (event);
|
||||
}
|
||||
}
|
||||
@@ -778,8 +794,8 @@ unsigned int caEventMask
|
||||
*/
|
||||
void epicsShareAPI db_post_single_event (dbEventSubscription es)
|
||||
{
|
||||
struct evSubscrip *event = (struct evSubscrip *) es;
|
||||
struct dbCommon *precord = event->paddr->precord;
|
||||
struct evSubscrip * const event = (struct evSubscrip *) es;
|
||||
struct dbCommon * const precord = event->paddr->precord;
|
||||
|
||||
dbScanLock (precord);
|
||||
db_post_single_event_private (event);
|
||||
@@ -898,8 +914,8 @@ static int event_read ( struct event_que *ev_que )
|
||||
*/
|
||||
static void event_task (void *pParm)
|
||||
{
|
||||
struct event_user *evUser = (struct event_user *) pParm;
|
||||
struct event_que *ev_que;
|
||||
struct event_user * const evUser = (struct event_user *) pParm;
|
||||
struct event_que * ev_que;
|
||||
|
||||
/* init hook */
|
||||
if (evUser->init_func) {
|
||||
@@ -934,12 +950,14 @@ static void event_task (void *pParm)
|
||||
epicsMutexMustLock ( evUser->lock );
|
||||
}
|
||||
evUser->extraLaborBusy = FALSE;
|
||||
epicsMutexUnlock ( evUser->lock );
|
||||
|
||||
for ( ev_que = &evUser->firstque; ev_que;
|
||||
ev_que = ev_que->nextque ) {
|
||||
epicsMutexUnlock ( evUser->lock );
|
||||
event_read (ev_que);
|
||||
epicsMutexMustLock ( evUser->lock );
|
||||
}
|
||||
epicsMutexUnlock ( evUser->lock );
|
||||
|
||||
} while( ! evUser->pendexit );
|
||||
|
||||
@@ -975,7 +993,7 @@ int epicsShareAPI db_start_events (
|
||||
dbEventCtx ctx,const char *taskname, void (*init_func)(void *),
|
||||
void *init_func_arg, unsigned osiPriority )
|
||||
{
|
||||
struct event_user *evUser = (struct event_user *) ctx;
|
||||
struct event_user * const evUser = (struct event_user *) ctx;
|
||||
|
||||
epicsMutexMustLock ( evUser->lock );
|
||||
|
||||
@@ -995,7 +1013,8 @@ int epicsShareAPI db_start_events (
|
||||
taskname = EVENT_PEND_NAME;
|
||||
}
|
||||
evUser->taskid = epicsThreadCreate (
|
||||
taskname, osiPriority, epicsThreadGetStackSize(epicsThreadStackMedium),
|
||||
taskname, osiPriority,
|
||||
epicsThreadGetStackSize(epicsThreadStackMedium),
|
||||
event_task, (void *)evUser);
|
||||
if (!evUser->taskid) {
|
||||
epicsMutexUnlock ( evUser->lock );
|
||||
@@ -1008,9 +1027,10 @@ int epicsShareAPI db_start_events (
|
||||
/*
|
||||
* db_event_change_priority()
|
||||
*/
|
||||
void epicsShareAPI db_event_change_priority ( dbEventCtx ctx, unsigned epicsPriority )
|
||||
void epicsShareAPI db_event_change_priority ( dbEventCtx ctx,
|
||||
unsigned epicsPriority )
|
||||
{
|
||||
struct event_user * evUser = ( struct event_user * ) ctx;
|
||||
struct event_user * const evUser = ( struct event_user * ) ctx;
|
||||
epicsThreadSetPriority ( evUser->taskid, epicsPriority );
|
||||
}
|
||||
|
||||
@@ -1019,9 +1039,11 @@ void epicsShareAPI db_event_change_priority ( dbEventCtx ctx, unsigned epicsPrio
|
||||
*/
|
||||
void epicsShareAPI db_event_flow_ctrl_mode_on (dbEventCtx ctx)
|
||||
{
|
||||
struct event_user *evUser = (struct event_user *) ctx;
|
||||
struct event_user * const evUser = (struct event_user *) ctx;
|
||||
|
||||
epicsMutexMustLock ( evUser->lock );
|
||||
evUser->flowCtrlMode = TRUE;
|
||||
epicsMutexUnlock ( evUser->lock );
|
||||
/*
|
||||
* notify the event handler task
|
||||
*/
|
||||
@@ -1036,9 +1058,11 @@ void epicsShareAPI db_event_flow_ctrl_mode_on (dbEventCtx ctx)
|
||||
*/
|
||||
void epicsShareAPI db_event_flow_ctrl_mode_off (dbEventCtx ctx)
|
||||
{
|
||||
struct event_user *evUser = (struct event_user *) ctx;
|
||||
struct event_user * const evUser = (struct event_user *) ctx;
|
||||
|
||||
epicsMutexMustLock ( evUser->lock );
|
||||
evUser->flowCtrlMode = FALSE;
|
||||
epicsMutexUnlock ( evUser->lock );
|
||||
/*
|
||||
* notify the event handler task
|
||||
*/
|
||||
|
||||
@@ -266,11 +266,11 @@ static void scanpplCallFunc(const iocshArgBuf *args)
|
||||
{ scanppl(args[0].dval);}
|
||||
|
||||
/* scanpel */
|
||||
static const iocshArg scanpelArg0 = { "event name",iocshArgString};
|
||||
static const iocshArg scanpelArg0 = { "event number",iocshArgInt};
|
||||
static const iocshArg * const scanpelArgs[1] = {&scanpelArg0};
|
||||
static const iocshFuncDef scanpelFuncDef = {"scanpel",1,scanpelArgs};
|
||||
static void scanpelCallFunc(const iocshArgBuf *args)
|
||||
{ scanpel(args[0].sval);}
|
||||
{ scanpel(args[0].ival);}
|
||||
|
||||
/* scanpiol */
|
||||
static const iocshFuncDef scanpiolFuncDef = {"scanpiol",0};
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
* Revision-Id: anj@aps.anl.gov-20101005192737-disfz3vs0f3fiixd
|
||||
* Revision-Id: johill@lanl.gov-20111019180700-7u25j7zwo2w1894n
|
||||
*
|
||||
*
|
||||
* L O S A L A M O S
|
||||
@@ -74,7 +74,7 @@ void dbPutNotifyBlocker::cancel (
|
||||
epicsGuard < epicsMutex > & guard )
|
||||
{
|
||||
guard.assertIdenticalMutex ( this->mutex );
|
||||
if ( this->pn.paddr ) {
|
||||
if ( this->pNotify ) {
|
||||
epicsGuardRelease < epicsMutex > unguard ( guard );
|
||||
dbNotifyCancel ( &this->pn );
|
||||
}
|
||||
@@ -100,26 +100,31 @@ void dbPutNotifyBlocker::expandValueBuf (
|
||||
|
||||
extern "C" void putNotifyCompletion ( putNotify *ppn )
|
||||
{
|
||||
dbPutNotifyBlocker * pBlocker = static_cast < dbPutNotifyBlocker * > ( ppn->usrPvt );
|
||||
{
|
||||
epicsGuard < epicsMutex > guard ( pBlocker->mutex );
|
||||
if ( pBlocker->pNotify ) {
|
||||
if ( pBlocker->pn.status != putNotifyOK) {
|
||||
pBlocker->pNotify->exception (
|
||||
guard, ECA_PUTFAIL, "put notify unsuccessful",
|
||||
static_cast <unsigned> (pBlocker->pn.dbrType),
|
||||
static_cast <unsigned> (pBlocker->pn.nRequest) );
|
||||
}
|
||||
else {
|
||||
pBlocker->pNotify->completion ( guard );
|
||||
}
|
||||
dbPutNotifyBlocker * const pBlocker =
|
||||
static_cast < dbPutNotifyBlocker * > ( ppn->usrPvt );
|
||||
epicsGuard < epicsMutex > guard ( pBlocker->mutex );
|
||||
cacWriteNotify * const pNtfy = pBlocker->pNotify;
|
||||
if ( pNtfy ) {
|
||||
pBlocker->pNotify = 0;
|
||||
// Its necessary to signal the initiators now before we call
|
||||
// the user callback. This is less efficent, and potentially
|
||||
// causes more thread context switching, but its probably
|
||||
// unavoidable because its possible that the use callback
|
||||
// might destroy this object.
|
||||
pBlocker->block.signal ();
|
||||
if ( pBlocker->pn.status != putNotifyOK ) {
|
||||
pNtfy->exception (
|
||||
guard, ECA_PUTFAIL, "put notify unsuccessful",
|
||||
static_cast < unsigned > (pBlocker->pn.dbrType),
|
||||
static_cast < unsigned > (pBlocker->pn.nRequest) );
|
||||
}
|
||||
else {
|
||||
errlogPrintf ( "put notify completion with nill pNotify?\n" );
|
||||
pNtfy->completion ( guard );
|
||||
}
|
||||
pBlocker->pNotify = 0;
|
||||
}
|
||||
pBlocker->block.signal ();
|
||||
else {
|
||||
errlogPrintf ( "put notify completion with nill pNotify?\n" );
|
||||
}
|
||||
}
|
||||
|
||||
void dbPutNotifyBlocker::initiatePutNotify (
|
||||
|
||||
+75
-94
@@ -101,13 +101,12 @@ static char *priorityName[NUM_CALLBACK_PRIORITIES] = {
|
||||
|
||||
/* EVENT */
|
||||
|
||||
typedef struct event_list {
|
||||
CALLBACK callback[NUM_CALLBACK_PRIORITIES];
|
||||
scan_list scan_list[NUM_CALLBACK_PRIORITIES];
|
||||
struct event_list *next;
|
||||
char event_name[MAX_STRING_SIZE];
|
||||
} event_list;
|
||||
static event_list * volatile pevent_list[256];
|
||||
#define MAX_EVENTS 256
|
||||
typedef struct event_scan_list {
|
||||
CALLBACK callback;
|
||||
scan_list scan_list;
|
||||
} event_scan_list;
|
||||
static event_scan_list *pevent_list[NUM_CALLBACK_PRIORITIES][MAX_EVENTS];
|
||||
|
||||
|
||||
/* IO_EVENT*/
|
||||
@@ -205,24 +204,35 @@ void scanAdd(struct dbCommon *precord)
|
||||
recGblRecordError(-1, (void *)precord,
|
||||
"scanAdd detected illegal SCAN value");
|
||||
} else if (scan == menuScanEvent) {
|
||||
char* eventname;
|
||||
int evnt;
|
||||
int prio;
|
||||
event_list *pel;
|
||||
event_scan_list *pesl;
|
||||
|
||||
eventname = precord->evnt;
|
||||
if (strlen(eventname) >= MAX_STRING_SIZE) {
|
||||
evnt = precord->evnt;
|
||||
if (evnt < 0 || evnt >= MAX_EVENTS) {
|
||||
recGblRecordError(S_db_badField, (void *)precord,
|
||||
"scanAdd: too long EVNT value");
|
||||
"scanAdd detected illegal EVNT value");
|
||||
precord->scan = menuScanPassive;
|
||||
return;
|
||||
}
|
||||
prio = precord->prio;
|
||||
if (prio < 0 || prio >= NUM_CALLBACK_PRIORITIES) {
|
||||
recGblRecordError(-1, (void *)precord,
|
||||
"scanAdd: illegal prio field");
|
||||
precord->scan = menuScanPassive;
|
||||
return;
|
||||
}
|
||||
pel = eventNameToHandle(eventname);
|
||||
if (pel) addToList(precord, &pel->scan_list[prio]);
|
||||
pesl = pevent_list[prio][evnt];
|
||||
if (pesl == NULL) {
|
||||
pesl = dbCalloc(1, sizeof(event_scan_list));
|
||||
pevent_list[prio][evnt] = pesl;
|
||||
pesl->scan_list.lock = epicsMutexMustCreate();
|
||||
callbackSetCallback(eventCallback, &pesl->callback);
|
||||
callbackSetPriority(prio, &pesl->callback);
|
||||
callbackSetUser(pesl, &pesl->callback);
|
||||
ellInit(&pesl->scan_list.list);
|
||||
}
|
||||
addToList(precord, &pesl->scan_list);
|
||||
} else if (scan == menuScanI_O_Intr) {
|
||||
io_scan_list *piosl = NULL;
|
||||
int prio;
|
||||
@@ -277,25 +287,31 @@ void scanDelete(struct dbCommon *precord)
|
||||
recGblRecordError(-1, (void *)precord,
|
||||
"scanDelete detected illegal SCAN value");
|
||||
} else if (scan == menuScanEvent) {
|
||||
char* eventname;
|
||||
int evnt;
|
||||
int prio;
|
||||
event_list *pel;
|
||||
event_scan_list *pesl;
|
||||
scan_list *psl = 0;
|
||||
|
||||
eventname = precord->evnt;
|
||||
evnt = precord->evnt;
|
||||
if (evnt < 0 || evnt >= MAX_EVENTS) {
|
||||
recGblRecordError(S_db_badField, (void *)precord,
|
||||
"scanAdd detected illegal EVNT value");
|
||||
precord->scan = menuScanPassive;
|
||||
return;
|
||||
}
|
||||
prio = precord->prio;
|
||||
if (prio < 0 || prio >= NUM_CALLBACK_PRIORITIES) {
|
||||
recGblRecordError(-1, (void *)precord,
|
||||
"scanDelete detected illegal PRIO field");
|
||||
"scanAdd: illegal prio field");
|
||||
precord->scan = menuScanPassive;
|
||||
return;
|
||||
}
|
||||
do /* multithreading: make sure pel is consistent */
|
||||
pel = pevent_list[0];
|
||||
while (pel != pevent_list[0]);
|
||||
for (; pel; pel=pel->next) {
|
||||
if (strcmp(pel->event_name, eventname) == 0) break;
|
||||
}
|
||||
if (pel && (psl = &pel->scan_list[prio]))
|
||||
pesl = pevent_list[prio][evnt];
|
||||
if (pesl) psl = &pesl->scan_list;
|
||||
if (!pesl || !psl)
|
||||
recGblRecordError(-1, (void *)precord,
|
||||
"scanDelete for bad evnt");
|
||||
else
|
||||
deleteFromList(precord, psl);
|
||||
} else if (scan == menuScanI_O_Intr) {
|
||||
io_scan_list *piosl=NULL;
|
||||
@@ -356,22 +372,21 @@ int scanppl(double period) /* print periodic list */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int scanpel(char* eventname) /* print event list */
|
||||
int scanpel(int event_number) /* print event list */
|
||||
{
|
||||
char message[80];
|
||||
int prio;
|
||||
event_list *pel;
|
||||
|
||||
do /* multithreading: make sure pel is consistent */
|
||||
pel = pevent_list[0];
|
||||
while (pel != pevent_list[0]);
|
||||
for (; pel; pel = pel->next) {
|
||||
if (!eventname || strcmp(pel->event_name, eventname) == 0) {
|
||||
for (prio = 0; prio < NUM_CALLBACK_PRIORITIES; prio++) {
|
||||
if (ellCount(&pel->scan_list[prio].list) == 0) continue;
|
||||
sprintf(message, "Event \"%s\" Priority %s", pel->event_name, priorityName[prio]);
|
||||
printList(&pel->scan_list[prio], message);
|
||||
}
|
||||
int prio, evnt;
|
||||
event_scan_list *pesl;
|
||||
|
||||
for (evnt = 0; evnt < MAX_EVENTS; evnt++) {
|
||||
if (event_number && evnt<event_number) continue;
|
||||
if (event_number && evnt>event_number) break;
|
||||
for (prio = 0; prio < NUM_CALLBACK_PRIORITIES; prio++) {
|
||||
pesl = pevent_list[prio][evnt];
|
||||
if (!pesl) continue;
|
||||
if (ellCount(&pesl->scan_list.list) == 0) continue;
|
||||
sprintf(message, "Event %d Priority %s", evnt, priorityName[prio]);
|
||||
printList(&pesl->scan_list, message);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
@@ -397,73 +412,39 @@ int scanpiol(void) /* print io_event list */
|
||||
|
||||
static void eventCallback(CALLBACK *pcallback)
|
||||
{
|
||||
scan_list *psl;
|
||||
event_scan_list *pesl;
|
||||
|
||||
callbackGetUser(psl, pcallback);
|
||||
scanList(psl);
|
||||
callbackGetUser(pesl, pcallback);
|
||||
scanList(&pesl->scan_list);
|
||||
}
|
||||
|
||||
static void initEvent(void)
|
||||
{
|
||||
}
|
||||
int evnt, prio;
|
||||
|
||||
event_list *eventNameToHandle(char *eventname)
|
||||
{
|
||||
int prio;
|
||||
event_list *pel;
|
||||
static epicsMutexId lock = NULL;
|
||||
|
||||
if (!lock) lock = epicsMutexMustCreate();
|
||||
if (!eventname || eventname[0] == 0) return NULL;
|
||||
epicsMutexMustLock(lock);
|
||||
for (pel = pevent_list[0]; pel; pel=pel->next) {
|
||||
if (strcmp(pel->event_name, eventname) == 0) break;
|
||||
}
|
||||
if (pel == NULL) {
|
||||
pel = dbCalloc(1, sizeof(event_list));
|
||||
strcpy(pel->event_name, eventname);
|
||||
for (prio = 0; prio < NUM_CALLBACK_PRIORITIES; prio++) {
|
||||
callbackSetUser(&pel->scan_list[prio], &pel->callback[prio]);
|
||||
callbackSetPriority(prio, &pel->callback[prio]);
|
||||
callbackSetCallback(eventCallback, &pel->callback[prio]);
|
||||
pel->scan_list[prio].lock = epicsMutexMustCreate();
|
||||
ellInit(&pel->scan_list[prio].list);
|
||||
}
|
||||
pel->next=pevent_list[0];
|
||||
pevent_list[0]=pel;
|
||||
{ /* backward compatibility */
|
||||
char* p;
|
||||
long e = strtol(eventname, &p, 0);
|
||||
if (*p == 0 && e > 0 && e <= 255)
|
||||
pevent_list[e]=pel;
|
||||
}
|
||||
}
|
||||
epicsMutexUnlock(lock);
|
||||
return pel;
|
||||
}
|
||||
|
||||
void postEvent(event_list *pel)
|
||||
{
|
||||
int prio;
|
||||
|
||||
if (scanCtl != ctlRun) return;
|
||||
if (!pel) return;
|
||||
for (prio = 0; prio < NUM_CALLBACK_PRIORITIES; prio++) {
|
||||
if (ellCount(&pel->scan_list[prio].list) >0)
|
||||
callbackRequest(&pel->callback[prio]);
|
||||
for (evnt = 0; evnt < MAX_EVENTS; evnt++) {
|
||||
pevent_list[prio][evnt] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* backward compatibility */
|
||||
void post_event(int event)
|
||||
{
|
||||
event_list* pel;
|
||||
|
||||
if (event <= 0 || event > 255) return;
|
||||
do { /* multithreading: make sure pel is consistent */
|
||||
pel = pevent_list[event];
|
||||
} while (pel != pevent_list[event]);
|
||||
postEvent(pel);
|
||||
int prio;
|
||||
event_scan_list *pesl;
|
||||
|
||||
if (scanCtl != ctlRun) return;
|
||||
if (event < 0 || event >= MAX_EVENTS) {
|
||||
errMessage(-1, "illegal event passed to post_event");
|
||||
return;
|
||||
}
|
||||
for (prio=0; prio<NUM_CALLBACK_PRIORITIES; prio++) {
|
||||
pesl = pevent_list[prio][event];
|
||||
if (!pesl) continue;
|
||||
if (ellCount(&pesl->scan_list.list) >0)
|
||||
callbackRequest((void *)pesl);
|
||||
}
|
||||
}
|
||||
|
||||
void scanIoInit(IOSCANPVT *ppioscanpvt)
|
||||
|
||||
+2
-8
@@ -19,7 +19,6 @@
|
||||
|
||||
#include "menuScan.h"
|
||||
#include "shareLib.h"
|
||||
#include "compilerDependencies.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -33,13 +32,10 @@ extern "C" {
|
||||
#define MAX_PHASE SHRT_MAX
|
||||
#define MIN_PHASE SHRT_MIN
|
||||
|
||||
#define HAVE_NAMED_SOFT_EVENTS
|
||||
|
||||
/*definitions for I/O Interrupt Scanning */
|
||||
struct io_scan_list;
|
||||
|
||||
typedef struct io_scan_list *IOSCANPVT;
|
||||
typedef struct event_list *EVENTPVT;
|
||||
|
||||
struct dbCommon;
|
||||
|
||||
@@ -47,9 +43,7 @@ epicsShareFunc long scanInit(void);
|
||||
epicsShareFunc void scanRun(void);
|
||||
epicsShareFunc void scanPause(void);
|
||||
|
||||
epicsShareFunc EVENTPVT eventNameToHandle(char* event);
|
||||
epicsShareFunc void postEvent(EVENTPVT epvt);
|
||||
epicsShareFunc void post_event(int event) EPICS_DEPRECATED;
|
||||
epicsShareFunc void post_event(int event);
|
||||
epicsShareFunc void scanAdd(struct dbCommon *);
|
||||
epicsShareFunc void scanDelete(struct dbCommon *);
|
||||
epicsShareFunc double scanPeriod(int scan);
|
||||
@@ -60,7 +54,7 @@ epicsShareFunc int scanOnceSetQueueSize(int size);
|
||||
epicsShareFunc int scanppl(double rate);
|
||||
|
||||
/*print event lists*/
|
||||
epicsShareFunc int scanpel(char *event_name);
|
||||
epicsShareFunc int scanpel(int event_number);
|
||||
|
||||
/*print io_event list*/
|
||||
epicsShareFunc int scanpiol(void);
|
||||
|
||||
+31
-27
@@ -1,14 +1,13 @@
|
||||
/*************************************************************************\
|
||||
* 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.
|
||||
\*************************************************************************/
|
||||
/* dbExpand.c */
|
||||
/* Author: Marty Kraimer Date: 30NOV95 */
|
||||
/* Author: Marty Kraimer Date: 30NOV95 */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
@@ -25,24 +24,25 @@
|
||||
#include "osiFileName.h"
|
||||
|
||||
DBBASE *pdbbase = NULL;
|
||||
|
||||
|
||||
void usage(void)
|
||||
{
|
||||
fprintf(stderr, "Usage:\n\tdbExpand -Ipath -ooutfile "
|
||||
"-S macro=value file1.dbd file2.dbd ...\n");
|
||||
fprintf(stderr, "Usage:\n\tdbExpand -b -Ipath -ooutfile "
|
||||
"-S macro=value file1.dbd file2.dbd ...\n");
|
||||
fprintf(stderr,"Specifying any path will replace the default of '.'\n");
|
||||
fprintf(stderr,"The -b option enables relaxed breakpoint table checking\n");
|
||||
}
|
||||
|
||||
int main(int argc,char **argv)
|
||||
{
|
||||
char *path = NULL;
|
||||
char *sub = NULL;
|
||||
int pathLength = 0;
|
||||
int subLength = 0;
|
||||
char *path = NULL;
|
||||
char *sub = NULL;
|
||||
int pathLength = 0;
|
||||
int subLength = 0;
|
||||
char *outFilename = NULL;
|
||||
FILE *outFP = stdout;
|
||||
long status;
|
||||
long returnStatus = 0;
|
||||
long status;
|
||||
long returnStatus = 0;
|
||||
static char *pathSep = OSI_PATH_LIST_SEPARATOR;
|
||||
static char *subSep = ",";
|
||||
|
||||
@@ -53,8 +53,8 @@ int main(int argc,char **argv)
|
||||
while ((argc > 1) && (**argv == '-')) {
|
||||
char optLtr = (*argv)[1];
|
||||
char *optArg;
|
||||
|
||||
if (strlen(*argv) > 2) {
|
||||
|
||||
if (strlen(*argv) > 2 || optLtr == 'b') {
|
||||
optArg = *argv+2;
|
||||
++argv;
|
||||
--argc;
|
||||
@@ -63,36 +63,40 @@ int main(int argc,char **argv)
|
||||
argv += 2;
|
||||
argc -= 2;
|
||||
}
|
||||
|
||||
|
||||
switch (optLtr) {
|
||||
case 'o':
|
||||
outFilename = optArg;
|
||||
break;
|
||||
|
||||
|
||||
case 'I':
|
||||
dbCatString(&path, &pathLength, optArg, pathSep);
|
||||
break;
|
||||
|
||||
|
||||
case 'S':
|
||||
dbCatString(&sub, &subLength, optArg, subSep);
|
||||
break;
|
||||
|
||||
|
||||
case 'b':
|
||||
dbBptNotMonotonic = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "dbExpand: Unknown option '-%c'\n", optLtr);
|
||||
usage();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (argc < 1) {
|
||||
fprintf(stderr, "dbExpand: No input file specified\n");
|
||||
fprintf(stderr, "dbExpand: No input file specified\n");
|
||||
usage();
|
||||
exit(1);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
for (; argc>0; --argc, ++argv) {
|
||||
status = dbReadDatabase(&pdbbase,*argv,path,sub);
|
||||
if (status) returnStatus = status;
|
||||
status = dbReadDatabase(&pdbbase,*argv,path,sub);
|
||||
if (status) returnStatus = status;
|
||||
}
|
||||
if (returnStatus) {
|
||||
errlogFlush();
|
||||
@@ -106,7 +110,7 @@ int main(int argc,char **argv)
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
dbWriteMenuFP(pdbbase,outFP,0);
|
||||
dbWriteRecordTypeFP(pdbbase,outFP,0);
|
||||
dbWriteDeviceFP(pdbbase,outFP);
|
||||
@@ -116,7 +120,7 @@ int main(int argc,char **argv)
|
||||
dbWriteVariableFP(pdbbase,outFP);
|
||||
dbWriteBreaktableFP(pdbbase,outFP);
|
||||
dbWriteRecordFP(pdbbase,outFP,0,0);
|
||||
|
||||
|
||||
free((void *)path);
|
||||
free((void *)sub);
|
||||
return 0;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* Revision-Id: anj@aps.anl.gov-20101005192737-disfz3vs0f3fiixd */
|
||||
/* Revision-Id: anj@aps.anl.gov-20111129221419-re5dzg24xgranr6t */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
@@ -3916,7 +3916,7 @@ void epicsShareAPI dbDumpField(
|
||||
else
|
||||
printf("\t field_type: %s\n", pamapdbfType[j].strvalue);
|
||||
printf("\tprocess_passive: %hd\n",pdbFldDes->process_passive);
|
||||
printf("\t base: %hd\n",pdbFldDes->base);
|
||||
printf("\t base: %d\n",pdbFldDes->base);
|
||||
if(!pdbFldDes->promptgroup) {
|
||||
printf("\t promptgroup: %d\n",pdbFldDes->promptgroup);
|
||||
} else {
|
||||
@@ -3929,7 +3929,7 @@ void epicsShareAPI dbDumpField(
|
||||
}
|
||||
}
|
||||
printf("\t interest: %hd\n", pdbFldDes->interest);
|
||||
printf("\t as_level: %hd\n",pdbFldDes->as_level);
|
||||
printf("\t as_level: %d\n",pdbFldDes->as_level);
|
||||
printf("\t initial: %s\n",
|
||||
(pdbFldDes->initial ? pdbFldDes->initial : ""));
|
||||
if(pdbFldDes->field_type==DBF_MENU) {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* Revision-Id: anj@aps.anl.gov-20101005192737-disfz3vs0f3fiixd
|
||||
/* Revision-Id: anj@aps.anl.gov-20111128185555-mu76mhfkfutzrdca
|
||||
*
|
||||
* Author: Marty Kraimer
|
||||
* Date: 06-08-93
|
||||
@@ -74,6 +74,8 @@ epicsShareFunc DBENTRY * epicsShareAPI dbCopyEntry(DBENTRY *pdbentry);
|
||||
epicsShareFunc void epicsShareAPI dbCopyEntryContents(DBENTRY *pfrom,
|
||||
DBENTRY *pto);
|
||||
|
||||
epicsShareExtern int dbBptNotMonotonic;
|
||||
|
||||
epicsShareFunc long epicsShareAPI dbReadDatabase(DBBASE **ppdbbase,
|
||||
const char *filename, const char *path, const char *substitutions);
|
||||
epicsShareFunc long epicsShareAPI dbReadDatabaseFP(DBBASE **ppdbbase,
|
||||
|
||||
@@ -51,7 +51,7 @@ static long init_record(eventRecord *prec)
|
||||
/* INP must be CONSTANT, PV_LINK, DB_LINK or CA_LINK*/
|
||||
switch (prec->inp.type) {
|
||||
case CONSTANT:
|
||||
if (recGblInitConstantLink(&prec->inp, DBF_STRING, &prec->val))
|
||||
if (recGblInitConstantLink(&prec->inp, DBF_USHORT, &prec->val))
|
||||
prec->udf = FALSE;
|
||||
break;
|
||||
case PV_LINK:
|
||||
@@ -69,20 +69,13 @@ static long init_record(eventRecord *prec)
|
||||
static long read_event(eventRecord *prec)
|
||||
{
|
||||
long status;
|
||||
char newEvent[MAX_STRING_SIZE];
|
||||
|
||||
if (prec->inp.type != CONSTANT)
|
||||
{
|
||||
status = dbGetLinkValue(&prec->inp, DBR_STRING, newEvent, 0, 0);
|
||||
if (status) return status;
|
||||
if (strcmp(newEvent, prec->val) != 0) {
|
||||
strcpy(prec->val, newEvent);
|
||||
prec->epvt = eventNameToHandle(prec->val);
|
||||
}
|
||||
status = dbGetLink(&prec->inp, DBR_USHORT, &prec->val, 0, 0);
|
||||
if (!status) {
|
||||
prec->udf = FALSE;
|
||||
if (prec->tsel.type == CONSTANT &&
|
||||
prec->tse == epicsTimeEventDeviceTime)
|
||||
dbGetTimeStamp(&prec->inp, &prec->time);
|
||||
}
|
||||
prec->udf = FALSE;
|
||||
if (prec->tsel.type == CONSTANT &&
|
||||
prec->tse == epicsTimeEventDeviceTime)
|
||||
dbGetTimeStamp(&prec->inp, &prec->time);
|
||||
return 0;
|
||||
return status;
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
#*************************************************************************
|
||||
# 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.
|
||||
@@ -19,7 +19,7 @@ SRC_DIRS += $(TOP)/src/makeBaseApp/top/caServerApp
|
||||
#
|
||||
# Added ws2_32 winmm user32 for the non-dll build
|
||||
#
|
||||
SYS_PROD_LIBS_WIN32 += ws2_32 advapi32 user32
|
||||
PROD_SYS_LIBS_WIN32 += ws2_32 advapi32 user32
|
||||
|
||||
|
||||
PROD_HOST = excas
|
||||
|
||||
+2
-2
@@ -10,7 +10,7 @@
|
||||
// Author: Jim Kowalkowski
|
||||
// Date: 2/96
|
||||
//
|
||||
// Revision-Id: anj@aps.anl.gov-20101005192737-disfz3vs0f3fiixd
|
||||
// Revision-Id: anj@aps.anl.gov-20111129221419-re5dzg24xgranr6t
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -1109,7 +1109,7 @@ gddStatus gdd::clearData(void)
|
||||
str->clear();
|
||||
}
|
||||
else if ( this->primitiveType() == aitEnumFixedString ) {
|
||||
memset ( this->data.FString, '\0', sizeof ( this->data.FString ) );
|
||||
memset ( this->data.FString, '\0', sizeof(aitFixedString) );
|
||||
}
|
||||
else {
|
||||
memset ( & this->data, '\0', sizeof ( this->data ) );
|
||||
|
||||
@@ -222,8 +222,6 @@ SRCS += epicsTempFile.cpp
|
||||
SRCS += epicsStdio.c
|
||||
SRCS += osdStdio.c
|
||||
|
||||
osdEnv_CFLAGS_WIN32= -U__STDC__
|
||||
|
||||
SRCS += osdThread.c
|
||||
SRCS += osdMutex.c
|
||||
SRCS += osdEvent.c
|
||||
|
||||
@@ -405,12 +405,10 @@ epicsShareFunc long
|
||||
pstacktop--;
|
||||
}
|
||||
|
||||
/*
|
||||
* if (cond_count != 0) {
|
||||
* *perror = CALC_ERR_CONDITIONAL;
|
||||
* goto bad;
|
||||
* }
|
||||
*/
|
||||
if (cond_count != 0) {
|
||||
*perror = CALC_ERR_CONDITIONAL;
|
||||
goto bad;
|
||||
}
|
||||
if (runtime_depth > 1) {
|
||||
*perror = CALC_ERR_TOOMANY;
|
||||
goto bad;
|
||||
@@ -454,12 +452,10 @@ epicsShareFunc long
|
||||
}
|
||||
*pout = END_EXPRESSION;
|
||||
|
||||
/*
|
||||
* if (cond_count != 0) {
|
||||
* *perror = CALC_ERR_CONDITIONAL;
|
||||
* goto bad;
|
||||
* }
|
||||
*/
|
||||
if (cond_count != 0) {
|
||||
*perror = CALC_ERR_CONDITIONAL;
|
||||
goto bad;
|
||||
}
|
||||
if (operand_needed || runtime_depth != 1) {
|
||||
*perror = CALC_ERR_INCOMPLETE;
|
||||
goto bad;
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
* Revision-Id: anj@aps.anl.gov-20101005192737-disfz3vs0f3fiixd
|
||||
* Revision-Id: ralph.lange@gmx.de-20110808163119-szktwmb8pwbw5cec
|
||||
*
|
||||
* Author: Jeffrey O. Hill
|
||||
*
|
||||
@@ -34,7 +34,7 @@ public:
|
||||
void * pInstance () const;
|
||||
private:
|
||||
void * _pInstance;
|
||||
size_t _refCount;
|
||||
std :: size_t _refCount;
|
||||
SingletonUntyped ( const SingletonUntyped & );
|
||||
SingletonUntyped & operator = ( const SingletonUntyped & );
|
||||
};
|
||||
|
||||
@@ -282,13 +282,6 @@ void ellFree2 (ELLLIST *pList, FREEFUNC freeFunc)
|
||||
pList->count = 0;
|
||||
}
|
||||
|
||||
/* for backward compatibility provide a function ellFree() in addition to macro */
|
||||
#undef ellFree
|
||||
void ellFree (ELLLIST *pList)
|
||||
{
|
||||
ellFree2 (pList, free);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* This function verifies that the list is consistent.
|
||||
|
||||
@@ -41,7 +41,6 @@
|
||||
/*Declare storage for errVerbose */
|
||||
epicsShareDef int errVerbose = 0;
|
||||
|
||||
static void errlogCleanup(void);
|
||||
static void exitHandler(void *);
|
||||
static void errlogThread(void);
|
||||
|
||||
@@ -391,8 +390,15 @@ static void exitHandler(void *pvt)
|
||||
pvtData.atExit = 1;
|
||||
epicsEventSignal(pvtData.waitForWork);
|
||||
epicsEventMustWait(pvtData.waitForExit);
|
||||
|
||||
free(pvtData.pbuffer);
|
||||
epicsMutexDestroy(pvtData.flushLock);
|
||||
epicsEventDestroy(pvtData.flush);
|
||||
epicsEventDestroy(pvtData.waitForFlush);
|
||||
epicsMutexDestroy(pvtData.listenerLock);
|
||||
epicsMutexDestroy(pvtData.msgQueueLock);
|
||||
epicsEventDestroy(pvtData.waitForWork);
|
||||
epicsEventDestroy(pvtData.waitForExit);
|
||||
return;
|
||||
}
|
||||
|
||||
struct initArgs {
|
||||
@@ -432,18 +438,6 @@ static void errlogInitPvt(void *arg)
|
||||
pvtData.errlogInitFailed = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void errlogCleanup(void)
|
||||
{
|
||||
free(pvtData.pbuffer);
|
||||
epicsMutexDestroy(pvtData.flushLock);
|
||||
epicsEventDestroy(pvtData.flush);
|
||||
epicsEventDestroy(pvtData.waitForFlush);
|
||||
epicsMutexDestroy(pvtData.listenerLock);
|
||||
epicsMutexDestroy(pvtData.msgQueueLock);
|
||||
epicsEventDestroy(pvtData.waitForWork);
|
||||
/*Note that exitHandler must destroy waitForExit*/
|
||||
}
|
||||
|
||||
epicsShareFunc int epicsShareAPI errlogInit2(int bufsize, int maxMsgSize)
|
||||
{
|
||||
@@ -514,7 +508,6 @@ static void errlogThread(void)
|
||||
epicsThreadSleep(.2); /*just wait an extra .2 seconds*/
|
||||
epicsEventSignal(pvtData.waitForFlush);
|
||||
}
|
||||
errlogCleanup();
|
||||
epicsEventSignal(pvtData.waitForExit);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Saskatchewan
|
||||
* 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.
|
||||
\*************************************************************************/
|
||||
/*
|
||||
* Revision-Id: anj@aps.anl.gov-20101005192737-disfz3vs0f3fiixd
|
||||
* Revision-Id: anj@aps.anl.gov-20110909221435-fdjubbxunee9gs44
|
||||
*
|
||||
* Author: Eric Norum
|
||||
*/
|
||||
@@ -13,10 +12,6 @@
|
||||
#ifndef osdSockH
|
||||
#define osdSockH
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
@@ -24,8 +19,6 @@ extern "C" {
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
/*#include <sys/filio.h>
|
||||
#include <sys/sockio.h>*/
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <arpa/inet.h>
|
||||
@@ -34,10 +27,6 @@ extern "C" {
|
||||
#include <unistd.h> /* close() and others */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef int SOCKET;
|
||||
#define INVALID_SOCKET (-1)
|
||||
#define SOCKERRNO errno
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
* 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.
|
||||
\*************************************************************************/
|
||||
|
||||
@@ -26,10 +25,6 @@
|
||||
#ifndef osdSockH
|
||||
#define osdSockH
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
@@ -37,8 +32,6 @@ extern "C" {
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
/*#include <sys/filio.h>
|
||||
#include <sys/sockio.h>*/
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <arpa/inet.h>
|
||||
@@ -47,10 +40,6 @@ extern "C" {
|
||||
#include <unistd.h> /* close() and others */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef int SOCKET;
|
||||
#define INVALID_SOCKET (-1)
|
||||
#define SOCKERRNO errno
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Saskatchewan
|
||||
* 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.
|
||||
\*************************************************************************/
|
||||
/*
|
||||
* RTEMS osdSock.h
|
||||
* Revision-Id: anj@aps.anl.gov-20101005192737-disfz3vs0f3fiixd
|
||||
* Revision-Id: anj@aps.anl.gov-20110909221435-fdjubbxunee9gs44
|
||||
* Author: W. Eric Norum
|
||||
* eric@cls.usask.ca
|
||||
* (306) 966-6055
|
||||
@@ -14,10 +13,6 @@
|
||||
#ifndef osdSockH
|
||||
#define osdSockH
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
@@ -32,6 +27,10 @@ extern "C" {
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/*
|
||||
* Revision-Id: ralph.lange@bessy.de-20101020143551-76qdww31y8v01l24
|
||||
* Revision-Id: anj@aps.anl.gov-20110823182000-bubidbqy4olqqdvq
|
||||
*
|
||||
* Author: W. Eric Norum
|
||||
*/
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <rtems/rtems_bsdnet_internal.h>
|
||||
#include "epicsTime.h"
|
||||
#include "osdTime.h"
|
||||
#include "osiNTPTime.h"
|
||||
@@ -117,17 +118,21 @@ double rtemsTicksPerSecond_double, rtemsTicksPerTwoSeconds_double;
|
||||
* explicitly calls osdTimeRegister() at the appropriate time.
|
||||
* However if we are loaded dynamically we *do* register our
|
||||
* standard time providers at static constructor time; in this
|
||||
* case the tick rate will have been set already.
|
||||
* case the network is available already.
|
||||
*/
|
||||
static int staticTimeRegister(void)
|
||||
{
|
||||
if (rtemsTicksPerSecond != 0)
|
||||
osdTimeRegister();
|
||||
|
||||
rtems_clock_get (RTEMS_CLOCK_GET_TICKS_PER_SECOND, &rtemsTicksPerSecond);
|
||||
rtemsTicksPerSecond_double = rtemsTicksPerSecond;
|
||||
rtemsTicksPerTwoSeconds_double = rtemsTicksPerSecond_double * 2.0;
|
||||
|
||||
/* If networking is already up at the time static constructors
|
||||
* are executed then we are probably run-time loaded and it's
|
||||
* OK to osdTimeRegister() at this point.
|
||||
*/
|
||||
if (rtems_bsdnet_ticks_per_second != 0)
|
||||
osdTimeRegister();
|
||||
|
||||
return 1;
|
||||
}
|
||||
static int done = staticTimeRegister();
|
||||
|
||||
@@ -3,15 +3,12 @@
|
||||
* 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.
|
||||
\*************************************************************************/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#ifndef osdSockH
|
||||
#define osdSockH
|
||||
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
@@ -25,9 +22,6 @@ extern "C" {
|
||||
#endif
|
||||
#include <winsock2.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#define SOCKERRNO WSAGetLastError()
|
||||
|
||||
@@ -79,3 +73,4 @@ typedef int osiSocklen_t;
|
||||
|
||||
epicsShareFunc unsigned epicsShareAPI wsaMajorVersion ();
|
||||
|
||||
#endif /*osdSockH*/
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
* Revision-Id: anj@aps.anl.gov-20110211223358-q0hz1pcfll3an46f
|
||||
* Revision-Id: anj@aps.anl.gov-20111108215715-d8j6l4lycpi3gvvb
|
||||
*
|
||||
* Author: Jeff Hill
|
||||
*
|
||||
@@ -272,10 +272,6 @@ static void threadCleanupWIN32 ( void )
|
||||
ellFirst ( & pGbl->threadList ) ) ) {
|
||||
epicsParmCleanupWIN32 ( pParm );
|
||||
}
|
||||
|
||||
TlsFree ( pGbl->tlsIndexThreadLibraryEPICS );
|
||||
|
||||
DeleteCriticalSection ( & pGbl->mutex );
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
\*************************************************************************/
|
||||
|
||||
//
|
||||
// Revision-Id: johill@lanl.gov-20110115005649-10sil49p7idx8lpe
|
||||
// Revision-Id: anj@aps.anl.gov-20111129200729-1bx6zsmjnog13sf0
|
||||
//
|
||||
// Author: Jeff Hill
|
||||
//
|
||||
@@ -61,6 +61,9 @@ static int osdTimeGetCurrent ( epicsTimeStamp *pDest );
|
||||
#if !defined ( MAXLONGLONG )
|
||||
#define MAXLONGLONG LL_CONSTANT(0x7fffffffffffffff)
|
||||
#endif
|
||||
#if !defined ( MINLONGLONG )
|
||||
#define MINLONGLONG LL_CONSTANT(~0x7fffffffffffffff)
|
||||
#endif
|
||||
|
||||
static const LONGLONG epicsEpochInFileTime = LL_CONSTANT(0x01b41e2a18d64000);
|
||||
|
||||
@@ -81,7 +84,7 @@ private:
|
||||
epicsTimerQueueActive * pTimerQueue;
|
||||
epicsTimer * pTimer;
|
||||
bool perfCtrPresent;
|
||||
|
||||
static const int pllDelay; /* integer seconds */
|
||||
epicsTimerNotify::expireStatus expire ( const epicsTime & );
|
||||
};
|
||||
|
||||
@@ -91,6 +94,8 @@ static const LONGLONG EPICS_TIME_TICKS_PER_SEC = 1000000000;
|
||||
static const LONGLONG ET_TICKS_PER_FT_TICK =
|
||||
EPICS_TIME_TICKS_PER_SEC / FILE_TIME_TICKS_PER_SEC;
|
||||
|
||||
const int currentTime :: pllDelay = 5;
|
||||
|
||||
//
|
||||
// Start and register time provider
|
||||
//
|
||||
@@ -302,8 +307,8 @@ currentTime::currentTime () :
|
||||
}
|
||||
else {
|
||||
errlogPrintf (
|
||||
"win32 osdTime.cpp detected questionable "
|
||||
"system date prior to EPICS epoch\n" );
|
||||
"win32 osdTime.cpp init detected questionable "
|
||||
"system date prior to EPICS epoch, epics time will not advance\n" );
|
||||
this->epicsTimeLast = 0;
|
||||
}
|
||||
|
||||
@@ -346,7 +351,7 @@ void currentTime::getCurrentTime ( epicsTimeStamp & dest )
|
||||
// counter resolution will more than likely improve over time.
|
||||
//
|
||||
offset = ( MAXLONGLONG - this->lastPerfCounter )
|
||||
+ ( curPerfCounter.QuadPart + MAXLONGLONG );
|
||||
+ ( curPerfCounter.QuadPart - MINLONGLONG ) + 1;
|
||||
}
|
||||
if ( offset < MAXLONGLONG / EPICS_TIME_TICKS_PER_SEC ) {
|
||||
offset *= EPICS_TIME_TICKS_PER_SEC;
|
||||
@@ -392,6 +397,8 @@ void currentTime::getCurrentTime ( epicsTimeStamp & dest )
|
||||
//
|
||||
epicsTimerNotify::expireStatus currentTime::expire ( const epicsTime & )
|
||||
{
|
||||
EnterCriticalSection ( & this->mutex );
|
||||
|
||||
// avoid interruptions by briefly becoming a time critical thread
|
||||
LARGE_INTEGER curFileTime;
|
||||
LARGE_INTEGER curPerfCounter;
|
||||
@@ -407,8 +414,6 @@ epicsTimerNotify::expireStatus currentTime::expire ( const epicsTime & )
|
||||
curFileTime.HighPart = ft.dwHighDateTime;
|
||||
}
|
||||
|
||||
EnterCriticalSection ( & this->mutex );
|
||||
|
||||
LONGLONG perfCounterDiff;
|
||||
if ( curPerfCounter.QuadPart >= this->lastPerfCounterPLL ) {
|
||||
perfCounterDiff = curPerfCounter.QuadPart - this->lastPerfCounterPLL;
|
||||
@@ -424,7 +429,7 @@ epicsTimerNotify::expireStatus currentTime::expire ( const epicsTime & )
|
||||
// counter resolution will more than likely improve over time.
|
||||
//
|
||||
perfCounterDiff = ( MAXLONGLONG - this->lastPerfCounterPLL )
|
||||
+ ( curPerfCounter.QuadPart + MAXLONGLONG );
|
||||
+ ( curPerfCounter.QuadPart - MINLONGLONG ) + 1;
|
||||
}
|
||||
this->lastPerfCounterPLL = curPerfCounter.QuadPart;
|
||||
|
||||
@@ -432,10 +437,10 @@ epicsTimerNotify::expireStatus currentTime::expire ( const epicsTime & )
|
||||
this->lastFileTimePLL = curFileTime.QuadPart;
|
||||
|
||||
// discard glitches
|
||||
if ( fileTimeDiff == 0 ) {
|
||||
if ( fileTimeDiff <= 0 ) {
|
||||
LeaveCriticalSection( & this->mutex );
|
||||
debugPrintf ( ( "currentTime: file time difference in PLL was zero\n" ) );
|
||||
return expireStatus ( restart, 1.0 /* sec */ );
|
||||
debugPrintf ( ( "currentTime: file time difference in PLL was less than zero\n" ) );
|
||||
return expireStatus ( restart, pllDelay /* sec */ );
|
||||
}
|
||||
|
||||
LONGLONG freq = ( FILE_TIME_TICKS_PER_SEC * perfCounterDiff ) / fileTimeDiff;
|
||||
@@ -449,7 +454,7 @@ epicsTimerNotify::expireStatus currentTime::expire ( const epicsTime & )
|
||||
static_cast < int > ( -bound ),
|
||||
static_cast < int > ( delta ),
|
||||
static_cast < int > ( bound ) ) );
|
||||
return expireStatus ( restart, 1.0 /* sec */ );
|
||||
return expireStatus ( restart, pllDelay /* sec */ );
|
||||
}
|
||||
|
||||
// update feedback loop estimating the performance counter's frequency
|
||||
@@ -473,7 +478,21 @@ epicsTimerNotify::expireStatus currentTime::expire ( const epicsTime & )
|
||||
//
|
||||
perfCounterDiffSinceLastFetch =
|
||||
( MAXLONGLONG - this->lastPerfCounter )
|
||||
+ ( curPerfCounter.QuadPart + MAXLONGLONG );
|
||||
+ ( curPerfCounter.QuadPart - MINLONGLONG ) + 1;
|
||||
}
|
||||
|
||||
// discard performance counter delay measurement glitches
|
||||
{
|
||||
const LONGLONG expectedDly = this->perfCounterFreq * pllDelay;
|
||||
const LONGLONG bnd = expectedDly / 4;
|
||||
if ( perfCounterDiffSinceLastFetch <= 0 ||
|
||||
perfCounterDiffSinceLastFetch >= expectedDly + bnd ) {
|
||||
LeaveCriticalSection( & this->mutex );
|
||||
debugPrintf ( ( "perf ctr measured delay out of bounds m=%d max=%d\n",
|
||||
static_cast < int > ( perfCounterDiffSinceLastFetch ),
|
||||
static_cast < int > ( expectedDly + bnd ) ) );
|
||||
return expireStatus ( restart, pllDelay /* sec */ );
|
||||
}
|
||||
}
|
||||
|
||||
// Update the current estimated time.
|
||||
@@ -482,9 +501,32 @@ epicsTimerNotify::expireStatus currentTime::expire ( const epicsTime & )
|
||||
/ this->perfCounterFreq;
|
||||
this->lastPerfCounter = curPerfCounter.QuadPart;
|
||||
|
||||
LONGLONG epicsTimeFromCurrentFileTime =
|
||||
( curFileTime.QuadPart - epicsEpochInFileTime ) *
|
||||
ET_TICKS_PER_FT_TICK;
|
||||
LONGLONG epicsTimeFromCurrentFileTime;
|
||||
|
||||
{
|
||||
static bool firstMessageWasSent = false;
|
||||
if ( curFileTime.QuadPart >= epicsEpochInFileTime ) {
|
||||
epicsTimeFromCurrentFileTime =
|
||||
( curFileTime.QuadPart - epicsEpochInFileTime ) *
|
||||
ET_TICKS_PER_FT_TICK;
|
||||
firstMessageWasSent = false;
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* if the system time jumps to before the EPICS epoch
|
||||
* then latch to the EPICS epoch printing only one
|
||||
* warning message the first time that the issue is
|
||||
* detected
|
||||
*/
|
||||
if ( ! firstMessageWasSent ) {
|
||||
errlogPrintf (
|
||||
"win32 osdTime.cpp time PLL update detected questionable "
|
||||
"system date prior to EPICS epoch, epics time will not advance\n" );
|
||||
firstMessageWasSent = true;
|
||||
}
|
||||
epicsTimeFromCurrentFileTime = 0;
|
||||
}
|
||||
}
|
||||
|
||||
delta = epicsTimeFromCurrentFileTime - this->epicsTimeLast;
|
||||
if ( delta > EPICS_TIME_TICKS_PER_SEC || delta < -EPICS_TIME_TICKS_PER_SEC ) {
|
||||
@@ -537,7 +579,7 @@ epicsTimerNotify::expireStatus currentTime::expire ( const epicsTime & )
|
||||
|
||||
LeaveCriticalSection ( & this->mutex );
|
||||
|
||||
return expireStatus ( restart, 1.0 /* sec */ );
|
||||
return expireStatus ( restart, pllDelay /* sec */ );
|
||||
}
|
||||
|
||||
void currentTime::startPLL ()
|
||||
@@ -546,7 +588,7 @@ void currentTime::startPLL ()
|
||||
if ( this->perfCtrPresent && ! this->pTimerQueue ) {
|
||||
this->pTimerQueue = & epicsTimerQueueActive::allocate ( true );
|
||||
this->pTimer = & this->pTimerQueue->createTimer ();
|
||||
this->pTimer->start ( *this, 1.0 );
|
||||
this->pTimer->start ( *this, pllDelay );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
* 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.
|
||||
\*************************************************************************/
|
||||
/*
|
||||
@@ -15,10 +14,6 @@
|
||||
#ifndef osdSockH
|
||||
#define osdSockH
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
@@ -31,10 +26,7 @@ extern "C" {
|
||||
#include <netdb.h>
|
||||
#include <unistd.h> /* close() and others */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
typedef int SOCKET;
|
||||
#define INVALID_SOCKET (-1)
|
||||
#define SOCKERRNO errno
|
||||
|
||||
@@ -10,10 +10,6 @@
|
||||
#ifndef osdSockH
|
||||
#define osdSockH
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
@@ -29,10 +25,6 @@ extern "C" {
|
||||
#include <unistd.h> /* close() and others */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef IPPORT_USERRESERVED
|
||||
#define IPPORT_USERRESERVED 5000
|
||||
#endif
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
* Revision-Id: anj@aps.anl.gov-20101005192737-disfz3vs0f3fiixd
|
||||
* Revision-Id: anj@aps.anl.gov-20110909221435-fdjubbxunee9gs44
|
||||
*
|
||||
* Author: Eric Norum
|
||||
*/
|
||||
@@ -13,10 +13,6 @@
|
||||
#ifndef osdSockH
|
||||
#define osdSockH
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
@@ -24,8 +20,6 @@ extern "C" {
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
/*#include <sys/filio.h>
|
||||
#include <sys/sockio.h>*/
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <arpa/inet.h>
|
||||
@@ -34,10 +28,6 @@ extern "C" {
|
||||
#include <unistd.h> /* close() and others */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef int SOCKET;
|
||||
#define INVALID_SOCKET (-1)
|
||||
#define SOCKERRNO errno
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef isfinite
|
||||
# undef finite
|
||||
# define finite(x) isfinite(x)
|
||||
#endif
|
||||
|
||||
epicsShareExtern float epicsNAN;
|
||||
epicsShareExtern float epicsINF;
|
||||
|
||||
|
||||
@@ -75,6 +75,13 @@ typedef struct epicsThreadOSD {
|
||||
char *name;
|
||||
} epicsThreadOSD;
|
||||
|
||||
#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
|
||||
typedef struct {
|
||||
int min_pri, max_pri;
|
||||
int policy;
|
||||
} priAvailable;
|
||||
#endif
|
||||
|
||||
static pthread_key_t getpthreadInfo;
|
||||
static pthread_mutex_t onceLock;
|
||||
static pthread_mutex_t listLock;
|
||||
@@ -201,6 +208,101 @@ static void free_threadInfo(epicsThreadOSD *pthreadInfo)
|
||||
free(pthreadInfo);
|
||||
}
|
||||
|
||||
#if defined (_POSIX_THREAD_PRIORITY_SCHEDULING)
|
||||
/*
|
||||
* The actually available range priority range (at least under linux)
|
||||
* may be restricted by resource limitations (but that is ignored
|
||||
* by sched_get_priority_max()). See bug #835138 which is fixed by
|
||||
* this code.
|
||||
*/
|
||||
|
||||
static int try_pri(int pri, int policy)
|
||||
{
|
||||
struct sched_param schedp;
|
||||
|
||||
schedp.sched_priority = pri;
|
||||
return pthread_setschedparam(pthread_self(), policy, &schedp);
|
||||
}
|
||||
|
||||
static void*
|
||||
find_pri_range(void *arg)
|
||||
{
|
||||
priAvailable *prm = arg;
|
||||
int min = sched_get_priority_min(prm->policy);
|
||||
int max = sched_get_priority_max(prm->policy);
|
||||
int low, try;
|
||||
|
||||
if ( -1 == min || -1 == max ) {
|
||||
/* something is very wrong; maintain old behavior
|
||||
* (warning message if sched_get_priority_xxx() fails
|
||||
* and use default policy's sched_priority [even if
|
||||
* that is likely to cause epicsThreadCreate to fail
|
||||
* because that priority is not suitable for SCHED_FIFO]).
|
||||
*/
|
||||
prm->min_pri = prm->max_pri = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if ( try_pri(min, prm->policy) ) {
|
||||
/* cannot create thread at minimum priority;
|
||||
* probably no permission to use SCHED_FIFO
|
||||
* at all. However, we still must return
|
||||
* a priority range accepted by the SCHED_FIFO
|
||||
* policy. Otherwise, epicsThreadCreate() cannot
|
||||
* detect the unsufficient permission (EPERM)
|
||||
* and fall back to a non-RT thread (because
|
||||
* pthread_attr_setschedparam would fail with
|
||||
* EINVAL due to the bad priority).
|
||||
*/
|
||||
prm->min_pri = prm->max_pri = min;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Binary search through available priorities.
|
||||
* The actually available range may be restricted
|
||||
* by resource limitations (but that is ignored
|
||||
* by sched_get_priority_max() [linux]).
|
||||
*/
|
||||
low = min;
|
||||
|
||||
while ( low < max ) {
|
||||
try = (max+low)/2;
|
||||
if ( try_pri(try, prm->policy) ) {
|
||||
max = try;
|
||||
} else {
|
||||
low = try + 1;
|
||||
}
|
||||
}
|
||||
|
||||
prm->min_pri = min;
|
||||
prm->max_pri = try_pri(max, prm->policy) ? max-1 : max;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void findPriorityRange(commonAttr *a_p)
|
||||
{
|
||||
priAvailable arg;
|
||||
pthread_t id;
|
||||
void *dummy;
|
||||
int status;
|
||||
|
||||
arg.policy = a_p->schedPolicy;
|
||||
|
||||
status = pthread_create(&id, 0, find_pri_range, &arg);
|
||||
checkStatusQuit(status, "pthread_create","epicsThreadInit");
|
||||
|
||||
status = pthread_join(id, &dummy);
|
||||
checkStatusQuit(status, "pthread_join","epicsThreadInit");
|
||||
|
||||
a_p->minPriority = arg.min_pri;
|
||||
a_p->maxPriority = arg.max_pri;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static void once(void)
|
||||
{
|
||||
epicsThreadOSD *pthreadInfo;
|
||||
@@ -230,13 +332,14 @@ static void once(void)
|
||||
status = pthread_attr_getschedparam(
|
||||
&pcommonAttr->attr,&pcommonAttr->schedParam);
|
||||
checkStatusOnce(status,"pthread_attr_getschedparam");
|
||||
pcommonAttr->maxPriority = sched_get_priority_max(pcommonAttr->schedPolicy);
|
||||
|
||||
findPriorityRange(pcommonAttr);
|
||||
|
||||
if(pcommonAttr->maxPriority == -1) {
|
||||
pcommonAttr->maxPriority = pcommonAttr->schedParam.sched_priority;
|
||||
fprintf(stderr,"sched_get_priority_max failed set to %d\n",
|
||||
pcommonAttr->maxPriority);
|
||||
}
|
||||
pcommonAttr->minPriority = sched_get_priority_min(pcommonAttr->schedPolicy);
|
||||
if(pcommonAttr->minPriority == -1) {
|
||||
pcommonAttr->minPriority = pcommonAttr->schedParam.sched_priority;
|
||||
fprintf(stderr,"sched_get_priority_min failed set to %d\n",
|
||||
@@ -422,7 +525,7 @@ static epicsThreadOSD *createImplicit(void)
|
||||
int status;
|
||||
|
||||
tid = pthread_self();
|
||||
sprintf(name, "non-EPICS_%d", (int)tid);
|
||||
sprintf(name, "non-EPICS_%ld", (long)tid);
|
||||
pthreadInfo = create_threadInfo(name);
|
||||
pthreadInfo->tid = tid;
|
||||
pthreadInfo->osiPriority = 0;
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
* 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.
|
||||
\*************************************************************************/
|
||||
|
||||
@@ -15,10 +14,6 @@
|
||||
#ifndef osdSockH
|
||||
#define osdSockH
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
@@ -35,10 +30,7 @@ extern "C" {
|
||||
#include <netdb.h>
|
||||
#include <unistd.h> /* close() and others */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
typedef int SOCKET;
|
||||
#define INVALID_SOCKET (-1)
|
||||
#define SOCKERRNO errno
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/*
|
||||
* Revision-Id: anj@aps.anl.gov-20101005192737-disfz3vs0f3fiixd
|
||||
* Revision-Id: anj@aps.anl.gov-20110721211050-gy5n916ntorc3gnp
|
||||
*
|
||||
* Archictecture dependent support for common device driver resources
|
||||
*
|
||||
@@ -50,9 +50,9 @@ static myISR *isrFetch(unsigned vectorNumber);
|
||||
|
||||
/*
|
||||
* this routine needs to be in the symbol table
|
||||
* for this code to work correctly
|
||||
* (i.e. not static) for this code to work correctly
|
||||
*/
|
||||
static void unsolicitedHandlerEPICS(int vectorNumber);
|
||||
void unsolicitedHandlerEPICS(int vectorNumber);
|
||||
|
||||
/*
|
||||
* this is in veclist.c
|
||||
@@ -412,8 +412,10 @@ static int vxDevInterruptInUseVME (unsigned vectorNumber)
|
||||
* interrupt and an interrupt arrives on the
|
||||
* disconnected vector
|
||||
*
|
||||
* This routine needs to be in the symbol table
|
||||
* (i.e. not static) for this code to work correctly
|
||||
*/
|
||||
static void unsolicitedHandlerEPICS(int vectorNumber)
|
||||
void unsolicitedHandlerEPICS(int vectorNumber)
|
||||
{
|
||||
/*
|
||||
* call logMsg() and not errMessage()
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
* 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.
|
||||
\*************************************************************************/
|
||||
/*
|
||||
@@ -14,12 +13,10 @@
|
||||
#ifndef osdSockH
|
||||
#define osdSockH
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* This is needed for vxWorks 6.8 to prevent an obnoxious compiler warning */
|
||||
#ifndef _VSB_CONFIG_FILE
|
||||
#define _VSB_CONFIG_FILE <../lib/h/config/vsbConfig.h>
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
@@ -36,6 +33,11 @@ extern "C" {
|
||||
#include <ioLib.h>
|
||||
#include <hostLib.h>
|
||||
#include <selectLib.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*This following is not defined in any vxWorks header files*/
|
||||
int sysClkRateGet(void);
|
||||
|
||||
|
||||
@@ -52,10 +52,10 @@ epicsStringTest_SRCS += epicsStringTest.c
|
||||
testHarness_SRCS += epicsStringTest.c
|
||||
TESTS += epicsStringTest
|
||||
|
||||
#TESTPROD_HOST += epicsTimeTest
|
||||
#epicsTimeTest_SRCS += epicsTimeTest.cpp
|
||||
#testHarness_SRCS += epicsTimeTest.cpp
|
||||
#TESTS += epicsTimeTest
|
||||
TESTPROD_HOST += epicsTimeTest
|
||||
epicsTimeTest_SRCS += epicsTimeTest.cpp
|
||||
testHarness_SRCS += epicsTimeTest.cpp
|
||||
TESTS += epicsTimeTest
|
||||
|
||||
TESTPROD_HOST += epicsThreadTest
|
||||
epicsThreadTest_SRCS += epicsThreadTest.cpp
|
||||
|
||||
@@ -143,7 +143,7 @@ MAIN(epicsErrlogTest)
|
||||
pvt.expect = "Testing";
|
||||
pvt.checkLen = strlen(pvt.expect);
|
||||
|
||||
errlogPrintfNoConsole(pvt.expect);
|
||||
errlogPrintfNoConsole("%s", pvt.expect);
|
||||
errlogFlush();
|
||||
|
||||
testOk1(pvt.count == 1);
|
||||
@@ -153,7 +153,7 @@ MAIN(epicsErrlogTest)
|
||||
pvt2.expect = pvt.expect = "Testing2";
|
||||
pvt2.checkLen = pvt.checkLen = strlen(pvt.expect);
|
||||
|
||||
errlogPrintfNoConsole(pvt.expect);
|
||||
errlogPrintfNoConsole("%s", pvt.expect);
|
||||
errlogFlush();
|
||||
|
||||
testOk1(pvt.count == 2);
|
||||
@@ -165,7 +165,7 @@ MAIN(epicsErrlogTest)
|
||||
pvt2.expect = "Testing3";
|
||||
pvt2.checkLen = strlen(pvt2.expect);
|
||||
|
||||
errlogPrintfNoConsole(pvt2.expect);
|
||||
errlogPrintfNoConsole("%s", pvt2.expect);
|
||||
errlogFlush();
|
||||
|
||||
testOk1(pvt.count == 2);
|
||||
@@ -188,7 +188,7 @@ MAIN(epicsErrlogTest)
|
||||
pvt.expect = truncmsg;
|
||||
pvt.checkLen = 255;
|
||||
|
||||
errlogPrintfNoConsole(longmsg);
|
||||
errlogPrintfNoConsole("%s", longmsg);
|
||||
errlogFlush();
|
||||
|
||||
testOk1(pvt.count == 3);
|
||||
@@ -201,7 +201,7 @@ MAIN(epicsErrlogTest)
|
||||
*/
|
||||
pvt.jam = 1;
|
||||
|
||||
errlogPrintfNoConsole(longmsg);
|
||||
errlogPrintfNoConsole("%s", longmsg);
|
||||
epicsThreadSleep(0.1);
|
||||
|
||||
testOk1(pvt.count == 3);
|
||||
@@ -227,7 +227,7 @@ MAIN(epicsErrlogTest)
|
||||
pvt.jam = 1;
|
||||
|
||||
for (i = 0; i < N; i++) {
|
||||
errlogPrintfNoConsole(msg);
|
||||
errlogPrintfNoConsole("%s", msg);
|
||||
}
|
||||
|
||||
epicsEventSignal(pvt.jammer);
|
||||
@@ -258,7 +258,7 @@ MAIN(epicsErrlogTest)
|
||||
testDiag("Filling with %d messages of size %d", (int) N, (int) mlen);
|
||||
|
||||
for (i = 0; i < N; i++) {
|
||||
errlogPrintfNoConsole(msg);
|
||||
errlogPrintfNoConsole("%s", msg);
|
||||
}
|
||||
epicsThreadSleep(0.1); /* should really be a second Event */
|
||||
|
||||
@@ -273,10 +273,10 @@ MAIN(epicsErrlogTest)
|
||||
testOk1(pvt.count == 2);
|
||||
|
||||
/* The buffer has space for 1 more message: sizeof(msgNode) + 256 bytes */
|
||||
errlogPrintfNoConsole(msg); /* Use up that space */
|
||||
errlogPrintfNoConsole("%s", msg); /* Use up that space */
|
||||
|
||||
testDiag("Overflow the buffer");
|
||||
errlogPrintfNoConsole(msg);
|
||||
errlogPrintfNoConsole("%s", msg);
|
||||
|
||||
testOk1(pvt.count == 2);
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/*
|
||||
* Revision-Id: anj@aps.anl.gov-20101005192737-disfz3vs0f3fiixd
|
||||
* Revision-Id: anj@aps.anl.gov-20111107175809-hd3rsaaa6xts2ano
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
@@ -42,7 +42,7 @@ static void check(const char *str, const char *expect)
|
||||
testDiag("Got \"%s\", expected \"%s\".\n", got, expect);
|
||||
pass = 0;
|
||||
}
|
||||
testOk(pass, str);
|
||||
testOk(pass, "%s", str);
|
||||
}
|
||||
|
||||
MAIN(macEnvExpandTest)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/*
|
||||
* Revision-Id: anj@aps.anl.gov-20101005192737-disfz3vs0f3fiixd
|
||||
* Revision-Id: anj@aps.anl.gov-20110601212718-lfoydufupy1vmabj
|
||||
*
|
||||
* Author Jeffrey O. Hill
|
||||
* johill@lanl.gov
|
||||
@@ -58,20 +58,21 @@ epicsTimerQueueActiveForC & timerQueueActiveMgr ::
|
||||
void timerQueueActiveMgr ::
|
||||
release ( epicsTimerQueueActiveForC & queue )
|
||||
{
|
||||
timerQueueActiveMgrPrivate * pPriv = & queue;
|
||||
{
|
||||
epicsGuard < epicsMutex > locker ( this->mutex );
|
||||
assert ( queue.timerQueueActiveMgrPrivate::referenceCount > 0u );
|
||||
queue.timerQueueActiveMgrPrivate::referenceCount--;
|
||||
if ( queue.timerQueueActiveMgrPrivate::referenceCount == 0u ) {
|
||||
if ( queue.sharingOK () ) {
|
||||
this->sharedQueueList.remove ( queue );
|
||||
}
|
||||
if ( queue.timerQueueActiveMgrPrivate::referenceCount > 0u ) {
|
||||
return;
|
||||
}
|
||||
else if ( queue.sharingOK () ) {
|
||||
this->sharedQueueList.remove ( queue );
|
||||
}
|
||||
}
|
||||
// delete only after we release the guard in case the embedded
|
||||
// reference is the last one and this object is destroyed
|
||||
// as a side effect
|
||||
timerQueueActiveMgrPrivate * pPriv = & queue;
|
||||
delete pPriv;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,12 +2,17 @@ eval 'exec perl -S $0 ${1+"$@"}' # -*- Mode: perl -*-
|
||||
if $running_under_some_shell; # makeBaseApp
|
||||
|
||||
# Authors: Ralph Lange, Marty Kraimer, Andrew Johnson and Janet Anderson
|
||||
# Revision-Id: anj@aps.anl.gov-20101005192737-disfz3vs0f3fiixd
|
||||
# Revision-Id: anj@aps.anl.gov-20111108235119-b2yn7ucijl5dbsuu
|
||||
|
||||
use FindBin qw($Bin);
|
||||
use lib ("$Bin/../../lib/perl", $Bin);
|
||||
|
||||
use Cwd;
|
||||
use Getopt::Std;
|
||||
use File::Find;
|
||||
use File::Path;
|
||||
use File::Path 'mkpath';
|
||||
use EPICS::Path;
|
||||
use EPICS::Release;
|
||||
|
||||
$app_top = cwd();
|
||||
|
||||
@@ -17,10 +22,8 @@ $app_top = cwd();
|
||||
$bad_ident_chars = '[^0-9A-Za-z_]';
|
||||
|
||||
&GetUser; # Ensure we know who's in charge
|
||||
&readRelease("configure/RELEASE", \%release, \@apps) if (-r "configure/RELEASE");
|
||||
&readRelease("configure/RELEASE.$ENV{EPICS_HOST_ARCH}", \%release, \@apps)
|
||||
if (-r "configure/RELEASE.$ENV{EPICS_HOST_ARCH}");
|
||||
&expandRelease(\%release, \@apps);
|
||||
&readReleaseFiles("configure/RELEASE", \%release, \@apps);
|
||||
&expandRelease(\%release);
|
||||
&get_commandline_opts; # Check command-line options
|
||||
|
||||
#
|
||||
@@ -297,57 +300,6 @@ sub get_commandline_opts { #no args
|
||||
. "EPICS-Base: $epics_base\n\n" if $opt_d;
|
||||
}
|
||||
|
||||
#
|
||||
# Parse a configure/RELEASE file.
|
||||
#
|
||||
# NB: This subroutine also appears in base/configure/tools/convertRelease.pl
|
||||
# If you make changes here, they will be needed there as well.
|
||||
#
|
||||
sub readRelease {
|
||||
my ($file, $Rmacros, $Rapps) = @_;
|
||||
# $Rmacros is a reference to a hash, $Rapps a ref to an array
|
||||
my ($pre, $var, $post, $macro, $path);
|
||||
local *IN;
|
||||
open(IN, $file) or die "Can't open $file: $!\n";
|
||||
while (<IN>) {
|
||||
chomp;
|
||||
s/\r$//; # Shouldn't need this, but sometimes...
|
||||
s/\s*#.*$//; # Remove trailing comments
|
||||
next if /^\s*$/; # Skip blank lines
|
||||
|
||||
# Expand all already-defined macros in the line:
|
||||
while (($pre,$var,$post) = /(.*)\$\((\w+)\)(.*)/) {
|
||||
last unless (exists $Rmacros->{$var});
|
||||
$_ = $pre . $Rmacros->{$var} . $post;
|
||||
}
|
||||
|
||||
# Handle "<macro> = <path>"
|
||||
($macro, $path) = /^\s*(\w+)\s*=\s*(.*)/;
|
||||
if ($macro ne "") {
|
||||
$Rmacros->{$macro} = $path;
|
||||
push @$Rapps, $macro;
|
||||
next;
|
||||
}
|
||||
# Handle "include <path>" syntax
|
||||
($path) = /^\s*include\s+(.*)/;
|
||||
&readRelease($path, $Rmacros, $Rapps) if (-r $path);
|
||||
}
|
||||
close IN;
|
||||
}
|
||||
|
||||
sub expandRelease {
|
||||
my ($Rmacros, $Rapps) = @_;
|
||||
# $Rmacros is a reference to a hash, $Rapps a ref to an array
|
||||
|
||||
# Expand any (possibly nested) macros that were defined after use
|
||||
while (($macro, $path) = each %$Rmacros) {
|
||||
while (($pre,$var,$post) = $path =~ /(.*)\$\((\w+)\)(.*)/) {
|
||||
$path = $pre . $Rmacros->{$var} . $post;
|
||||
$Rmacros->{$macro} = $path;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# List application types
|
||||
#
|
||||
@@ -480,29 +432,3 @@ sub GetUser {
|
||||
}
|
||||
die "No user name" unless $user;
|
||||
}
|
||||
|
||||
# Path rewriting rules for various OSs
|
||||
# These functions are duplicated in configure/convertRelease.pl
|
||||
sub UnixPath {
|
||||
my ($newpath) = @_;
|
||||
if ($^O eq 'cygwin') {
|
||||
$newpath =~ s{\\}{/}go;
|
||||
$newpath =~ s{^([a-zA-Z]):/}{/cygdrive/$1/};
|
||||
} elsif ($^O eq 'MSWin32') {
|
||||
$newpath =~ s{\\}{/}go;
|
||||
} elsif ($^O eq 'sunos') {
|
||||
$newpath =~ s{^/tmp_mnt/}{/};
|
||||
}
|
||||
return $newpath;
|
||||
}
|
||||
|
||||
sub LocalPath {
|
||||
my ($newpath) = @_;
|
||||
if ($^O eq "cygwin") {
|
||||
$newpath =~ s{^/cygdrive/([a-zA-Z])/}{$1:/};
|
||||
} elsif ($^O eq "darwin") {
|
||||
# These rules are likely to be site-specific
|
||||
$newpath =~ s{^/private/var/auto\.home/}{/home/}; # APS
|
||||
}
|
||||
return $newpath;
|
||||
}
|
||||
|
||||
@@ -17,15 +17,15 @@ PROD_LIBS += $(EPICS_BASE_HOST_LIBS)
|
||||
#
|
||||
# Added ws2_32 winmm user32 for the non-dll build
|
||||
#
|
||||
SYS_PROD_LIBS_WIN32 += ws2_32 advapi32 user32
|
||||
PROD_SYS_LIBS_WIN32 += ws2_32 advapi32 user32
|
||||
|
||||
SRCS += main.cc
|
||||
SRCS += exServer.cc
|
||||
SRCS += exPV.cc
|
||||
SRCS += exVectorPV.cc
|
||||
SRCS += exScalarPV.cc
|
||||
SRCS += exAsyncPV.cc
|
||||
SRCS += exChannel.cc
|
||||
casexample_SRCS += main.cc
|
||||
casexample_SRCS += exServer.cc
|
||||
casexample_SRCS += exPV.cc
|
||||
casexample_SRCS += exVectorPV.cc
|
||||
casexample_SRCS += exScalarPV.cc
|
||||
casexample_SRCS += exAsyncPV.cc
|
||||
casexample_SRCS += exChannel.cc
|
||||
|
||||
PROD_HOST = casexample
|
||||
|
||||
|
||||
+96
-3
@@ -6,7 +6,7 @@
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* Revision-Id: anj@aps.anl.gov-20101005192737-disfz3vs0f3fiixd */
|
||||
/* Revision-Id: anj@aps.anl.gov-20110926214215-c1ma6lbqwz4dkeqx */
|
||||
/*
|
||||
* Original Author: Marty Kraimer
|
||||
* Date: 06-01-91
|
||||
@@ -44,6 +44,7 @@
|
||||
#include "dbLock.h"
|
||||
#include "devSup.h"
|
||||
#include "drvSup.h"
|
||||
#include "menuConvert.h"
|
||||
#include "menuPini.h"
|
||||
#include "registryRecordType.h"
|
||||
#include "registryDeviceSupport.h"
|
||||
@@ -68,6 +69,7 @@ static enum {
|
||||
} iocState = iocVirgin;
|
||||
|
||||
/* define forward references*/
|
||||
static int checkDatabase(dbBase *pdbbase);
|
||||
static void initDrvSup(void);
|
||||
static void initRecSup(void);
|
||||
static void initDevSup(void);
|
||||
@@ -98,8 +100,8 @@ int iocBuild(void)
|
||||
}
|
||||
|
||||
errlogPrintf("Starting iocInit\n");
|
||||
if (!pdbbase) {
|
||||
errlogPrintf("iocBuild: Aborting, no database loaded!\n");
|
||||
if (checkDatabase(pdbbase)) {
|
||||
errlogPrintf("iocBuild: Aborting, bad database definition (DBD)!\n");
|
||||
return -1;
|
||||
}
|
||||
epicsSignalInstallSigHupIgnore();
|
||||
@@ -203,6 +205,83 @@ int iocPause(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Database sanity checks
|
||||
*
|
||||
* This is not an attempt to sanity-check the whole .dbd file, only
|
||||
* two menus normally get modified by users: menuConvert and menuScan.
|
||||
*
|
||||
* The menuConvert checks were added to flag problems with IOCs
|
||||
* converted from 3.13.x, where the SLOPE choice didn't exist.
|
||||
*
|
||||
* The menuScan checks make sure the user didn't fiddle too much
|
||||
* when creating new periodic scan choices.
|
||||
*/
|
||||
|
||||
static int checkDatabase(dbBase *pdbbase)
|
||||
{
|
||||
const dbMenu *pMenu;
|
||||
|
||||
if (!pdbbase) {
|
||||
errlogPrintf("checkDatabase: No database definitions loaded.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
pMenu = dbFindMenu(pdbbase, "menuConvert");
|
||||
if (!pMenu) {
|
||||
errlogPrintf("checkDatabase: menuConvert not defined.\n");
|
||||
return -1;
|
||||
}
|
||||
if (pMenu->nChoice <= menuConvertLINEAR) {
|
||||
errlogPrintf("checkDatabase: menuConvert has too few choices.\n");
|
||||
return -1;
|
||||
}
|
||||
if (strcmp(pMenu->papChoiceName[menuConvertNO_CONVERSION],
|
||||
"menuConvertNO_CONVERSION")) {
|
||||
errlogPrintf("checkDatabase: menuConvertNO_CONVERSION doesn't match.\n");
|
||||
return -1;
|
||||
}
|
||||
if (strcmp(pMenu->papChoiceName[menuConvertSLOPE], "menuConvertSLOPE")) {
|
||||
errlogPrintf("checkDatabase: menuConvertSLOPE doesn't match.\n");
|
||||
return -1;
|
||||
}
|
||||
if (strcmp(pMenu->papChoiceName[menuConvertLINEAR], "menuConvertLINEAR")) {
|
||||
errlogPrintf("checkDatabase: menuConvertLINEAR doesn't match.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
pMenu = dbFindMenu(pdbbase, "menuScan");
|
||||
if (!pMenu) {
|
||||
errlogPrintf("checkDatabase: menuScan not defined.\n");
|
||||
return -1;
|
||||
}
|
||||
if (pMenu->nChoice <= menuScanI_O_Intr) {
|
||||
errlogPrintf("checkDatabase: menuScan has too few choices.\n");
|
||||
return -1;
|
||||
}
|
||||
if (strcmp(pMenu->papChoiceName[menuScanPassive],
|
||||
"menuScanPassive")) {
|
||||
errlogPrintf("checkDatabase: menuScanPassive doesn't match.\n");
|
||||
return -1;
|
||||
}
|
||||
if (strcmp(pMenu->papChoiceName[menuScanEvent],
|
||||
"menuScanEvent")) {
|
||||
errlogPrintf("checkDatabase: menuScanEvent doesn't match.\n");
|
||||
return -1;
|
||||
}
|
||||
if (strcmp(pMenu->papChoiceName[menuScanI_O_Intr],
|
||||
"menuScanI_O_Intr")) {
|
||||
errlogPrintf("checkDatabase: menuScanI_O_Intr doesn't match.\n");
|
||||
return -1;
|
||||
}
|
||||
if (pMenu->nChoice <= SCAN_1ST_PERIODIC) {
|
||||
errlogPrintf("checkDatabase: menuScan has no periodic choices.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void initDrvSup(void) /* Locate all driver support entry tables */
|
||||
{
|
||||
@@ -506,6 +585,7 @@ static void doCloseLinks(dbRecordType *pdbRecordType, dbCommon *precord,
|
||||
devSup *pdevSup;
|
||||
struct dsxt *pdsxt;
|
||||
int j;
|
||||
int locked = 0;
|
||||
|
||||
for (j = 0; j < pdbRecordType->no_links; j++) {
|
||||
dbFldDes *pdbFldDes =
|
||||
@@ -513,7 +593,12 @@ static void doCloseLinks(dbRecordType *pdbRecordType, dbCommon *precord,
|
||||
DBLINK *plink = (DBLINK *)((char *)precord + pdbFldDes->offset);
|
||||
|
||||
if (plink->type == CA_LINK) {
|
||||
if (!locked) {
|
||||
dbScanLock(precord);
|
||||
locked = 1;
|
||||
}
|
||||
dbCaRemoveLink(plink);
|
||||
plink->type = CONSTANT;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -521,8 +606,16 @@ static void doCloseLinks(dbRecordType *pdbRecordType, dbCommon *precord,
|
||||
(pdevSup = dbDSETtoDevSup(pdbRecordType, precord->dset)) &&
|
||||
(pdsxt = pdevSup->pdsxt) &&
|
||||
pdsxt->del_record) {
|
||||
if (!locked) {
|
||||
dbScanLock(precord);
|
||||
locked = 1;
|
||||
}
|
||||
pdsxt->del_record(precord);
|
||||
}
|
||||
if (locked) {
|
||||
precord->pact = TRUE;
|
||||
dbScanUnlock(precord);
|
||||
}
|
||||
}
|
||||
|
||||
static void exitDatabase(void *dummy)
|
||||
|
||||
+2
-3
@@ -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.
|
||||
#*************************************************************************
|
||||
TOP=../..
|
||||
|
||||
+12
-11
@@ -197,8 +197,6 @@ static long init_record(calcoutRecord *prec, int pass)
|
||||
callbackSetUser(prec, &prpvt->checkLinkCb);
|
||||
prpvt->cbScheduled = 0;
|
||||
|
||||
prec->epvt = eventNameToHandle(prec->oevt);
|
||||
|
||||
if (pcalcoutDSET->init_record) pcalcoutDSET->init_record(prec);
|
||||
prec->pval = prec->val;
|
||||
prec->mlst = prec->val;
|
||||
@@ -359,9 +357,6 @@ static long special(DBADDR *paddr, int after)
|
||||
}
|
||||
db_post_events(prec, plinkValid, DBE_VALUE);
|
||||
return 0;
|
||||
case(calcoutRecordOEVT):
|
||||
prec->epvt = eventNameToHandle(prec->oevt);
|
||||
return 0;
|
||||
default:
|
||||
recGblDbaddrError(S_db_badChoice, paddr, "calc: special");
|
||||
return(S_db_badChoice);
|
||||
@@ -545,21 +540,27 @@ static void execOutput(calcoutRecord *prec)
|
||||
if (prec->nsev < INVALID_ALARM ) {
|
||||
/* Output the value */
|
||||
status = writeValue(prec);
|
||||
/* post output event if set */
|
||||
if (prec->epvt) postEvent(prec->epvt);
|
||||
/* post event if output event != 0 */
|
||||
if (prec->oevt > 0) {
|
||||
post_event((int)prec->oevt);
|
||||
}
|
||||
} else switch (prec->ivoa) {
|
||||
case menuIvoaContinue_normally:
|
||||
status = writeValue(prec);
|
||||
/* post output event if set */
|
||||
if (prec->epvt) postEvent(prec->epvt);
|
||||
/* post event if output event != 0 */
|
||||
if (prec->oevt > 0) {
|
||||
post_event((int)prec->oevt);
|
||||
}
|
||||
break;
|
||||
case menuIvoaDon_t_drive_outputs:
|
||||
break;
|
||||
case menuIvoaSet_output_to_IVOV:
|
||||
prec->oval = prec->ivov;
|
||||
status = writeValue(prec);
|
||||
/* post output event if set */
|
||||
if (prec->epvt) postEvent(prec->epvt);
|
||||
/* post event if output event != 0 */
|
||||
if (prec->oevt > 0) {
|
||||
post_event((int)prec->oevt);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
status = -1;
|
||||
|
||||
@@ -255,19 +255,10 @@ recordtype(calcout) {
|
||||
prompt("OCAL Valid")
|
||||
interest(1)
|
||||
}
|
||||
field(OEVT,DBF_STRING) {
|
||||
field(OEVT,DBF_USHORT) {
|
||||
prompt("Event To Issue")
|
||||
promptgroup(GUI_CLOCK)
|
||||
special(SPC_MOD)
|
||||
asl(ASL0)
|
||||
size(40)
|
||||
}
|
||||
%#include "dbScan.h"
|
||||
field(EPVT, DBF_NOACCESS) {
|
||||
prompt("Event private")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
extra("EVENTPVT epvt")
|
||||
}
|
||||
field(IVOA,DBF_MENU) {
|
||||
prompt("INVALID output action")
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/* Revision-Id: anj@aps.anl.gov-20101005192737-disfz3vs0f3fiixd */
|
||||
/* Revision-Id: anj@aps.anl.gov-20110608161626-57vf3rfrk73ppemb */
|
||||
/*
|
||||
* Original Author: Bob Dalesio
|
||||
* Date: 7-14-89
|
||||
@@ -92,12 +92,14 @@ static void reset(compressRecord *prec)
|
||||
|
||||
static void monitor(compressRecord *prec)
|
||||
{
|
||||
unsigned short monitor_mask;
|
||||
unsigned short alarm_mask = recGblResetAlarms(prec);
|
||||
unsigned short monitor_mask = alarm_mask | DBE_LOG | DBE_VALUE;
|
||||
|
||||
monitor_mask = recGblResetAlarms(prec);
|
||||
monitor_mask |= (DBE_LOG|DBE_VALUE);
|
||||
if(monitor_mask) db_post_events(prec,prec->bptr,monitor_mask);
|
||||
return;
|
||||
if (alarm_mask || prec->nuse != prec->ouse) {
|
||||
db_post_events(prec, &prec->nuse, monitor_mask);
|
||||
prec->ouse = prec->nuse;
|
||||
}
|
||||
db_post_events(prec, prec->bptr, monitor_mask);
|
||||
}
|
||||
|
||||
static void put_value(compressRecord *prec,double *psource, epicsInt32 n)
|
||||
|
||||
@@ -95,6 +95,10 @@ recordtype(compress) {
|
||||
prompt("Number Used")
|
||||
special(SPC_NOMOD)
|
||||
}
|
||||
field(OUSE,DBF_ULONG) {
|
||||
prompt("Old Number Used")
|
||||
special(SPC_NOMOD)
|
||||
}
|
||||
field(BPTR,DBF_NOACCESS) {
|
||||
prompt("Buffer Pointer")
|
||||
special(SPC_NOMOD)
|
||||
|
||||
+6
-24
@@ -32,7 +32,6 @@
|
||||
#include "errMdef.h"
|
||||
#include "recSup.h"
|
||||
#include "recGbl.h"
|
||||
#include "special.h"
|
||||
#include "menuYesNo.h"
|
||||
#define GEN_SIZE_OFFSET
|
||||
#include "eventRecord.h"
|
||||
@@ -44,7 +43,7 @@
|
||||
#define initialize NULL
|
||||
static long init_record(eventRecord *, int);
|
||||
static long process(eventRecord *);
|
||||
static long special(DBADDR *, int);
|
||||
#define special NULL
|
||||
static long get_value(eventRecord *, struct valueDes *);
|
||||
#define cvt_dbaddr NULL
|
||||
#define get_array_info NULL
|
||||
@@ -104,11 +103,9 @@ static long init_record(eventRecord *prec, int pass)
|
||||
}
|
||||
|
||||
if (prec->siol.type == CONSTANT) {
|
||||
recGblInitConstantLink(&prec->siol,DBF_STRING,&prec->sval);
|
||||
recGblInitConstantLink(&prec->siol,DBF_USHORT,&prec->sval);
|
||||
}
|
||||
|
||||
prec->epvt = eventNameToHandle(prec->val);
|
||||
|
||||
if( (pdset=(struct eventdset *)(prec->dset)) && (pdset->init_record) )
|
||||
status=(*pdset->init_record)(prec);
|
||||
return(status);
|
||||
@@ -126,7 +123,7 @@ static long process(eventRecord *prec)
|
||||
if ( !pact && prec->pact ) return(0);
|
||||
prec->pact = TRUE;
|
||||
|
||||
postEvent(prec->epvt);
|
||||
if(prec->val>0) post_event((int)prec->val);
|
||||
|
||||
recGblGetTimeStamp(prec);
|
||||
|
||||
@@ -140,22 +137,10 @@ static long process(eventRecord *prec)
|
||||
return(status);
|
||||
}
|
||||
|
||||
|
||||
static long special(DBADDR *paddr, int after)
|
||||
{
|
||||
eventRecord *prec = (eventRecord *)paddr->precord;
|
||||
|
||||
if (!after) return 0;
|
||||
if (dbGetFieldIndex(paddr) == eventRecordVAL) {
|
||||
prec->epvt = eventNameToHandle(prec->val);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static long get_value(eventRecord *prec, struct valueDes *pvdes)
|
||||
{
|
||||
pvdes->field_type = DBF_STRING;
|
||||
pvdes->field_type = DBF_USHORT;
|
||||
pvdes->no_elements=1;
|
||||
pvdes->pvalue = (void *)(&prec->val);
|
||||
return(0);
|
||||
@@ -192,13 +177,10 @@ static long readValue(eventRecord *prec)
|
||||
return(status);
|
||||
}
|
||||
if (prec->simm == menuYesNoYES){
|
||||
status=dbGetLink(&(prec->siol),DBR_STRING,
|
||||
status=dbGetLink(&(prec->siol),DBR_USHORT,
|
||||
&(prec->sval),0,0);
|
||||
if (status==0) {
|
||||
if (strcmp(prec->sval, prec->val) != 0) {
|
||||
strcpy(prec->val, prec->sval);
|
||||
prec->epvt = eventNameToHandle(prec->val);
|
||||
}
|
||||
prec->val=prec->sval;
|
||||
prec->udf=FALSE;
|
||||
}
|
||||
} else {
|
||||
|
||||
+3
-13
@@ -9,19 +9,10 @@
|
||||
#*************************************************************************
|
||||
recordtype(event) {
|
||||
include "dbCommon.dbd"
|
||||
field(VAL,DBF_STRING) {
|
||||
prompt("Event Name To Post")
|
||||
field(VAL,DBF_USHORT) {
|
||||
prompt("Event Number To Post")
|
||||
promptgroup(GUI_INPUTS)
|
||||
special(SPC_MOD)
|
||||
asl(ASL0)
|
||||
size(40)
|
||||
}
|
||||
%#include "dbScan.h"
|
||||
field(EPVT, DBF_NOACCESS) {
|
||||
prompt("Event private")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
extra("EVENTPVT epvt")
|
||||
}
|
||||
field(INP,DBF_INLINK) {
|
||||
prompt("Input Specification")
|
||||
@@ -33,9 +24,8 @@ recordtype(event) {
|
||||
promptgroup(GUI_INPUTS)
|
||||
interest(1)
|
||||
}
|
||||
field(SVAL,DBF_STRING) {
|
||||
field(SVAL,DBF_USHORT) {
|
||||
prompt("Simulation Value")
|
||||
size(40)
|
||||
}
|
||||
field(SIML,DBF_INLINK) {
|
||||
prompt("Sim Mode Location")
|
||||
|
||||
@@ -14,6 +14,8 @@ die "Path to INSTALL_LOCATION missing\n" unless @ARGV == 1;
|
||||
my $path = shift;
|
||||
|
||||
$path =~ s/\\/\\\\/gx;
|
||||
$path =~ s/^'//;
|
||||
$path =~ s/'$//;
|
||||
|
||||
print "/* THIS IS A GENERATED FILE. DO NOT EDIT! */\n",
|
||||
"\n",
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
# in file LICENSE that is included with this distribution.
|
||||
#*************************************************************************
|
||||
|
||||
# Revision-Id: anj@aps.anl.gov-20101005192737-disfz3vs0f3fiixd
|
||||
# Revision-Id: anj@aps.anl.gov-20110523213458-3lhktmvu73otws64
|
||||
|
||||
use Carp;
|
||||
use Cwd qw(getcwd abs_path);
|
||||
@@ -64,7 +64,6 @@ put into a file. It converts paths from the Unix form that Perl understands to
|
||||
any necessary external representation, and also removes automounter prefixes to
|
||||
put the path into its canonical form.
|
||||
|
||||
On cygwin we convert cygdrive paths to their equivalent Windows drive specs.
|
||||
Before Leopard, the Mac OS X automounter inserted a verbose prefix, and in case
|
||||
anyone is still using SunOS it adds its own prefix as well.
|
||||
|
||||
@@ -72,9 +71,7 @@ anyone is still using SunOS it adds its own prefix as well.
|
||||
|
||||
sub LocalPath {
|
||||
my ($newpath) = @_;
|
||||
if ($^O eq 'cygwin') {
|
||||
$newpath =~ s{^/cygdrive/([a-zA-Z])/}{$1:/};
|
||||
} elsif ($^O eq 'darwin') {
|
||||
if ($^O eq 'darwin') {
|
||||
# Darwin automounter
|
||||
$newpath =~ s{^/private/var/auto\.}{/};
|
||||
} elsif ($^O eq 'sunos') {
|
||||
|
||||
@@ -9,7 +9,7 @@ eval 'exec perl -S $0 ${1+"$@"}' # -*- Mode: perl -*-
|
||||
# in file LICENSE that is included with this distribution.
|
||||
#*************************************************************************
|
||||
#
|
||||
# Revision-Id: anj@aps.anl.gov-20101216230215-3416a76xyxueijr9
|
||||
# Revision-Id: anj@aps.anl.gov-20110713153813-utpd5swcmji6ce4l
|
||||
#
|
||||
# Convert configure/RELEASE file(s) into something else.
|
||||
#
|
||||
@@ -19,7 +19,7 @@ use strict;
|
||||
use FindBin qw($Bin);
|
||||
use lib ("$Bin/../../lib/perl", $Bin);
|
||||
|
||||
use Cwd qw(cwd abs_path);
|
||||
use Cwd qw(cwd);
|
||||
use Getopt::Std;
|
||||
use EPICS::Path;
|
||||
use EPICS::Release;
|
||||
@@ -215,7 +215,7 @@ sub checkRelease {
|
||||
|
||||
while (my ($parent, $ppath) = each %check) {
|
||||
if (exists $macros{$parent} &&
|
||||
abs_path($macros{$parent}) ne abs_path($ppath)) {
|
||||
AbsPath($macros{$parent}) ne AbsPath($ppath)) {
|
||||
print "\n" unless ($status);
|
||||
print "Definition of $parent conflicts with $app support.\n";
|
||||
print "In this application a RELEASE file defines\n";
|
||||
|
||||
@@ -7,7 +7,7 @@ eval 'exec perl -S -w $0 ${1+"$@"}' # -*- Mode: perl -*-
|
||||
# in file LICENSE that is included with this distribution.
|
||||
#*************************************************************************
|
||||
|
||||
# Revision-Id: anj@aps.anl.gov-20101216230215-3416a76xyxueijr9
|
||||
# Revision-Id: anj@aps.anl.gov-20110608171518-onrlqi2bcf4wmbhs
|
||||
|
||||
# Determines an absolute pathname for its argument,
|
||||
# which may be either a relative or absolute path and
|
||||
@@ -29,7 +29,7 @@ $Getopt::Std::OUTPUT_HELP_VERSION = 1;
|
||||
my $path = AbsPath(shift);
|
||||
|
||||
# Escape shell special characters unless on Windows, which doesn't allow them.
|
||||
$path =~ s/([!"\$&'\(\)*,:;<=>?\[\\\]^`{|}])/\\\1/g unless $^O eq 'MSWin32';
|
||||
$path =~ s/([!"\$&'\(\)*,:;<=>?\[\\\]^`{|}])/\\$1/g unless $^O eq 'MSWin32';
|
||||
|
||||
print "$path\n";
|
||||
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
#!/usr/bin/perl
|
||||
#*************************************************************************
|
||||
# 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.
|
||||
#*************************************************************************
|
||||
#
|
||||
@@ -62,18 +61,13 @@ foreach $source ( @files )
|
||||
$basename=$source;
|
||||
$basename=~s'.*[/\\]'';
|
||||
$target = "$install_dir/$basename";
|
||||
$temp = "$target.$$";
|
||||
|
||||
# The Win32 filesystem seems to be 'slow',
|
||||
# i.e. $target may look like 'up to date'
|
||||
# unless you wait an hour.
|
||||
# -> skip this test on WIN32 ?
|
||||
#if (-f $target and $^O ne "MSWin32")
|
||||
if (-f $target)
|
||||
{
|
||||
if (-M $target < -M $source and
|
||||
if (-M $target < -M $source and
|
||||
-C $target < -C $source)
|
||||
{
|
||||
print "$target is up to date\n";
|
||||
next;
|
||||
}
|
||||
else
|
||||
@@ -84,8 +78,9 @@ foreach $source ( @files )
|
||||
}
|
||||
}
|
||||
|
||||
# print "Installing $source into $install_dir\n";
|
||||
copy ($source, $target) or die "Copy failed";
|
||||
# Using copy + rename fixes problems with parallel builds:
|
||||
copy ($source, $temp) or die "Copy failed: $!\n";
|
||||
rename ($temp, $target) or die "Rename failed: $!\n";
|
||||
|
||||
# chmod 0555 <read-only> DOES work on WIN32, but:
|
||||
# Another chmod 0777 to make it write- and deletable
|
||||
|
||||
+15
-24
@@ -3,31 +3,22 @@ eval 'exec perl -S $0 ${1+"$@"}' # -*- Mode: perl -*-
|
||||
|
||||
# Called from within RULES.Db in the Db directories.
|
||||
# Searches .substitutions and .template files (from the command line) for
|
||||
# "file xxx {" entries to create a DEPENDS file
|
||||
# and
|
||||
# 'include "xxx"' entries to create a DEPENDS file
|
||||
# file ["']xxx["'] {
|
||||
# and
|
||||
# include "xxx"
|
||||
# entries to include in the DEPENDS file
|
||||
|
||||
use strict;
|
||||
|
||||
$target = $ARGV[0];
|
||||
shift @ARGV;
|
||||
my $target = shift @ARGV;
|
||||
my %depends;
|
||||
|
||||
|
||||
foreach $file (@ARGV) {
|
||||
open(IN, "<$file") or die "Cannot open $file: $!";
|
||||
@infile = <IN>;
|
||||
close IN or die "Cannot close $file: $!";
|
||||
|
||||
@depends = grep { s/^\s*file\s*(.*)\s*\{.*$/\1/ } @infile;
|
||||
chomp @depends;
|
||||
|
||||
if (@depends) {
|
||||
print "$target: @depends\n";
|
||||
}
|
||||
|
||||
@depends2 = grep { s/^\s*include\s*\"\s*(.*)\s*\".*$/\1/ } @infile;
|
||||
chomp @depends2;
|
||||
|
||||
if (@depends2) {
|
||||
print "$target: @depends2\n";
|
||||
}
|
||||
while (my $line = <>) {
|
||||
$depends{$2}++ if $line =~ m/^\s*file\s*(["']?)(.*)\1/;
|
||||
$depends{$1}++ if $line =~ m/^\s*include\s+"(.*)"/;
|
||||
}
|
||||
|
||||
if (%depends) {
|
||||
my @depends = keys %depends;
|
||||
print "$target: @depends\n";
|
||||
}
|
||||
|
||||
+20
-26
@@ -1,17 +1,16 @@
|
||||
/*************************************************************************\
|
||||
* 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.
|
||||
\*************************************************************************/
|
||||
/* iocLogServer.c */
|
||||
/* base/src/util Revision-Id: anj@aps.anl.gov-20101005192737-disfz3vs0f3fiixd */
|
||||
/* Revision-Id: anj@aps.anl.gov-20110601205510-1lmsijq2jslrhe9m */
|
||||
|
||||
/*
|
||||
* archive logMsg() from several IOC's to a common rotating file
|
||||
* archive logMsg() from several IOC's to a common rotating file
|
||||
*
|
||||
*
|
||||
* Author: Jeffrey O. Hill
|
||||
@@ -903,40 +902,35 @@ static void serviceSighupRequest(void *pParam)
|
||||
}
|
||||
|
||||
/*
|
||||
* If it's changed, open the new file.
|
||||
* Try (re)opening the file.
|
||||
*/
|
||||
if (strcmp(ioc_log_file_name, pserver->outfile) == 0) {
|
||||
status = openLogFile(pserver);
|
||||
if(status<0){
|
||||
fprintf(stderr,
|
||||
"iocLogServer: log file name unchanged; not re-opened\n");
|
||||
}
|
||||
else {
|
||||
"File access problems to `%s' because `%s'\n",
|
||||
ioc_log_file_name,
|
||||
strerror(errno));
|
||||
/* Revert to old filename */
|
||||
strcpy(ioc_log_file_name, pserver->outfile);
|
||||
status = openLogFile(pserver);
|
||||
if(status<0){
|
||||
fprintf(stderr,
|
||||
"File access problems to `%s' because `%s'\n",
|
||||
"File access problems to `%s' because `%s'\n",
|
||||
ioc_log_file_name,
|
||||
strerror(errno));
|
||||
strcpy(ioc_log_file_name, pserver->outfile);
|
||||
status = openLogFile(pserver);
|
||||
if(status<0){
|
||||
fprintf(stderr,
|
||||
"File access problems to `%s' because `%s'\n",
|
||||
ioc_log_file_name,
|
||||
strerror(errno));
|
||||
return;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr,
|
||||
"iocLogServer: re-opened old log file %s\n",
|
||||
ioc_log_file_name);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr,
|
||||
"iocLogServer: opened new log file %s\n",
|
||||
"iocLogServer: re-opened old log file %s\n",
|
||||
ioc_log_file_name);
|
||||
}
|
||||
}
|
||||
else {
|
||||
fprintf(stderr,
|
||||
"iocLogServer: opened new log file %s\n",
|
||||
ioc_log_file_name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
#!/bin/sh
|
||||
#*************************************************************************
|
||||
# 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.
|
||||
#*************************************************************************
|
||||
#
|
||||
@@ -37,9 +36,9 @@ case $sysname in
|
||||
Darwin )
|
||||
os=darwin
|
||||
cpu=`uname -m`
|
||||
case "$cpu" in
|
||||
case $cpu in
|
||||
"Power Macintosh") cpu=ppc ;;
|
||||
"i386") cpu=x86 ;;
|
||||
i386 | x86_64 ) cpu=x86 ;;
|
||||
esac
|
||||
echo ${os}-${cpu}${suffix}
|
||||
;;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
eval 'exec perl -S $0 ${1+"$@"}' # -*- Mode: perl -*-
|
||||
if $running_under_some_shell; # EpicsHostArch.pl
|
||||
#*************************************************************************
|
||||
# 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.
|
||||
@@ -9,7 +9,7 @@ eval 'exec perl -S $0 ${1+"$@"}' # -*- Mode: perl -*-
|
||||
# in file LICENSE that is included with this distribution.
|
||||
#*************************************************************************
|
||||
|
||||
# Revision-Id: anj@aps.anl.gov-20101014190140-s9gxgtnoyhbck6id
|
||||
# Revision-Id: anj@aps.anl.gov-20110627200954-dl56anmi4ikl332u
|
||||
# Returns the Epics host architecture suitable
|
||||
# for assigning to the EPICS_HOST_ARCH variable
|
||||
|
||||
@@ -34,6 +34,7 @@ sub GetEpicsHostArch { # no args
|
||||
my($kernel, $hostname, $release, $version, $cpu) = POSIX::uname();
|
||||
if ($cpu =~ m/Power Macintosh/) { return "darwin-ppc"; }
|
||||
elsif ($cpu =~ m/i386/) { return "darwin-x86"; }
|
||||
elsif ($cpu =~ m/x86_64/) { return "darwin-x86"; }
|
||||
else { return "unsupported"; }
|
||||
} else { return "unsupported"; }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user