Line data Source code
1 : /********************************************************************\
2 :
3 : Name: mtfe.c
4 : Created by: Stefan Ritt
5 :
6 : Contents: Multi-threaded frontend example.
7 :
8 : $Id: frontend.c 4089 2007-11-27 07:28:17Z ritt@PSI.CH $
9 :
10 : \********************************************************************/
11 :
12 : #include <stdio.h>
13 : #include <stdlib.h>
14 : #include "midas.h"
15 : #include "msystem.h"
16 :
17 : #include "mfe.h"
18 :
19 : /*-- Globals -------------------------------------------------------*/
20 :
21 : /* The frontend name (client name) as seen by other MIDAS clients */
22 : const char *frontend_name = "Sample Frontend";
23 : /* The frontend file name, don't change it */
24 : const char *frontend_file_name = __FILE__;
25 :
26 : /*-- Function declarations -----------------------------------------*/
27 :
28 : INT trigger_thread(void *param);
29 :
30 : /*-- Equipment list ------------------------------------------------*/
31 :
32 : BOOL equipment_common_overwrite = TRUE;
33 :
34 : EQUIPMENT equipment[] = {
35 :
36 : {"Trigger", /* equipment name */
37 : {1, 0, /* event ID, trigger mask */
38 : "SYSTEM", /* event buffer */
39 : EQ_USER, /* equipment type */
40 : 0, /* event source (not used) */
41 : "MIDAS", /* format */
42 : TRUE, /* enabled */
43 : RO_RUNNING, /* read only when running */
44 : 500, /* poll for 500ms */
45 : 0, /* stop run after this event limit */
46 : 0, /* number of sub events */
47 : 0, /* don't log history */
48 : "", "", "",},
49 : NULL, /* readout routine */
50 : },
51 :
52 : {""}
53 : };
54 :
55 : /*-- Frontend Init -------------------------------------------------*/
56 :
57 0 : INT frontend_init()
58 : {
59 : /* for this demo, use three readout threads */
60 0 : for (int i=0 ; i<3 ; i++) {
61 :
62 : /* create a ring buffer for each thread */
63 0 : create_event_rb(i);
64 :
65 : /* create readout thread */
66 0 : ss_thread_create(trigger_thread, (void*)(PTYPE)i);
67 : }
68 :
69 0 : return SUCCESS;
70 : }
71 :
72 : /*-- Event readout -------------------------------------------------*/
73 :
74 0 : INT trigger_thread(void *param)
75 : {
76 : EVENT_HEADER *pevent;
77 : WORD *pdata, *padc;
78 0 : int index, i, status, exit = FALSE;
79 : INT rbh;
80 :
81 : /* index of this thread */
82 0 : index = (int)(PTYPE)param;
83 :
84 : /* tell framework that we are alive */
85 0 : signal_readout_thread_active(index, TRUE);
86 :
87 : /* set name of thread as seen by OS */
88 0 : ss_thread_set_name(std::string(equipment[0].name) + "RT" + std::to_string(index));
89 :
90 : /* Initialize hardware here ... */
91 0 : printf("Start readout thread %d\n", index);
92 :
93 : /* Obtain ring buffer for inter-thread data exchange */
94 0 : rbh = get_event_rbh(index);
95 :
96 0 : while (is_readout_thread_enabled()) {
97 :
98 0 : if (!readout_enabled()) {
99 : // do not produce events when run is stopped
100 0 : ss_sleep(10);
101 0 : continue;
102 : }
103 :
104 : /* check for new event (poll) */
105 0 : status = ss_sleep(100); // for this demo, just sleep a bit
106 :
107 0 : if (status) { // if event available, read it out
108 :
109 : // check once more in case state changed during the poll
110 0 : if (!is_readout_thread_enabled())
111 0 : break;
112 :
113 : // obtain buffer space
114 : do {
115 0 : status = rb_get_wp(rbh, (void **) &pevent, 0);
116 0 : if (status == DB_TIMEOUT) {
117 0 : ss_sleep(10);
118 : // check for readout thread disable, thread might be stop from main thread
119 : // in case Ctrl-C is hit for example
120 0 : if (!is_readout_thread_enabled()) {
121 0 : exit = TRUE;
122 0 : break;
123 : }
124 : }
125 0 : } while (status != DB_SUCCESS);
126 :
127 0 : if (exit)
128 0 : break;
129 :
130 0 : bm_compose_event_threadsafe(pevent, 1, 0, 0, &equipment[0].serial_number);
131 0 : pdata = (WORD *)(pevent + 1);
132 :
133 : /* init bank structure */
134 0 : bk_init32(pdata);
135 :
136 : /* create ADC0 bank */
137 0 : bk_create(pdata, "ADC0", TID_WORD, (void **)&padc);
138 :
139 : /* just put in some random numbers in this demo */
140 0 : int len = 32 + rand() % 10000;
141 0 : for (i=0 ; i<len; i++)
142 0 : *padc++ = len;
143 :
144 0 : bk_close(pdata, padc);
145 :
146 0 : pevent->data_size = bk_size(pdata);
147 :
148 : /* send event to ring buffer */
149 0 : rb_increment_wp(rbh, sizeof(EVENT_HEADER) + pevent->data_size);
150 : }
151 : }
152 :
153 : /* tell framework that we are finished */
154 0 : signal_readout_thread_active(index, FALSE);
155 :
156 0 : printf("Stop readout thread %d\n", index);
157 :
158 0 : return 0;
159 : }
|