AlcapDAQ  1
rpc_slave_x.cpp
Go to the documentation of this file.
1 #include <stdio.h>
2 #include <stdlib.h>
3 
4 #include <unistd.h>
5 #include <sys/io.h>
6 #include <sys/time.h>
7 
8 #include "midas.h"
9 
10 #include "crate.h"
11 #include "diag.h"
12 #include "odb_wrapper.h"
13 
14 #include "rpc_mucap.h"
15 
16 INT rpc_end_of_cycle(INT index, void *prpc_param[]);
17 INT rpc_slave_init();
18 INT rpc_slave_bor();
19 INT rpc_slave_eor();
23 INT rpc_slave_read(char *pevent);
24 
26 
27 static HNDLE rpc_conn_master_crate;
28 static BOOL enable_rpc_slave;
29 
30 static BOOL event_ended = FALSE;
31 static INT last_cycle = 0;
32 static INT last_event_number = 0;
33 static INT sent_stop_request = -1;
34 
36  rpc_slave_init, // init
37  NULL, // exit
38  NULL, // pre_bor
39  rpc_slave_bor, // bor
40  rpc_slave_eor, // eor
41  rpc_slave_poll_live, // poll_live
42  rpc_slave_poll_dead, // poll_dead
43  NULL, // start_block
44  rpc_slave_stop_block, // stop_block
45  rpc_slave_read, // read
46 };
47 
48 <<<<<<< rpc_slave.cpp
49 /* ********************************************************************* */
50 INT rpc_end_of_cycle(INT index, void *prpc_param[])
51 {
52  INT cycle_number = CINT(0);
53  INT event_number = CINT(1);
54 
55  diag_print(2, "Cycle ended: RAM %d, event %d\n", cycle_number, event_number);
56 
57  // first send out "fake" zero-length events for those cycles
58  // where we didn't participate
59  for(INT fake_evnum=last_event_number+1; fake_evnum < event_number;
60  fake_evnum++)
61  {
62  diag_print(2, "Sending fake catch-up event for %d\n", fake_evnum);
63  char fake_event[sizeof(EVENT_HEADER) + sizeof(BANK_HEADER)];
64  char *pevent = fake_event + sizeof(EVENT_HEADER);
65 
66  rpc_flush_event();
67  bk_init32(pevent);
68  bm_compose_event((EVENT_HEADER *) fake_event, 4, 0,
69  bk_size(pevent), fake_evnum);
70  bm_send_event(equipment[0].buffer_handle, fake_event,
71  sizeof(fake_event), SYNC);
72  bm_flush_cache(equipment[0].buffer_handle, SYNC);
73  }
74 
75  event_ended = true;
76  last_cycle = cycle_number;
78 
79  return SUCCESS;
80 }
81 
82 /* ********************************************************************* */
83 =======
84 /* ********************************************************************* */
85 INT rpc_end_of_cycle(INT index, void *prpc_param[])
86 {
87  INT cycle_number = CINT(0);
88  INT event_number = CINT(1);
89 
90  diag_print(2, "Cycle ended: RAM %d, event %d\n", cycle_number, event_number);
91 
92  // first send out "fake" zero-length events for those cycles
93  // where we didn't participate
94  for(INT fake_evnum=last_event_number+1; fake_evnum < event_number;
95  fake_evnum++)
96  {
97  diag_print(2, "Sending fake catch-up event for %d\n", fake_evnum);
98  char fake_event[sizeof(EVENT_HEADER) + sizeof(BANK_HEADER)];
99  char *pevent = fake_event + sizeof(EVENT_HEADER);
100 
101  rpc_flush_event();
102  bk_init32(pevent);
103  bm_compose_event((EVENT_HEADER *) fake_event, equipment[0].info.event_id, 0,
104  bk_size(pevent), fake_evnum);
105  bm_send_event(equipment[0].buffer_handle, fake_event,
106  sizeof(fake_event), SYNC);
107  bm_flush_cache(equipment[0].buffer_handle, SYNC);
108  }
109 
110  event_ended = true;
111  last_cycle = cycle_number;
113 
114  return SUCCESS;
115 }
116 
117 /* ********************************************************************* */
118 >>>>>>> 1.4
119 INT rpc_slave_init()
120 {
121  // register the RPC function that we provide
122  rpc_register_functions(rpc_list_mucap, NULL);
123  rpc_register_function(RPC_END_OF_CYCLE, rpc_end_of_cycle);
124 
125  return SUCCESS;
126 }
127 
128 /* ********************************************************************* */
129 INT rpc_slave_bor()
130 {
131  event_ended = FALSE;
132  last_event_number = 0;
133  sent_stop_request = -1;
134  last_cycle = 0;
135 
136  // find the master crate
137  int master_crate = -1;
138  for(int i = 0; i < MAX_CRATES; i++) {
139  if(odb_find_key("/Equipment/Crate %d", i) != NULL) {
140  BOOL master = odb_get_bool("/Equipment/Crate %d/Settings/Master", i);
141  if(master) master_crate = i;
142  }
143  }
144 
145  // maybe we're the master...in that case, disable slave function
146  if(master_crate == crate_number) {
148  diag_print(1, "Disabling RPC slave function\n");
149  return SUCCESS;
150  } else {
152  diag_print(1, "Enabling RPC slave function\n");
153  }
154 
155  // return error if unable to find the master crate
156  if(master_crate < 0) {
157  diag_print(0, "Unable to locate master crate\n");
158  return FE_ERR_HW;
159  }
160  diag_print(1, "Found master crate %d\n", master_crate);
161 
162  // establish RPC connections to the master crate
163  char master_crate_label[10];
164  sprintf(master_crate_label, "Crate %d", master_crate);
165 
166  cm_connect_client(master_crate_label, &rpc_conn_master_crate);
167  rpc_set_option(rpc_conn_master_crate, RPC_OTRANSPORT, RPC_FTCP);
168  rpc_set_option(rpc_conn_master_crate, RPC_NODELAY, TRUE);
169 
171 
172  return SUCCESS;
173 }
174 
175 /* ********************************************************************* */
176 INT rpc_slave_eor()
177 {
178  if(enable_rpc_slave) {
179  cm_disconnect_client(rpc_conn_master_crate, 0);
180  }
181  return SUCCESS;
182 }
183 
184 /* ********************************************************************* */
186 {
187  if(!enable_rpc_slave) {
188  return SUCCESS;
189  }
190 
191  // Yield to receive any pending RPCs
192  cm_yield(0);
193 
194  // Have we received an end-of-event notice?
195  if(event_ended) {
196  event_ended = FALSE;
197  diag_print(2, "event ended\n");
198  return FE_END_BLOCK;
199  } else {
200  return SUCCESS;
201  }
202 }
203 
204 /* ********************************************************************* */
206 {
207  if(!enable_rpc_slave) {
208  return SUCCESS;
209  }
210 
211  return FE_NEED_START;
212 }
213 
214 /* ********************************************************************* */
216 {
217  if(!enable_rpc_slave) {
218  return SUCCESS;
219  }
220 
221  int event_number = last_event_number + 1;
222 
223  // Send a request to the master crate for the block to end.
224  if(sent_stop_request < event_number) {
226  event_number);
228  }
229 
230  return SUCCESS;
231 }
232 
233 /* ********************************************************************* */
234 INT rpc_slave_read(char *pevent)
235 {
236  if(!enable_rpc_slave) {
237  return SUCCESS;
238  }
239 
240 <<<<<<< rpc_slave.cpp
242 }
243 =======
244  // Fill in event number
245  (((EVENT_HEADER *)pevent)-1)->serial_number = last_event_number;
246 
247  // Announce that we're ready for the next cycle
248 >>>>>>> 1.4
249 
250 <<<<<<< rpc_slave.cpp
251 /* ********************************************************************* */
253 {
254 =======
256 }
257 
258 /* ********************************************************************* */
260 {
261 >>>>>>> 1.4
262  // Send "ready to go"
263  struct timeval tv1, tv2;
264  gettimeofday(&tv1, NULL);
266  gettimeofday(&tv2, NULL);
267 
268  diag_print(2, "Waited %f microseconds for RPC_READY_FOR_CYCLE.\n",
269  (tv2.tv_sec-tv1.tv_sec)*1e6 + (tv2.tv_usec-tv1.tv_usec));
270 
271  return SUCCESS;
272 }
273 
274 /* ********************************************************************* */