Merged Michael Davidsaver's array-opt branch

This commit is contained in:
Andrew Johnson
2013-04-02 17:01:53 -05:00
6 changed files with 38 additions and 8 deletions

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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 */

View File

@@ -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)

View File

@@ -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)

View File

@@ -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);
}
}