MIDAS
Loading...
Searching...
No Matches
fetest.cxx
Go to the documentation of this file.
1/*******************************************************************\
2
3 Name: fetest.cxx
4 Created by: K.Olchanski
5
6 Contents: Front end for testing MIDAS
7
8\********************************************************************/
9
10#undef NDEBUG // midas required assert() to be always enabled
11
12#include <stdio.h>
13#include <signal.h> // SIGPIPE
14#include <assert.h> // assert()
15#include <stdlib.h> // malloc()
16#include <math.h> // M_PI
17
18#include "midas.h"
19#include "tmfe.h"
20
21#include <string> // std::string
22#include <thread> // std::thread
23#include <atomic> // atd::atomic
24
25class EqRandom :
26 public TMFeEquipment
27{
28public:
29 EqRandom(const char* eqname, const char* eqfilename) // ctor
31 {
37 }
38
39 TMFeResult HandleInit(const std::vector<std::string>& args)
40 {
44 return TMFeOk();
45 }
46
48 {
49 char event[fEqConfMaxEventSize];
50
52
53 char* pbh = event + sizeof(EVENT_HEADER);
54
55 double r = drand48();
56 if (r < 0.3)
57 bk_init(pbh);
58 else if (r < 0.6)
60 else
62
63 int nbank = 0+9*drand48(); // nbank range: 0..9, see how bank names are generated: RND0..RND9
64
65 for (int i=0; i<nbank; i++) {
66 int tid = 1+(TID_LAST-1)*drand48();
67 int size = 0+100*drand48();
68
69 //int total = bk_size(pbh);
70 //printf("total %d, add %d, max %d\n", total, size, (int)fMaxEventSize);
71
72 char name[5];
73 name[0] = 'R';
74 name[1] = 'N';
75 name[2] = 'D';
76 name[3] = '0' + (nbank-i-1);
77 name[4] = 0;
78
79 char* ptr;
80 bk_create(pbh, name, tid, (void**)&ptr);
81
82 for (int j=0; j<size; j++)
83 ptr[j] = (nbank-i-1);
84
85 bk_close(pbh, ptr + size);
86 }
87
88 //printf("sending %d, max %d\n", (int)bk_size(pbh), (int)fMaxEventSize);
89
90 EqSendEvent(event);
91 }
92
93#if 0
94 { "random" , /* equipment name */
95 {
96 EVID_RANDOM, (1<<EVID_RANDOM), /* event ID, trigger mask */
97 "SYSTEM", /* event buffer */
98 EQ_PERIODIC, /* equipment type */
99 0, /* event source */
100 "MIDAS", /* format */
101 TRUE, /* enabled */
102 RO_RUNNING, /* Read when running */
103 100, /* poll every so milliseconds */
104 0, /* stop run after this event limit */
105 0, /* number of sub events */
106 0, /* history period */
107 "", "", ""
108 },
109 read_random_event,/* readout routine */
110 },
111#endif
112
113};
114
115class EqSlow :
116 public TMFeEquipment
117{
118public:
119 EqSlow(const char* eqname, const char* eqfilename) // ctor
121 {
122 fEqConfEventID = 3;
126 }
127
128 TMFeResult HandleInit(const std::vector<std::string>& args)
129 {
132 //fEqConfLogHistory = 1;
133 return TMFeOk();
134 }
135
136 void SendData(double dvalue)
137 {
138 char buf[1024];
139 ComposeEvent(buf, sizeof(buf));
140 BkInit(buf, sizeof(buf));
141
142 double* ptr = (double*)BkOpen(buf, "data", TID_DOUBLE);
143 *ptr++ = dvalue;
144 BkClose(buf, ptr);
145
146 EqSendEvent(buf);
147 }
148
149//#define TEST_PERIOD 1
150
151#ifdef TEST_PERIOD
152 double first = 0;
153 double prev = 0;
154 int count = 0;
155#endif
156
158 {
159#ifdef TEST_PERIOD
160 double now = TMFE::GetTime();
161 if (first == 0)
162 first = now;
163 double elapsed = now - prev;
164 double expected = first + count*fEqConfPeriodMilliSec/1000.0;
165 printf("count %d, periodic %f, expected %f, diff %f, elapsed %f\n", count, now, expected, now-expected, elapsed);
166 prev = now;
167 count++;
168
169 //TMFE::Sleep(2);
170#endif
171
172 //printf("EqSlow::HandlePeriodic!\n");
173 double t = TMFE::GetTime();
174 double data = 100.0*sin(-M_PI/2.0+M_PI*t/60);
175 SendData(data);
176 char status_buf[256];
177 sprintf(status_buf, "value %.1f", data);
178 EqSetStatus(status_buf, "#00FF00");
179 }
180
181#if 0
182 { "slow" , /* equipment name */
183 {
184 EVID_SLOW, (1<<EVID_SLOW), /* event ID, trigger mask */
185 "SYSTEM", /* event buffer */
186 EQ_PERIODIC, /* equipment type */
187 0, /* event source */
188 "MIDAS", /* format */
189 TRUE, /* enabled */
190 RO_ALWAYS, /* Read when running */
191 1000, /* poll every so milliseconds */
192 0, /* stop run after this event limit */
193 0, /* number of sub events */
194 1, /* history period */
195 "", "", ""
196 },
197 read_slow_event,/* readout routine */
198 },
199#endif
200};
201
202class EqRare :
203 public TMFeEquipment
204{
205public:
206 EqRare(const char* eqname, const char* eqfilename) // ctor
208 {
209 fEqConfEventID = 4;
210 fEqConfPeriodMilliSec = 10000;
214 }
215
216 TMFeResult HandleInit(const std::vector<std::string>& args)
217 {
218 return TMFeOk();
219 }
220
221 void SendData(double dvalue)
222 {
223 char buf[1024];
224 ComposeEvent(buf, sizeof(buf));
225 BkInit(buf, sizeof(buf));
226
227 double* ptr = (double*)BkOpen(buf, "rare", TID_DOUBLE);
228 *ptr++ = dvalue;
229 BkClose(buf, ptr);
230
231 EqSendEvent(buf);
232 }
233
235 {
236 //printf("EqSlow::HandlePeriodic!\n");
237 double t = TMFE::GetTime();
238 double data = 100.0*sin(-M_PI/2.0+M_PI*t/60);
239 SendData(data);
240 char status_buf[256];
241 sprintf(status_buf, "value %.1f", data);
242 EqSetStatus(status_buf, "#00FF00");
243 }
244};
245
246class EqBulk :
247 public TMFeEquipment
248{
249public: // configuration
250 int fEventSize = 0;
251 double fEventSleep = 1.0;
252 std::vector<char> fEventBuffer;
253
254public: // internal state
255 std::atomic_bool fThreadRunning{false};
256 std::thread *fThread = NULL;
257
258public:
259 EqBulk(const char* eqname, const char* eqfilename) // ctor
261 {
263 fEqConfEventID = 3;
265 }
266
267 ~EqBulk() // dtor
268 {
269 // wait for thread to finish
270 while (fThreadRunning) {
271 fMfe->Sleep(0.1);
272 }
273
274 if (fThread) {
275 fThread->join();
276 delete fThread;
277 fThread = NULL;
278 }
279 }
280
281 TMFeResult HandleInit(const std::vector<std::string>& args)
282 {
283 EqSetStatus("Starting...", "white");
284
287
288 fOdbEqSettings->RI("event_size", &fEventSize, true);
289 fOdbEqSettings->RD("event_sleep_sec", &fEventSleep, true);
290
291 printf("Event size set to %d bytes\n", fEventSize);
292
293 fEventBuffer.resize(16+8+16+fEventSize+100);
294
295 //size = sizeof(test_rb_wait_sleep);
296 //status = db_get_value(hDB, hSet, "rb_wait_sleep", &test_rb_wait_sleep, &size, TID_DWORD, TRUE);
297 //assert(status == DB_SUCCESS);
298 //printf("Ring buffer wait sleep %d ms\n", test_rb_wait_sleep);
299
300 fThread = new std::thread(&EqBulk::Thread, this);
301
302 return TMFeOk();
303 }
304
306 {
307 char* buf = fEventBuffer.data();
308 size_t bufsize = fEventBuffer.size();
309 ComposeEvent(buf, bufsize);
310 BkInit(buf, bufsize);
311
312 char* ptr = (char*)BkOpen(buf, "bulk", TID_BYTE);
313 ptr += fEventSize;
314 BkClose(buf, ptr);
315
316 EqSendEvent(buf);
317 }
318
319 void Thread()
320 {
321 printf("FeBulk::Thread: thread started\n");
322
323 EqSetStatus("Thread running", "#00FF00");
324
325 fThreadRunning = true;
326 while (!fMfe->fShutdownRequested) {
329 SendEvent();
330 } else {
331 fMfe->Sleep(1.0);
332 }
333 }
334
335 printf("FeBulk::Thread: thread finished\n");
336 fThreadRunning = false;
337 }
338
339#if 0
340 EQUIPMENT equipment[] = {
341
342 { "test" , /* equipment name */
343 {
344 EVID_TEST, (1<<EVID_TEST), /* event ID, trigger mask */
345 "SYSTEM", /* event buffer */
346 EQ_USER, /* equipment type */
347 0, /* event source */
348 "MIDAS", /* format */
349 TRUE, /* enabled */
350 RO_RUNNING, /* Read when running */
351 100, /* poll every so milliseconds */
352 0, /* stop run after this event limit */
353 0, /* number of sub events */
354 0, /* no history */
355 "", "", ""
356 },
357 read_test_event,/* readout routine */
358 },
359 { "" }
360};
361#endif
362};
363
364class EqRpc :
365 public TMFeEquipment
366{
367public:
368 EqRpc(const char* eqname, const char* eqfilename) // ctor
370 {
371 fEqConfEventID = 1;
372 }
373
374 ~EqRpc() // dtor
375 {
376 }
377
378 TMFeResult HandleInit(const std::vector<std::string>& args)
379 {
380 fEqConfBuffer = "SYSTEM";
381 EqSetStatus("Started...", "white");
382 fMfe->Msg(MINFO, "HandleInit", std::string("Init") + " Ok!");
383 return TMFeOk();
384 }
385
386 TMFeResult HandleRpc(const char* cmd, const char* args, std::string& response)
387 {
388 fMfe->Msg(MINFO, "HandleRpc", "RPC cmd [%s], args [%s]", cmd, args);
389
390 // RPC handler
391
392 char tmp[256];
393 time_t now = time(NULL);
394 sprintf(tmp, "{ \"current_time\" : [ %d, \"%s\"] }", (int)now, ctime(&now));
395
396 response = tmp;
397
398 return TMFeOk();
399 }
400
401 TMFeResult HandleBinaryRpc(const char* cmd, const char* args, std::vector<char>& response)
402 {
403 fMfe->Msg(MINFO, "HandleBinaryRpc", "RPC cmd [%s], args [%s]", cmd, args);
404
405 // RPC handler
406
407 response.resize(8*64);
408
409 uint64_t* p64 = (uint64_t*)response.data();
410
411 for (size_t i=0; i<response.size()/sizeof(p64[0]); i++) {
412 *p64++ = (1<<i);
413 }
414
415 return TMFeOk();
416 }
417
419 {
420 fMfe->Msg(MINFO, "HandleBeginRun", "Begin run %d!", run_number);
421 EqSetStatus("Running", "#00FF00");
422
423 printf("begin_of_run %d\n", run_number);
424
425 int fail = 0;
426 fOdbEqSettings->RI("begin_of_run_fail", &fail, true);
427
428 if (fail) {
429 printf("fail_begin_of_run: returning error status %d\n", fail);
430 return TMFeErrorMessage("begin of run failed by ODB setting!");
431 }
432
433 double s = 0;
434 fOdbEqSettings->RD("begin_of_run_sleep_sec", &s, true);
435
436 if (s) {
437 fMfe->SetWatchdogSec(s + 1);
438 int ms = int(s*1000.0);
439 printf("sleep_begin_of_run: calling ss_sleep(%d)\n", ms);
440 ss_sleep(ms);
441 }
442
443 return TMFeOk();
444 }
445
447 {
448 fMfe->Msg(MINFO, "HandleEndRun", "End run %d!", run_number);
449 EqSetStatus("Stopped", "#00FF00");
450
451 printf("end_of_run %d\n", run_number);
452
453 int fail = 0;
454 fOdbEqSettings->RI("end_of_run_fail", &fail, true);
455
456 if (fail) {
457 printf("fail_end_of_run: returning error status %d\n", fail);
458 return TMFeResult(fail, "end of run failed by ODB setting!");
459 }
460
461 double s = 0;
462 fOdbEqSettings->RD("end_of_run_sleep_sec", &s, true);
463
464 if (s) {
465 fMfe->SetWatchdogSec(s + 1);
466 int ms = int(s*1000.0);
467 printf("sleep_end_of_run: calling ss_sleep(%d)\n", ms);
468 ss_sleep(ms);
469 }
470
471 return TMFeOk();
472 }
473
475 {
476 fMfe->Msg(MINFO, "HandlePauseRun", "Pause run %d!", run_number);
477 EqSetStatus("Stopped", "#00FF00");
478
479 printf("pause_run %d\n", run_number);
480
481 int fail = 0;
482 fOdbEqSettings->RI("pause_run_fail", &fail, true);
483
484 if (fail) {
485 printf("fail_pause_run: returning error status %d\n", fail);
486 return TMFeResult(fail, "pause run failed by ODB setting!");
487 }
488
489 return TMFeOk();
490 }
491
493 {
494 fMfe->Msg(MINFO, "HandleResumeRun", "Resume run %d!", run_number);
495 EqSetStatus("Stopped", "#00FF00");
496
497 printf("resume_run %d\n", run_number);
498
499 int fail = 0;
500 fOdbEqSettings->RI("resume_run_fail", &fail, true);
501
502 if (fail) {
503 printf("fail_resume_run: returning error status %d\n", fail);
504 return TMFeResult(fail, "resume run failed by ODB setting!");
505 }
506
507 return TMFeOk();
508 }
509
511 {
512 fMfe->Msg(MINFO, "HandleStartAbortRun", "Begin run %d aborted!", run_number);
513 EqSetStatus("Stopped", "#00FF00");
514
515 printf("start abort run %d\n", run_number);
516
517 int fail = 0;
518 fOdbEqSettings->RI("start_abort_fail", &fail, true);
519
520 if (fail) {
521 printf("fail_start_abort: returning error status %d\n", fail);
522 return TMFeResult(fail, "start abort failed by ODB setting!");
523 }
524
525 return TMFeOk();
526 }
527};
528
529class FeTest: public TMFrontend
530{
531public:
532 FeTest() // ctor
533 {
534 FeSetName("fetest");
535 FeAddEquipment(new EqRpc("test_rpc", __FILE__));
536 FeAddEquipment(new EqRandom("test_random", __FILE__));
537 FeAddEquipment(new EqSlow("test_slow", __FILE__));
538 FeAddEquipment(new EqRare("test_rare", __FILE__));
539 FeAddEquipment(new EqBulk("test_bulk", __FILE__));
540 }
541
543 {
544 //printf("FeEverything::HandleUsage!\n");
545 };
546
547 TMFeResult HandleArguments(const std::vector<std::string>& args)
548 {
549 //printf("FeEverything::HandleArguments!\n");
550 return TMFeOk();
551 };
552
553 TMFeResult HandleFrontendInit(const std::vector<std::string>& args)
554 {
555 //printf("FeEverything::HandleFrontendInit!\n");
556 return TMFeOk();
557 };
558
559 TMFeResult HandleFrontendReady(const std::vector<std::string>& args)
560 {
561 //printf("FeEverything::HandleFrontendReady!\n");
562 //FeStartPeriodicThread();
563 //fMfe->StartRpcThread();
564 return TMFeOk();
565 };
566
568 {
569 //printf("FeEverything::HandleFrontendExit!\n");
570 };
571};
572
573// boilerplate main function
574
575int main(int argc, char* argv[])
576{
578 return fe_test.FeMain(argc, argv);
579}
580
581/* emacs
582 * Local Variables:
583 * tab-width: 8
584 * c-basic-offset: 3
585 * indent-tabs-mode: nil
586 * End:
587 */
~EqBulk()
Definition fetest.cxx:267
EqBulk(const char *eqname, const char *eqfilename)
Definition fetest.cxx:259
std::vector< char > fEventBuffer
Definition fetest.cxx:252
void SendEvent()
Definition fetest.cxx:305
std::atomic_bool fThreadRunning
Definition fetest.cxx:255
void Thread()
Definition fetest.cxx:319
std::thread * fThread
Definition fetest.cxx:256
int fEventSize
Definition fetest.cxx:250
double fEventSleep
Definition fetest.cxx:251
TMFeResult HandleInit(const std::vector< std::string > &args)
Definition fetest.cxx:281
void HandlePeriodic()
Definition fetest.cxx:47
EqRandom(const char *eqname, const char *eqfilename)
Definition fetest.cxx:29
TMFeResult HandleInit(const std::vector< std::string > &args)
Definition fetest.cxx:39
void SendData(double dvalue)
Definition fetest.cxx:221
void HandlePeriodic()
Definition fetest.cxx:234
EqRare(const char *eqname, const char *eqfilename)
Definition fetest.cxx:206
TMFeResult HandleInit(const std::vector< std::string > &args)
Definition fetest.cxx:216
TMFeResult HandleInit(const std::vector< std::string > &args)
Definition fetest.cxx:378
~EqRpc()
Definition fetest.cxx:374
TMFeResult HandleResumeRun(int run_number)
Definition fetest.cxx:492
TMFeResult HandleEndRun(int run_number)
Definition fetest.cxx:446
TMFeResult HandleBinaryRpc(const char *cmd, const char *args, std::vector< char > &response)
Definition fetest.cxx:401
TMFeResult HandleBeginRun(int run_number)
Definition fetest.cxx:418
EqRpc(const char *eqname, const char *eqfilename)
Definition fetest.cxx:368
TMFeResult HandlePauseRun(int run_number)
Definition fetest.cxx:474
TMFeResult HandleRpc(const char *cmd, const char *args, std::string &response)
Definition fetest.cxx:386
TMFeResult HandleStartAbortRun(int run_number)
Definition fetest.cxx:510
EqSlow(const char *eqname, const char *eqfilename)
Definition fetest.cxx:119
void HandlePeriodic()
Definition fetest.cxx:157
TMFeResult HandleInit(const std::vector< std::string > &args)
Definition fetest.cxx:128
void SendData(double dvalue)
Definition fetest.cxx:136
TMFeResult HandleFrontendReady(const std::vector< std::string > &args)
Definition fetest.cxx:559
TMFeResult HandleFrontendInit(const std::vector< std::string > &args)
Definition fetest.cxx:553
void HandleFrontendExit()
Definition fetest.cxx:567
FeTest()
Definition fetest.cxx:532
TMFeResult HandleArguments(const std::vector< std::string > &args)
Definition fetest.cxx:547
void HandleUsage()
Definition fetest.cxx:542
bool fStateRunning
run state is running or paused
Definition tmfe.h:402
static double GetTime()
return current time in seconds, with micro-second precision
Definition tmfe.cxx:1011
void Msg(int message_type, const char *filename, int line, const char *routine, const char *format,...) MATTRPRINTF(6
Definition tmfe.cxx:991
static void Sleep(double sleep_time_sec)
sleep, with micro-second precision
Definition tmfe.cxx:1019
std::atomic_bool fShutdownRequested
shutdown was requested by Ctrl-C or by RPC command
Definition tmfe.h:398
TMFeResult SetWatchdogSec(int sec)
Definition tmfe.cxx:144
void * BkOpen(char *pevent, const char *bank_name, int bank_type) const
Definition tmfe.cxx:2201
TMFeResult BkInit(char *pevent, size_t size) const
Definition tmfe.cxx:2195
MVOdb * fOdbEqSettings
ODB Equipment/EQNAME/Settings.
Definition tmfe.h:213
TMFE * fMfe
Definition tmfe.h:207
TMFeResult EqSetStatus(const char *status, const char *color)
Definition tmfe.cxx:2215
bool fEqConfWriteEventsToOdb
Definition tmfe.h:197
uint16_t fEqConfEventID
Definition tmfe.h:171
int fEqConfPeriodMilliSec
Definition tmfe.h:178
TMFeResult BkClose(char *pevent, void *ptr) const
Definition tmfe.cxx:2208
int fEqConfLogHistory
Definition tmfe.h:181
TMFeResult ComposeEvent(char *pevent, size_t size) const
Definition tmfe.cxx:1995
TMFeResult EqSendEvent(const char *pevent, bool write_to_odb=true)
Definition tmfe.cxx:2006
std::string fEqConfBuffer
Definition tmfe.h:173
size_t fEqConfMaxEventSize
Definition tmfe.h:200
bool fEqConfReadOnlyWhenRunning
Definition tmfe.h:196
void FeSetName(const char *program_name)
Definition tmfe.cxx:1647
TMFeResult FeAddEquipment(TMFeEquipment *eq)
Definition tmfe.cxx:1600
int FeMain(int argc, char *argv[])
Definition tmfe.cxx:2279
void bk_init32a(void *event)
Definition midas.cxx:16482
INT bk_close(void *event, void *pdata)
Definition midas.cxx:16780
void bk_init(void *event)
Definition midas.cxx:16406
void bk_init32(void *event)
Definition midas.cxx:16469
void bk_create(void *event, const char *name, WORD type, void **pdata)
Definition midas.cxx:16561
#define TID_DOUBLE
Definition midas.h:343
#define EQ_USER
Definition midas.h:422
#define EQ_PERIODIC
Definition midas.h:414
#define MINFO
Definition midas.h:560
#define TID_BYTE
Definition midas.h:327
#define TID_LAST
Definition midas.h:354
#define RO_ALWAYS
Definition midas.h:436
#define RO_RUNNING
Definition midas.h:426
INT ss_sleep(INT millisec)
Definition system.cxx:3628
int read_slow_event(char *pevent, int off)
Definition feslow.cxx:252
int main()
Definition hwtest.cxx:23
INT run_number[2]
Definition mana.cxx:246
void * data
Definition mana.cxx:268
double count
Definition mdump.cxx:33
INT i
Definition mdump.cxx:32
char response[10000]
Definition melog.cxx:90
#define TRUE
Definition midas.h:182
#define name(x)
Definition midas_macro.h:24
#define equipment(name, id, type, source, readon, period, readout, cd, driver)
Definition midas_macro.h:60
#define ctime
Definition msystem.h:264
INT j
Definition odbhist.cxx:40
TH1X EXPRT * h1_book(const char *name, const char *title, int bins, double min, double max)
Definition rmidas.h:24
TMFeResult TMFeErrorMessage(const std::string &message)
Definition tmfe.cxx:29
TMFeResult TMFeOk()
Definition tmfe.h:106