update to 3.14.12.2

This commit is contained in:
zimoch
2011-12-14 09:19:54 +00:00
parent 12cc2fdecb
commit f058c2d142
78 changed files with 1228 additions and 873 deletions
+28
View File
@@ -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
+6 -2
View File
@@ -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
+6 -2
View File
@@ -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
+7 -8
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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 );
}
+69
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
+2 -2
View File
@@ -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
+12 -12
View File
@@ -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
View File
@@ -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 */
+3 -3
View File
@@ -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
View File
@@ -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
View File
@@ -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 */
-2
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
*/
+2 -2
View File
@@ -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};
+23 -18
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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;
+3 -3
View File
@@ -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) {
+3 -1
View File
@@ -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,
+8 -15
View File
@@ -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
View File
@@ -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
View File
@@ -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 ) );
-2
View File
@@ -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
+8 -12
View File
@@ -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;
+2 -2
View File
@@ -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 & );
};
-7
View File
@@ -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.
+8 -15
View File
@@ -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);
}
+2 -13
View File
@@ -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
+1 -12
View File
@@ -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
+6 -7
View File
@@ -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
+10 -5
View File
@@ -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();
+4 -9
View File
@@ -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*/
+1 -5
View File
@@ -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 );
}
/*
+60 -18
View File
@@ -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 );
}
}
+2 -10
View File
@@ -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
-8
View File
@@ -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
+1 -11
View File
@@ -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
+5
View File
@@ -17,6 +17,11 @@
extern "C" {
#endif
#ifdef isfinite
# undef finite
# define finite(x) isfinite(x)
#endif
epicsShareExtern float epicsNAN;
epicsShareExtern float epicsINF;
+106 -3
View File
@@ -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;
+2 -10
View File
@@ -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
+6 -4
View File
@@ -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()
+8 -6
View File
@@ -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);
+4 -4
View File
@@ -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
+9 -9
View File
@@ -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);
+2 -2
View File
@@ -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)
+7 -6
View File
@@ -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;
}
+9 -83
View File
@@ -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;
}
+8 -8
View File
@@ -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
View File
@@ -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
View File
@@ -1,10 +1,9 @@
#*************************************************************************
# Copyright (c) 2002 The University of Chicago, as Operator of Argonne
# Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne
# National Laboratory.
# Copyright (c) 2002 The Regents of the University of California, as
# Operator of Los Alamos National Laboratory.
# EPICS BASE Versions 3.13.7
# and higher are distributed subject to a Software License Agreement found
# EPICS BASE is distributed subject to a Software License Agreement found
# in file LICENSE that is included with this distribution.
#*************************************************************************
TOP=../..
+12 -11
View File
@@ -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;
+1 -10
View File
@@ -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")
+8 -6
View File
@@ -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)
+4
View File
@@ -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
View File
@@ -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
View File
@@ -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")
+2
View File
@@ -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",
+2 -5
View File
@@ -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') {
+3 -3
View File
@@ -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";
+2 -2
View File
@@ -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";
+7 -12
View File
@@ -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
View File
@@ -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
View File
@@ -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);
}
}
+4 -5
View File
@@ -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}
;;
+3 -2
View File
@@ -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"; }
}