Merged Michael Davidsaver's array-opt branch
This commit is contained in:
@@ -15,6 +15,22 @@ EPICS Base 3.15.0.x releases are not intended for use in production systems.</p>
|
||||
<h2 align="center">Changes between 3.15.0.1 and 3.15.0.2</h2>
|
||||
<!-- Insert new items immediately below here ... -->
|
||||
|
||||
<h3>Array field double-buffering</h3>
|
||||
|
||||
<p>Array data can now be moved, without copying, into and out of the VAL field
|
||||
of the waveform, aai, and aao record types by replacing the pointer in BPTR.
|
||||
The basic rules which device support must follow are:</p>
|
||||
|
||||
<ol>
|
||||
<li>BPTR, and the memory it is currently pointing to, can only be accessed
|
||||
while the record is locked.</li>
|
||||
<li>NELM may not be changed; NORD should be updated whenever the number of
|
||||
valid data elements changes.</li>
|
||||
<li>When BPTR is replaced it must always point to a block of memory large
|
||||
enough to hold the maximum number of elements, as given by the NELM and
|
||||
FTVL fields.</li>
|
||||
</ol>
|
||||
|
||||
<h3>Spin-locks API added</h3>
|
||||
|
||||
<p>The new header file epicsSpin.h adds a portable spin-locks API which is
|
||||
|
||||
@@ -780,6 +780,7 @@ long dbGet(DBADDR *paddr, short dbrType,
|
||||
void *pbuffer, long *options, long *nRequest, void *pflin)
|
||||
{
|
||||
char *pbuf = pbuffer;
|
||||
void *pfieldsave;
|
||||
db_field_log *pfl = (db_field_log *)pflin;
|
||||
short field_type;
|
||||
long no_elements;
|
||||
@@ -815,6 +816,13 @@ long dbGet(DBADDR *paddr, short dbrType,
|
||||
return S_db_badDbrtype;
|
||||
}
|
||||
|
||||
/* For array field, the rset function
|
||||
* get_array_info() is allowed to modify
|
||||
* paddr->pfield. So we store the original
|
||||
* value and restore it later.
|
||||
*/
|
||||
pfieldsave = paddr->pfield;
|
||||
|
||||
/* check for array */
|
||||
if ((!pfl || pfl->type == dbfl_type_rec) &&
|
||||
paddr->special == SPC_DBADDR &&
|
||||
@@ -860,7 +868,8 @@ long dbGet(DBADDR *paddr, short dbrType,
|
||||
sprintf(message, "dbGet: Missing conversion for [%d][%d]\n",
|
||||
field_type, dbrType);
|
||||
recGblDbaddrError(S_db_badDbrtype, paddr, message);
|
||||
return S_db_badDbrtype;
|
||||
status = S_db_badDbrtype;
|
||||
goto done;
|
||||
}
|
||||
/* convert database field and place it in the buffer */
|
||||
if (n <= 0) {
|
||||
@@ -880,6 +889,8 @@ long dbGet(DBADDR *paddr, short dbrType,
|
||||
status = convert(&localAddr, pbuf, n, no_elements, offset);
|
||||
}
|
||||
}
|
||||
done:
|
||||
paddr->pfield = pfieldsave;
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
@@ -104,7 +104,9 @@ static db_field_log* filter(void* pvt, dbChannel *chan, db_field_log *pfl) {
|
||||
if (chan->addr.special == SPC_DBADDR &&
|
||||
nSource > 1 &&
|
||||
(prset = dbGetRset(&chan->addr)) &&
|
||||
prset->get_array_info) {
|
||||
prset->get_array_info)
|
||||
{
|
||||
void *pfieldsave = chan->addr.pfield;
|
||||
prec = dbChannelRecord(chan);
|
||||
dbScanLock(prec);
|
||||
prset->get_array_info(&chan->addr, &nSource, &offset);
|
||||
@@ -126,6 +128,7 @@ static db_field_log* filter(void* pvt, dbChannel *chan, db_field_log *pfl) {
|
||||
pfl->u.r.field = pdst;
|
||||
}
|
||||
dbScanUnlock(prec);
|
||||
chan->addr.pfield = pfieldsave;
|
||||
}
|
||||
|
||||
/* Extract from buffer */
|
||||
|
||||
@@ -183,7 +183,6 @@ static long cvt_dbaddr(DBADDR *paddr)
|
||||
{
|
||||
aaiRecord *prec = (aaiRecord *)paddr->precord;
|
||||
|
||||
paddr->pfield = prec->bptr;
|
||||
paddr->no_elements = prec->nelm;
|
||||
paddr->field_type = prec->ftvl;
|
||||
paddr->field_size = dbValueSize(prec->ftvl);
|
||||
@@ -195,6 +194,7 @@ static long get_array_info(DBADDR *paddr, long *no_elements, long *offset)
|
||||
{
|
||||
aaiRecord *prec = (aaiRecord *)paddr->precord;
|
||||
|
||||
paddr->pfield = prec->bptr;
|
||||
*no_elements = prec->nord;
|
||||
*offset = 0;
|
||||
return 0;
|
||||
@@ -308,7 +308,7 @@ static void monitor(aaiRecord *prec)
|
||||
}
|
||||
|
||||
if (monitor_mask)
|
||||
db_post_events(prec, prec->bptr, monitor_mask);
|
||||
db_post_events(prec, &prec->val, monitor_mask);
|
||||
}
|
||||
|
||||
static long readValue(aaiRecord *prec)
|
||||
|
||||
@@ -183,7 +183,6 @@ static long cvt_dbaddr(DBADDR *paddr)
|
||||
{
|
||||
aaoRecord *prec = (aaoRecord *)paddr->precord;
|
||||
|
||||
paddr->pfield = prec->bptr;
|
||||
paddr->no_elements = prec->nelm;
|
||||
paddr->field_type = prec->ftvl;
|
||||
paddr->field_size = dbValueSize(prec->ftvl);
|
||||
@@ -195,6 +194,7 @@ static long get_array_info(DBADDR *paddr, long *no_elements, long *offset)
|
||||
{
|
||||
aaoRecord *prec = (aaoRecord *)paddr->precord;
|
||||
|
||||
paddr->pfield = prec->bptr;
|
||||
*no_elements = prec->nord;
|
||||
*offset = 0;
|
||||
return 0;
|
||||
@@ -308,7 +308,7 @@ static void monitor(aaoRecord *prec)
|
||||
}
|
||||
|
||||
if (monitor_mask)
|
||||
db_post_events(prec, prec->bptr, monitor_mask);
|
||||
db_post_events(prec, &prec->val, monitor_mask);
|
||||
}
|
||||
|
||||
static long writeValue(aaoRecord *prec)
|
||||
|
||||
@@ -163,7 +163,6 @@ static long cvt_dbaddr(DBADDR *paddr)
|
||||
{
|
||||
waveformRecord *prec = (waveformRecord *) paddr->precord;
|
||||
|
||||
paddr->pfield = prec->bptr;
|
||||
paddr->no_elements = prec->nelm;
|
||||
paddr->field_type = prec->ftvl;
|
||||
paddr->field_size = dbValueSize(prec->ftvl);
|
||||
@@ -176,6 +175,7 @@ static long get_array_info(DBADDR *paddr, long *no_elements, long *offset)
|
||||
{
|
||||
waveformRecord *prec = (waveformRecord *) paddr->precord;
|
||||
|
||||
paddr->pfield = prec->bptr;
|
||||
*no_elements = prec->nord;
|
||||
*offset = 0;
|
||||
|
||||
@@ -300,7 +300,7 @@ static void monitor(waveformRecord *prec)
|
||||
}
|
||||
|
||||
if (monitor_mask) {
|
||||
db_post_events(prec, prec->bptr, monitor_mask);
|
||||
db_post_events(prec, &prec->val, monitor_mask);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user