EPICS exampleJava/exampleLink

2016.08.26

Abstract

exampleLink implements a PVRecord that uses pvAccess to access another channel.

Table of Contents


Overview

This example provides the following:

exampleLinkMain
A database with records named exampleMonitorLink, exampleGetLink, and examplePutLink. Each has a link to another channel. The process method of the records use pvaChannelMonitor, pvaChannelGet, and pvaChannelPut to connect to the other channel.
exampleLinkClient
This uses pvaClientPut to change values in the record to which exampleLinkMain connects and uses pvaClientMonitor to monitor changes in pvaChannelMonitor.
doubleArrayMain
This is an PVDatabase that holds a PVRecord in another IOC to which exampleLinkMain can connect.
v3IOC
A V3 softIOC that can be used to create a V3 DBRecord to which exampleLinkMain can connect.

exampleLinkMain

exampleLinkMain supports help as follows:

mrk> pwd
/home/epicsv4/release4_6/exampleJava/exampleLink
mrk> scripts/exampleLinkMain -help
provider linkedRecordName generateLinkedRecord
default
pva doubleArray true
mrk> 
The arguments are:
provider
This can be pva or ca or local.
ca only works if channelName is a accessable via the ca network protocol, e. g. it is the name of a DBRecord in a V3 IOC.
local only works if generateLinkedRecord is true.
linkedRecordName
The name of the channel to which records exampleMonitorLink, exampleGetLink, and examplePutLink connect.
generateLinkedRecord
If true then record generateLinkedRecord is allocated in the same IOC.

exampleLinkClient

exampleLinkClient supports help as follows:

mrk> pwd
/home/epicsv4/release4_6/exampleJava/exampleLink
mrk> scripts/exampleLinkClient -help
provider linkedRecordName
default
pva doubleArray
The arguments are:
provider
This can be pva or ca or local.
ca only works if channelName is a accessable via the ca network protocol, e. g. it is the name of a DBRecord in a V3 IOC.
local only works if generateLinkedRecord is true.
linkedRecordName
The name of the channel to which records exampleMonitorLink, exampleGetLink, and examplePutLink connect.

doubleArrayMain

doubleArrayMain supports help as follows:

mrk> pwd
/home/epicsv4/release4_6/exampleJava/exampleLink
mrk> scripts/exampleLinkdoubleArrayMain -help
doubleArrayRecordName
default
doubleArrayExternal
The argument is:
doubleArrayRecordName
The channel name of the PVRecord.
linkedRecordName
The name of the channel to which records exampleMonitorLink, exampleGetLink, and examplePutLink connect.

Using exampleLinkMain to test providers pva, local and ca

channel provider pva

Just start exampleLinkMain and exampleLinkClient with the default options.

channel provider local

start exampleLinkMain as:

scripts/exampleLinkMain local

exampleLinkClient can be started with the default options.

channel provider ca

In order to test using provider ca a softIoc for record doubleArray must also be started:

mrk> pwd
/home/epicsv4/master/exampleJava/exampleLink/v3IOC
mrk> softIoc st.cmd

Start exampleLinkMain:

scripts/exampleLinkMain ca doubleArray false

Start exampleLinkClient:

scripts/exampleLinkClient ca

Discussion

Access Alternatives

The process routine of a PVRecord can access other PVRecords in two ways:

Directly accessing local pvDatabase
If the other PVRecord is accessed via the master PVDatabase then threading issues are up to the implementation.
Access via channelProvider pva or ca
If provider pva or ca is used then locking is handled by pvAccess.
Access via channelProvider local
If provider local is used the implementation must be careful that it does not cause deadlocks. When the process method is called the pvRecord for the process method is locked. When it makes a pvAccess get, put, etc request the other record is locked. Thus if a set of pvAccess links are implemented the possibility of deadlocks exists. A simple example is two records that have links to each other. More complex sets are easily created. Unless the developer has complete control of the set of records then remote pvAccess should be used. But this results in more context switches.

Data synchronization

If pvAccess (provider pva or ca) is used then it handles data synchronization. This is done by making a copy of the data that is transferred between the two pvRecords. This is true if either remote or local pvAccess is used. Each get, put, etc request results in data being copied between the two records.

If the linked channel is a local pvRecord then, for scalar and structure arrays, raw data is NOT copied for gets. This is because pvData uses shared_vector to hold the raw data. Instead of copying the raw data the reference count is incremented.

For puts the linked array will force a new allocation of the raw data in the linked record, i. e. copy on write semantics are enforced. This is done automatically by pvData and not by pvDatabase.