Merge lp:~khkim/epics-base/compression-3.15 into lp:~epics-core/epics-base/3.15

Proposed by Kim, Kukhee
Status: Superseded
Proposed branch: lp:~khkim/epics-base/compression-3.15
Merge into: lp:~epics-core/epics-base/3.15
Diff against target: 261 lines (+110/-9)
8 files modified
src/libCom/iocsh/libComRegister.c (+2/-3)
src/libCom/osi/epicsThread.h (+1/-0)
src/libCom/osi/os/RTEMS/osdThread.c (+7/-0)
src/libCom/osi/os/WIN32/osdThread.c (+11/-0)
src/libCom/osi/os/posix/osdThread.c (+18/-0)
src/libCom/osi/os/vxWorks/osdThread.c (+12/-0)
src/std/rec/compressRecord.c (+48/-6)
src/std/rec/compressRecord.dbd.pod (+11/-0)
To merge this branch: bzr merge lp:~khkim/epics-base/compression-3.15
Reviewer Review Type Date Requested Status
Ralph Lange Needs Fixing
mdavidsaver Approve
Andrew Johnson Pending
Review via email: mp+232653@code.launchpad.net

This proposal has been superseded by a proposal from 2016-01-14.

Description of the change

- Implement LIFO behavior in compress record
- Prepare new field BALG (Buffering Algorithm) to allow to choose FIFO and LIFO

To post a comment you must log in.
12520. By Kim, Kukhee

add epics thread id validate routine and check the thread id to avoid iocshell crash for epicsThreadResume() command

12521. By Kim, Kukhee

add epics thread id validate routine

12522. By Kim, Kukhee

add epics thread id validate routine

12523. By Kim, Kukhee

add epics thread id validate routine - dummy, the validate function need to be complete

Revision history for this message
Kim, Kukhee (khkim) wrote :

Revision 12520 - 12523

Add epics thread id validation routine
Modify epicsThreadGetName to check up if the thread id is valid to avoid crash
Modify epicsThreadResume() command to avoid crash when user inputs an invalid thread id

Revision history for this message
mdavidsaver (mdavidsaver) wrote :

What should be done about switching between FIFO and LIFO at runtime? At present LIFO -> FIFO clears the buffer. FIFO -> LIFO can't clear the buffer, but could zero it. Alternately, make the BALG field read only somehow.

Otherwise this works as I expect.

To save Andrew the trouble, please add to RELEASE_NOTES.html

review: Needs Fixing
12524. By Kim, Kukhee

fill zeros into buffer when BALG is changed to LIFO from FIFO.

Revision history for this message
mdavidsaver (mdavidsaver) wrote :

Zeroing the buffer on reset seems sufficient.

As for epicsThreadValidateId(), it seems reasonable for the current implementation of epicsThreadResume(). IMO epicsThreadResume() is broken by design and should be removed, or epicsThread needs to be reimplemented around it. But this is the subject of another development.

Also, I'm commenting now because I've just noticed that there was activity on this branch. Since launchpad is sparing with email notifications it's a good idea to send a note to core-talk when pushing changes to a branch after a long period of inactivity.

review: Approve
Revision history for this message
Ralph Lange (ralph-lange) wrote :

Should have some tests added, shouldn't it?

review: Needs Fixing
Revision history for this message
Andrew Johnson (anj) wrote :

Results of AJ+MD+RL discussion about this today:
* This should be a 3.16 change (3.16.0.2 maybe), not 3.15.
* Needs Release Notes entry and POD documentation for the new field (AJ?).
* Remove the epicsThreadValidateId() changes, not ready.
* Automated tests would be nice given the complexity of the record, but we will accept the change without them.

Unmerged revisions

12524. By Kim, Kukhee

fill zeros into buffer when BALG is changed to LIFO from FIFO.

12523. By Kim, Kukhee

add epics thread id validate routine - dummy, the validate function need to be complete

12522. By Kim, Kukhee

add epics thread id validate routine

12521. By Kim, Kukhee

add epics thread id validate routine

12520. By Kim, Kukhee

add epics thread id validate routine and check the thread id to avoid iocshell crash for epicsThreadResume() command

12519. By Kim, Kukhee

Implement LIFO behavior in compress record

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/libCom/iocsh/libComRegister.c'
2--- src/libCom/iocsh/libComRegister.c 2014-10-31 17:19:09 +0000
3+++ src/libCom/iocsh/libComRegister.c 2015-07-09 21:24:24 +0000
4@@ -328,9 +328,8 @@
5 }
6 else {
7 tid =(epicsThreadId)ltmp;
8- epicsThreadGetName(tid, nameBuf, sizeof nameBuf);
9- if (nameBuf[0] == '\0') {
10- fprintf(stderr, "'%s' is not a valid thread id\n", cp);
11+ if(!epicsThreadValidateId(tid)) {
12+ fprintf(stderr, "%s' is not a valid thread id\n", cp);
13 continue;
14 }
15
16
17=== modified file 'src/libCom/osi/epicsThread.h'
18--- src/libCom/osi/epicsThread.h 2014-08-25 21:27:18 +0000
19+++ src/libCom/osi/epicsThread.h 2015-07-09 21:24:24 +0000
20@@ -94,6 +94,7 @@
21 /* Failure results in an empty string stored in name */
22 epicsShareFunc void epicsShareAPI epicsThreadGetName(
23 epicsThreadId id, char *name, size_t size);
24+epicsShareFunc epicsThreadId epicsShareAPI epicsThreadValidateId(const epicsThreadId id);
25
26 epicsShareFunc int epicsShareAPI epicsThreadIsOkToBlock(void);
27 epicsShareFunc void epicsShareAPI epicsThreadSetOkToBlock(int isOkToBlock);
28
29=== modified file 'src/libCom/osi/os/RTEMS/osdThread.c'
30--- src/libCom/osi/os/RTEMS/osdThread.c 2013-03-28 14:03:29 +0000
31+++ src/libCom/osi/os/RTEMS/osdThread.c 2015-07-09 21:24:24 +0000
32@@ -455,6 +455,13 @@
33 name[size-1] = '\0';
34 }
35
36+
37+/* the thread id validation routine needs to be completed */
38+epicsThreadId epicsThreadValidateId(epicsThreadId id)
39+{
40+ return id;
41+}
42+
43 epicsThreadId epicsThreadGetId (const char *name)
44 {
45 struct taskVar *v;
46
47=== modified file 'src/libCom/osi/os/WIN32/osdThread.c'
48--- src/libCom/osi/os/WIN32/osdThread.c 2014-08-27 00:14:35 +0000
49+++ src/libCom/osi/os/WIN32/osdThread.c 2015-07-09 21:24:24 +0000
50@@ -894,6 +894,12 @@
51 return "anonymous";
52 }
53
54+/* the thread id validation routine need to be completed */
55+epicsShareFunc epicsThreadId epicsShareAPI epicsThreadValidateId(epicsThreadId id)
56+{
57+ return id;
58+}
59+
60 /*
61 * epicsThreadGetName ()
62 */
63@@ -902,6 +908,11 @@
64 {
65 win32ThreadParam * pParm = ( win32ThreadParam * ) id;
66
67+ if(!epicsThreadValidateId(id)) {
68+ pName[0] = '\0';
69+ return;
70+ }
71+
72 if ( size ) {
73 size_t sizeMinusOne = size-1;
74 strncpy ( pName, pParm->pName, sizeMinusOne );
75
76=== modified file 'src/libCom/osi/os/posix/osdThread.c'
77--- src/libCom/osi/os/posix/osdThread.c 2015-03-19 15:22:15 +0000
78+++ src/libCom/osi/os/posix/osdThread.c 2015-07-09 21:24:24 +0000
79@@ -763,9 +763,27 @@
80 epicsShareFunc void epicsShareAPI epicsThreadGetName(epicsThreadId pthreadInfo, char *name, size_t size)
81 {
82 assert(epicsThreadOnceCalled);
83+
84+ if(!epicsThreadValidateId(pthreadInfo)) {
85+ name[0] = '\0';
86+ return;
87+ }
88+
89 strncpy(name, pthreadInfo->name, size-1);
90 name[size-1] = '\0';
91 }
92+
93+epicsShareFunc epicsThreadId epicsShareAPI epicsThreadValidateId(epicsThreadId id)
94+{
95+ epicsThreadOSD *pthreadInfo;
96+
97+ pthreadInfo = (epicsThreadOSD *)ellFirst(&pthreadList);
98+ while(pthreadInfo) {
99+ if(pthreadInfo == (epicsThreadOSD *)id) break;
100+ pthreadInfo = (epicsThreadOSD *) ellNext(&pthreadInfo->node);
101+ }
102+ return(pthreadInfo);
103+}
104
105
106 epicsShareFunc void epicsThreadMap(EPICS_THREAD_HOOK_ROUTINE func)
107 {
108
109=== modified file 'src/libCom/osi/os/vxWorks/osdThread.c'
110--- src/libCom/osi/os/vxWorks/osdThread.c 2014-05-19 14:44:05 +0000
111+++ src/libCom/osi/os/vxWorks/osdThread.c 2015-07-09 21:24:24 +0000
112@@ -327,9 +327,21 @@
113 return taskName(taskIdSelf());
114 }
115
116+/* the thread id validation routine needs to be completed */
117+epicsThreadId epicsThreadValidateId(epicsThreadId id)
118+{
119+ return id;
120+}
121+
122 void epicsThreadGetName (epicsThreadId id, char *name, size_t size)
123 {
124 int tid = (int)id;
125+
126+ if(!epicsThreadValidateId(id)) {
127+ name[0] = '\0';
128+ return;
129+ }
130+
131 strncpy(name,taskName(tid),size-1);
132 name[size-1] = '\0';
133 }
134
135=== modified file 'src/std/rec/compressRecord.c'
136--- src/std/rec/compressRecord.c 2013-12-17 18:54:04 +0000
137+++ src/std/rec/compressRecord.c 2015-07-09 21:24:24 +0000
138@@ -92,6 +92,8 @@
139 if (prec->alg == compressALG_Average && prec->sptr == 0){
140 prec->sptr = calloc(prec->nsam, sizeof(double));
141 }
142+
143+ if(prec->bptr && prec->nsam) memset(prec->bptr, 0, prec->nsam * sizeof(double));
144 }
145
146 static void monitor(compressRecord *prec)
147@@ -106,7 +108,7 @@
148 db_post_events(prec, prec->bptr, monitor_mask);
149 }
150
151-static void put_value(compressRecord *prec, double *psource, int n)
152+static void put_value_FIFO(compressRecord *prec, double *psource, int n)
153 {
154 epicsInt32 offset = prec->off;
155 epicsInt32 nuse = prec->nuse;
156@@ -130,6 +132,42 @@
157 prec->nuse = nuse;
158 return;
159 }
160+
161+static void put_value_LIFO(compressRecord *prec, double *psource, int n)
162+{
163+ epicsInt32 offset = prec->off;
164+ epicsInt32 nuse = prec->nuse;
165+ epicsInt32 nsam = prec->nsam;
166+ epicsInt32 start = offset - nuse;
167+ double *pdest;
168+ int i;
169+ if(start<0) start += nsam;
170+
171+ for(i = 0; i < n; i++) {
172+ if(--start < 0) start += nsam;
173+ pdest = prec->bptr + start;
174+ *pdest = *psource++;
175+ }
176+ nuse += n;
177+ if(nuse > nsam) nuse = nsam;
178+ offset = start + nuse;
179+ if(offset>=nsam) offset -= nsam;
180+
181+ prec->off = offset;
182+ prec->nuse = nuse;
183+
184+ return;
185+}
186+
187+static void put_value(compressRecord *prec, double *psource, int n)
188+{
189+ switch(prec->balg) {
190+ case bufferingALG_FIFO: put_value_FIFO(prec, psource, n); break;
191+ case bufferingALG_LIFO: put_value_LIFO(prec, psource, n); break;
192+ }
193+ return;
194+}
195+
196
197
198 /* qsort comparison function (for median calculation) */
199 static int compare(const void *arg1, const void *arg2)
200@@ -305,6 +343,7 @@
201 prec->bptr = calloc(prec->nsam, sizeof(double));
202 reset(prec);
203 }
204+
205 return 0;
206 }
207
208@@ -388,18 +427,21 @@
209 paddr->field_type = DBF_DOUBLE;
210 paddr->field_size = sizeof(double);
211 paddr->dbr_field_type = DBF_DOUBLE;
212+
213+ if(prec->balg == bufferingALG_LIFO) paddr->special = SPC_NOMOD;
214 return 0;
215 }
216
217 static long get_array_info(DBADDR *paddr, long *no_elements, long *offset)
218 {
219 compressRecord *prec = (compressRecord *) paddr->precord;
220+ epicsInt32 start = prec->off - prec->nuse;
221+ if(start<0) start += prec->nsam;
222+ if(prec->balg == bufferingALG_FIFO)
223+ *no_elements = prec->nuse;
224+ else *no_elements = prec->nsam;
225+ *offset = start;
226
227- *no_elements = prec->nuse;
228- if (prec->nuse == prec->nsam)
229- *offset = prec->off;
230- else
231- *offset = 0;
232 return 0;
233 }
234
235
236=== modified file 'src/std/rec/compressRecord.dbd.pod'
237--- src/std/rec/compressRecord.dbd.pod 2013-09-30 22:48:06 +0000
238+++ src/std/rec/compressRecord.dbd.pod 2015-07-09 21:24:24 +0000
239@@ -41,6 +41,10 @@
240 choice(compressALG_Circular_Buffer,"Circular Buffer")
241 choice(compressALG_N_to_1_Median,"N to 1 Median")
242 }
243+menu(bufferingALG) {
244+ choice(bufferingALG_FIFO, "FIFO Buffer")
245+ choice(bufferingALG_LIFO, "LIFO Buffer")
246+}
247 recordtype(compress) {
248
249 =fields VAL
250@@ -76,6 +80,13 @@
251 interest(1)
252 menu(compressALG)
253 }
254+ field(BALG,DBF_MENU) {
255+ prompt("Buffering Algorithm")
256+ promptgroup(GUI_ALARMS)
257+ special(SPC_RESET)
258+ interest(1)
259+ menu(bufferingALG)
260+ }
261 field(NSAM,DBF_ULONG) {
262 prompt("Number of Values")
263 promptgroup(GUI_COMPRESS)

Subscribers

People subscribed via source and target branches