From 4f6040d35b936c60e4e4f35f0d07307251490941 Mon Sep 17 00:00:00 2001
From: Michael Davidsaver
Date: Wed, 23 Jan 2013 10:38:30 -0500
Subject: [PATCH 1/5] get_array_info() can modifiy DBADDR::pfield
Allow the record support function get_array_info()
to modify its first argument to provide a different
pointer from which values should be read.
Remember the original and restore it afterwards.
---
src/ioc/db/dbAccess.c | 13 ++++++++++++-
src/std/filters/arr.c | 5 ++++-
2 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/src/ioc/db/dbAccess.c b/src/ioc/db/dbAccess.c
index 82aa18c11..c4661d9e1 100644
--- a/src/ioc/db/dbAccess.c
+++ b/src/ioc/db/dbAccess.c
@@ -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;
}
diff --git a/src/std/filters/arr.c b/src/std/filters/arr.c
index 201118d24..f2f5f82f1 100644
--- a/src/std/filters/arr.c
+++ b/src/std/filters/arr.c
@@ -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 */
From 92d52cc415599b7dffa7df1f23d5ba8227fb4d3a Mon Sep 17 00:00:00 2001
From: Michael Davidsaver
Date: Wed, 23 Jan 2013 10:38:31 -0500
Subject: [PATCH 2/5] Allow waveformRecord to replace BPTR
---
src/std/rec/waveformRecord.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/std/rec/waveformRecord.c b/src/std/rec/waveformRecord.c
index 76e06a681..513f61029 100644
--- a/src/std/rec/waveformRecord.c
+++ b/src/std/rec/waveformRecord.c
@@ -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, (void*)&prec->val, monitor_mask);
}
}
From 1b0ff46d336d821a83acde946e6dd3202401dcff Mon Sep 17 00:00:00 2001
From: Michael Davidsaver
Date: Wed, 23 Jan 2013 10:38:32 -0500
Subject: [PATCH 3/5] Allow BPTR replacement in aai and aao
---
src/std/rec/aaiRecord.c | 4 ++--
src/std/rec/aaoRecord.c | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/std/rec/aaiRecord.c b/src/std/rec/aaiRecord.c
index 428916de9..36ab25e3b 100644
--- a/src/std/rec/aaiRecord.c
+++ b/src/std/rec/aaiRecord.c
@@ -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, (void*)&prec->val, monitor_mask);
}
static long readValue(aaiRecord *prec)
diff --git a/src/std/rec/aaoRecord.c b/src/std/rec/aaoRecord.c
index 46c837310..51c432ae7 100644
--- a/src/std/rec/aaoRecord.c
+++ b/src/std/rec/aaoRecord.c
@@ -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, (void*)&prec->val, monitor_mask);
}
static long writeValue(aaoRecord *prec)
From 738c135ed82042676438f37980c196ffa2a5dac9 Mon Sep 17 00:00:00 2001
From: Michael Davidsaver
Date: Tue, 2 Apr 2013 17:07:53 -0400
Subject: [PATCH 4/5] Don't need void* cast
Implicit case from void** to void*
is allowed.
---
src/std/rec/aaiRecord.c | 2 +-
src/std/rec/aaoRecord.c | 2 +-
src/std/rec/waveformRecord.c | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/std/rec/aaiRecord.c b/src/std/rec/aaiRecord.c
index 36ab25e3b..96e0960ce 100644
--- a/src/std/rec/aaiRecord.c
+++ b/src/std/rec/aaiRecord.c
@@ -308,7 +308,7 @@ static void monitor(aaiRecord *prec)
}
if (monitor_mask)
- db_post_events(prec, (void*)&prec->val, monitor_mask);
+ db_post_events(prec, &prec->val, monitor_mask);
}
static long readValue(aaiRecord *prec)
diff --git a/src/std/rec/aaoRecord.c b/src/std/rec/aaoRecord.c
index 51c432ae7..ca26aac52 100644
--- a/src/std/rec/aaoRecord.c
+++ b/src/std/rec/aaoRecord.c
@@ -308,7 +308,7 @@ static void monitor(aaoRecord *prec)
}
if (monitor_mask)
- db_post_events(prec, (void*)&prec->val, monitor_mask);
+ db_post_events(prec, &prec->val, monitor_mask);
}
static long writeValue(aaoRecord *prec)
diff --git a/src/std/rec/waveformRecord.c b/src/std/rec/waveformRecord.c
index 513f61029..0818fa983 100644
--- a/src/std/rec/waveformRecord.c
+++ b/src/std/rec/waveformRecord.c
@@ -300,7 +300,7 @@ static void monitor(waveformRecord *prec)
}
if (monitor_mask) {
- db_post_events(prec, (void*)&prec->val, monitor_mask);
+ db_post_events(prec, &prec->val, monitor_mask);
}
}
From fb21c7c6e7edb2c4b9ef6caafd0a44523d235b89 Mon Sep 17 00:00:00 2001
From: Michael Davidsaver
Date: Tue, 2 Apr 2013 17:07:54 -0400
Subject: [PATCH 5/5] update release notes
---
documentation/RELEASE_NOTES.html | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html
index fd3dc4673..37167cf63 100644
--- a/documentation/RELEASE_NOTES.html
+++ b/documentation/RELEASE_NOTES.html
@@ -15,6 +15,22 @@ EPICS Base 3.15.0.x releases are not intended for use in production systems.
Changes between 3.15.0.1 and 3.15.0.2
+Array field memory mangement
+
+This allows array data to be moved, without copying, into and out of the
+value (aka BPTR) field of the waveform, aai, and aao types.
+
+Making use of this feature involves replacing the pointer stored in the BPTR
+field with another (user allocated) pointer. The basic rules are:
+
+
+ - BPTR, and the memory it is currently pointing to, can only be accessed
+ while the record is locked.
+ - NELM may not be changed.
+ - BPTR must always point to a piece of memory large enough to accommodate
+ the maximum number of elements (as given by the NELM field).
+
+
mbboDirect and mbbiDirect records
These record types have undergone some significant rework, and will behave