Compare commits
149 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b3b01959e5 | ||
|
|
9db7ed360b | ||
|
|
1f7881010e | ||
|
|
90a96f4ee4 | ||
|
|
1050b980ec | ||
|
|
2bdb012709 | ||
|
|
b20fd4c5c5 | ||
|
|
409b045779 | ||
|
|
fda81767a5 | ||
|
|
fe1b167e23 | ||
|
|
dc0f20cc5f | ||
|
|
6e7d887e6e | ||
|
|
699a6cd8b4 | ||
|
|
70454a6006 | ||
|
|
deebe46378 | ||
|
|
18dc4279ad | ||
|
|
61e9dc0368 | ||
|
|
6b0d1ce49b | ||
|
|
81b160d7b6 | ||
|
|
4e22a056d2 | ||
|
|
4af5ba92d9 | ||
|
|
e79c70c74c | ||
|
|
c0694e2d69 | ||
|
|
36dac883f4 | ||
|
|
35dcbf35b3 | ||
|
|
30dd2ed046 | ||
|
|
e30e4f3638 | ||
|
|
15578d1647 | ||
|
|
e3e270e242 | ||
|
|
ec44251df0 | ||
|
|
3344165f19 | ||
|
|
c2ea402be0 | ||
|
|
0535ff990d | ||
|
|
18ff90e641 | ||
|
|
a781195458 | ||
|
|
1a641f0d1b | ||
|
|
0e6639c149 | ||
|
|
93ba23aeb8 | ||
|
|
7743f3e3fd | ||
|
|
e9ce6a2f0b | ||
|
|
1ed48c15f1 | ||
|
|
d27f929595 | ||
|
|
b4e17f271b | ||
|
|
79f407486a | ||
|
|
3c359728f7 | ||
|
|
7b9693562a | ||
|
|
f1c39ca5d2 | ||
|
|
16b1775b98 | ||
|
|
f6ee7333bb | ||
|
|
9f45bdfa75 | ||
|
|
03aa15b5f7 | ||
|
|
8093952ca2 | ||
|
|
2bea54e218 | ||
|
|
e81230dba5 | ||
|
|
50b8f306c3 | ||
|
|
65be8e5678 | ||
|
|
dbb9310adc | ||
|
|
50fbb396e8 | ||
|
|
ff19fe1cd8 | ||
|
|
230938220e | ||
|
|
334ed3b70a | ||
|
|
4c7e51d8ad | ||
|
|
4973a6297e | ||
|
|
f0d1481a28 | ||
|
|
d5235db54c | ||
|
|
b125035a11 | ||
|
|
9551b0e4c6 | ||
|
|
d6aa03815e | ||
|
|
ce0d62fbbc | ||
|
|
2fe3e66047 | ||
|
|
fa53d72258 | ||
|
|
b010cf0849 | ||
|
|
7fd707cb4b | ||
|
|
5d823307f0 | ||
|
|
d41d5726d2 | ||
|
|
723f98bc44 | ||
|
|
1544147bdd | ||
|
|
0447441cfa | ||
|
|
8ce42ebb9a | ||
|
|
c39b966121 | ||
|
|
61edf17cdf | ||
|
|
39f537d7da | ||
|
|
ba496de2d3 | ||
|
|
38574ed76f | ||
|
|
92be294bbf | ||
|
|
35429bf4df | ||
|
|
552925dfe6 | ||
|
|
d1791393ad | ||
|
|
3dbad700f7 | ||
|
|
c06e33e197 | ||
|
|
1d8f01517a | ||
|
|
8c1b142e48 | ||
|
|
ca27cb5e3c | ||
|
|
8fb02d5602 | ||
|
|
38f8f1de51 | ||
|
|
a5fa17aca7 | ||
|
|
fe62a7181f | ||
|
|
69fe610c5d | ||
|
|
83f2fa9d9a | ||
|
|
5faa9902ea | ||
|
|
f10a5f8279 | ||
|
|
fcb82fd31f | ||
|
|
16fbd0f205 | ||
|
|
597bca1ca5 | ||
|
|
3e790e34e3 | ||
|
|
144da546ea | ||
|
|
2d450bdd5b | ||
|
|
333bbca2f2 | ||
|
|
d17192804e | ||
|
|
63e7401ff1 | ||
|
|
42e2e72474 | ||
|
|
342ab45dc8 | ||
|
|
c91f2e7263 | ||
|
|
f3dc67e620 | ||
|
|
127830e3c7 | ||
|
|
9d3873c3fe | ||
|
|
3ce6df5b0d | ||
|
|
0f1c0c28d0 | ||
|
|
e740687635 | ||
|
|
d1df670c83 | ||
|
|
6b47485810 | ||
|
|
228b46a622 | ||
|
|
e932c01cf1 | ||
|
|
c6f6465457 | ||
|
|
068d3070e2 | ||
|
|
4ad2e56a08 | ||
|
|
d63610c7f5 | ||
|
|
92509abde8 | ||
|
|
c445368537 | ||
|
|
2269a5bd66 | ||
|
|
876ec8062f | ||
|
|
53c3901099 | ||
|
|
51f4820c24 | ||
|
|
a21189cfda | ||
|
|
61d884334a | ||
|
|
9a798bc05a | ||
|
|
94bd84211b | ||
|
|
5d0718ab3a | ||
|
|
e8a9771d1e | ||
|
|
ac971042de | ||
|
|
ce116eefb8 | ||
|
|
3e1a405d01 | ||
|
|
3039e1cdb0 | ||
|
|
006859120e | ||
|
|
14b3640e9a | ||
|
|
ed5bf2d79b | ||
|
|
313ba68a06 | ||
|
|
22786bb07e | ||
|
|
534671dbe8 |
13
.gitignore
vendored
Normal file
13
.gitignore
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
bin/
|
||||
lib/
|
||||
doc/
|
||||
include/
|
||||
db/
|
||||
dbd/
|
||||
documentation/html
|
||||
documentation/*.tag
|
||||
envPaths
|
||||
configure/*.local
|
||||
!configure/ExampleRELEASE.local
|
||||
**/O.*
|
||||
QtC-*
|
||||
11
.hgignore
11
.hgignore
@@ -1,11 +0,0 @@
|
||||
^QtC-
|
||||
^bin/
|
||||
^lib/
|
||||
^doc/
|
||||
^include/
|
||||
^db/
|
||||
^dbd/
|
||||
^documentation/html
|
||||
envPaths
|
||||
configure/.*\.local
|
||||
/O\..*
|
||||
2
LICENSE
2
LICENSE
@@ -2,7 +2,7 @@
|
||||
Copyright (c) 2008 Martin R. Kraimer
|
||||
Copyright (c) 2006 The University of Chicago, as Operator of Argonne
|
||||
National Laboratory.
|
||||
Copyright (c) 2006 Deutsches Elektronen-Synchroton,
|
||||
Copyright (c) 2006 Deutsches Elektronen-Synchrotron,
|
||||
Member of the Helmholtz Association, (DESY), HAMBURG, GERMANY.
|
||||
Copyright (c) 2007 Control System Laboratory,
|
||||
(COSYLAB) Ljubljana Slovenia
|
||||
|
||||
27
Makefile
27
Makefile
@@ -1,16 +1,27 @@
|
||||
#Makefile at top of application tree
|
||||
TOP = .
|
||||
include $(TOP)/configure/CONFIG
|
||||
DIRS += configure
|
||||
DIRS := $(DIRS) $(filter-out $(DIRS), configure)
|
||||
DIRS := $(DIRS) $(filter-out $(DIRS), src)
|
||||
DIRS := $(DIRS) $(filter-out $(DIRS), test)
|
||||
DIRS := $(DIRS) $(filter-out $(DIRS), arrayPerformance)
|
||||
DIRS := $(DIRS) $(filter-out $(DIRS), $(wildcard example*))
|
||||
|
||||
DIRS += src
|
||||
src_DEPEND_DIRS = configure
|
||||
EMBEDDED_TOPS := $(EMBEDDED_TOPS) $(filter-out $(EMBEDDED_TOPS), test)
|
||||
EMBEDDED_TOPS := $(EMBEDDED_TOPS) $(filter-out $(EMBEDDED_TOPS), arrayPerformance)
|
||||
EMBEDDED_TOPS := $(EMBEDDED_TOPS) $(filter-out $(EMBEDDED_TOPS), $(wildcard example*))
|
||||
|
||||
DIRS += example
|
||||
test_DEPEND_DIRS = src
|
||||
define DIR_template
|
||||
$(1)_DEPEND_DIRS = configure
|
||||
endef
|
||||
$(foreach dir, $(filter-out configure,$(DIRS)),$(eval $(call DIR_template,$(dir))))
|
||||
|
||||
DIRS += iocBoot
|
||||
define EMB_template
|
||||
$(1)_DEPEND_DIRS = src
|
||||
endef
|
||||
$(foreach dir, $(EMBEDDED_TOPS),$(eval $(call EMB_template,$(dir))))
|
||||
|
||||
#exampleDatabase_DEPEND_DIRS += test
|
||||
#examplePowerSupply_DEPEND_DIRS += test
|
||||
|
||||
include $(TOP)/configure/RULES_TOP
|
||||
|
||||
|
||||
|
||||
38
README.md
Normal file
38
README.md
Normal file
@@ -0,0 +1,38 @@
|
||||
pvaDatabaseCPP
|
||||
============
|
||||
|
||||
|
||||
A brief description of a pvDatabase is that it is a set of network accessible, smart, memory resident records. Each record has data composed of a top level PVStructure. Each record has a name which is the channelName for pvAccess. A local Channel Provider implements the complete ChannelProvider and Channel interfaces as defined by pvAccess. The local provider provides access to the records in the pvDatabase. This local provider is accessed by the remote pvAccess server. A record is smart because code can be attached to a record, which is accessed via a method named process.
|
||||
pvaDatabase is a synchronous Database interface to pvAccess,
|
||||
which is callback based.
|
||||
pvaDatabase is thus easier to use than pvAccess itself.
|
||||
|
||||
See documentation/pvaDatabaseCPP.html for details.
|
||||
|
||||
Building
|
||||
--------
|
||||
|
||||
If a proper RELEASE.local file exists one directory level above pvaDatabaseCPP
|
||||
then just type:
|
||||
|
||||
make
|
||||
|
||||
If RELEASE.local does not exist then look at <b>configure/RELEASE</b>
|
||||
for directions for how to build.
|
||||
|
||||
Examples
|
||||
------------
|
||||
|
||||
The examples require the database in pvaDatabaseTestCPP.
|
||||
For example:
|
||||
|
||||
mrk> pwd
|
||||
/home/epicsv4/pvaDatabaseTestCPP/database/iocBoot/exampleDatabase
|
||||
mrk> ../../bin/linux-x86_64/exampleDatabase st.cmd
|
||||
|
||||
Status
|
||||
------
|
||||
|
||||
* The API is for EPICS Version 4 release 4.5.0
|
||||
|
||||
|
||||
10
RELEASE_NOTES.md
Normal file
10
RELEASE_NOTES.md
Normal file
@@ -0,0 +1,10 @@
|
||||
EPICS V4 release 4.5
|
||||
====================
|
||||
|
||||
This release is one component of EPICS V4 release 4.5.
|
||||
|
||||
This is the first release of pvDatabaseCPP.
|
||||
|
||||
It provides functionality equivalent to pvDatabaseJava.
|
||||
|
||||
|
||||
11
arrayPerformance/Makefile
Normal file
11
arrayPerformance/Makefile
Normal file
@@ -0,0 +1,11 @@
|
||||
#Makefile at top of application tree
|
||||
TOP = .
|
||||
include $(TOP)/configure/CONFIG
|
||||
DIRS += configure
|
||||
|
||||
DIRS += src
|
||||
src_DEPEND_DIRS = configure
|
||||
|
||||
include $(TOP)/configure/RULES_TOP
|
||||
|
||||
|
||||
29
arrayPerformance/configure/CONFIG
Normal file
29
arrayPerformance/configure/CONFIG
Normal file
@@ -0,0 +1,29 @@
|
||||
# CONFIG - Load build configuration data
|
||||
#
|
||||
# Do not make changes to this file!
|
||||
|
||||
# Allow user to override where the build rules come from
|
||||
RULES = $(EPICS_BASE)
|
||||
|
||||
# RELEASE files point to other application tops
|
||||
include $(TOP)/configure/RELEASE
|
||||
-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).Common
|
||||
ifdef T_A
|
||||
-include $(TOP)/configure/RELEASE.Common.$(T_A)
|
||||
-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).$(T_A)
|
||||
endif
|
||||
|
||||
CONFIG = $(RULES)/configure
|
||||
include $(CONFIG)/CONFIG
|
||||
|
||||
# Override the Base definition:
|
||||
INSTALL_LOCATION = $(TOP)
|
||||
|
||||
# CONFIG_SITE files contain other build configuration settings
|
||||
include $(TOP)/configure/CONFIG_SITE
|
||||
-include $(TOP)/configure/CONFIG_SITE.$(EPICS_HOST_ARCH).Common
|
||||
ifdef T_A
|
||||
-include $(TOP)/configure/CONFIG_SITE.Common.$(T_A)
|
||||
-include $(TOP)/configure/CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A)
|
||||
endif
|
||||
|
||||
39
arrayPerformance/configure/CONFIG_SITE
Normal file
39
arrayPerformance/configure/CONFIG_SITE
Normal file
@@ -0,0 +1,39 @@
|
||||
# CONFIG_SITE
|
||||
|
||||
# Make any application-specific changes to the EPICS build
|
||||
# configuration variables in this file.
|
||||
#
|
||||
# Host/target specific settings can be specified in files named
|
||||
# CONFIG_SITE.$(EPICS_HOST_ARCH).Common
|
||||
# CONFIG_SITE.Common.$(T_A)
|
||||
# CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A)
|
||||
|
||||
# CHECK_RELEASE controls the consistency checking of the support
|
||||
# applications pointed to by the RELEASE* files.
|
||||
# Normally CHECK_RELEASE should be set to YES.
|
||||
# Set CHECK_RELEASE to NO to disable checking completely.
|
||||
# Set CHECK_RELEASE to WARN to perform consistency checking but
|
||||
# continue building anyway if conflicts are found.
|
||||
#CHECK_RELEASE = YES
|
||||
|
||||
# Set this when you only want to compile this application
|
||||
# for a subset of the cross-compiled target architectures
|
||||
# that Base is built for.
|
||||
#CROSS_COMPILER_TARGET_ARCHS = vxWorks-68040
|
||||
|
||||
# To install files into a location other than $(TOP) define
|
||||
# INSTALL_LOCATION here.
|
||||
#INSTALL_LOCATION=</path/name/to/install/top>
|
||||
|
||||
# Set this when your IOC and the host use different paths
|
||||
# to access the application. This will be needed to boot
|
||||
# from a Microsoft FTP server or with some NFS mounts.
|
||||
# You must rebuild in the iocBoot directory for this to
|
||||
# take effect.
|
||||
#IOCS_APPL_TOP = </IOC/path/to/application/top>
|
||||
|
||||
INSTALL_INCLUDE = $(INSTALL_LOCATION)/include/pv
|
||||
USR_INCLUDES += -I $(INSTALL_LOCATION)/include
|
||||
|
||||
-include $(TOP)/../../CONFIG_SITE.local
|
||||
-include $(TOP)/../configure/CONFIG_SITE.local
|
||||
8
arrayPerformance/configure/ExampleRELEASE.local
Normal file
8
arrayPerformance/configure/ExampleRELEASE.local
Normal file
@@ -0,0 +1,8 @@
|
||||
EPICS_BASE=/home/install/epics/base
|
||||
TEMPLATE_TOP=$(EPICS_BASE)/templates/makeBaseApp/top
|
||||
EPICSV4HOME=/home/hg
|
||||
PVCOMMON=${EPICSV4HOME}/pvCommonCPP
|
||||
PVDATA=${EPICSV4HOME}/pvDataCPP
|
||||
PVACCESS=${EPICSV4HOME}/pvAccessCPP
|
||||
PVDATABASE=${EPICSV4HOME}/pvDatabaseCPP
|
||||
PVASRV=${EPICSV4HOME}/pvaSrv
|
||||
8
arrayPerformance/configure/Makefile
Normal file
8
arrayPerformance/configure/Makefile
Normal file
@@ -0,0 +1,8 @@
|
||||
TOP=..
|
||||
|
||||
include $(TOP)/configure/CONFIG
|
||||
|
||||
TARGETS = $(CONFIG_TARGETS)
|
||||
CONFIGS += $(subst ../,,$(wildcard $(CONFIG_INSTALLS)))
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
40
arrayPerformance/configure/RELEASE
Normal file
40
arrayPerformance/configure/RELEASE
Normal file
@@ -0,0 +1,40 @@
|
||||
# pvDatabaseCPP/arrayPerformance RELEASE - Location of external support modules
|
||||
#
|
||||
# IF YOU CHANGE this file or any file it includes you must
|
||||
# subsequently do a "gnumake rebuild" in the application's
|
||||
# top level directory.
|
||||
#
|
||||
# The build process does not check dependencies against files
|
||||
# that are outside this application, thus you should also do a
|
||||
# "gnumake rebuild" in the top level directory after EPICS_BASE
|
||||
# or any other external module pointed to below is rebuilt.
|
||||
#
|
||||
# Host- or target-specific settings can be given in files named
|
||||
# RELEASE.$(EPICS_HOST_ARCH).Common
|
||||
# RELEASE.Common.$(T_A)
|
||||
# RELEASE.$(EPICS_HOST_ARCH).$(T_A)
|
||||
|
||||
# EPICS V4 Developers: Do not edit the locations in this file!
|
||||
#
|
||||
# Create a file RELEASE.local pointing to your places
|
||||
# for the dependencies, e.g.
|
||||
# PVACCESS = /path/to/epics/pvAccessCPP
|
||||
# PVDATA = /path/to/epics/pvDataCPP
|
||||
# PVCOMMON = /path/to/epics/pvCommonCPP
|
||||
# EPICS_BASE = /path/to/epics/base
|
||||
|
||||
# If this example is built in a directory under pvDatabaseCPP,
|
||||
# use the following definitions:
|
||||
|
||||
PVDATABASE = $(TOP)/..
|
||||
-include $(TOP)/../../RELEASE.local
|
||||
-include $(TOP)/../configure/RELEASE.local
|
||||
|
||||
# If you copied this example from pvDatabaseCPP to be built as a
|
||||
# standalone TOP, define
|
||||
# PVDATABASE = /path/to/epics/pvDatabaseCPP
|
||||
# in the appropriate RELEASE[.local],
|
||||
# and use the following definitions instead:
|
||||
|
||||
#-include $(TOP)/../RELEASE.local
|
||||
#-include $(TOP)/configure/RELEASE.local
|
||||
6
arrayPerformance/configure/RULES
Normal file
6
arrayPerformance/configure/RULES
Normal file
@@ -0,0 +1,6 @@
|
||||
# RULES
|
||||
|
||||
include $(CONFIG)/RULES
|
||||
|
||||
# Library should be rebuilt because LIBOBJS may have changed.
|
||||
$(LIBNAME): ../Makefile
|
||||
2
arrayPerformance/configure/RULES.ioc
Normal file
2
arrayPerformance/configure/RULES.ioc
Normal file
@@ -0,0 +1,2 @@
|
||||
#RULES.ioc
|
||||
include $(CONFIG)/RULES.ioc
|
||||
2
arrayPerformance/configure/RULES_DIRS
Normal file
2
arrayPerformance/configure/RULES_DIRS
Normal file
@@ -0,0 +1,2 @@
|
||||
#RULES_DIRS
|
||||
include $(CONFIG)/RULES_DIRS
|
||||
2
arrayPerformance/configure/RULES_TOP
Normal file
2
arrayPerformance/configure/RULES_TOP
Normal file
@@ -0,0 +1,2 @@
|
||||
#RULES_TOP
|
||||
include $(CONFIG)/RULES_TOP
|
||||
45
arrayPerformance/src/Makefile
Normal file
45
arrayPerformance/src/Makefile
Normal file
@@ -0,0 +1,45 @@
|
||||
TOP = ..
|
||||
include $(TOP)/configure/CONFIG
|
||||
|
||||
LIBRARY_IOC += pvDatabaseExample
|
||||
pvDatabaseExample_LIBS += pvDatabase pvAccess pvData Com
|
||||
pvDatabaseExample_LIBS += $(EPICS_BASE_IOC_LIBS)
|
||||
|
||||
|
||||
INC+= arrayPerformance.h
|
||||
LIBSRCS += arrayPerformance.cpp
|
||||
INC+= longArrayMonitor.h
|
||||
LIBSRCS += longArrayMonitor.cpp
|
||||
INC+= longArrayGet.h
|
||||
LIBSRCS += longArrayGet.cpp
|
||||
INC+= longArrayPut.h
|
||||
LIBSRCS += longArrayPut.cpp
|
||||
|
||||
PROD_HOST += arrayPerformanceMain
|
||||
arrayPerformanceMain_SRCS += arrayPerformanceMain.cpp
|
||||
arrayPerformanceMain_LIBS += pvDatabase pvAccess pvData Com
|
||||
arrayPerformanceMain_LIBS += pvDatabaseExample
|
||||
|
||||
PROD_HOST += longArrayMonitorMain
|
||||
longArrayMonitorMain_SRCS += longArrayMonitorMain.cpp
|
||||
longArrayMonitorMain_LIBS += pvDatabase pvAccess pvData Com
|
||||
longArrayMonitorMain_LIBS += pvDatabaseExample
|
||||
|
||||
PROD_HOST += longArrayGetMain
|
||||
longArrayGetMain_SRCS += longArrayGetMain.cpp
|
||||
longArrayGetMain_LIBS += pvDatabase pvAccess pvData Com
|
||||
longArrayGetMain_LIBS += pvDatabaseExample
|
||||
|
||||
PROD_HOST += longArrayPutMain
|
||||
longArrayPutMain_SRCS += longArrayPutMain.cpp
|
||||
longArrayPutMain_LIBS += pvDatabase pvAccess pvData Com
|
||||
longArrayPutMain_LIBS += pvDatabaseExample
|
||||
|
||||
PROD_HOST += vectorPerformanceMain
|
||||
vectorPerformanceMain_SRCS += vectorPerformanceMain.cpp
|
||||
vectorPerformanceMain_LIBS += pvDatabase pvAccess pvData Com
|
||||
vectorPerformanceMain_LIBS += pvDatabaseExample
|
||||
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
|
||||
@@ -8,8 +8,13 @@
|
||||
* @author mrk
|
||||
* @date 2013.08.08
|
||||
*/
|
||||
|
||||
#include <pv/lock.h>
|
||||
#include <pv/arrayPerformance.h>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <arrayPerformance.h>
|
||||
|
||||
|
||||
|
||||
namespace epics { namespace pvDatabase {
|
||||
|
||||
@@ -18,9 +23,10 @@ using std::tr1::static_pointer_cast;
|
||||
using std::tr1::dynamic_pointer_cast;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::ostringstream;
|
||||
|
||||
ArrayPerformancePtr ArrayPerformance::create(
|
||||
epics::pvData::String const & recordName,
|
||||
std::string const & recordName,
|
||||
size_t size,
|
||||
double delay)
|
||||
{
|
||||
@@ -33,7 +39,7 @@ ArrayPerformancePtr ArrayPerformance::create(
|
||||
}
|
||||
|
||||
ArrayPerformance::ArrayPerformance(
|
||||
epics::pvData::String const & recordName,
|
||||
std::string const & recordName,
|
||||
epics::pvData::PVStructurePtr const & pvStructure,
|
||||
size_t size,
|
||||
double delay)
|
||||
@@ -53,9 +59,9 @@ bool ArrayPerformance::init()
|
||||
{
|
||||
|
||||
initPVRecord();
|
||||
PVScalarArrayPtr pvScalarArray = getPVStructure()->getScalarArrayField("value",pvLong);
|
||||
if(pvScalarArray==NULL) return false;
|
||||
pvValue = static_pointer_cast<PVLongArray>(pvScalarArray);
|
||||
PVLongArrayPtr pvLongArray = getPVStructure()->getSubField<PVLongArray>("value");
|
||||
if(!pvLongArray) return false;
|
||||
pvValue = pvLongArray;
|
||||
ArrayPerformancePtr xxx = dynamic_pointer_cast<ArrayPerformance>(getPtrSelf());
|
||||
arrayPerformanceThread = ArrayPerformanceThreadPtr(new ArrayPerformanceThread(xxx));
|
||||
arrayPerformanceThread->init();
|
||||
@@ -87,7 +93,8 @@ ArrayPerformanceThread::ArrayPerformanceThread(ArrayPerformancePtr const & array
|
||||
arrayPerformance(arrayPerformance),
|
||||
isDestroyed(false),
|
||||
runReturned(false),
|
||||
threadName("arrayPerformance")
|
||||
threadName("arrayPerformance"),
|
||||
value(0)
|
||||
{}
|
||||
|
||||
void ArrayPerformanceThread::init()
|
||||
@@ -138,29 +145,55 @@ void ArrayPerformanceThread::run()
|
||||
timeStamp.getCurrent();
|
||||
double diff = TimeStamp::diff(timeStamp,timeStampLast);
|
||||
if(diff>=1.0) {
|
||||
cout << "arrayPerformance value " << value;
|
||||
cout << " time " << diff;
|
||||
ostringstream out;
|
||||
out << "arrayPerformance value " << value;
|
||||
out << " time " << diff ;
|
||||
double iterations = nSinceLastReport;
|
||||
iterations /= diff;
|
||||
cout << " iterations/sec " << iterations;
|
||||
if(iterations>10.0e9) {
|
||||
iterations /= 1e9;
|
||||
out << " gigaIterations/sec " << iterations;
|
||||
} else if(iterations>10.0e6) {
|
||||
iterations /= 1e6;
|
||||
out << " megaIterations/sec " << iterations;
|
||||
} else if(iterations>10.0e3) {
|
||||
iterations /= 1e3;
|
||||
out << " kiloIterations/sec " << iterations;
|
||||
} else {
|
||||
out << " Iterations/sec " << iterations;
|
||||
}
|
||||
double elementSize = arrayPerformance->size;
|
||||
double elementsPerSecond = elementSize*nSinceLastReport;
|
||||
elementsPerSecond /= diff;
|
||||
elementsPerSecond /= 1e6;
|
||||
cout << " elements/sec " << elementsPerSecond << "million" << endl;
|
||||
cout.flush();
|
||||
if(elementsPerSecond>10.0e9) {
|
||||
elementsPerSecond /= 1e9;
|
||||
out << " gigaElements/sec " << elementsPerSecond;
|
||||
} else if(elementsPerSecond>10.0e6) {
|
||||
elementsPerSecond /= 1e6;
|
||||
out << " megaElements/sec " << elementsPerSecond;
|
||||
} else if(elementsPerSecond>10.0e3) {
|
||||
elementsPerSecond /= 1e3;
|
||||
out << " kiloElements/sec " << elementsPerSecond;
|
||||
} else {
|
||||
out << " Elements/sec " << elementsPerSecond;
|
||||
}
|
||||
cout << out.str() << endl;
|
||||
timeStampLast = timeStamp;
|
||||
nSinceLastReport = 0;
|
||||
}
|
||||
++nSinceLastReport;
|
||||
shared_vector<int64> xxx(arrayPerformance->size,value++);
|
||||
shared_vector<const int64> data(freeze(xxx));
|
||||
arrayPerformance->lock();
|
||||
try {
|
||||
arrayPerformance->beginGroupPut();
|
||||
arrayPerformance->pvValue->replace(data);
|
||||
arrayPerformance->process();
|
||||
arrayPerformance->endGroupPut();
|
||||
if(arrayPerformance->getTraceLevel()>1) {
|
||||
cout << "arrayPerformance size " << arrayPerformance->size;
|
||||
cout << " value " << value +1 << endl;
|
||||
}
|
||||
shared_vector<int64> xxx(arrayPerformance->size,value++);
|
||||
shared_vector<const int64> data(freeze(xxx));
|
||||
arrayPerformance->beginGroupPut();
|
||||
arrayPerformance->pvValue->replace(data);
|
||||
arrayPerformance->process();
|
||||
arrayPerformance->endGroupPut();
|
||||
} catch(...) {
|
||||
arrayPerformance->unlock();
|
||||
throw;
|
||||
@@ -11,12 +11,24 @@
|
||||
#ifndef ARRAYPERFORMANCE_H
|
||||
#define ARRAYPERFORMANCE_H
|
||||
|
||||
|
||||
#ifdef epicsExportSharedSymbols
|
||||
# define arrayperformanceEpicsExportSharedSymbols
|
||||
# undef epicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#include <epicsThread.h>
|
||||
#include <pv/standardPVField.h>
|
||||
#include <pv/timeStamp.h>
|
||||
#include <pv/pvTimeStamp.h>
|
||||
#include <pv/pvDatabase.h>
|
||||
|
||||
#ifdef arrayperformanceEpicsExportSharedSymbols
|
||||
# define epicsExportSharedSymbols
|
||||
# undef arrayperformanceEpicsExportSharedSymbols
|
||||
# include <shareLib.h>
|
||||
#endif
|
||||
|
||||
namespace epics { namespace pvDatabase {
|
||||
|
||||
class ArrayPerformance;
|
||||
@@ -25,13 +37,13 @@ typedef std::tr1::shared_ptr<ArrayPerformance> ArrayPerformancePtr;
|
||||
class ArrayPerformanceThread;
|
||||
typedef std::tr1::shared_ptr<ArrayPerformanceThread> ArrayPerformanceThreadPtr;
|
||||
|
||||
class ArrayPerformance :
|
||||
class epicsShareClass ArrayPerformance :
|
||||
public PVRecord
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(ArrayPerformance);
|
||||
static ArrayPerformancePtr create(
|
||||
epics::pvData::String const & recordName,
|
||||
std::string const & recordName,
|
||||
size_t size,
|
||||
double delay);
|
||||
virtual ~ArrayPerformance();
|
||||
@@ -40,7 +52,7 @@ public:
|
||||
virtual void process();
|
||||
virtual void destroy();
|
||||
private:
|
||||
ArrayPerformance(epics::pvData::String const & recordName,
|
||||
ArrayPerformance(std::string const & recordName,
|
||||
epics::pvData::PVStructurePtr const & pvStructure,
|
||||
size_t size,
|
||||
double delay);
|
||||
@@ -54,7 +66,7 @@ private:
|
||||
friend class ArrayPerformanceThread;
|
||||
};
|
||||
|
||||
class ArrayPerformanceThread :
|
||||
class epicsShareClass ArrayPerformanceThread :
|
||||
public epicsThreadRunable
|
||||
{
|
||||
public:
|
||||
@@ -68,7 +80,7 @@ private:
|
||||
ArrayPerformancePtr arrayPerformance;
|
||||
bool isDestroyed;
|
||||
bool runReturned;
|
||||
epics::pvData::String threadName;
|
||||
std::string threadName;
|
||||
epics::pvData::Mutex mutex;
|
||||
epics::pvData::int64 value;
|
||||
std::auto_ptr<epicsThread> thread;
|
||||
@@ -22,13 +22,14 @@
|
||||
|
||||
#include <pv/standardField.h>
|
||||
#include <pv/standardPVField.h>
|
||||
#include <pv/arrayPerformance.h>
|
||||
#include <pv/longArrayMonitor.h>
|
||||
#include <pv/traceRecord.h>
|
||||
#include <pv/channelProviderLocal.h>
|
||||
#include <pv/serverContext.h>
|
||||
#include <pv/clientFactory.h>
|
||||
|
||||
#include <arrayPerformance.h>
|
||||
#include <longArrayMonitor.h>
|
||||
|
||||
using namespace std;
|
||||
using std::tr1::static_pointer_cast;
|
||||
using namespace epics::pvData;
|
||||
@@ -38,16 +39,17 @@ using namespace epics::pvDatabase;
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
bool result(false);
|
||||
String recordName;
|
||||
string recordName;
|
||||
recordName = "arrayPerformance";
|
||||
size_t size = 50000000;
|
||||
double delay = .01;
|
||||
String providerName("local");
|
||||
size_t size = 10000000;
|
||||
double delay = .0001;
|
||||
string providerName("local");
|
||||
size_t nMonitor = 1;
|
||||
bool useQueue = false;
|
||||
if(argc==2 && String(argv[1])==String("-help")) {
|
||||
int queueSize = 2;
|
||||
double waitTime = 0.0;
|
||||
if(argc==2 && string(argv[1])==string("-help")) {
|
||||
cout << "arrayPerformanceMain recordName size";
|
||||
cout << " delay providerName nMonitor useQueue" << endl;
|
||||
cout << " delay providerName nMonitor queueSize waitTime" << endl;
|
||||
cout << "default" << endl;
|
||||
cout << "arrayPerformance ";
|
||||
cout << recordName << " ";
|
||||
@@ -55,7 +57,8 @@ int main(int argc,char *argv[])
|
||||
cout << delay << " ";
|
||||
cout << providerName << " ";
|
||||
cout << nMonitor << " ";
|
||||
cout << (useQueue ? "true" : "false") << endl;
|
||||
cout << queueSize << " ";
|
||||
cout << "0.0" << endl;
|
||||
return 0;
|
||||
}
|
||||
if(argc>1) recordName = argv[1];
|
||||
@@ -63,20 +66,24 @@ int main(int argc,char *argv[])
|
||||
if(argc>3) delay = atof(argv[3]);
|
||||
if(argc>4) providerName = argv[4];
|
||||
if(argc>5) nMonitor = strtoul(argv[5],0,0);
|
||||
if(argc>6) useQueue = (argv[6]==String("true") ? true : false);
|
||||
if(argc>6) queueSize = strtol(argv[6],0,0);
|
||||
if(argc>7) waitTime = atof(argv[7]);
|
||||
cout << "arrayPerformance ";
|
||||
cout << recordName << " ";
|
||||
cout << size << " ";
|
||||
cout << delay << " ";
|
||||
cout << providerName << " ";
|
||||
cout << nMonitor << " ";
|
||||
cout << (useQueue ? "true" : "false") << endl;
|
||||
cout << queueSize << " ";
|
||||
cout << waitTime << endl;
|
||||
ClientFactory::start();
|
||||
PVDatabasePtr master = PVDatabase::getMaster();
|
||||
ChannelProviderLocalPtr channelProvider = getChannelProviderLocal();
|
||||
PVRecordPtr pvRecord;
|
||||
pvRecord = ArrayPerformance::create(recordName,size,delay);
|
||||
result = master->addRecord(pvRecord);
|
||||
PVRecordPtr arrayPreformance = pvRecord;
|
||||
arrayPreformance->setTraceLevel(0);
|
||||
pvRecord = TraceRecord::create("traceRecordPGRPC");
|
||||
result = master->addRecord(pvRecord);
|
||||
if(!result) cout<< "record " << recordName << " not added" << endl;
|
||||
@@ -86,8 +93,9 @@ int main(int argc,char *argv[])
|
||||
std::vector<LongArrayMonitorPtr> longArrayMonitor(nMonitor);
|
||||
for(size_t i=0; i<nMonitor; ++i) {
|
||||
longArrayMonitor[i]
|
||||
= LongArrayMonitor::create(providerName,recordName,useQueue);
|
||||
= LongArrayMonitor::create(providerName,recordName,queueSize,waitTime);
|
||||
}
|
||||
epicsThreadSleep(1.0);
|
||||
for(size_t i=0; i<nMonitor; ++i) longArrayMonitor[i]->start();
|
||||
cout << "arrayPerformance\n";
|
||||
string str;
|
||||
@@ -97,11 +105,14 @@ int main(int argc,char *argv[])
|
||||
if(str.compare("exit")==0) break;
|
||||
|
||||
}
|
||||
arrayPreformance.reset();
|
||||
for(size_t i=0; i<nMonitor; ++i) longArrayMonitor[i]->stop();
|
||||
for(size_t i=0; i<nMonitor; ++i) longArrayMonitor[i]->destroy();
|
||||
pvaServer->shutdown();
|
||||
epicsThreadSleep(1.0);
|
||||
pvaServer->destroy();
|
||||
ClientFactory::stop();
|
||||
epicsThreadSleep(1.0);
|
||||
channelProvider->destroy();
|
||||
return 0;
|
||||
}
|
||||
543
arrayPerformance/src/longArrayGet.cpp
Normal file
543
arrayPerformance/src/longArrayGet.cpp
Normal file
@@ -0,0 +1,543 @@
|
||||
/* longArrayGet.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
* @date 2013.08.09
|
||||
*/
|
||||
|
||||
#include <epicsThread.h>
|
||||
#include <pv/caProvider.h>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <longArrayGet.h>
|
||||
|
||||
namespace epics { namespace pvDatabase {
|
||||
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
using std::tr1::static_pointer_cast;
|
||||
using std::tr1::dynamic_pointer_cast;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::ostringstream;
|
||||
using std::string;
|
||||
|
||||
static string requesterName("longArrayGet");
|
||||
static string request("value,timeStamp,alarm");
|
||||
static epics::pvData::Mutex printMutex;
|
||||
|
||||
class LongArrayChannelRequester;
|
||||
typedef std::tr1::shared_ptr<LongArrayChannelRequester> LongArrayChannelRequesterPtr;
|
||||
class LongArrayChannelGetRequester;
|
||||
typedef std::tr1::shared_ptr<LongArrayChannelGetRequester> LongArrayChannelGetRequesterPtr;
|
||||
|
||||
class LongArrayChannelRequester :
|
||||
virtual public ChannelRequester,
|
||||
public std::tr1::enable_shared_from_this<LongArrayChannelRequester>
|
||||
{
|
||||
public:
|
||||
LongArrayChannelRequester(
|
||||
LongArrayChannelGetPtr const & longArrayChannelGet)
|
||||
: longArrayChannelGet(longArrayChannelGet),
|
||||
isDestroyed(false)
|
||||
{}
|
||||
virtual ~LongArrayChannelRequester(){}
|
||||
virtual void destroy()
|
||||
{
|
||||
Lock guard(mutex);
|
||||
if(isDestroyed) return;
|
||||
isDestroyed = true;
|
||||
longArrayChannelGet.reset();
|
||||
}
|
||||
virtual string getRequesterName() { return requesterName;}
|
||||
virtual void message(string const & message, MessageType messageType)
|
||||
{
|
||||
Lock guard(printMutex);
|
||||
cout << requesterName << " message " << message << endl;
|
||||
}
|
||||
virtual void channelCreated(
|
||||
const Status& status,
|
||||
Channel::shared_pointer const & channel);
|
||||
virtual void channelStateChange(
|
||||
Channel::shared_pointer const & channel,
|
||||
Channel::ConnectionState connectionState);
|
||||
private:
|
||||
LongArrayChannelRequesterPtr getPtrSelf()
|
||||
{
|
||||
return shared_from_this();
|
||||
}
|
||||
LongArrayChannelGetPtr longArrayChannelGet;
|
||||
bool isDestroyed;
|
||||
Mutex mutex;
|
||||
};
|
||||
|
||||
|
||||
class LongArrayChannelGetRequester :
|
||||
virtual public ChannelGetRequester,
|
||||
public std::tr1::enable_shared_from_this<LongArrayChannelGetRequester>
|
||||
{
|
||||
public:
|
||||
LongArrayChannelGetRequester(
|
||||
LongArrayChannelGetPtr const & longArrayChannelGet)
|
||||
: longArrayChannelGet(longArrayChannelGet),
|
||||
isDestroyed(false)
|
||||
{}
|
||||
virtual ~LongArrayChannelGetRequester(){}
|
||||
virtual void destroy()
|
||||
{
|
||||
Lock guard(mutex);
|
||||
if(isDestroyed) return;
|
||||
isDestroyed = true;
|
||||
longArrayChannelGet.reset();
|
||||
}
|
||||
virtual string getRequesterName() { return requesterName;}
|
||||
virtual void message(string const & message, MessageType messageType)
|
||||
{
|
||||
Lock guard(printMutex);
|
||||
cout << requesterName << " message " << message << endl;
|
||||
}
|
||||
virtual void channelGetConnect(
|
||||
Status const & status,
|
||||
ChannelGet::shared_pointer const & channelGet,
|
||||
StructureConstPtr const &structure);
|
||||
virtual void getDone(
|
||||
Status const & status,
|
||||
ChannelGet::shared_pointer const & channelGet,
|
||||
PVStructurePtr const &pvStructure,
|
||||
BitSetPtr const & bitSet);
|
||||
private:
|
||||
LongArrayChannelGetRequesterPtr getPtrSelf()
|
||||
{
|
||||
return shared_from_this();
|
||||
}
|
||||
LongArrayChannelGetPtr longArrayChannelGet;
|
||||
bool isDestroyed;
|
||||
Mutex mutex;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class LongArrayChannelGet :
|
||||
public std::tr1::enable_shared_from_this<LongArrayChannelGet>,
|
||||
public epicsThreadRunable
|
||||
{
|
||||
public:
|
||||
LongArrayChannelGet(
|
||||
string providerName,
|
||||
string channelName,
|
||||
int iterBetweenCreateChannel,
|
||||
int iterBetweenCreateChannelGet,
|
||||
double delayTime)
|
||||
: providerName(providerName),
|
||||
channelName(channelName),
|
||||
iterBetweenCreateChannel(iterBetweenCreateChannel),
|
||||
iterBetweenCreateChannelGet(iterBetweenCreateChannelGet),
|
||||
delayTime(delayTime),
|
||||
isDestroyed(false),
|
||||
runReturned(false),
|
||||
threadName("longArrayGet")
|
||||
{}
|
||||
virtual ~LongArrayChannelGet(){}
|
||||
bool init();
|
||||
virtual void destroy();
|
||||
virtual void run();
|
||||
void message(string const & message, MessageType messageType)
|
||||
{
|
||||
Lock guard(printMutex);
|
||||
cout << requesterName << " message " << message << endl;
|
||||
}
|
||||
virtual void channelCreated(
|
||||
const Status& status,
|
||||
Channel::shared_pointer const & channel);
|
||||
virtual void channelStateChange(
|
||||
Channel::shared_pointer const & channel,
|
||||
Channel::ConnectionState connectionState);
|
||||
virtual void channelGetConnect(
|
||||
Status const & status,
|
||||
ChannelGet::shared_pointer const & channelGet,
|
||||
StructureConstPtr const &structure);
|
||||
virtual void getDone(
|
||||
Status const & status,
|
||||
ChannelGet::shared_pointer channelGet,
|
||||
PVStructurePtr const &pvStructure,
|
||||
BitSetPtr const & bitSet);
|
||||
private:
|
||||
LongArrayChannelGetPtr getPtrSelf()
|
||||
{
|
||||
return shared_from_this();
|
||||
}
|
||||
size_t checkResult();
|
||||
string providerName;
|
||||
string channelName;
|
||||
int iterBetweenCreateChannel;
|
||||
int iterBetweenCreateChannelGet;
|
||||
double delayTime;
|
||||
bool isDestroyed;
|
||||
bool runReturned;
|
||||
std::string threadName;
|
||||
Status status;
|
||||
Event event;
|
||||
Mutex mutex;
|
||||
std::auto_ptr<epicsThread> thread;
|
||||
Channel::shared_pointer channel;
|
||||
ChannelGet::shared_pointer channelGet;
|
||||
PVStructurePtr pvStructure;
|
||||
BitSetPtr bitSet;
|
||||
LongArrayChannelRequesterPtr longArrayChannelRequester;
|
||||
LongArrayChannelGetRequesterPtr longArrayChannelGetRequester;
|
||||
};
|
||||
|
||||
void LongArrayChannelRequester::channelCreated(
|
||||
const Status& status,
|
||||
Channel::shared_pointer const & channel)
|
||||
{
|
||||
Lock guard(mutex);
|
||||
if(isDestroyed) return;
|
||||
longArrayChannelGet->channelCreated(status,channel);
|
||||
}
|
||||
|
||||
void LongArrayChannelRequester::channelStateChange(
|
||||
Channel::shared_pointer const & channel,
|
||||
Channel::ConnectionState connectionState)
|
||||
{
|
||||
string mess(Channel::ConnectionStateNames[connectionState]);
|
||||
message(mess,infoMessage);
|
||||
Lock guard(mutex);
|
||||
if(isDestroyed) return;
|
||||
longArrayChannelGet->channelStateChange(channel,connectionState);
|
||||
}
|
||||
|
||||
void LongArrayChannelGetRequester::channelGetConnect(
|
||||
Status const & status,
|
||||
ChannelGet::shared_pointer const & channelGet,
|
||||
StructureConstPtr const &structure)
|
||||
{
|
||||
Lock guard(mutex);
|
||||
if(isDestroyed) return;
|
||||
longArrayChannelGet->channelGetConnect(
|
||||
status,channelGet,structure);
|
||||
}
|
||||
|
||||
void LongArrayChannelGetRequester::getDone(
|
||||
Status const & status,
|
||||
ChannelGet::shared_pointer const & channelGet,
|
||||
PVStructurePtr const &pvStructure,
|
||||
BitSetPtr const & bitSet)
|
||||
{
|
||||
Lock guard(mutex);
|
||||
if(isDestroyed) return;
|
||||
longArrayChannelGet->getDone(status,channelGet,pvStructure,bitSet);
|
||||
}
|
||||
|
||||
void LongArrayChannelGet::channelCreated(
|
||||
const Status& status,
|
||||
Channel::shared_pointer const & channel)
|
||||
{
|
||||
if(!status.isOK()) message(status.getMessage(),errorMessage);
|
||||
this->status = status;
|
||||
this->channel = channel;
|
||||
event.signal();
|
||||
}
|
||||
|
||||
void LongArrayChannelGet::channelStateChange(
|
||||
Channel::shared_pointer const & channel,
|
||||
Channel::ConnectionState connectionState)
|
||||
{
|
||||
MessageType messageType =
|
||||
(connectionState==Channel::CONNECTED ? infoMessage : errorMessage);
|
||||
message("channelStateChange",messageType);
|
||||
}
|
||||
void LongArrayChannelGet::channelGetConnect(
|
||||
Status const & status,
|
||||
ChannelGet::shared_pointer const & channelGet,
|
||||
StructureConstPtr const &structure)
|
||||
{
|
||||
this->status = status;
|
||||
if(!status.isOK()) {
|
||||
message(status.getMessage(),errorMessage);
|
||||
event.signal();
|
||||
return;
|
||||
}
|
||||
this->channelGet = channelGet;
|
||||
bool structureOK(true);
|
||||
PVStructurePtr pvStructure = getPVDataCreate()->createPVStructure(structure);
|
||||
PVFieldPtr pvField = pvStructure->getSubField("timeStamp");
|
||||
if(!pvField) structureOK = false;
|
||||
pvField = pvStructure->getSubField("value");
|
||||
if(!pvField) {
|
||||
structureOK = false;
|
||||
} else {
|
||||
FieldConstPtr field = pvField->getField();
|
||||
if(field->getType()!=scalarArray) {
|
||||
structureOK = false;
|
||||
} else {
|
||||
ScalarArrayConstPtr scalarArray = dynamic_pointer_cast<const ScalarArray>(field);
|
||||
if(scalarArray->getElementType()!=pvLong) structureOK = false;
|
||||
}
|
||||
}
|
||||
if(!structureOK) {
|
||||
string mess("channelGetConnect: illegal structure");
|
||||
message(mess,errorMessage);
|
||||
this->status = Status(Status::STATUSTYPE_ERROR,mess);
|
||||
}
|
||||
event.signal();
|
||||
}
|
||||
|
||||
|
||||
bool LongArrayChannelGet::init()
|
||||
{
|
||||
ChannelProvider::shared_pointer channelProvider =
|
||||
getChannelProviderRegistry()->getProvider(providerName);
|
||||
if(!channelProvider) {
|
||||
cout << "provider " << providerName << " not found" << endl;
|
||||
return false;
|
||||
}
|
||||
longArrayChannelRequester.reset(new LongArrayChannelRequester(getPtrSelf()));
|
||||
channel = channelProvider->createChannel(
|
||||
channelName,
|
||||
longArrayChannelRequester);
|
||||
event.wait();
|
||||
channelProvider.reset();
|
||||
if(!status.isOK()) return false;
|
||||
CreateRequest::shared_pointer createRequest = CreateRequest::create();
|
||||
PVStructurePtr pvRequest = createRequest->createRequest(request);
|
||||
if(!pvRequest) {
|
||||
cout << "request logic error " << createRequest->getMessage() << endl;
|
||||
return false;
|
||||
}
|
||||
longArrayChannelGetRequester.reset(new LongArrayChannelGetRequester(getPtrSelf()));
|
||||
channelGet = channel->createChannelGet(
|
||||
longArrayChannelGetRequester,
|
||||
pvRequest);
|
||||
event.wait();
|
||||
if(!status.isOK()) return false;
|
||||
thread = std::auto_ptr<epicsThread>(new epicsThread(
|
||||
*this,
|
||||
threadName.c_str(),
|
||||
epicsThreadGetStackSize(epicsThreadStackSmall),
|
||||
epicsThreadPriorityLow));
|
||||
thread->start();
|
||||
event.signal();
|
||||
return true;
|
||||
}
|
||||
|
||||
void LongArrayChannelGet::destroy()
|
||||
{
|
||||
if(isDestroyed) return;
|
||||
isDestroyed = true;
|
||||
event.signal();
|
||||
while(true) {
|
||||
if(runReturned) break;
|
||||
epicsThreadSleep(.01);
|
||||
}
|
||||
if(longArrayChannelRequester) {
|
||||
longArrayChannelRequester->destroy();
|
||||
}
|
||||
if(longArrayChannelGetRequester) {
|
||||
longArrayChannelGetRequester->destroy();
|
||||
}
|
||||
thread->exitWait();
|
||||
channel->destroy();
|
||||
channelGet.reset();
|
||||
channel.reset();
|
||||
}
|
||||
|
||||
|
||||
void LongArrayChannelGet::run()
|
||||
{
|
||||
while(true) {
|
||||
event.wait();
|
||||
if(isDestroyed) {
|
||||
runReturned = true;
|
||||
return;
|
||||
}
|
||||
TimeStamp timeStamp;
|
||||
TimeStamp timeStampLast;
|
||||
timeStampLast.getCurrent();
|
||||
int numChannelGet = 0;
|
||||
int numChannelCreate = 0;
|
||||
size_t nElements = 0;
|
||||
while(true) {
|
||||
channelGet->get();
|
||||
event.wait();
|
||||
if(isDestroyed) {
|
||||
runReturned = true;
|
||||
return;
|
||||
}
|
||||
size_t latestSize = checkResult();
|
||||
nElements += latestSize;
|
||||
timeStamp.getCurrent();
|
||||
double diff = TimeStamp::diff(timeStamp,timeStampLast);
|
||||
if(diff>=1.0) {
|
||||
ostringstream out;
|
||||
out << "get";
|
||||
double elementsPerSec = nElements;
|
||||
elementsPerSec /= diff;
|
||||
if(elementsPerSec>10.0e9) {
|
||||
elementsPerSec /= 1e9;
|
||||
out << " gigaElements/sec " << elementsPerSec;
|
||||
} else if(elementsPerSec>10.0e6) {
|
||||
elementsPerSec /= 1e6;
|
||||
out << " megaElements/sec " << elementsPerSec;
|
||||
} else if(elementsPerSec>10.0e3) {
|
||||
elementsPerSec /= 1e3;
|
||||
out << " kiloElements/sec " << elementsPerSec;
|
||||
} else {
|
||||
out << " Elements/sec " << elementsPerSec;
|
||||
}
|
||||
cout << out.str() << endl;
|
||||
timeStampLast = timeStamp;
|
||||
nElements = 0;
|
||||
}
|
||||
if(delayTime>0.0) epicsThreadSleep(delayTime);
|
||||
if(isDestroyed) {
|
||||
runReturned = true;
|
||||
return;
|
||||
}
|
||||
++numChannelCreate;
|
||||
bool createGet = false;
|
||||
if(iterBetweenCreateChannel!=0) {
|
||||
if(numChannelCreate>=iterBetweenCreateChannel) {
|
||||
longArrayChannelRequester->destroy();
|
||||
channel->destroy();
|
||||
ChannelProvider::shared_pointer channelProvider =
|
||||
getChannelProviderRegistry()->getProvider(providerName);
|
||||
longArrayChannelRequester.reset(new LongArrayChannelRequester(getPtrSelf()));
|
||||
channel = channelProvider->createChannel(
|
||||
channelName,
|
||||
longArrayChannelRequester);
|
||||
event.wait();
|
||||
channelProvider.reset();
|
||||
if(!status.isOK()) {
|
||||
message(status.getMessage(),errorMessage);
|
||||
return;
|
||||
}
|
||||
cout<< "createChannel success" << endl;
|
||||
createGet = true;
|
||||
numChannelCreate = 0;
|
||||
}
|
||||
}
|
||||
++numChannelGet;
|
||||
if(iterBetweenCreateChannelGet!=0) {
|
||||
if(numChannelGet>=iterBetweenCreateChannelGet) createGet = true;
|
||||
}
|
||||
if(createGet) {
|
||||
numChannelGet = 0;
|
||||
longArrayChannelGetRequester->destroy();
|
||||
channelGet->destroy();
|
||||
CreateRequest::shared_pointer createRequest =
|
||||
CreateRequest::create();
|
||||
PVStructurePtr pvRequest =
|
||||
createRequest->createRequest(request);
|
||||
if(!pvRequest) {
|
||||
cout << "request logic error " << createRequest->getMessage() << endl;
|
||||
return ;
|
||||
}
|
||||
longArrayChannelGetRequester.reset(new LongArrayChannelGetRequester(getPtrSelf()));
|
||||
channelGet = channel->createChannelGet(
|
||||
longArrayChannelGetRequester,
|
||||
pvRequest);
|
||||
event.wait();
|
||||
if(!status.isOK()) {
|
||||
message(status.getMessage(),errorMessage);
|
||||
return;
|
||||
}
|
||||
cout<< "createChannelGet success" << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LongArrayChannelGet::getDone(
|
||||
Status const & status,
|
||||
ChannelGet::shared_pointer channelGet,
|
||||
PVStructurePtr const &pvStructure,
|
||||
BitSetPtr const & bitSet)
|
||||
{
|
||||
this->pvStructure = pvStructure;
|
||||
this->bitSet = bitSet;
|
||||
event.signal();
|
||||
}
|
||||
|
||||
size_t LongArrayChannelGet::checkResult()
|
||||
{
|
||||
PVLongArrayPtr pvValue;
|
||||
if(!status.isOK()) {
|
||||
message(status.getMessage(),errorMessage);
|
||||
return 0;
|
||||
}
|
||||
pvValue = dynamic_pointer_cast<PVLongArray>(pvStructure->getSubField("value"));
|
||||
if(!bitSet->get(pvValue->getFieldOffset())) {
|
||||
return 0;
|
||||
}
|
||||
bitSet->clear();
|
||||
shared_vector<const int64> data = pvValue->view();
|
||||
if(data.size()>0) {
|
||||
int64 first = data[0];
|
||||
int64 last = data[data.size()-1];
|
||||
if(first!=last) {
|
||||
cout << "error first=" << first << " last=" << last << endl;
|
||||
}
|
||||
}
|
||||
return data.size();
|
||||
}
|
||||
|
||||
|
||||
LongArrayGetPtr LongArrayGet::create(
|
||||
string const &providerName,
|
||||
string const & channelName,
|
||||
int iterBetweenCreateChannel,
|
||||
int iterBetweenCreateChannelGet,
|
||||
double delayTime)
|
||||
{
|
||||
LongArrayGetPtr longArrayGet(
|
||||
new LongArrayGet(
|
||||
providerName,
|
||||
channelName,
|
||||
iterBetweenCreateChannel,
|
||||
iterBetweenCreateChannelGet,
|
||||
delayTime));
|
||||
if(!longArrayGet->init()) longArrayGet.reset();
|
||||
return longArrayGet;
|
||||
}
|
||||
|
||||
LongArrayGet::LongArrayGet(
|
||||
string const &providerName,
|
||||
string const & channelName,
|
||||
int iterBetweenCreateChannel,
|
||||
int iterBetweenCreateChannelGet,
|
||||
double delayTime)
|
||||
: providerName(providerName),
|
||||
channelName(channelName),
|
||||
iterBetweenCreateChannel(iterBetweenCreateChannel),
|
||||
iterBetweenCreateChannelGet(iterBetweenCreateChannelGet),
|
||||
delayTime(delayTime)
|
||||
{}
|
||||
|
||||
|
||||
LongArrayGet::~LongArrayGet() {}
|
||||
|
||||
bool LongArrayGet::init()
|
||||
{
|
||||
longArrayChannelGet = LongArrayChannelGetPtr(new LongArrayChannelGet(
|
||||
providerName,
|
||||
channelName,
|
||||
iterBetweenCreateChannel,
|
||||
iterBetweenCreateChannelGet,
|
||||
delayTime));
|
||||
return longArrayChannelGet->init();
|
||||
}
|
||||
|
||||
void LongArrayGet::destroy()
|
||||
{
|
||||
longArrayChannelGet->destroy();
|
||||
longArrayChannelGet.reset();
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
|
||||
81
arrayPerformance/src/longArrayGet.h
Normal file
81
arrayPerformance/src/longArrayGet.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/* longArrayGet.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
* @date 2013.08.09
|
||||
*/
|
||||
#ifndef LONGARRAYGET_H
|
||||
#define LONGARRAYGET_H
|
||||
|
||||
|
||||
#ifdef epicsExportSharedSymbols
|
||||
# define longarraygetEpicsExportSharedSymbols
|
||||
# undef epicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#include <pv/event.h>
|
||||
#include <pv/lock.h>
|
||||
#include <pv/standardPVField.h>
|
||||
#include <pv/timeStamp.h>
|
||||
#include <pv/pvTimeStamp.h>
|
||||
#include <pv/pvAccess.h>
|
||||
|
||||
|
||||
#ifdef longarraygetEpicsExportSharedSymbols
|
||||
# define epicsExportSharedSymbols
|
||||
# undef longarraygetEpicsExportSharedSymbols
|
||||
# include <shareLib.h>
|
||||
#endif
|
||||
|
||||
namespace epics { namespace pvDatabase {
|
||||
|
||||
|
||||
class LongArrayGet;
|
||||
typedef std::tr1::shared_ptr<LongArrayGet> LongArrayGetPtr;
|
||||
|
||||
|
||||
class LongArrayChannelGet;
|
||||
typedef std::tr1::shared_ptr<LongArrayChannelGet> LongArrayChannelGetPtr;
|
||||
|
||||
class epicsShareClass LongArrayGet :
|
||||
public std::tr1::enable_shared_from_this<LongArrayGet>
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(LongArrayGet);
|
||||
static LongArrayGetPtr create(
|
||||
std::string const & providerName,
|
||||
std::string const & channelName,
|
||||
int iterBetweenCreateChannel = 0,
|
||||
int iterBetweenCreateChannelGet = 0,
|
||||
double delayTime = 0.0);
|
||||
~LongArrayGet();
|
||||
void destroy();
|
||||
private:
|
||||
LongArrayGetPtr getPtrSelf()
|
||||
{
|
||||
return shared_from_this();
|
||||
}
|
||||
LongArrayGet(
|
||||
std::string const & providerName,
|
||||
std::string const & channelName,
|
||||
int iterBetweenCreateChannel = 0,
|
||||
int iterBetweenCreateChannelGet = 0,
|
||||
double delayTime = 0.0);
|
||||
bool init();
|
||||
|
||||
std::string providerName;
|
||||
std::string channelName;
|
||||
int iterBetweenCreateChannel;
|
||||
int iterBetweenCreateChannelGet;
|
||||
double delayTime;
|
||||
LongArrayChannelGetPtr longArrayChannelGet;
|
||||
};
|
||||
|
||||
|
||||
}}
|
||||
|
||||
#endif /* LONGARRAYGET_H */
|
||||
87
arrayPerformance/src/longArrayGetMain.cpp
Normal file
87
arrayPerformance/src/longArrayGetMain.cpp
Normal file
@@ -0,0 +1,87 @@
|
||||
/*longArrayGetMain.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
* @date 2013.08.10
|
||||
*/
|
||||
|
||||
/* Author: Marty Kraimer */
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
#include <memory>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#include <pv/standardField.h>
|
||||
#include <pv/standardPVField.h>
|
||||
#include <pv/traceRecord.h>
|
||||
#include <pv/channelProviderLocal.h>
|
||||
#include <pv/serverContext.h>
|
||||
#include <pv/clientFactory.h>
|
||||
|
||||
#include <arrayPerformance.h>
|
||||
#include <longArrayGet.h>
|
||||
|
||||
using namespace std;
|
||||
using std::tr1::static_pointer_cast;
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
using namespace epics::pvDatabase;
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
string channelName("arrayPerformance");
|
||||
int iterBetweenCreateChannel = 0;
|
||||
int iterBetweenCreateChannelGet = 0;
|
||||
double delayTime = 1.0;
|
||||
if(argc==2 && string(argv[1])==string("-help")) {
|
||||
cout << "longArrayGetMain channelName ";
|
||||
cout << "iterBetweenCreateChannel iterBetweenCreateChannelGet delayTime" << endl;
|
||||
cout << "default" << endl;
|
||||
cout << "longArrayGetMain " << channelName << " ";
|
||||
cout << iterBetweenCreateChannel << " ";
|
||||
cout << iterBetweenCreateChannelGet << " ";
|
||||
cout << delayTime << endl;
|
||||
return 0;
|
||||
}
|
||||
ClientFactory::start();
|
||||
if(argc>1) channelName = argv[1];
|
||||
if(argc>2) iterBetweenCreateChannel = strtol(argv[2],0,0);
|
||||
if(argc>3) iterBetweenCreateChannelGet = strtol(argv[3],0,0);
|
||||
if(argc>4) delayTime = atof(argv[4]);
|
||||
cout << "longArrayGetMain " << channelName << " ";
|
||||
cout << iterBetweenCreateChannel << " ";
|
||||
cout << iterBetweenCreateChannelGet << " ";
|
||||
cout << delayTime << endl;
|
||||
LongArrayGetPtr longArrayGet
|
||||
= LongArrayGet::create(
|
||||
"pvAccess",
|
||||
channelName,
|
||||
iterBetweenCreateChannel,
|
||||
iterBetweenCreateChannelGet,
|
||||
delayTime);
|
||||
cout << "longArrayGet\n";
|
||||
string str;
|
||||
while(true) {
|
||||
cout << "Type exit to stop: \n";
|
||||
getline(cin,str);
|
||||
if(str.compare("exit")==0) break;
|
||||
|
||||
}
|
||||
longArrayGet->destroy();
|
||||
longArrayGet.reset();
|
||||
double xxx = 1.0;
|
||||
if(xxx<delayTime) xxx = delayTime;
|
||||
ClientFactory::stop();
|
||||
epicsThreadSleep(xxx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -9,10 +9,14 @@
|
||||
* @date 2013.08.09
|
||||
*/
|
||||
|
||||
|
||||
#include <epicsThread.h>
|
||||
#include <pv/longArrayMonitor.h>
|
||||
#include <pv/caProvider.h>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <longArrayMonitor.h>
|
||||
|
||||
|
||||
namespace epics { namespace pvDatabase {
|
||||
|
||||
using namespace epics::pvData;
|
||||
@@ -21,10 +25,12 @@ using std::tr1::static_pointer_cast;
|
||||
using std::tr1::dynamic_pointer_cast;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::string;
|
||||
using std::ostringstream;
|
||||
|
||||
static String requesterName("longArrayMonitor");
|
||||
static string requesterName("longArrayMonitor");
|
||||
|
||||
static void messagePvt(String const & message, MessageType messageType)
|
||||
static void messagePvt(string const & message, MessageType messageType)
|
||||
{
|
||||
cout << requesterName << " message " << message << endl;
|
||||
}
|
||||
@@ -37,8 +43,9 @@ public:
|
||||
: longArrayMonitor(longArrayMonitor)
|
||||
{}
|
||||
virtual ~LAMChannelRequester(){}
|
||||
virtual String getRequesterName() { return requesterName;}
|
||||
virtual void message(String const & message, MessageType messageType)
|
||||
virtual void destroy(){longArrayMonitor.reset();}
|
||||
virtual string getRequesterName() { return requesterName;}
|
||||
virtual void message(string const & message, MessageType messageType)
|
||||
{ messagePvt(message,messageType);}
|
||||
virtual void channelCreated(const Status& status, Channel::shared_pointer const & channel);
|
||||
virtual void channelStateChange(Channel::shared_pointer const & channel, Channel::ConnectionState connectionState);
|
||||
@@ -66,8 +73,9 @@ class LAMMonitorRequester :
|
||||
public epicsThreadRunable
|
||||
{
|
||||
public:
|
||||
LAMMonitorRequester(LongArrayMonitorPtr const &longArrayMonitor)
|
||||
LAMMonitorRequester(LongArrayMonitorPtr const &longArrayMonitor,double waitTime)
|
||||
: longArrayMonitor(longArrayMonitor),
|
||||
waitTime(waitTime),
|
||||
isDestroyed(false),
|
||||
runReturned(false),
|
||||
threadName("longArrayMonitor")
|
||||
@@ -76,20 +84,21 @@ public:
|
||||
void init();
|
||||
virtual void destroy();
|
||||
virtual void run();
|
||||
virtual String getRequesterName() { return requesterName;}
|
||||
virtual void message(String const & message, MessageType messageType)
|
||||
virtual string getRequesterName() { return requesterName;}
|
||||
virtual void message(string const & message, MessageType messageType)
|
||||
{ messagePvt(message,messageType);}
|
||||
virtual void monitorConnect(Status const & status,
|
||||
MonitorPtr const & monitor, StructureConstPtr const & structure);
|
||||
virtual void monitorEvent(MonitorPtr const & monitor);
|
||||
virtual void unlisten(MonitorPtr const & monitor);
|
||||
private:
|
||||
void handleMonitor();
|
||||
LongArrayMonitorPtr longArrayMonitor;
|
||||
double waitTime;
|
||||
bool isDestroyed;
|
||||
bool runReturned;
|
||||
epics::pvData::String threadName;
|
||||
std::string threadName;
|
||||
Event event;
|
||||
Mutex mutex;
|
||||
std::auto_ptr<epicsThread> thread;
|
||||
};
|
||||
|
||||
@@ -129,9 +138,9 @@ void LAMMonitorRequester::monitorConnect(Status const & status,
|
||||
}
|
||||
bool structureOK(true);
|
||||
FieldConstPtr field = structure->getField("timeStamp");
|
||||
if(field==NULL) structureOK = false;
|
||||
if(!field) structureOK = false;
|
||||
field = structure->getField("value");
|
||||
if(field==NULL) {
|
||||
if(!field) {
|
||||
structureOK = false;
|
||||
} else {
|
||||
if(field->getType()!=scalarArray) {
|
||||
@@ -142,7 +151,7 @@ void LAMMonitorRequester::monitorConnect(Status const & status,
|
||||
}
|
||||
}
|
||||
if(!structureOK) {
|
||||
String message("monitorConnect: illegal structure");
|
||||
string message("monitorConnect: illegal structure");
|
||||
messagePvt(message,errorMessage);
|
||||
longArrayMonitor->status = Status(Status::STATUSTYPE_ERROR,message);
|
||||
}
|
||||
@@ -156,6 +165,8 @@ void LAMMonitorRequester::run()
|
||||
TimeStamp timeStamp;
|
||||
TimeStamp timeStampLast;
|
||||
timeStampLast.getCurrent();
|
||||
size_t nElements = 0;
|
||||
int nSinceLastReport = 0;
|
||||
while(true) {
|
||||
event.wait();
|
||||
if(isDestroyed) {
|
||||
@@ -163,35 +174,55 @@ void LAMMonitorRequester::run()
|
||||
return;
|
||||
}
|
||||
while(true) {
|
||||
MonitorElementPtr monitorElement = longArrayMonitor->monitor->poll();
|
||||
if(monitorElement==NULL) break;
|
||||
PVStructurePtr pvStructure = monitorElement->pvStructurePtr;
|
||||
MonitorElementPtr monitorElement;
|
||||
PVStructurePtr pvStructure;
|
||||
{
|
||||
Lock xx(mutex);
|
||||
monitorElement = longArrayMonitor->monitor->poll();
|
||||
if(monitorElement) pvStructure = monitorElement->pvStructurePtr;
|
||||
}
|
||||
if(!monitorElement) break;
|
||||
if(waitTime>0.0) epicsThreadSleep(waitTime);
|
||||
pvTimeStamp.attach(pvStructure->getSubField("timeStamp"));
|
||||
pvTimeStamp.get(timeStamp);
|
||||
pvValue = dynamic_pointer_cast<PVLongArray>(pvStructure->getSubField("value"));
|
||||
shared_vector<const int64> data = pvValue->view();
|
||||
if(data.size()>0) {
|
||||
nElements += data.size();
|
||||
int64 first = data[0];
|
||||
int64 last = data[data.size()-1];
|
||||
int64 sum = 0;
|
||||
for(size_t i=0; i<data.size(); ++i) sum += data[i];
|
||||
if(first!=last) {
|
||||
cout << "error first=" << first << " last=" << last << endl;
|
||||
}
|
||||
double diff = TimeStamp::diff(timeStamp,timeStampLast);
|
||||
double elementsPerSecond = data.size();
|
||||
elementsPerSecond = 1e-6*elementsPerSecond/diff;
|
||||
cout.flush();
|
||||
cout << "first " << first << " last " << last << " sum " << sum;
|
||||
cout << " elements/sec " << elementsPerSecond << "million";
|
||||
BitSetPtr changed = monitorElement->changedBitSet;
|
||||
BitSetPtr overrun = monitorElement->overrunBitSet;
|
||||
String buffer;
|
||||
changed->toString(&buffer);
|
||||
cout << " changed " << buffer;
|
||||
buffer.clear();
|
||||
overrun->toString(&buffer);
|
||||
cout << " overrun " << buffer;
|
||||
cout << endl;
|
||||
cout.flush();
|
||||
timeStampLast = timeStamp;
|
||||
if(diff>=1.0) {
|
||||
ostringstream out;
|
||||
out << " monitors/sec " << nSinceLastReport << " ";
|
||||
out << "first " << first << " last " << last ;
|
||||
BitSetPtr changed = monitorElement->changedBitSet;
|
||||
BitSetPtr overrun = monitorElement->overrunBitSet;
|
||||
out << " changed " << *changed;
|
||||
out << " overrun " << *overrun;
|
||||
double elementsPerSec = nElements;
|
||||
elementsPerSec /= diff;
|
||||
if(elementsPerSec>10.0e9) {
|
||||
elementsPerSec /= 1e9;
|
||||
out << " gigaElements/sec " << elementsPerSec;
|
||||
} else if(elementsPerSec>10.0e6) {
|
||||
elementsPerSec /= 1e6;
|
||||
out << " megaElements/sec " << elementsPerSec;
|
||||
} else if(elementsPerSec>10.0e3) {
|
||||
elementsPerSec /= 1e3;
|
||||
out << " kiloElements/sec " << elementsPerSec;
|
||||
} else {
|
||||
out << " Elements/sec " << elementsPerSec;
|
||||
}
|
||||
cout << out.str() << endl;
|
||||
timeStampLast = timeStamp;
|
||||
nSinceLastReport = 0;
|
||||
nElements = 0;
|
||||
}
|
||||
++nSinceLastReport;
|
||||
} else {
|
||||
cout << "size = 0" << endl;
|
||||
}
|
||||
@@ -212,12 +243,13 @@ void LAMMonitorRequester::unlisten(MonitorPtr const & monitor)
|
||||
|
||||
|
||||
LongArrayMonitorPtr LongArrayMonitor::create(
|
||||
String const &providerName,
|
||||
String const & channelName,
|
||||
bool useQueue)
|
||||
string const &providerName,
|
||||
string const & channelName,
|
||||
int queueSize,
|
||||
double waitTime)
|
||||
{
|
||||
LongArrayMonitorPtr longArrayMonitor(new LongArrayMonitor());
|
||||
if(!longArrayMonitor->init(providerName,channelName,useQueue)) longArrayMonitor.reset();
|
||||
if(!longArrayMonitor->init(providerName,channelName,queueSize,waitTime)) longArrayMonitor.reset();
|
||||
return longArrayMonitor;
|
||||
}
|
||||
|
||||
@@ -226,30 +258,32 @@ LongArrayMonitor::LongArrayMonitor() {}
|
||||
LongArrayMonitor::~LongArrayMonitor() {}
|
||||
|
||||
bool LongArrayMonitor::init(
|
||||
String const &providerName,
|
||||
String const &channelName,
|
||||
bool useQueue)
|
||||
string const &providerName,
|
||||
string const &channelName,
|
||||
int queueSize,
|
||||
double waitTime)
|
||||
{
|
||||
channelRequester = LAMChannelRequesterPtr(new LAMChannelRequester(getPtrSelf()));
|
||||
monitorRequester = LAMMonitorRequesterPtr(new LAMMonitorRequester(getPtrSelf()));
|
||||
monitorRequester = LAMMonitorRequesterPtr(new LAMMonitorRequester(getPtrSelf(),waitTime));
|
||||
monitorRequester->init();
|
||||
ChannelProvider::shared_pointer channelProvider = getChannelAccess()->getProvider(providerName);
|
||||
if(channelProvider==NULL) {
|
||||
ChannelProvider::shared_pointer channelProvider =
|
||||
getChannelProviderRegistry()->getProvider(providerName);
|
||||
if(!channelProvider) {
|
||||
cout << "provider " << providerName << " not found" << endl;
|
||||
return false;
|
||||
}
|
||||
channel = channelProvider->createChannel(channelName,channelRequester,0);
|
||||
event.wait();
|
||||
if(!status.isOK()) return false;
|
||||
String queueSize("0");
|
||||
if(useQueue) queueSize="2";
|
||||
String request("record[queueSize=");
|
||||
request += queueSize;
|
||||
string request("record[queueSize=");
|
||||
char buff[20];
|
||||
sprintf(buff,"%d",queueSize);
|
||||
request += buff;
|
||||
request += "]field(value,timeStamp,alarm)";
|
||||
PVStructurePtr pvRequest =
|
||||
getCreateRequest()->createRequest(request,channelRequester);
|
||||
if(pvRequest==NULL) {
|
||||
cout << "request logic error " << request << endl;
|
||||
CreateRequest::shared_pointer createRequest = CreateRequest::create();
|
||||
PVStructurePtr pvRequest = createRequest->createRequest(request);
|
||||
if(!pvRequest) {
|
||||
cout << "request logic error " << createRequest->getMessage() << endl;
|
||||
return false;
|
||||
}
|
||||
monitor = channel->createMonitor(monitorRequester,pvRequest);
|
||||
@@ -276,6 +310,7 @@ void LongArrayMonitor::destroy()
|
||||
monitor.reset();
|
||||
channel->destroy();
|
||||
channel.reset();
|
||||
channelRequester->destroy();
|
||||
channelRequester.reset();
|
||||
}
|
||||
|
||||
@@ -11,6 +11,11 @@
|
||||
#ifndef LONGARRAYMONITOR_H
|
||||
#define LONGARRAYMONITOR_H
|
||||
|
||||
#ifdef epicsExportSharedSymbols
|
||||
# define longarraymonitorEpicsExportSharedSymbols
|
||||
# undef epicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#include <pv/event.h>
|
||||
#include <pv/lock.h>
|
||||
#include <pv/standardPVField.h>
|
||||
@@ -18,6 +23,13 @@
|
||||
#include <pv/pvTimeStamp.h>
|
||||
#include <pv/pvAccess.h>
|
||||
|
||||
#ifdef longarraymonitorEpicsExportSharedSymbols
|
||||
# define epicsExportSharedSymbols
|
||||
# undef longarraymonitorEpicsExportSharedSymbols
|
||||
# include <shareLib.h>
|
||||
#endif
|
||||
|
||||
|
||||
namespace epics { namespace pvDatabase {
|
||||
|
||||
|
||||
@@ -30,15 +42,16 @@ typedef std::tr1::shared_ptr<LAMChannelRequester> LAMChannelRequesterPtr;
|
||||
class LAMMonitorRequester;
|
||||
typedef std::tr1::shared_ptr<LAMMonitorRequester> LAMMonitorRequesterPtr;
|
||||
|
||||
class LongArrayMonitor :
|
||||
class epicsShareClass LongArrayMonitor :
|
||||
public std::tr1::enable_shared_from_this<LongArrayMonitor>
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(LongArrayMonitor);
|
||||
static LongArrayMonitorPtr create(
|
||||
epics::pvData::String const & providerName,
|
||||
epics::pvData::String const & channelName,
|
||||
bool useQueue = false);
|
||||
std::string const & providerName,
|
||||
std::string const & channelName,
|
||||
int queueSize = 1,
|
||||
double waitTime = 0.0);
|
||||
~LongArrayMonitor();
|
||||
void start();
|
||||
void stop();
|
||||
@@ -46,9 +59,10 @@ public:
|
||||
private:
|
||||
static epics::pvData::Mutex printMutex;
|
||||
bool init(
|
||||
epics::pvData::String const & providerName,
|
||||
epics::pvData::String const & channelName,
|
||||
bool useQueue);
|
||||
std::string const & providerName,
|
||||
std::string const & channelName,
|
||||
int queueSize,
|
||||
double waitTime);
|
||||
LongArrayMonitorPtr getPtrSelf()
|
||||
{
|
||||
return shared_from_this();
|
||||
@@ -22,13 +22,14 @@
|
||||
|
||||
#include <pv/standardField.h>
|
||||
#include <pv/standardPVField.h>
|
||||
#include <pv/arrayPerformance.h>
|
||||
#include <pv/longArrayMonitor.h>
|
||||
#include <pv/traceRecord.h>
|
||||
#include <pv/channelProviderLocal.h>
|
||||
#include <pv/serverContext.h>
|
||||
#include <pv/clientFactory.h>
|
||||
|
||||
#include <arrayPerformance.h>
|
||||
#include <longArrayMonitor.h>
|
||||
|
||||
using namespace std;
|
||||
using std::tr1::static_pointer_cast;
|
||||
using namespace epics::pvData;
|
||||
@@ -37,22 +38,26 @@ using namespace epics::pvDatabase;
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
String channelName("arrayPerformance");
|
||||
bool useQueue = false;
|
||||
if(argc==2 && String(argv[1])==String("-help")) {
|
||||
cout << "longArrayMonitorMain channelName useQueue" << endl;
|
||||
string channelName("arrayPerformance");
|
||||
int queueSize = 2;
|
||||
double waitTime = 0.0;
|
||||
if(argc==2 && string(argv[1])==string("-help")) {
|
||||
cout << "longArrayMonitorMain channelName queueSize waitTime" << endl;
|
||||
cout << "default" << endl;
|
||||
cout << "longArrayMonitorMain " << channelName << " ";
|
||||
cout << (useQueue ? "true" : "false") << endl;
|
||||
cout << queueSize << " ";
|
||||
cout << "0.0" << endl;
|
||||
return 0;
|
||||
}
|
||||
ClientFactory::start();
|
||||
if(argc>1) channelName = argv[1];
|
||||
if(argc>2) useQueue = (String(argv[2])==String("true") ? true : false);
|
||||
if(argc>2) queueSize = strtol(argv[2],0,0);
|
||||
if(argc>3) waitTime = atof(argv[3]);
|
||||
cout << "longArrayMonitorMain " << channelName << " ";
|
||||
cout << (useQueue ? "true" : "false") << endl;
|
||||
cout << queueSize << " ";
|
||||
cout << waitTime << endl;
|
||||
LongArrayMonitorPtr longArrayMonitor
|
||||
= LongArrayMonitor::create("pvAccess",channelName,useQueue);
|
||||
= LongArrayMonitor::create("pvAccess",channelName,queueSize,waitTime);
|
||||
longArrayMonitor->start();
|
||||
cout << "longArrayMonitor\n";
|
||||
string str;
|
||||
@@ -65,6 +70,7 @@ int main(int argc,char *argv[])
|
||||
longArrayMonitor->destroy();
|
||||
longArrayMonitor.reset();
|
||||
ClientFactory::stop();
|
||||
epicsThreadSleep(1.0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
383
arrayPerformance/src/longArrayPut.cpp
Normal file
383
arrayPerformance/src/longArrayPut.cpp
Normal file
@@ -0,0 +1,383 @@
|
||||
/* longArrayPut.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
* @date 2013.08.09
|
||||
*/
|
||||
|
||||
#include <epicsThread.h>
|
||||
#include <pv/caProvider.h>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <longArrayPut.h>
|
||||
|
||||
namespace epics { namespace pvDatabase {
|
||||
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
using std::tr1::static_pointer_cast;
|
||||
using std::tr1::dynamic_pointer_cast;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::ostringstream;
|
||||
using std::string;
|
||||
|
||||
static string requesterName("longArrayPut");
|
||||
static string request("value");
|
||||
static epics::pvData::Mutex printMutex;
|
||||
|
||||
class LongArrayChannelPut :
|
||||
virtual public ChannelRequester,
|
||||
virtual public ChannelPutRequester,
|
||||
public std::tr1::enable_shared_from_this<LongArrayChannelPut>,
|
||||
public epicsThreadRunable
|
||||
{
|
||||
public:
|
||||
LongArrayChannelPut(
|
||||
string providerName,
|
||||
string channelName,
|
||||
size_t arraySize,
|
||||
int iterBetweenCreateChannel,
|
||||
int iterBetweenCreateChannelPut,
|
||||
double delayTime)
|
||||
: providerName(providerName),
|
||||
channelName(channelName),
|
||||
arraySize(arraySize),
|
||||
iterBetweenCreateChannel(iterBetweenCreateChannel),
|
||||
iterBetweenCreateChannelPut(iterBetweenCreateChannelPut),
|
||||
delayTime(delayTime),
|
||||
isDestroyed(false),
|
||||
runReturned(false),
|
||||
threadName("longArrayPut")
|
||||
{}
|
||||
virtual ~LongArrayChannelPut(){}
|
||||
bool init();
|
||||
virtual void destroy();
|
||||
virtual void run();
|
||||
virtual string getRequesterName() { return requesterName;}
|
||||
virtual void message(string const & message, MessageType messageType)
|
||||
{
|
||||
Lock guard(printMutex);
|
||||
cout << requesterName << " message " << message << endl;
|
||||
}
|
||||
virtual void channelCreated(
|
||||
const Status& status,
|
||||
Channel::shared_pointer const & channel);
|
||||
virtual void channelStateChange(
|
||||
Channel::shared_pointer const & channel,
|
||||
Channel::ConnectionState connectionState);
|
||||
virtual void channelPutConnect(
|
||||
Status const & status,
|
||||
ChannelPut::shared_pointer const & channelPut,
|
||||
StructureConstPtr const &structure);
|
||||
virtual void putDone(
|
||||
Status const & status,
|
||||
ChannelPut::shared_pointer const & channelPut);
|
||||
virtual void getDone(
|
||||
Status const & status,
|
||||
ChannelPut::shared_pointer const & channelPut,
|
||||
PVStructurePtr const &pvStructure,
|
||||
BitSetPtr const & bitSet){}
|
||||
private:
|
||||
LongArrayChannelPutPtr getPtrSelf()
|
||||
{
|
||||
return shared_from_this();
|
||||
}
|
||||
string providerName;
|
||||
string channelName;
|
||||
size_t arraySize;
|
||||
int iterBetweenCreateChannel;
|
||||
int iterBetweenCreateChannelPut;
|
||||
double delayTime;
|
||||
bool isDestroyed;
|
||||
bool runReturned;
|
||||
std::string threadName;
|
||||
Status status;
|
||||
Event event;
|
||||
Mutex mutex;
|
||||
std::auto_ptr<epicsThread> thread;
|
||||
Channel::shared_pointer channel;
|
||||
ChannelPut::shared_pointer channelPut;
|
||||
PVStructurePtr pvStructure;
|
||||
PVLongArrayPtr pvLongArray;
|
||||
BitSetPtr bitSet;
|
||||
};
|
||||
|
||||
bool LongArrayChannelPut::init()
|
||||
{
|
||||
ChannelProvider::shared_pointer channelProvider = getChannelProviderRegistry()->getProvider(providerName);
|
||||
if(!channelProvider) {
|
||||
cout << "provider " << providerName << " not found" << endl;
|
||||
return false;
|
||||
}
|
||||
channel = channelProvider->createChannel(channelName,getPtrSelf(),0);
|
||||
event.wait();
|
||||
if(!status.isOK()) return false;
|
||||
CreateRequest::shared_pointer createRequest = CreateRequest::create();
|
||||
PVStructurePtr pvRequest = createRequest->createRequest(request);
|
||||
if(!pvRequest) {
|
||||
cout << "request logic error " << createRequest->getMessage() << endl;
|
||||
return false;
|
||||
}
|
||||
channelPut = channel->createChannelPut(getPtrSelf(),pvRequest);
|
||||
event.wait();
|
||||
if(!status.isOK()) return false;
|
||||
thread = std::auto_ptr<epicsThread>(new epicsThread(
|
||||
*this,
|
||||
threadName.c_str(),
|
||||
epicsThreadGetStackSize(epicsThreadStackSmall),
|
||||
epicsThreadPriorityLow));
|
||||
thread->start();
|
||||
event.signal();
|
||||
return true;
|
||||
}
|
||||
|
||||
void LongArrayChannelPut::destroy()
|
||||
{
|
||||
if(isDestroyed) return;
|
||||
isDestroyed = true;
|
||||
event.signal();
|
||||
while(true) {
|
||||
if(runReturned) break;
|
||||
epicsThreadSleep(.01);
|
||||
}
|
||||
thread->exitWait();
|
||||
channel->destroy();
|
||||
channelPut.reset();
|
||||
channel.reset();
|
||||
}
|
||||
|
||||
void LongArrayChannelPut::channelCreated(
|
||||
const Status& status,
|
||||
Channel::shared_pointer const & channel)
|
||||
{
|
||||
if(!status.isOK()) message(status.getMessage(),errorMessage);
|
||||
this->status = status;
|
||||
this->channel = channel;
|
||||
event.signal();
|
||||
}
|
||||
|
||||
void LongArrayChannelPut::channelStateChange(
|
||||
Channel::shared_pointer const & channel,
|
||||
Channel::ConnectionState connectionState)
|
||||
{
|
||||
MessageType messageType =
|
||||
(connectionState==Channel::CONNECTED ? infoMessage : errorMessage);
|
||||
message("channelStateChange",messageType);
|
||||
}
|
||||
|
||||
|
||||
void LongArrayChannelPut::channelPutConnect(
|
||||
Status const & status,
|
||||
ChannelPut::shared_pointer const & channelPut,
|
||||
StructureConstPtr const &structure)
|
||||
{
|
||||
this->status = status;
|
||||
if(!status.isOK()) {
|
||||
message(status.getMessage(),errorMessage);
|
||||
event.signal();
|
||||
return;
|
||||
}
|
||||
this->channelPut = channelPut;
|
||||
pvStructure = getPVDataCreate()->createPVStructure(structure);
|
||||
bitSet = BitSetPtr(new BitSet(pvStructure->getNumberFields()));
|
||||
bool structureOK(true);
|
||||
PVFieldPtr pvField = pvStructure->getSubField("value");
|
||||
if(!pvField) {
|
||||
structureOK = false;
|
||||
} else {
|
||||
FieldConstPtr field = pvField->getField();
|
||||
if(field->getType()!=scalarArray) {
|
||||
structureOK = false;
|
||||
} else {
|
||||
ScalarArrayConstPtr scalarArray = dynamic_pointer_cast<const ScalarArray>(field);
|
||||
if(scalarArray->getElementType()!=pvLong) structureOK = false;
|
||||
}
|
||||
}
|
||||
if(!structureOK) {
|
||||
string mess("channelPutConnect: illegal structure");
|
||||
message(mess,errorMessage);
|
||||
this->status = Status(Status::STATUSTYPE_ERROR,mess);
|
||||
}
|
||||
pvLongArray = static_pointer_cast<PVLongArray>(pvField);
|
||||
event.signal();
|
||||
}
|
||||
|
||||
void LongArrayChannelPut::run()
|
||||
{
|
||||
while(true) {
|
||||
event.wait();
|
||||
if(isDestroyed) {
|
||||
runReturned = true;
|
||||
return;
|
||||
}
|
||||
TimeStamp timeStamp;
|
||||
TimeStamp timeStampLast;
|
||||
timeStampLast.getCurrent();
|
||||
int numChannelPut = 0;
|
||||
int numChannelCreate = 0;
|
||||
size_t nElements = 0;
|
||||
while(true) {
|
||||
nElements += sizeof(int64) * arraySize;
|
||||
shared_vector<int64> xxx(arraySize,numChannelPut);
|
||||
shared_vector<const int64> data(freeze(xxx));
|
||||
pvLongArray->replace(data);
|
||||
bitSet->set(pvLongArray->getFieldOffset());
|
||||
channelPut->put(pvStructure,bitSet);
|
||||
event.wait();
|
||||
if(isDestroyed) {
|
||||
runReturned = true;
|
||||
return;
|
||||
}
|
||||
if(delayTime>0.0) epicsThreadSleep(delayTime);
|
||||
if(isDestroyed) {
|
||||
runReturned = true;
|
||||
return;
|
||||
}
|
||||
timeStamp.getCurrent();
|
||||
double diff = TimeStamp::diff(timeStamp,timeStampLast);
|
||||
if(diff>=1.0) {
|
||||
ostringstream out;
|
||||
out << "put numChannelPut " << numChannelPut;
|
||||
out << " time " << diff ;
|
||||
double elementsPerSec = nElements;
|
||||
elementsPerSec /= diff;
|
||||
if(elementsPerSec>10.0e9) {
|
||||
elementsPerSec /= 1e9;
|
||||
out << " gigaElements/sec " << elementsPerSec;
|
||||
} else if(elementsPerSec>10.0e6) {
|
||||
elementsPerSec /= 1e6;
|
||||
out << " megaElements/sec " << elementsPerSec;
|
||||
} else if(elementsPerSec>10.0e3) {
|
||||
elementsPerSec /= 1e3;
|
||||
out << " kiloElements/sec " << elementsPerSec;
|
||||
} else {
|
||||
out << " Elements/sec " << elementsPerSec;
|
||||
}
|
||||
cout << out.str() << endl;
|
||||
timeStampLast = timeStamp;
|
||||
nElements = 0;
|
||||
}
|
||||
++numChannelCreate;
|
||||
bool createPut = false;
|
||||
if(iterBetweenCreateChannel!=0) {
|
||||
if(numChannelCreate>=iterBetweenCreateChannel) {
|
||||
channel->destroy();
|
||||
ChannelProvider::shared_pointer channelProvider =
|
||||
getChannelProviderRegistry()->getProvider(providerName);
|
||||
channel = channelProvider->createChannel(
|
||||
channelName,getPtrSelf(),0);
|
||||
event.wait();
|
||||
if(isDestroyed) {
|
||||
runReturned = true;
|
||||
return;
|
||||
}
|
||||
if(!status.isOK()) {
|
||||
message(status.getMessage(),errorMessage);
|
||||
return;
|
||||
}
|
||||
cout<< "createChannel success" << endl;
|
||||
createPut = true;
|
||||
numChannelCreate = 0;
|
||||
}
|
||||
}
|
||||
++numChannelPut;
|
||||
if(iterBetweenCreateChannelPut!=0) {
|
||||
if(numChannelPut>=iterBetweenCreateChannelPut) createPut = true;
|
||||
}
|
||||
if(createPut) {
|
||||
numChannelPut = 0;
|
||||
channelPut->destroy();
|
||||
CreateRequest::shared_pointer createRequest = CreateRequest::create();
|
||||
PVStructurePtr pvRequest = createRequest->createRequest(request);
|
||||
if(!pvRequest) {
|
||||
cout << "request logic error " << createRequest->getMessage() << endl;
|
||||
return ;
|
||||
}
|
||||
channelPut = channel->createChannelPut(getPtrSelf(),pvRequest);
|
||||
event.wait();
|
||||
if(isDestroyed) {
|
||||
runReturned = true;
|
||||
return;
|
||||
}
|
||||
if(!status.isOK()) {
|
||||
message(status.getMessage(),errorMessage);
|
||||
return;
|
||||
}
|
||||
cout<< "createChannelPut success" << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LongArrayChannelPut::putDone(
|
||||
Status const & status,
|
||||
ChannelPut::shared_pointer const & channelPut)
|
||||
{
|
||||
event.signal();
|
||||
}
|
||||
|
||||
|
||||
LongArrayPutPtr LongArrayPut::create(
|
||||
string const &providerName,
|
||||
string const & channelName,
|
||||
size_t arraySize,
|
||||
int iterBetweenCreateChannel,
|
||||
int iterBetweenCreateChannelPut,
|
||||
double delayTime)
|
||||
{
|
||||
LongArrayPutPtr longArrayPut(
|
||||
new LongArrayPut(
|
||||
providerName,
|
||||
channelName,
|
||||
arraySize,
|
||||
iterBetweenCreateChannel,
|
||||
iterBetweenCreateChannelPut,
|
||||
delayTime));
|
||||
if(!longArrayPut->init()) longArrayPut.reset();
|
||||
return longArrayPut;
|
||||
}
|
||||
|
||||
LongArrayPut::LongArrayPut(
|
||||
string const &providerName,
|
||||
string const & channelName,
|
||||
size_t arraySize,
|
||||
int iterBetweenCreateChannel,
|
||||
int iterBetweenCreateChannelPut,
|
||||
double delayTime)
|
||||
: providerName(providerName),
|
||||
channelName(channelName),
|
||||
arraySize(arraySize),
|
||||
iterBetweenCreateChannel(iterBetweenCreateChannel),
|
||||
iterBetweenCreateChannelPut(iterBetweenCreateChannelPut),
|
||||
delayTime(delayTime)
|
||||
{}
|
||||
|
||||
|
||||
LongArrayPut::~LongArrayPut() {}
|
||||
|
||||
bool LongArrayPut::init()
|
||||
{
|
||||
longArrayChannelPut = LongArrayChannelPutPtr(new LongArrayChannelPut(
|
||||
providerName,
|
||||
channelName,
|
||||
arraySize,
|
||||
iterBetweenCreateChannel,
|
||||
iterBetweenCreateChannelPut,
|
||||
delayTime));
|
||||
return longArrayChannelPut->init();
|
||||
}
|
||||
|
||||
void LongArrayPut::destroy()
|
||||
{
|
||||
longArrayChannelPut->destroy();
|
||||
longArrayChannelPut.reset();
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
|
||||
84
arrayPerformance/src/longArrayPut.h
Normal file
84
arrayPerformance/src/longArrayPut.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/* longArrayPut.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
* @date 2013.08.09
|
||||
*/
|
||||
#ifndef LONGARRAYPUT_H
|
||||
#define LONGARRAYPUT_H
|
||||
|
||||
|
||||
#ifdef epicsExportSharedSymbols
|
||||
# define longarrayputEpicsExportSharedSymbols
|
||||
# undef epicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#include <pv/event.h>
|
||||
#include <pv/lock.h>
|
||||
#include <pv/standardPVField.h>
|
||||
#include <pv/timeStamp.h>
|
||||
#include <pv/pvTimeStamp.h>
|
||||
#include <pv/pvAccess.h>
|
||||
|
||||
|
||||
#ifdef longarrayputEpicsExportSharedSymbols
|
||||
# define epicsExportSharedSymbols
|
||||
# undef longarrayputEpicsExportSharedSymbols
|
||||
# include <shareLib.h>
|
||||
#endif
|
||||
|
||||
namespace epics { namespace pvDatabase {
|
||||
|
||||
|
||||
class LongArrayPut;
|
||||
typedef std::tr1::shared_ptr<LongArrayPut> LongArrayPutPtr;
|
||||
|
||||
|
||||
class LongArrayChannelPut;
|
||||
typedef std::tr1::shared_ptr<LongArrayChannelPut> LongArrayChannelPutPtr;
|
||||
|
||||
class epicsShareClass LongArrayPut :
|
||||
public std::tr1::enable_shared_from_this<LongArrayPut>
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(LongArrayPut);
|
||||
static LongArrayPutPtr create(
|
||||
std::string const & providerName,
|
||||
std::string const & channelName,
|
||||
size_t arraySize = 100,
|
||||
int iterBetweenCreateChannel = 0,
|
||||
int iterBetweenCreateChannelPut = 0,
|
||||
double delayTime = 0.0);
|
||||
~LongArrayPut();
|
||||
void destroy();
|
||||
private:
|
||||
LongArrayPutPtr getPtrSelf()
|
||||
{
|
||||
return shared_from_this();
|
||||
}
|
||||
LongArrayPut(
|
||||
std::string const & providerName,
|
||||
std::string const & channelName,
|
||||
size_t arraySize,
|
||||
int iterBetweenCreateChannel,
|
||||
int iterBetweenCreateChannelPut,
|
||||
double delayTime);
|
||||
bool init();
|
||||
|
||||
std::string providerName;
|
||||
std::string channelName;
|
||||
size_t arraySize;
|
||||
int iterBetweenCreateChannel;
|
||||
int iterBetweenCreateChannelPut;
|
||||
double delayTime;
|
||||
LongArrayChannelPutPtr longArrayChannelPut;
|
||||
};
|
||||
|
||||
|
||||
}}
|
||||
|
||||
#endif /* LONGARRAYPUT_H */
|
||||
93
arrayPerformance/src/longArrayPutMain.cpp
Normal file
93
arrayPerformance/src/longArrayPutMain.cpp
Normal file
@@ -0,0 +1,93 @@
|
||||
/*longArrayPutMain.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
* @date 2013.08.10
|
||||
*/
|
||||
|
||||
/* Author: Marty Kraimer */
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
#include <memory>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#include <pv/standardField.h>
|
||||
#include <pv/standardPVField.h>
|
||||
#include <pv/traceRecord.h>
|
||||
#include <pv/channelProviderLocal.h>
|
||||
#include <pv/serverContext.h>
|
||||
#include <pv/clientFactory.h>
|
||||
|
||||
#include <arrayPerformance.h>
|
||||
#include <longArrayPut.h>
|
||||
|
||||
using namespace std;
|
||||
using std::tr1::static_pointer_cast;
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
using namespace epics::pvDatabase;
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
string channelName("arrayPerformance");
|
||||
size_t arraySize = 10;
|
||||
int iterBetweenCreateChannel = 0;
|
||||
int iterBetweenCreateChannelPut = 0;
|
||||
double delayTime = 1.0;
|
||||
if(argc==2 && string(argv[1])==string("-help")) {
|
||||
cout << "longArrayPutMain channelName arraySize ";
|
||||
cout << "iterBetweenCreateChannel iterBetweenCreateChannelPut delayTime" << endl;
|
||||
cout << "default" << endl;
|
||||
cout << "longArrayPutMain " << channelName << " ";
|
||||
cout << arraySize << " ";
|
||||
cout << iterBetweenCreateChannel << " ";
|
||||
cout << iterBetweenCreateChannelPut << " ";
|
||||
cout << delayTime << endl;
|
||||
return 0;
|
||||
}
|
||||
ClientFactory::start();
|
||||
if(argc>1) channelName = argv[1];
|
||||
if(argc>2) arraySize = strtoul(argv[2],0,0);
|
||||
if(argc>3) iterBetweenCreateChannel = strtol(argv[3],0,0);
|
||||
if(argc>4) iterBetweenCreateChannelPut = strtol(argv[4],0,0);
|
||||
if(argc>5) delayTime = atof(argv[5]);
|
||||
cout << "longArrayPutMain " << channelName << " ";
|
||||
cout << arraySize << " ";
|
||||
cout << iterBetweenCreateChannel << " ";
|
||||
cout << iterBetweenCreateChannelPut << " ";
|
||||
cout << delayTime << endl;
|
||||
LongArrayPutPtr longArrayPut
|
||||
= LongArrayPut::create(
|
||||
"pvAccess",
|
||||
channelName,
|
||||
arraySize,
|
||||
iterBetweenCreateChannel,
|
||||
iterBetweenCreateChannelPut,
|
||||
delayTime);
|
||||
cout << "longArrayPut\n";
|
||||
string str;
|
||||
while(true) {
|
||||
cout << "Type exit to stop: \n";
|
||||
getline(cin,str);
|
||||
if(str.compare("exit")==0) break;
|
||||
|
||||
}
|
||||
longArrayPut->destroy();
|
||||
longArrayPut.reset();
|
||||
double xxx = 1.0;
|
||||
if(xxx<delayTime) xxx = delayTime;
|
||||
epicsThreadSleep(xxx);
|
||||
ClientFactory::stop();
|
||||
epicsThreadSleep(1.0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
189
arrayPerformance/src/vectorPerformanceMain.cpp
Normal file
189
arrayPerformance/src/vectorPerformanceMain.cpp
Normal file
@@ -0,0 +1,189 @@
|
||||
/*vectorPerformanceMain.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
* @date 2013.09.02
|
||||
*/
|
||||
|
||||
/* Author: Marty Kraimer */
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
#include <memory>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#include <epicsThread.h>
|
||||
#include <pv/timeStamp.h>
|
||||
|
||||
|
||||
using namespace std;
|
||||
using std::tr1::static_pointer_cast;
|
||||
using namespace epics::pvData;
|
||||
|
||||
class VectorPerformanceThread;
|
||||
typedef std::tr1::shared_ptr<VectorPerformanceThread> VectorPerformanceThreadPtr;
|
||||
|
||||
class VectorPerformanceThread :
|
||||
public epicsThreadRunable
|
||||
{
|
||||
public:
|
||||
VectorPerformanceThread(int threadNumber,size_t size,double delay);
|
||||
virtual ~VectorPerformanceThread(){};
|
||||
void init();
|
||||
void start();
|
||||
virtual void run();
|
||||
void destroy();
|
||||
private:
|
||||
bool isDestroyed;
|
||||
bool runReturned;
|
||||
int threadNumber;
|
||||
size_t size;
|
||||
epics::pvData::int64 value;
|
||||
double delay;
|
||||
Mutex mutex;
|
||||
std::vector<int64> vector;
|
||||
std::auto_ptr<epicsThread> thread;
|
||||
};
|
||||
|
||||
VectorPerformanceThread::VectorPerformanceThread(
|
||||
int threadNumber,size_t size,double delay)
|
||||
:
|
||||
isDestroyed(false),
|
||||
runReturned(false),
|
||||
threadNumber(threadNumber),
|
||||
size(size),
|
||||
value(0),
|
||||
delay(delay)
|
||||
{}
|
||||
|
||||
void VectorPerformanceThread::init()
|
||||
{
|
||||
vector.resize(size);
|
||||
thread = std::auto_ptr<epicsThread>(new epicsThread(
|
||||
*this,
|
||||
"vectorPerform",
|
||||
epicsThreadGetStackSize(epicsThreadStackSmall),
|
||||
epicsThreadPriorityHigh));
|
||||
}
|
||||
|
||||
void VectorPerformanceThread::start()
|
||||
{
|
||||
thread->start();
|
||||
}
|
||||
|
||||
void VectorPerformanceThread::destroy()
|
||||
{
|
||||
Lock lock(mutex);
|
||||
if(isDestroyed) return;
|
||||
isDestroyed = true;
|
||||
while(true) {
|
||||
if(runReturned) break;
|
||||
lock.unlock();
|
||||
epicsThreadSleep(.01);
|
||||
lock.lock();
|
||||
}
|
||||
thread->exitWait();
|
||||
thread.reset();
|
||||
}
|
||||
|
||||
|
||||
void VectorPerformanceThread::run()
|
||||
{
|
||||
TimeStamp timeStamp;
|
||||
TimeStamp timeStampLast;
|
||||
timeStampLast.getCurrent();
|
||||
int nSinceLastReport = 0;
|
||||
while(true) {
|
||||
if(delay>0.0) epicsThreadSleep(delay);
|
||||
{
|
||||
Lock lock(mutex);
|
||||
if(isDestroyed) {
|
||||
cout << " found isDestroyed " << threadNumber << endl;
|
||||
runReturned = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
timeStamp.getCurrent();
|
||||
double diff = TimeStamp::diff(timeStamp,timeStampLast);
|
||||
if(diff>=1.0) {
|
||||
cout << "thread" << threadNumber;
|
||||
cout << " value " << value;
|
||||
cout << " time " << diff;
|
||||
double iterations = nSinceLastReport;
|
||||
iterations /= diff;
|
||||
cout << " iterations/sec " << iterations;
|
||||
double elementSize = size;
|
||||
double elementsPerSecond = elementSize*nSinceLastReport;
|
||||
elementsPerSecond /= diff;
|
||||
elementsPerSecond /= 1e6;
|
||||
cout << " elements/sec " << elementsPerSecond << "million" << endl;
|
||||
cout.flush();
|
||||
timeStampLast = timeStamp;
|
||||
nSinceLastReport = 0;
|
||||
}
|
||||
++nSinceLastReport;
|
||||
++value;
|
||||
for(size_t i=0; i<size; ++i) vector[i] = value;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
size_t size = 50000000;
|
||||
double delay = .01;
|
||||
size_t nThread = 1;
|
||||
if(argc==2 && string(argv[1])==string("-help")) {
|
||||
cout << "vectorPerformanceMain size delay nThread" << endl;
|
||||
cout << "default" << endl;
|
||||
cout << "vectorPerformance ";
|
||||
cout << size << " ";
|
||||
cout << delay << " ";
|
||||
cout << nThread << " ";
|
||||
cout << endl;
|
||||
return 0;
|
||||
}
|
||||
if(argc>1) size = strtoul(argv[1],0,0);
|
||||
if(argc>2) delay = atof(argv[2]);
|
||||
if(argc>3) nThread = strtoul(argv[3],0,0);
|
||||
cout << "vectorPerformance ";
|
||||
cout << size << " ";
|
||||
cout << delay << " ";
|
||||
cout << nThread << " ";
|
||||
cout << endl;
|
||||
cout << "vectorPerformance\n";
|
||||
std::vector<VectorPerformanceThreadPtr> threads;
|
||||
for(size_t i=0; i<nThread; ++i) {
|
||||
threads.push_back(
|
||||
VectorPerformanceThreadPtr(
|
||||
new VectorPerformanceThread(i,size,delay)));
|
||||
}
|
||||
epicsThreadSleep(.1);
|
||||
for(size_t i=0; i<nThread; ++i) {
|
||||
threads[i]->init();
|
||||
}
|
||||
for(size_t i=0; i<nThread; ++i) {
|
||||
threads[i]->start();
|
||||
}
|
||||
string str;
|
||||
while(true) {
|
||||
cout << "Type exit to stop: \n";
|
||||
getline(cin,str);
|
||||
if(str.compare("exit")==0) break;
|
||||
|
||||
}
|
||||
for(size_t i=0; i<nThread; ++i) {
|
||||
cout << "" << i << " calling destroy" << endl;
|
||||
threads[i]->destroy();
|
||||
threads[i].reset();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -16,24 +16,12 @@
|
||||
# continue building anyway if conflicts are found.
|
||||
#CHECK_RELEASE = YES
|
||||
|
||||
# Set this when you only want to compile this application
|
||||
# for a subset of the cross-compiled target architectures
|
||||
# that Base is built for.
|
||||
#CROSS_COMPILER_TARGET_ARCHS = vxWorks-68040
|
||||
|
||||
# To install files into a location other than $(TOP) define
|
||||
# INSTALL_LOCATION here.
|
||||
#INSTALL_LOCATION=</path/name/to/install/top>
|
||||
|
||||
# Set this when your IOC and the host use different paths
|
||||
# to access the application. This will be needed to boot
|
||||
# from a Microsoft FTP server or with some NFS mounts.
|
||||
# You must rebuild in the iocBoot directory for this to
|
||||
# take effect.
|
||||
#IOCS_APPL_TOP = </IOC/path/to/application/top>
|
||||
|
||||
INSTALL_INCLUDE = $(INSTALL_LOCATION)/include/pv
|
||||
USR_INCLUDES += -I $(INSTALL_LOCATION)/include
|
||||
|
||||
-include $(TOP)/../CONFIG_SITE.local
|
||||
-include $(TOP)/configure/CONFIG_SITE.local
|
||||
-include $(TOP)/../CONFIG.local
|
||||
|
||||
10
configure/ExampleRELEASE.local
Normal file
10
configure/ExampleRELEASE.local
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
TEMPLATE_TOP=$(EPICS_BASE)/templates/makeBaseApp/top
|
||||
|
||||
EPICS_BASE=/home/install/epics/base
|
||||
V4BASE=/home/epicsv4
|
||||
PVCOMMON=${V4BASE}/pvCommonCPP
|
||||
PVDATA=${V4BASE}/pvDataCPP
|
||||
NORMATIVETYPES=${V4BASE}/normativeTypesCPP
|
||||
PVACCESS=${V4BASE}/pvAccessCPP
|
||||
PVASRV=${V4BASE}/pvaSrv
|
||||
@@ -6,3 +6,4 @@ TARGETS = $(CONFIG_TARGETS)
|
||||
CONFIGS += $(subst ../,,$(wildcard $(CONFIG_INSTALLS)))
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
# RELEASE - Location of external support modules
|
||||
# pvDatabaseCPP RELEASE - Location of external support modules
|
||||
#
|
||||
# IF YOU MAKE ANY CHANGES to this file you must subsequently
|
||||
# do a "gnumake rebuild" in this application's top level
|
||||
# directory.
|
||||
# IF YOU CHANGE this file or any file it includes you must
|
||||
# subsequently do a "gnumake rebuild" in the application's
|
||||
# top level directory.
|
||||
#
|
||||
# The build process does not check dependencies against files
|
||||
# that are outside this application, thus you should do a
|
||||
# that are outside this application, thus you should also do a
|
||||
# "gnumake rebuild" in the top level directory after EPICS_BASE
|
||||
# or any other external module pointed to below is rebuilt.
|
||||
#
|
||||
@@ -13,32 +13,16 @@
|
||||
# RELEASE.$(EPICS_HOST_ARCH).Common
|
||||
# RELEASE.Common.$(T_A)
|
||||
# RELEASE.$(EPICS_HOST_ARCH).$(T_A)
|
||||
|
||||
# EPICS V4 Developers: Do not edit the locations in this file!
|
||||
#
|
||||
# This file should ONLY define paths to other support modules,
|
||||
# or include statements that pull in similar RELEASE files.
|
||||
# Build settings that are NOT module paths should appear in a
|
||||
# CONFIG_SITE file.
|
||||
# Create a file RELEASE.local pointing to your PVASRV, PVACCESS,
|
||||
# PVDATA, PVCOMMON and EPICS_BASE build directories, e.g.
|
||||
# PVASRV = /path/to/epics/pvaSrvCPP
|
||||
# PVACCESS = /path/to/epics/pvAccessCPP
|
||||
# PVDATA = /path/to/epics/pvDataCPP
|
||||
# PVCOMMON = /path/to/epics/pvCommonCPP
|
||||
# EPICS_BASE = /path/to/epics/base
|
||||
|
||||
TEMPLATE_TOP=$(EPICS_BASE)/templates/makeBaseApp/top
|
||||
|
||||
# If using the sequencer, point SNCSEQ at its top directory:
|
||||
#SNCSEQ=$(EPICS_BASE)/../modules/soft/seq
|
||||
|
||||
# EPICS_BASE usually appears last so other apps can override stuff:
|
||||
|
||||
# do not edit the locations in this file
|
||||
# create RELEASE.local with the paths to your EPICS_BASE, PVDATA, and PVACCESS
|
||||
# these default locations are needed for the BNL Jenkins server to work
|
||||
|
||||
# Set RULES here if you want to take build rules from somewhere
|
||||
# other than EPICS_BASE:
|
||||
#RULES=/path/to/epics/support/module/rules/x-y
|
||||
|
||||
# Leave these in for the Jenkins build at BNL to work
|
||||
EPICS_BASE=/home/install/epics/base
|
||||
PVDATA=/home/mrk/hg/pvDataCPP
|
||||
PVACCESS=/home/mrk/hg/pvAccessCPP
|
||||
|
||||
# set your EPICS_BASE, PVDATA and PVACCESS paths in here
|
||||
-include $(TOP)/configure/RELEASE.local
|
||||
-include $(TOP)/../RELEASE.local
|
||||
-include $(TOP)/configure/RELEASE.local
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
#RULES_TOP
|
||||
include $(CONFIG)/RULES_TOP
|
||||
|
||||
EMTOPACTIONS += cvsclean realuninstall
|
||||
|
||||
distclean: emtop_distclean
|
||||
|
||||
emtopDistcleanTargets += $(foreach dir, $(EMBEDDED_TOPS), \
|
||||
$(dir)$(DIVIDER)emtop_dummy_action)
|
||||
|
||||
$(emtopDistcleanTargets) :
|
||||
$(MAKE) -C $(dirPart) $(EMTOPACTIONS)
|
||||
|
||||
emtop_distclean : $(emtopDistcleanTargets)
|
||||
|
||||
.PHONY : $(emtopDistcleanTargets)
|
||||
|
||||
8
documentation/TODO.html
Normal file
8
documentation/TODO.html
Normal file
@@ -0,0 +1,8 @@
|
||||
<h1>TODO</h1>
|
||||
<h2>monitorPlugin</h2>
|
||||
<p>A debate is on-going about what semantics should be.</p>
|
||||
<h2>Must test record delete.</h2>
|
||||
<p>Must test removing a record from the PVDatabase while a pvAccess client
|
||||
is attached. Also why do both unlisten and detach exists?</p>
|
||||
<h2>create more regression tests</h2>
|
||||
<p>Currently only some simple tests exist. Most of the testing has been via the examples</p>
|
||||
19
documentation/TODO.md
Normal file
19
documentation/TODO.md
Normal file
@@ -0,0 +1,19 @@
|
||||
TODO
|
||||
===========
|
||||
|
||||
monitorPlugin
|
||||
-------------
|
||||
|
||||
A debate is on-going about what semantics should be.
|
||||
|
||||
Must test record delete.
|
||||
-------------------
|
||||
|
||||
Must test removing a record from the PVDatabase while a pvAccess client
|
||||
is attached. Also why do both unlisten and detach exists?
|
||||
|
||||
|
||||
create more regression tests
|
||||
----------------
|
||||
|
||||
Currently only some simple tests exist. Most of the testing has been via the examples
|
||||
File diff suppressed because it is too large
Load Diff
@@ -70,28 +70,9 @@ The minimum that an extenson must provide is a top level PVStructure and a proce
|
||||
but the framework provides for complex extensions.</p>
|
||||
|
||||
<p>EPICS version 4 is a set of related products in the EPICS
|
||||
V4 control system programming environment:</p>
|
||||
<dl>
|
||||
<dt><a
|
||||
href="http://epics-pvdata.sourceforge.net/docbuild/pvDataJava/tip/documentation/pvDataJava.html">pvData</a></dt>
|
||||
<dd>pvData (Process Variable Data) defines and implements an efficent way
|
||||
to store, access, and communicate memory resident structured data</dd>
|
||||
<dt><a
|
||||
href="http://epics-pvdata.sourceforge.net/docbuild/pvAccessJava/tip/documentation/pvAccessJava.html">pvAccess</a></dt>
|
||||
<dd>pvAccess is a software library for high speed controls network communications,
|
||||
optimized for pvData</dd>
|
||||
<dt><a
|
||||
href="http://epics-pvdata.sourceforge.net/docbuild/pvIOCJava/tip/documentation/pvIOCJava.html">pvIOC</a></dt>
|
||||
<dd>pvIOC is a software framework for building network accessable "smart" real time
|
||||
databases, suitable for interfacing devices in a distributed control system,
|
||||
that can exchange pvData over pvAccess.
|
||||
</dd>
|
||||
<dt><a
|
||||
href="http://epics-pvdata.sourceforge.net/docbuild/pvServiceJava/tip/documentation/pvAccessJava.html">pvService</a></dt>
|
||||
<dd>A middle layer for implementing data services.</dd>
|
||||
</dl>
|
||||
|
||||
<p>Each of these products has a Java and a C++ implementation.</p>
|
||||
V4 control system programming environment:<br />
|
||||
<a href="http://epics-pvdata.sourceforge.net/relatedDocumemntsV4.html">relatedDocumentsV4.html</a>
|
||||
</p>
|
||||
|
||||
<h2 class="nocount">Status of this Document</h2>
|
||||
|
||||
|
||||
@@ -72,28 +72,10 @@ The minimum that an extenson must provide is a top level PVStructure and a proce
|
||||
but the framework provides for complex extensions.</p>
|
||||
|
||||
<p>EPICS version 4 is a set of related products in the EPICS
|
||||
V4 control system programming environment:</p>
|
||||
<dl>
|
||||
<dt><a
|
||||
href="http://epics-pvdata.sourceforge.net/docbuild/pvDataJava/tip/documentation/pvDataJava.html">pvData</a></dt>
|
||||
<dd>pvData (Process Variable Data) defines and implements an efficent way
|
||||
to store, access, and communicate memory resident structured data</dd>
|
||||
<dt><a
|
||||
href="http://epics-pvdata.sourceforge.net/docbuild/pvAccessJava/tip/documentation/pvAccessJava.html">pvAccess</a></dt>
|
||||
<dd>pvAccess is a software library for high speed controls network communications,
|
||||
optimized for pvData</dd>
|
||||
<dt><a
|
||||
href="http://epics-pvdata.sourceforge.net/docbuild/pvIOCJava/tip/documentation/pvIOCJava.html">pvIOC</a></dt>
|
||||
<dd>pvIOC is a software framework for building network accessable "smart" real time
|
||||
databases, suitable for interfacing devices in a distributed control system,
|
||||
that can exchange pvData over pvAccess.
|
||||
</dd>
|
||||
<dt><a
|
||||
href="http://epics-pvdata.sourceforge.net/docbuild/pvServiceJava/tip/documentation/pvAccessJava.html">pvService</a></dt>
|
||||
<dd>A middle layer for implementing data services.</dd>
|
||||
</dl>
|
||||
V4 control system programming environment:<br />
|
||||
<a href="http://epics-pvdata.sourceforge.net/relatedDocumentsV4.html">relatedDocumentsV4.html</a>
|
||||
</p>
|
||||
|
||||
<p>Each of these products has a Java and a C++ implementation.</p>
|
||||
|
||||
<h2 class="nocount">Status of this Document</h2>
|
||||
|
||||
|
||||
@@ -71,6 +71,11 @@ The framework can be extended in order to create record instances that implement
|
||||
The minimum that an extenson must provide is a top level PVStructure and a process method.
|
||||
</p>
|
||||
|
||||
<p>EPICS version 4 is a set of related products in the EPICS
|
||||
V4 control system programming environment:<br />
|
||||
<a href="http://epics-pvdata.sourceforge.net/relatedDocumentsV4.html">relatedDocumentsV4.html</a>
|
||||
</p>
|
||||
|
||||
|
||||
<h2 class="nocount">Status of this Document</h2>
|
||||
|
||||
|
||||
@@ -71,6 +71,11 @@ The framework can be extended in order to create record instances that implement
|
||||
The minimum that an extenson must provide is a top level PVStructure and a process method.
|
||||
</p>
|
||||
|
||||
<p>EPICS version 4 is a set of related products in the EPICS
|
||||
V4 control system programming environment:<br />
|
||||
<a href="http://epics-pvdata.sourceforge.net/relatedDocumentsV4.html">relatedDocumentsV4.html</a>
|
||||
</p>
|
||||
|
||||
|
||||
<h2 class="nocount">Status of this Document</h2>
|
||||
|
||||
|
||||
@@ -71,6 +71,11 @@ The framework can be extended in order to create record instances that implement
|
||||
The minimum that an extenson must provide is a top level PVStructure and a process method.
|
||||
</p>
|
||||
|
||||
<p>EPICS version 4 is a set of related products in the EPICS
|
||||
V4 control system programming environment:<br />
|
||||
<a href="http://epics-pvdata.sourceforge.net/relatedDocumentsV4.html">relatedDocumentsV4.html</a>
|
||||
</p>
|
||||
|
||||
|
||||
<h2 class="nocount">Status of this Document</h2>
|
||||
|
||||
|
||||
@@ -71,6 +71,11 @@ The framework can be extended in order to create record instances that implement
|
||||
The minimum that an extenson must provide is a top level PVStructure and a process method.
|
||||
</p>
|
||||
|
||||
<p>EPICS version 4 is a set of related products in the EPICS
|
||||
V4 control system programming environment:<br />
|
||||
<a href="http://epics-pvdata.sourceforge.net/relatedDocumentsV4.html">relatedDocumentsV4.html</a>
|
||||
</p>
|
||||
|
||||
|
||||
<h2 class="nocount">Status of this Document</h2>
|
||||
|
||||
|
||||
@@ -71,6 +71,11 @@ The framework can be extended in order to create record instances that implement
|
||||
The minimum that an extenson must provide is a top level PVStructure and a process method.
|
||||
</p>
|
||||
|
||||
<p>EPICS version 4 is a set of related products in the EPICS
|
||||
V4 control system programming environment:<br />
|
||||
<a href="http://epics-pvdata.sourceforge.net/relatedDocumentsV4.html">relatedDocumentsV4.html</a>
|
||||
</p>
|
||||
|
||||
|
||||
<h2 class="nocount">Status of this Document</h2>
|
||||
|
||||
|
||||
@@ -70,6 +70,11 @@ The framework can be extended in order to create record instances that implement
|
||||
The minimum that an extenson must provide is a top level PVStructure and a process method.
|
||||
</p>
|
||||
|
||||
<p>EPICS version 4 is a set of related products in the EPICS
|
||||
V4 control system programming environment:<br />
|
||||
<a href="http://epics-pvdata.sourceforge.net/relatedDocumentsV4.html">relatedDocumentsV4.html</a>
|
||||
</p>
|
||||
|
||||
|
||||
<h2 class="nocount">Status of this Document</h2>
|
||||
|
||||
|
||||
1809
documentation/pvDatabaseCPP_20130904.html
Normal file
1809
documentation/pvDatabaseCPP_20130904.html
Normal file
File diff suppressed because it is too large
Load Diff
1831
documentation/pvDatabaseCPP_20131112.html
Normal file
1831
documentation/pvDatabaseCPP_20131112.html
Normal file
File diff suppressed because it is too large
Load Diff
1803
documentation/pvDatabaseCPP_20131113.html
Normal file
1803
documentation/pvDatabaseCPP_20131113.html
Normal file
File diff suppressed because it is too large
Load Diff
1936
documentation/pvDatabaseCPP_20131120.html
Normal file
1936
documentation/pvDatabaseCPP_20131120.html
Normal file
File diff suppressed because it is too large
Load Diff
1936
documentation/pvDatabaseCPP_20131121.html
Normal file
1936
documentation/pvDatabaseCPP_20131121.html
Normal file
File diff suppressed because it is too large
Load Diff
2040
documentation/pvDatabaseCPP_20140207.html
Normal file
2040
documentation/pvDatabaseCPP_20140207.html
Normal file
File diff suppressed because it is too large
Load Diff
2043
documentation/pvDatabaseCPP_20140219.html
Normal file
2043
documentation/pvDatabaseCPP_20140219.html
Normal file
File diff suppressed because it is too large
Load Diff
1940
documentation/pvDatabaseCPP_20140710.html
Normal file
1940
documentation/pvDatabaseCPP_20140710.html
Normal file
File diff suppressed because it is too large
Load Diff
2111
documentation/pvDatabaseCPP_20140811.html
Normal file
2111
documentation/pvDatabaseCPP_20140811.html
Normal file
File diff suppressed because it is too large
Load Diff
2052
documentation/pvDatabaseCPP_20151002.html
Normal file
2052
documentation/pvDatabaseCPP_20151002.html
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,12 +0,0 @@
|
||||
TOP = ..
|
||||
include $(TOP)/configure/CONFIG
|
||||
DIRS += src
|
||||
DIRS += record
|
||||
DIRS += pvCopy
|
||||
DIRS += exampleCounter
|
||||
DIRS += exampleServer
|
||||
DIRS += examplePVADoubleArrayGet
|
||||
DIRS += arrayPerformance
|
||||
DIRS += v3IOC
|
||||
include $(TOP)/configure/RULES_DIRS
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
TOP=../..
|
||||
|
||||
include $(TOP)/configure/CONFIG
|
||||
|
||||
PROD_HOST += arrayPerformanceMain
|
||||
arrayPerformanceMain_SRCS += arrayPerformanceMain.cpp
|
||||
arrayPerformanceMain_LIBS += pvDatabase pvAccess pvData Com
|
||||
arrayPerformanceMain_LIBS += pvDatabaseExample
|
||||
|
||||
PROD_HOST += longArrayMonitorMain
|
||||
longArrayMonitorMain_SRCS += longArrayMonitorMain.cpp
|
||||
longArrayMonitorMain_LIBS += pvDatabase pvAccess pvData Com
|
||||
longArrayMonitorMain_LIBS += pvDatabaseExample
|
||||
|
||||
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
#----------------------------------------
|
||||
# ADD RULES AFTER THIS LINE
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
TOP=../..
|
||||
|
||||
include $(TOP)/configure/CONFIG
|
||||
|
||||
PROD_HOST += exampleCounterMain
|
||||
exampleCounterMain_SRCS += exampleCounterMain.cpp
|
||||
exampleCounterMain_LIBS += pvDatabase pvAccess pvData Com
|
||||
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
#----------------------------------------
|
||||
# ADD RULES AFTER THIS LINE
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
/*ExampleCounterMain.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
|
||||
/* Author: Marty Kraimer */
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
#include <memory>
|
||||
#include <iostream>
|
||||
|
||||
#include <pv/standardField.h>
|
||||
#include <pv/standardPVField.h>
|
||||
#include <pv/exampleCounter.h>
|
||||
#include <pv/traceRecord.h>
|
||||
#include <pv/channelProviderLocal.h>
|
||||
#include <pv/serverContext.h>
|
||||
|
||||
using namespace std;
|
||||
using std::tr1::static_pointer_cast;
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
using namespace epics::pvDatabase;
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
PVDatabasePtr master = PVDatabase::getMaster();
|
||||
ChannelProviderLocalPtr channelProvider = getChannelProviderLocal();
|
||||
PVRecordPtr pvRecord;
|
||||
bool result(false);
|
||||
String recordName;
|
||||
recordName = "exampleCounter";
|
||||
pvRecord = ExampleCounter::create(recordName);
|
||||
result = master->addRecord(pvRecord);
|
||||
cout << "result of addRecord " << recordName << " " << result << endl;
|
||||
recordName = "traceRecordPGRPC";
|
||||
pvRecord = TraceRecord::create(recordName);
|
||||
result = master->addRecord(pvRecord);
|
||||
if(!result) cout<< "record " << recordName << " not added" << endl;
|
||||
pvRecord.reset();
|
||||
ServerContext::shared_pointer pvaServer =
|
||||
startPVAServer(PVACCESS_ALL_PROVIDERS,0,true,true);
|
||||
cout << "exampleCounter\n";
|
||||
string str;
|
||||
while(true) {
|
||||
cout << "Type exit to stop: \n";
|
||||
getline(cin,str);
|
||||
if(str.compare("exit")==0) break;
|
||||
|
||||
}
|
||||
pvaServer->shutdown();
|
||||
epicsThreadSleep(1.0);
|
||||
pvaServer->destroy();
|
||||
channelProvider->destroy();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
TOP=../..
|
||||
|
||||
include $(TOP)/configure/CONFIG
|
||||
|
||||
PROD_HOST += examplePVADoubleArrayGetMain
|
||||
examplePVADoubleArrayGetMain_SRCS += examplePVADoubleArrayGetMain.cpp
|
||||
examplePVADoubleArrayGetMain_LIBS += pvDatabase pvAccess pvData Com
|
||||
examplePVADoubleArrayGetMain_LIBS += pvDatabaseExample
|
||||
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
#----------------------------------------
|
||||
# ADD RULES AFTER THIS LINE
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
/*ExamplePVADoubleArrayGetMain.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
|
||||
/* Author: Marty Kraimer */
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
#include <memory>
|
||||
#include <iostream>
|
||||
|
||||
#include <pv/standardField.h>
|
||||
#include <pv/standardPVField.h>
|
||||
#include <pv/examplePVADoubleArrayGet.h>
|
||||
#include <pv/traceRecord.h>
|
||||
#include <pv/channelProviderLocal.h>
|
||||
#include <pv/serverContext.h>
|
||||
#include <pv/clientFactory.h>
|
||||
|
||||
using namespace std;
|
||||
using std::tr1::static_pointer_cast;
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
using namespace epics::pvDatabase;
|
||||
|
||||
static StandardPVFieldPtr standardPVField = getStandardPVField();
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
PVDatabasePtr master = PVDatabase::getMaster();
|
||||
ClientFactory::start();
|
||||
ChannelProviderLocalPtr channelProvider = getChannelProviderLocal();
|
||||
PVRecordPtr pvRecord;
|
||||
bool result(false);
|
||||
String recordName;
|
||||
PVStructurePtr pvStructure = standardPVField->scalarArray(
|
||||
pvDouble,"alarm,timeStamp");
|
||||
recordName = "doubleArray";
|
||||
pvRecord = PVRecord::create(recordName,pvStructure);
|
||||
result = master->addRecord(pvRecord);
|
||||
if(!result) cout<< "record " << recordName << " not added" << endl;
|
||||
ServerContext::shared_pointer serverContext = startPVAServer(PVACCESS_ALL_PROVIDERS,0,true,true);
|
||||
recordName = "examplePVADoubleArrayGet";
|
||||
if(argc>1) recordName = argv[1];
|
||||
String providerName("local");
|
||||
if(argc>2) providerName = argv[2];
|
||||
String channelName("doubleArray");
|
||||
if(argc>3) channelName = argv[3];
|
||||
pvRecord = ExamplePVADoubleArrayGet::create(
|
||||
recordName,providerName,channelName);
|
||||
if(pvRecord!=NULL) {
|
||||
result = master->addRecord(pvRecord);
|
||||
cout << "result of addRecord " << recordName << " " << result << endl;
|
||||
} else {
|
||||
cout << "ExamplePVADoubleArrayGet::create failed" << endl;
|
||||
}
|
||||
string str;
|
||||
while(true) {
|
||||
cout << "Type exit to stop: \n";
|
||||
getline(cin,str);
|
||||
if(str.compare("exit")==0) break;
|
||||
|
||||
}
|
||||
serverContext->shutdown();
|
||||
epicsThreadSleep(1.0);
|
||||
serverContext->destroy();
|
||||
ClientFactory::stop();
|
||||
channelProvider->destroy();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
TOP=../..
|
||||
|
||||
include $(TOP)/configure/CONFIG
|
||||
|
||||
PROD_HOST += exampleServerMain
|
||||
exampleServerMain_SRCS += exampleServerMain.cpp
|
||||
exampleServerMain_LIBS += pvDatabase pvDatabaseExample pvAccess pvData Com
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
#----------------------------------------
|
||||
# ADD RULES AFTER THIS LINE
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
/*exampleServerMain.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
|
||||
/* Author: Marty Kraimer */
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
#include <pv/channelProviderLocal.h>
|
||||
#include <pv/exampleServerCreateRecords.h>
|
||||
#include <pv/serverContext.h>
|
||||
|
||||
using namespace std;
|
||||
using std::tr1::static_pointer_cast;
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
using namespace epics::pvDatabase;
|
||||
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
PVDatabasePtr master = PVDatabase::getMaster();
|
||||
ChannelProviderLocalPtr channelProvider = getChannelProviderLocal();
|
||||
ExampleServerCreateRecords::create();
|
||||
ServerContext::shared_pointer ctx =
|
||||
startPVAServer(PVACCESS_ALL_PROVIDERS,0,true,true);
|
||||
cout << "exampleServer\n";
|
||||
PVStringArrayPtr pvNames = master->getRecordNames();
|
||||
String buffer;
|
||||
pvNames->toString(&buffer);
|
||||
cout << "recordNames" << endl << buffer << endl;
|
||||
string str;
|
||||
while(true) {
|
||||
cout << "Type exit to stop: \n";
|
||||
getline(cin,str);
|
||||
if(str.compare("exit")==0) break;
|
||||
|
||||
}
|
||||
ctx->destroy();
|
||||
epicsThreadSleep(1.0);
|
||||
channelProvider->destroy();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
TOP=../..
|
||||
|
||||
include $(TOP)/configure/CONFIG
|
||||
|
||||
PROD_HOST += testPVCopy
|
||||
testPVCopy_SRCS += testPVCopy.cpp
|
||||
testPVCopy_LIBS += pvDatabase pvAccess pvData Com
|
||||
|
||||
PROD_HOST += testPVRecord
|
||||
testPVRecord_SRCS += testPVRecord.cpp
|
||||
testPVRecord_LIBS += pvDatabase pvAccess pvData Com
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
#----------------------------------------
|
||||
# ADD RULES AFTER THIS LINE
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
TOP=../..
|
||||
|
||||
include $(TOP)/configure/CONFIG
|
||||
|
||||
PROD_HOST += testExampleRecord
|
||||
testExampleRecord_SRCS += testExampleRecordMain.cpp
|
||||
testExampleRecord_LIBS += pvDatabase pvAccess pvData Com
|
||||
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
#----------------------------------------
|
||||
# ADD RULES AFTER THIS LINE
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
TOP = ../..
|
||||
include $(TOP)/configure/CONFIG
|
||||
|
||||
EXAMPLESRC = $(TOP)/example/src/
|
||||
|
||||
LIBRARY_IOC += pvDatabaseExample
|
||||
pvDatabaseExample_LIBS += $(EPICS_BASE_IOC_LIBS)
|
||||
pvDatabaseExample_LIBS += Com pvData pvAccess pvDatabase
|
||||
|
||||
SRC_DIRS += $(EXAMPLESRC)/exampleCounter
|
||||
INC += exampleCounter.h
|
||||
|
||||
SRC_DIRS += $(EXAMPLESRC)/exampleServer
|
||||
INC+= exampleServerCreateRecords.h
|
||||
LIBSRCS += exampleServerCreateRecords.cpp
|
||||
|
||||
SRC_DIRS += $(EXAMPLESRC)/examplePVADoubleArrayGet
|
||||
INC+= examplePVADoubleArrayGet.h
|
||||
LIBSRCS += examplePVADoubleArrayGet.cpp
|
||||
|
||||
SRC_DIRS += $(EXAMPLESRC)/arrayPerformance
|
||||
INC+= arrayPerformance.h
|
||||
LIBSRCS += arrayPerformance.cpp
|
||||
INC+= longArrayMonitor.h
|
||||
LIBSRCS += longArrayMonitor.cpp
|
||||
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
/* exampleCounter.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
* @date 2013.04.02
|
||||
*/
|
||||
#ifndef EXAMPLECOUNTER_H
|
||||
#define EXAMPLECOUNTER_H
|
||||
|
||||
|
||||
#include <pv/pvDatabase.h>
|
||||
#include <pv/standardPVField.h>
|
||||
#include <pv/timeStamp.h>
|
||||
#include <pv/pvTimeStamp.h>
|
||||
|
||||
namespace epics { namespace pvDatabase {
|
||||
|
||||
|
||||
class ExampleCounter;
|
||||
typedef std::tr1::shared_ptr<ExampleCounter> ExampleCounterPtr;
|
||||
|
||||
class ExampleCounter :
|
||||
public PVRecord
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(ExampleCounter);
|
||||
static ExampleCounterPtr create(
|
||||
epics::pvData::String const & recordName);
|
||||
virtual ~ExampleCounter();
|
||||
virtual void destroy();
|
||||
virtual bool init();
|
||||
virtual void process();
|
||||
private:
|
||||
ExampleCounter(epics::pvData::String const & recordName,
|
||||
epics::pvData::PVStructurePtr const & pvStructure);
|
||||
epics::pvData::PVLongPtr pvValue;
|
||||
epics::pvData::PVTimeStamp pvTimeStamp;
|
||||
epics::pvData::TimeStamp timeStamp;
|
||||
};
|
||||
|
||||
ExampleCounterPtr ExampleCounter::create(
|
||||
epics::pvData::String const & recordName)
|
||||
{
|
||||
epics::pvData::PVStructurePtr pvStructure =
|
||||
epics::pvData::getStandardPVField()->scalar(epics::pvData::pvLong,"timeStamp,alarm");
|
||||
ExampleCounterPtr pvRecord(
|
||||
new ExampleCounter(recordName,pvStructure));
|
||||
if(!pvRecord->init()) pvRecord.reset();
|
||||
return pvRecord;
|
||||
}
|
||||
|
||||
ExampleCounter::ExampleCounter(
|
||||
epics::pvData::String const & recordName,
|
||||
epics::pvData::PVStructurePtr const & pvStructure)
|
||||
: PVRecord(recordName,pvStructure)
|
||||
{
|
||||
pvTimeStamp.attach(pvStructure->getSubField("timeStamp"));
|
||||
}
|
||||
|
||||
ExampleCounter::~ExampleCounter()
|
||||
{
|
||||
}
|
||||
|
||||
void ExampleCounter::destroy()
|
||||
{
|
||||
PVRecord::destroy();
|
||||
}
|
||||
|
||||
bool ExampleCounter::init()
|
||||
{
|
||||
|
||||
initPVRecord();
|
||||
epics::pvData::PVFieldPtr pvField;
|
||||
pvValue = getPVStructure()->getLongField("value");
|
||||
if(pvValue.get()==NULL) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void ExampleCounter::process()
|
||||
{
|
||||
pvValue->put(pvValue->get() + 1.0);
|
||||
timeStamp.getCurrent();
|
||||
pvTimeStamp.set(timeStamp);
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif /* EXAMPLECOUNTER_H */
|
||||
@@ -1,27 +0,0 @@
|
||||
/* exampleServerCreateRecords.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
* @date 2013.07.24
|
||||
*/
|
||||
#ifndef EXAMPLESERVERCREATERECORDS_H
|
||||
#define EXAMPLESERVERCREATERECORDS_H
|
||||
|
||||
|
||||
#include <pv/pvDatabase.h>
|
||||
|
||||
namespace epics { namespace pvDatabase {
|
||||
|
||||
class ExampleServerCreateRecords {
|
||||
public:
|
||||
static void create();
|
||||
};
|
||||
|
||||
|
||||
}}
|
||||
|
||||
#endif /* EXAMPLESERVERCREATERECORDS_H */
|
||||
@@ -1,7 +0,0 @@
|
||||
TOP = ../..
|
||||
include $(TOP)/configure/CONFIG
|
||||
DIRS += exampleCounter
|
||||
DIRS += exampleServer
|
||||
DIRS += examplePVADoubleArrayGet
|
||||
include $(TOP)/configure/RULES_DIRS
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
TOP=../../../..
|
||||
|
||||
include $(TOP)/configure/CONFIG
|
||||
#----------------------------------------
|
||||
# ADD MACRO DEFINITIONS AFTER THIS LINE
|
||||
#=============================
|
||||
|
||||
#==================================================
|
||||
# Build an IOC support library
|
||||
#
|
||||
|
||||
DBD += exampleCounter.dbd
|
||||
|
||||
LIBRARY_IOC += exampleCounterSupport
|
||||
exampleCounterSupport_SRCS += exampleCounter.cpp
|
||||
exampleCounterSupport_LIBS += pvData
|
||||
exampleCounterSupport_LIBS += pvAccess
|
||||
exampleCounterSupport_LIBS += pvDatabase
|
||||
exampleCounterSupport_LIBS += pvDatabaseExample
|
||||
exampleCounterSupport_LIBS += $(EPICS_BASE_IOC_LIBS)
|
||||
|
||||
#=============================
|
||||
# build an ioc application
|
||||
|
||||
PROD_IOC += exampleCounter
|
||||
|
||||
|
||||
# <name>_registerRecordDeviceDriver.cpp will be created from <name>.dbd
|
||||
exampleCounter_SRCS += exampleCounter_registerRecordDeviceDriver.cpp
|
||||
exampleCounter_SRCS_DEFAULT += exampleCounterMain.cpp
|
||||
exampleCounter_SRCS_vxWorks += -nil-
|
||||
|
||||
|
||||
# The following adds support from base/src/vxWorks
|
||||
exampleCounter_OBJS_vxWorks += $(EPICS_BASE_BIN)/vxComLibrary
|
||||
|
||||
exampleCounter_LIBS += pvData pvAccess
|
||||
exampleCounter_LIBS += pvDatabase
|
||||
exampleCounter_LIBS += pvDatabaseExample
|
||||
exampleCounter_LIBS += exampleCounterSupport
|
||||
exampleCounter_LIBS += $(EPICS_BASE_IOC_LIBS)
|
||||
|
||||
#===========================
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
#----------------------------------------
|
||||
# ADD RULES AFTER THIS LINE
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
include "base.dbd"
|
||||
include "PVAServerRegister.dbd"
|
||||
registrar("exampleCounterRegister")
|
||||
@@ -1,48 +0,0 @@
|
||||
TOP=../../../..
|
||||
|
||||
include $(TOP)/configure/CONFIG
|
||||
#----------------------------------------
|
||||
# ADD MACRO DEFINITIONS AFTER THIS LINE
|
||||
#=============================
|
||||
|
||||
#==================================================
|
||||
# Build an IOC support library
|
||||
#
|
||||
|
||||
DBD += examplePVADoubleArrayGet.dbd
|
||||
|
||||
LIBRARY_IOC += examplePVADoubleArrayGetSupport
|
||||
examplePVADoubleArrayGetSupport_SRCS += examplePVADoubleArrayGet.cpp
|
||||
examplePVADoubleArrayGetSupport_LIBS += pvData
|
||||
examplePVADoubleArrayGetSupport_LIBS += pvAccess
|
||||
examplePVADoubleArrayGetSupport_LIBS += pvDatabase
|
||||
examplePVADoubleArrayGetSupport_LIBS += pvDatabaseExample
|
||||
examplePVADoubleArrayGetSupport_LIBS += $(EPICS_BASE_IOC_LIBS)
|
||||
|
||||
#=============================
|
||||
# build an ioc application
|
||||
|
||||
PROD_IOC += examplePVADoubleArrayGet
|
||||
|
||||
|
||||
# <name>_registerRecordDeviceDriver.cpp will be created from <name>.dbd
|
||||
examplePVADoubleArrayGet_SRCS += examplePVADoubleArrayGet_registerRecordDeviceDriver.cpp
|
||||
examplePVADoubleArrayGet_SRCS_DEFAULT += examplePVADoubleArrayGetMain.cpp
|
||||
examplePVADoubleArrayGet_SRCS_vxWorks += -nil-
|
||||
|
||||
|
||||
# The following adds support from base/src/vxWorks
|
||||
examplePVADoubleArrayGet_OBJS_vxWorks += $(EPICS_BASE_BIN)/vxComLibrary
|
||||
|
||||
examplePVADoubleArrayGet_LIBS += pvData pvAccess
|
||||
examplePVADoubleArrayGet_LIBS += pvDatabase
|
||||
examplePVADoubleArrayGet_LIBS += pvDatabaseExample
|
||||
examplePVADoubleArrayGet_LIBS += examplePVADoubleArrayGetSupport
|
||||
examplePVADoubleArrayGet_LIBS += $(EPICS_BASE_IOC_LIBS)
|
||||
|
||||
#===========================
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
#----------------------------------------
|
||||
# ADD RULES AFTER THIS LINE
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
include "base.dbd"
|
||||
include "PVAServerRegister.dbd"
|
||||
registrar("exampleServerRegister")
|
||||
19
exampleDatabase/Makefile
Normal file
19
exampleDatabase/Makefile
Normal file
@@ -0,0 +1,19 @@
|
||||
# Makefile at top of application tree
|
||||
|
||||
TOP = .
|
||||
include $(TOP)/configure/CONFIG
|
||||
|
||||
DIRS += configure
|
||||
|
||||
DIRS += src
|
||||
src_DEPEND_DIRS = configure
|
||||
|
||||
DIRS += ioc
|
||||
ioc_DEPEND_DIRS = src
|
||||
|
||||
DIRS += iocBoot
|
||||
iocBoot_DEPEND_DIRS = src
|
||||
|
||||
include $(TOP)/configure/RULES_TOP
|
||||
|
||||
|
||||
29
exampleDatabase/configure/CONFIG
Normal file
29
exampleDatabase/configure/CONFIG
Normal file
@@ -0,0 +1,29 @@
|
||||
# CONFIG - Load build configuration data
|
||||
#
|
||||
# Do not make changes to this file!
|
||||
|
||||
# Allow user to override where the build rules come from
|
||||
RULES = $(EPICS_BASE)
|
||||
|
||||
# RELEASE files point to other application tops
|
||||
include $(TOP)/configure/RELEASE
|
||||
-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).Common
|
||||
ifdef T_A
|
||||
-include $(TOP)/configure/RELEASE.Common.$(T_A)
|
||||
-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).$(T_A)
|
||||
endif
|
||||
|
||||
CONFIG = $(RULES)/configure
|
||||
include $(CONFIG)/CONFIG
|
||||
|
||||
# Override the Base definition:
|
||||
INSTALL_LOCATION = $(TOP)
|
||||
|
||||
# CONFIG_SITE files contain other build configuration settings
|
||||
include $(TOP)/configure/CONFIG_SITE
|
||||
-include $(TOP)/configure/CONFIG_SITE.$(EPICS_HOST_ARCH).Common
|
||||
ifdef T_A
|
||||
-include $(TOP)/configure/CONFIG_SITE.Common.$(T_A)
|
||||
-include $(TOP)/configure/CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A)
|
||||
endif
|
||||
|
||||
27
exampleDatabase/configure/CONFIG_SITE
Normal file
27
exampleDatabase/configure/CONFIG_SITE
Normal file
@@ -0,0 +1,27 @@
|
||||
# CONFIG_SITE
|
||||
|
||||
# Make any application-specific changes to the EPICS build
|
||||
# configuration variables in this file.
|
||||
#
|
||||
# Host/target specific settings can be specified in files named
|
||||
# CONFIG_SITE.$(EPICS_HOST_ARCH).Common
|
||||
# CONFIG_SITE.Common.$(T_A)
|
||||
# CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A)
|
||||
|
||||
# CHECK_RELEASE controls the consistency checking of the support
|
||||
# applications pointed to by the RELEASE* files.
|
||||
# Normally CHECK_RELEASE should be set to YES.
|
||||
# Set CHECK_RELEASE to NO to disable checking completely.
|
||||
# Set CHECK_RELEASE to WARN to perform consistency checking but
|
||||
# continue building anyway if conflicts are found.
|
||||
CHECK_RELEASE = WARN
|
||||
|
||||
# To install files into a location other than $(TOP) define
|
||||
# INSTALL_LOCATION here.
|
||||
#INSTALL_LOCATION=</path/name/to/install/top>
|
||||
|
||||
INSTALL_INCLUDE = $(INSTALL_LOCATION)/include/pv
|
||||
USR_INCLUDES += -I $(INSTALL_LOCATION)/include
|
||||
|
||||
-include $(TOP)/../../CONFIG_SITE.local
|
||||
-include $(TOP)/../configure/CONFIG_SITE.local
|
||||
9
exampleDatabase/configure/ExampleRELEASE.local
Normal file
9
exampleDatabase/configure/ExampleRELEASE.local
Normal file
@@ -0,0 +1,9 @@
|
||||
EPICS_BASE=/home/install/epics/base
|
||||
TEMPLATE_TOP=$(EPICS_BASE)/templates/makeBaseApp/top
|
||||
EPICSV4HOME=/home/hg
|
||||
PVCOMMON=${EPICSV4HOME}/pvCommonCPP
|
||||
PVDATA=${EPICSV4HOME}/pvDataCPP
|
||||
PVACCESS=${EPICSV4HOME}/pvAccessCPP
|
||||
PVDATABASE=${EPICSV4HOME}/pvDatabaseCPP
|
||||
PVDATABASETEST=${EPICSV4HOME}/pvDatabaseCPP/test
|
||||
PVASRV=${EPICSV4HOME}/pvaSrv
|
||||
8
exampleDatabase/configure/Makefile
Normal file
8
exampleDatabase/configure/Makefile
Normal file
@@ -0,0 +1,8 @@
|
||||
TOP=..
|
||||
|
||||
include $(TOP)/configure/CONFIG
|
||||
|
||||
TARGETS = $(CONFIG_TARGETS)
|
||||
CONFIGS += $(subst ../,,$(wildcard $(CONFIG_INSTALLS)))
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
43
exampleDatabase/configure/RELEASE
Normal file
43
exampleDatabase/configure/RELEASE
Normal file
@@ -0,0 +1,43 @@
|
||||
# pvDatabaseCPP/example RELEASE - Location of external support modules
|
||||
#
|
||||
# IF YOU CHANGE this file or any file it includes you must
|
||||
# subsequently do a "gnumake rebuild" in the application's
|
||||
# top level directory.
|
||||
#
|
||||
# The build process does not check dependencies against files
|
||||
# that are outside this application, thus you should also do a
|
||||
# "gnumake rebuild" in the top level directory after EPICS_BASE
|
||||
# or any other external module pointed to below is rebuilt.
|
||||
#
|
||||
# Host- or target-specific settings can be given in files named
|
||||
# RELEASE.$(EPICS_HOST_ARCH).Common
|
||||
# RELEASE.Common.$(T_A)
|
||||
# RELEASE.$(EPICS_HOST_ARCH).$(T_A)
|
||||
|
||||
# EPICS V4 Developers: Do not edit the locations in this file!
|
||||
#
|
||||
# Create a file RELEASE.local pointing to your PVASRV, PVACCESS,
|
||||
# PVDATA, PVCOMMON and EPICS_BASE build directories, e.g.
|
||||
# PVASRV = /path/to/epics/pvaSrvCPP
|
||||
# PVACCESS = /path/to/epics/pvAccessCPP
|
||||
# PVDATA = /path/to/epics/pvDataCPP
|
||||
# PVCOMMON = /path/to/epics/pvCommonCPP
|
||||
# EPICS_BASE = /path/to/epics/base
|
||||
|
||||
# If this example is built in a directory under pvDatabaseCPP,
|
||||
# use the following definitions:
|
||||
|
||||
PVDATABASETEST = $(TOP)/../test
|
||||
PVDATABASE = $(TOP)/..
|
||||
|
||||
-include $(TOP)/../configure/RELEASE.local
|
||||
-include $(TOP)/../../RELEASE.local
|
||||
|
||||
# If you copied this example from pvDatabaseCPP to be built as a
|
||||
# standalone TOP, adjust and use the following definitions:
|
||||
|
||||
#PVDATABASETEST = /path/to/epics/pvDatabaseCPP/testTop
|
||||
#PVDATABASE = /path/to/epics/pvDatabaseCPP
|
||||
|
||||
#-include $(TOP)/../RELEASE.local
|
||||
#-include $(TOP)/configure/RELEASE.local
|
||||
6
exampleDatabase/configure/RULES
Normal file
6
exampleDatabase/configure/RULES
Normal file
@@ -0,0 +1,6 @@
|
||||
# RULES
|
||||
|
||||
include $(CONFIG)/RULES
|
||||
|
||||
# Library should be rebuilt because LIBOBJS may have changed.
|
||||
$(LIBNAME): ../Makefile
|
||||
2
exampleDatabase/configure/RULES.ioc
Normal file
2
exampleDatabase/configure/RULES.ioc
Normal file
@@ -0,0 +1,2 @@
|
||||
#RULES.ioc
|
||||
include $(CONFIG)/RULES.ioc
|
||||
2
exampleDatabase/configure/RULES_DIRS
Normal file
2
exampleDatabase/configure/RULES_DIRS
Normal file
@@ -0,0 +1,2 @@
|
||||
#RULES_DIRS
|
||||
include $(CONFIG)/RULES_DIRS
|
||||
3
exampleDatabase/configure/RULES_TOP
Normal file
3
exampleDatabase/configure/RULES_TOP
Normal file
@@ -0,0 +1,3 @@
|
||||
#RULES_TOP
|
||||
include $(CONFIG)/RULES_TOP
|
||||
|
||||
29
exampleDatabase/ioc/Db/Makefile
Normal file
29
exampleDatabase/ioc/Db/Makefile
Normal file
@@ -0,0 +1,29 @@
|
||||
TOP=../..
|
||||
include $(TOP)/configure/CONFIG
|
||||
#----------------------------------------
|
||||
# ADD MACRO DEFINITIONS AFTER THIS LINE
|
||||
|
||||
#----------------------------------------------------
|
||||
# Optimization of db files using dbst (DEFAULT: NO)
|
||||
#DB_OPT = YES
|
||||
|
||||
#----------------------------------------------------
|
||||
# Create and install (or just install)
|
||||
# databases, templates, substitutions like this
|
||||
DB += dbScalar.db
|
||||
DB += dbInteger.db
|
||||
DB += dbArray.db
|
||||
DB += dbString.db
|
||||
DB += dbStringArray.db
|
||||
DB += dbEnum.db
|
||||
DB += dbCounter.db
|
||||
DB += dbDouble.db
|
||||
|
||||
#----------------------------------------------------
|
||||
# If <anyname>.db template is not named <anyname>*.template add
|
||||
# <anyname>_TEMPLATE = <templatename>
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
#----------------------------------------
|
||||
# ADD RULES AFTER THIS LINE
|
||||
|
||||
3
exampleDatabase/ioc/Db/dbDouble.db
Normal file
3
exampleDatabase/ioc/Db/dbDouble.db
Normal file
@@ -0,0 +1,3 @@
|
||||
record(ao, "$(name)")
|
||||
{
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
TOP = ../../..
|
||||
TOP = ..
|
||||
include $(TOP)/configure/CONFIG
|
||||
DIRS := $(DIRS) $(filter-out $(DIRS), $(wildcard *src*))
|
||||
DIRS := $(DIRS) $(filter-out $(DIRS), $(wildcard *Src*))
|
||||
43
exampleDatabase/ioc/src/Makefile
Normal file
43
exampleDatabase/ioc/src/Makefile
Normal file
@@ -0,0 +1,43 @@
|
||||
TOP=../..
|
||||
|
||||
include $(TOP)/configure/CONFIG
|
||||
#----------------------------------------
|
||||
# ADD MACRO DEFINITIONS AFTER THIS LINE
|
||||
#=============================
|
||||
|
||||
#==================================================
|
||||
# Build an IOC support library
|
||||
#
|
||||
|
||||
DBD += exampleDatabase.dbd
|
||||
|
||||
#=============================
|
||||
# build an ioc application
|
||||
|
||||
PROD_IOC += exampleDatabase
|
||||
|
||||
|
||||
# <name>_registerRecordDeviceDriver.cpp will be created from <name>.dbd
|
||||
exampleDatabase_SRCS += exampleDatabase_registerRecordDeviceDriver.cpp
|
||||
exampleDatabase_SRCS_DEFAULT += exampleDatabaseMain.cpp
|
||||
exampleDatabase_SRCS_vxWorks += -nil-
|
||||
|
||||
|
||||
# The following adds support from base/src/vxWorks
|
||||
exampleDatabase_OBJS_vxWorks += $(EPICS_BASE_BIN)/vxComLibrary
|
||||
|
||||
exampleDatabase_LIBS += exampleDatabase
|
||||
exampleDatabase_LIBS += powerSupply
|
||||
exampleDatabase_LIBS += pvDatabase
|
||||
exampleDatabase_LIBS += pvaSrv
|
||||
exampleDatabase_LIBS += pvAccess
|
||||
exampleDatabase_LIBS += pvData
|
||||
exampleDatabase_LIBS += Com
|
||||
exampleDatabase_LIBS += $(EPICS_BASE_IOC_LIBS)
|
||||
|
||||
#===========================
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
#----------------------------------------
|
||||
# ADD RULES AFTER THIS LINE
|
||||
|
||||
6
exampleDatabase/ioc/src/exampleDatabaseInclude.dbd
Normal file
6
exampleDatabase/ioc/src/exampleDatabaseInclude.dbd
Normal file
@@ -0,0 +1,6 @@
|
||||
include "base.dbd"
|
||||
include "PVAServerRegister.dbd"
|
||||
include "registerChannelProviderLocal.dbd"
|
||||
include "dbPv.dbd"
|
||||
include "powerSupplyRegister.dbd"
|
||||
registrar("exampleDatabaseRegister")
|
||||
33
exampleDatabase/ioc/src/exampleDatabaseMain.cpp
Normal file
33
exampleDatabase/ioc/src/exampleDatabaseMain.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
/*exampleDatabaseMain.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
|
||||
/* Author: Marty Kraimer */
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "epicsExit.h"
|
||||
#include "epicsThread.h"
|
||||
#include "iocsh.h"
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
if(argc>=2) {
|
||||
iocsh(argv[1]);
|
||||
epicsThreadSleep(.2);
|
||||
}
|
||||
iocsh(NULL);
|
||||
epicsExit(0);
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -3,5 +3,5 @@ include $(TOP)/configure/CONFIG
|
||||
DIRS += $(wildcard *ioc*)
|
||||
DIRS += $(wildcard as*)
|
||||
DIRS += $(wildcard example*)
|
||||
include $(EPICS_BASE)/configure/RULES_DIRS
|
||||
include $(CONFIG)/RULES_DIRS
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user