AlcapDAQ  1
Macros | Functions | Variables
mfe_mucap.c File Reference
#include <stdio.h>
#include <assert.h>
#include "midas.h"
#include "msystem.h"
#include "mcstd.h"

Go to the source code of this file.

Macros

#define SERVER_CACHE_SIZE   100000 /* event cache before buffer */
 
#define ODB_UPDATE_TIME   1000 /* 1 seconds for ODB update */
 
#define DEFAULT_FE_TIMEOUT   60000 /* 60 seconds for watchdog timeout */
 
#define EQUIPMENT_COMMON_STR   "\Event ID = WORD : 0\n\Trigger mask = WORD : 0\n\Buffer = STRING : [32] SYSTEM\n\Type = INT : 0\n\Source = INT : 0\n\Format = STRING : [8] FIXED\n\Enabled = BOOL : 0\n\Read on = INT : 0\n\Period = INT : 0\n\Event limit = DOUBLE : 0\n\Num subevents = DWORD : 0\n\Log history = INT : 0\n\Frontend host = STRING : [32] \n\Frontend name = STRING : [32] \n\Frontend file name = STRING : [256] \n\"
 
#define EQUIPMENT_STATISTICS_STR   "\Events sent = DOUBLE : 0\n\Events per sec. = DOUBLE : 0\n\kBytes per sec. = DOUBLE : 0\n\"
 

Functions

INT frontend_init (void)
 
INT frontend_exit (void)
 
INT frontend_loop (void)
 
INT begin_of_run (INT run_number, char *error)
 
INT end_of_run (INT run_number, char *error)
 
INT pause_run (INT run_number, char *error)
 
INT resume_run (INT run_number, char *error)
 
INT poll_event (INT source, INT count, BOOL test)
 
INT interrupt_configure (INT cmd, INT source, PTYPE adr)
 
int send_event (INT index)
 
void send_all_periodic_events (INT transition)
 
void interrupt_routine (void)
 
void interrupt_enable (BOOL flag)
 
void display (BOOL bInit)
 
INT tr_start (INT rn, char *error)
 
INT tr_stop (INT rn, char *error)
 
INT tr_pause (INT rn, char *error)
 
INT tr_resume (INT rn, char *error)
 
INT manual_trigger (INT index, void *prpc_param[])
 
INT register_equipment (void)
 
void update_odb (EVENT_HEADER *pevent, HNDLE hKey, INT format)
 
int message_print (const char *msg)
 
BOOL logger_root ()
 
INT scheduler (void)
 
INT get_frontend_index ()
 
int main (int argc, char *argv[])
 

Variables

char * frontend_name
 
char * frontend_file_name
 
int crate_number
 
BOOL frontend_call_loop
 
INT max_event_size
 
INT max_event_size_frag
 
INT event_buffer_size
 
INT display_period
 
INT run_state
 
INT run_number
 
DWORD actual_time
 
DWORD actual_millitime
 
char host_name [HOST_NAME_LENGTH]
 
char exp_name [NAME_LENGTH]
 
char full_frontend_name [256]
 
INT max_bytes_per_sec
 
INT optimize = 0
 
INT fe_stop = 0
 
BOOL debug
 
DWORD auto_restart = 0
 
INT manual_trigger_event_id = 0
 
INT frontend_index = -1
 
HNDLE hDB
 
EQUIPMENT equipment []
 
EQUIPMENT * interrupt_eq = NULL
 
EVENT_HEADER * interrupt_odb_buffer
 
BOOL interrupt_odb_buffer_valid
 
BOOL interrupt_enabled
 

Macro Definition Documentation

#define DEFAULT_FE_TIMEOUT   60000 /* 60 seconds for watchdog timeout */

Definition at line 297 of file mfe_mucap.c.

Referenced by main().

#define EQUIPMENT_COMMON_STR   "\Event ID = WORD : 0\n\Trigger mask = WORD : 0\n\Buffer = STRING : [32] SYSTEM\n\Type = INT : 0\n\Source = INT : 0\n\Format = STRING : [8] FIXED\n\Enabled = BOOL : 0\n\Read on = INT : 0\n\Period = INT : 0\n\Event limit = DOUBLE : 0\n\Num subevents = DWORD : 0\n\Log history = INT : 0\n\Frontend host = STRING : [32] \n\Frontend name = STRING : [32] \n\Frontend file name = STRING : [256] \n\"

Definition at line 349 of file mfe_mucap.c.

Referenced by register_equipment().

#define EQUIPMENT_STATISTICS_STR   "\Events sent = DOUBLE : 0\n\Events per sec. = DOUBLE : 0\n\kBytes per sec. = DOUBLE : 0\n\"

Definition at line 367 of file mfe_mucap.c.

Referenced by register_equipment().

#define ODB_UPDATE_TIME   1000 /* 1 seconds for ODB update */

Definition at line 295 of file mfe_mucap.c.

Referenced by scheduler().

#define SERVER_CACHE_SIZE   100000 /* event cache before buffer */

Definition at line 291 of file mfe_mucap.c.

Referenced by register_equipment(), and scheduler().

Function Documentation

INT begin_of_run ( INT  run_number,
char *  error 
)

Definition at line 295 of file crate.cpp.

References readout_module::bor, diag_print(), i, num_periodic_modules, num_trigger_modules, status, and SUCCESS.

Referenced by tr_start().

296 {
297  diag_print(1, "*** Begin of run %d ***\n", run_number);
298 
299  for(int i = 0; i < num_trigger_modules; i++) {
300  if((*trigger_modules[i]).bor != NULL) {
301  int status = (*trigger_modules[i]).bor();
302  if(status != SUCCESS) {
303  return status;
304  }
305  }
306  }
307 
308  for(int i = 0; i < num_periodic_modules; i++) {
309  if((*periodic_modules[i]).bor != NULL) {
310  int status = (*periodic_modules[i]).bor();
311  if(status != SUCCESS) {
312  return status;
313  }
314  }
315  }
316 
317  cycle_active = 0;
318  event_avail = false;
319 
320  between_runs = false;
321 
322  return SUCCESS;
323 }
void display ( BOOL  bInit)
INT end_of_run ( INT  run_number,
char *  error 
)

Definition at line 330 of file crate.cpp.

References diag_print(), readout_module::eor, i, num_periodic_modules, num_trigger_modules, status, and SUCCESS.

Referenced by tr_prestop(), and tr_stop().

331 {
332  diag_print(1, "*** End of run %d ***\n", run_number);
333 
334  between_runs = true;
335 
336  for(int i = 0; i < num_trigger_modules; i++) {
337  if((*trigger_modules[i]).eor != NULL) {
338  int status = (*trigger_modules[i]).eor();
339  if(status != SUCCESS) {
340  return status;
341  }
342  }
343  }
344 
345  for(int i = 0; i < num_periodic_modules; i++) {
346  if((*periodic_modules[i]).eor != NULL) {
347  int status = (*periodic_modules[i]).eor();
348  if(status != SUCCESS) {
349  return status;
350  }
351  }
352  }
353 
354 
355  return SUCCESS;
356 }
INT frontend_exit ( void  )

Definition at line 244 of file crate.cpp.

References readout_module::exit, i, num_periodic_modules, num_trigger_modules, and SUCCESS.

Referenced by main().

245 {
246  for(int i = 0; i < num_trigger_modules; i++) {
247  if((*trigger_modules[i]).exit != NULL) {
248  (*trigger_modules[i]).exit();
249  }
250  }
251 
252  for(int i = 0; i < num_periodic_modules; i++) {
253  if((*periodic_modules[i]).exit != NULL) {
254  (*periodic_modules[i]).exit();
255  }
256  }
257 
258  return SUCCESS;
259 }
INT frontend_init ( void  )

Definition at line 207 of file crate.cpp.

References ACK, Alarm, FALSE, hDB, hKey, i, readout_module::init, INQ_MODE, kJustFilled, kLastFilled, kTimeLimit, missed_reads, num_periodic_modules, num_trigger_modules, odb_get_int(), printf(), resp, run_state, sJustFilled, sLastFilled, status, sTimeLimit, SUCCESS, vac_ready, vac_timeout, vacuum, vacuum_config, and vacuum_port.

Referenced by main().

208 {
209  printf("Entering frontend_init() ... \n");
210  INT run_state = odb_get_int("/Runinfo/State");
211  if (run_state != STATE_STOPPED) {
212  cm_msg(MERROR, "Crate",
213  "Run must be stopped before starting crate program.");
214  return FE_ERR_HW;
215  }
216 
217  for(int i = 0; i < num_trigger_modules; i++) {
218  if((*trigger_modules[i]).init != NULL) {
219  int status = (*trigger_modules[i]).init();
220  if(status != SUCCESS) {
221  return status;
222  }
223  }
224  }
225 
226  for(int i = 0; i < num_periodic_modules; i++) {
227  if((*periodic_modules[i]).init != NULL) {
228  int status = (*periodic_modules[i]).init();
229  if(status != SUCCESS) {
230  return status;
231  }
232  }
233  }
234 
235  return SUCCESS;
236 }
INT frontend_loop ( void  )

Definition at line 435 of file crate.cpp.

References consider_start(), FE_END_BLOCK, FE_NEED_STOP, i, num_trigger_modules, run_state, status, stop_cycle(), SUCCESS, and TRUE.

Referenced by poll_event(), and scheduler().

436 {
437  // If we're going to be pre-empted, get it over with during livetime
438  // rather than deadtime.
439  if (cycle_active || run_state != STATE_RUNNING || between_runs == TRUE) {
440  dm_area_flush();
441  sched_yield();
442  }
443 
444  // Exit immediately if no run in progress
445  if (run_state != STATE_RUNNING || between_runs == TRUE) {
446  return SUCCESS;
447  }
448 
449  // Call appropriate poll functions, depending on whether we're live or dead
450  //printf("fe loop: cycle_active %i\n",cycle_active);
451  if (cycle_active) {
452 
453  for(int i = 0; i < num_trigger_modules; i++) {
454  if((*trigger_modules[i]).poll_live != NULL) {
455 
456  // There are conditions that can lead to changes in run state between
457  // modules...
458  if (run_state != STATE_RUNNING || between_runs == TRUE) {
459  return SUCCESS;
460  }
461  int status = (*trigger_modules[i]).poll_live();
462 
463  if(status == FE_END_BLOCK) {
464  cycle_active = 0;
465  event_avail = true;
466  } else if(status == FE_NEED_STOP) {
467  stop_cycle();
468  } else if(status != SUCCESS) {
469  return status;
470  }
471  }
472  }
473  } else {
474  consider_start();
475  }
476 
477  return SUCCESS;
478 }
INT get_frontend_index ( )

Definition at line 1928 of file mfe_mucap.c.

References frontend_index.

1929 {
1930  return frontend_index;
1931 }
INT interrupt_configure ( INT  cmd,
INT  source,
PTYPE  adr 
)

Definition at line 505 of file crate.cpp.

References FALSE, interrupt_handler, interrupts_enabled, SUCCESS, and TRUE.

Referenced by interrupt_enable(), main(), and register_equipment().

506 {
507  switch (cmd) {
508  case CMD_INTERRUPT_ENABLE:
510  break;
511  case CMD_INTERRUPT_DISABLE:
513  break;
514  case CMD_INTERRUPT_ATTACH:
515  interrupt_handler = (void (*)(void)) adr;
516  break;
517  case CMD_INTERRUPT_DETACH:
519  interrupt_handler = NULL;
520  break;
521  }
522  return SUCCESS;
523 }
void interrupt_enable ( BOOL  flag)
void interrupt_routine ( void  )
BOOL logger_root ( )

Definition at line 1335 of file mfe_mucap.c.

References FALSE, hDB, hKey, i, size, status, and TRUE.

1337 {
1338  int size, i, status;
1339  char str[80];
1340  HNDLE hKeyRoot, hKey;
1341 
1342  if (db_find_key(hDB, 0, "/Logger/Channels", &hKeyRoot) == DB_SUCCESS) {
1343  for (i = 0;; i++) {
1344  status = db_enum_key(hDB, hKeyRoot, i, &hKey);
1345  if (status == DB_NO_MORE_SUBKEYS)
1346  break;
1347 
1348  strcpy(str, "MIDAS");
1349  size = sizeof(str);
1350  db_get_value(hDB, hKey, "Settings/Format", str, &size, TID_STRING, TRUE);
1351 
1352  if (equal_ustring(str, "ROOT"))
1353  return TRUE;
1354  }
1355  }
1356 
1357  return FALSE;
1358 }
int main ( int  argc,
char *  argv[] 
)

Definition at line 1938 of file mfe_mucap.c.

References cm_get_environment(), cnaf_callback(), crate_number, debug, DEFAULT_FE_TIMEOUT, display(), display_period, equipment, event_buffer_size, exp_name, FALSE, frontend_early_init(), frontend_exit(), frontend_index, frontend_init(), frontend_name, full_frontend_name, hDB, host_name, i, interrupt_configure(), interrupt_enable(), interrupt_eq, interrupt_odb_buffer, message_print(), printf(), register_equipment(), run_state, scheduler(), sprintf(), status, SUCCESS, tr_pause(), tr_prestart, tr_resume(), tr_start(), tr_stop, TRUE, and usage().

1940 {
1941  INT status, i, dm_size;
1942  INT daemon;
1943 
1944  host_name[0] = 0;
1945  exp_name[0] = 0;
1946  debug = FALSE;
1947  daemon = 0;
1948 
1949  setbuf(stdout, 0);
1950  setbuf(stderr, 0);
1951 
1952 #ifdef SIGPIPE
1953  signal(SIGPIPE, SIG_IGN);
1954 #endif
1955 
1956 #ifdef OS_VXWORKS
1957  if (ahost_name)
1958  strcpy(host_name, ahost_name);
1959  if (aexp_name)
1960  strcpy(exp_name, aexp_name);
1961  debug = adebug;
1962 #else
1963 
1964  /* get default from environment */
1966 
1967  /* parse command line parameters */
1968  for (i = 1; i < argc; i++) {
1969  if (argv[i][0] == '-' && argv[i][1] == 'd')
1970  debug = TRUE;
1971  else if (argv[i][0] == '-' && argv[i][1] == 'D')
1972  daemon = 1;
1973  else if (argv[i][0] == '-' && argv[i][1] == 'O')
1974  daemon = 2;
1975  else if (argv[i][0] == '-') {
1976  if (i + 1 >= argc || argv[i + 1][0] == '-')
1977  goto usage;
1978  if (argv[i][1] == 'e')
1979  strcpy(exp_name, argv[++i]);
1980  else if (argv[i][1] == 'h')
1981  strcpy(host_name, argv[++i]);
1982  else if (argv[i][1] == 'i')
1983  frontend_index = atoi(argv[++i]);
1984  else {
1985  usage:
1986  printf("usage: frontend [-h Hostname] [-e Experiment] [-d] [-D] [-O] [-i n]\n");
1987  printf(" [-d] Used to debug the frontend\n");
1988  printf(" [-D] Become a daemon\n");
1989  printf(" [-O] Become a daemon but keep stdout\n");
1990  printf(" [-i n] Set frontend index (used for event building)\n");
1991  return 0;
1992  }
1993  }
1994  }
1995 #endif
1996 
1997 #ifdef PART_OF_MUCAP
1999 #endif
2000 
2001  /* check event and buffer sizes */
2002  if (event_buffer_size < 2 * max_event_size) {
2003  printf("event_buffer_size too small for max. event size\n");
2004  ss_sleep(5000);
2005  return 1;
2006  }
2007 
2008  if (max_event_size > MAX_EVENT_SIZE) {
2009  printf("Requested max_event_size (%d) exceeds max. system event size (%d)",
2010  max_event_size, MAX_EVENT_SIZE);
2011  ss_sleep(5000);
2012  return 1;
2013  }
2014 
2015  dm_size = event_buffer_size;
2016 
2017 #ifdef OS_VXWORKS
2018  /* override dm_size in case of VxWorks
2019  take remaining free memory and use 20% of it for dm_ */
2020  dm_size = 2 * 10 * (max_event_size + sizeof(EVENT_HEADER) + sizeof(INT));
2021  if (dm_size > memFindMax()) {
2022  cm_msg(MERROR, "mainFE", "Not enough mem space for event size");
2023  return 0;
2024  }
2025  /* takes overall 20% of the available memory resource for dm_() */
2026  dm_size = 0.2 * memFindMax();
2027 
2028  /* there are two buffers */
2029  dm_size /= 2;
2030 #endif
2031 
2032  /* reduce memory size for MS-DOS */
2033 #ifdef OS_MSDOS
2034  if (dm_size > 0x4000)
2035  dm_size = 0x4000; /* 16k */
2036 #endif
2037 
2038  /* add frontend index to frontend name if present */
2040  if (frontend_index >= 0)
2042 
2043  /* inform user of settings */
2044  printf("Frontend name : %s\n", full_frontend_name);
2045  printf("Event buffer size : %d\n", event_buffer_size);
2046  printf("Buffer allocation : 2 x %d\n", dm_size);
2047  printf("System max event size : %d\n", MAX_EVENT_SIZE);
2048  printf("User max event size : %d\n", max_event_size);
2049  if (max_event_size_frag > 0)
2050  printf("User max frag. size : %d\n", max_event_size_frag);
2051  printf("# of events per buffer : %d\n\n", dm_size / max_event_size);
2052 
2053  if (daemon) {
2054  printf("\nBecoming a daemon...\n");
2055  ss_daemon_init(daemon == 2);
2056  }
2057 
2058  /* now connect to server */
2059  if (display_period) {
2060  if (host_name[0])
2061  printf("Connect to experiment %s on host %s...", exp_name, host_name);
2062  else
2063  printf("Connect to experiment %s...", exp_name);
2064  }
2065 
2066  status = cm_connect_experiment1(host_name, exp_name, full_frontend_name,
2067  NULL, DEFAULT_ODB_SIZE, DEFAULT_FE_TIMEOUT);
2068  if (status != CM_SUCCESS) {
2069  /* let user read message before window might close */
2070  ss_sleep(5000);
2071  return 1;
2072  }
2073 
2074  if (display_period)
2075  printf("OK\n");
2076 
2077  /* book buffer space */
2078  status = dm_buffer_create(dm_size, max_event_size);
2079  if (status != CM_SUCCESS) {
2080  printf("dm_buffer_create: Not enough memory or event too big\n");
2081  return 1;
2082  }
2083 
2084  /* remomve any dead frontend */
2085  cm_cleanup(full_frontend_name, FALSE);
2086 
2087  /* shutdown previous frontend */
2088  status = cm_shutdown(full_frontend_name, FALSE);
2089  if (status == CM_SUCCESS && display_period) {
2090  printf("Previous frontend stopped\n");
2091 
2092  /* let user read message */
2093  ss_sleep(3000);
2094  }
2095 
2096  /* register transition callbacks */
2097  if (cm_register_transition(TR_START, tr_prestart, 400+crate_number) != CM_SUCCESS ||
2098  cm_register_transition(TR_START, tr_start, 500+crate_number) != CM_SUCCESS ||
2099  cm_register_transition(TR_STOP, tr_stop, 500+crate_number) != CM_SUCCESS ||
2100  cm_register_transition(TR_PAUSE, tr_pause, 500+crate_number) != CM_SUCCESS ||
2101  cm_register_transition(TR_RESUME, tr_resume, 500+crate_number) != CM_SUCCESS) {
2102  printf("Failed to start local RPC server");
2103  cm_disconnect_experiment();
2104  dm_buffer_release();
2105 
2106  /* let user read message before window might close */
2107  ss_sleep(5000);
2108  return 1;
2109  }
2110 #ifdef HAVE_CAMAC
2111 
2112  /* register CNAF callback */
2113  cm_register_function(RPC_CNAF16, cnaf_callback);
2114  cm_register_function(RPC_CNAF24, cnaf_callback);
2115 
2116 #endif
2117 
2118  cm_get_experiment_database(&hDB, &status);
2119 
2120  /* set time from server */
2121 #ifdef OS_VXWORKS
2122  cm_synchronize(NULL);
2123 #endif
2124 
2125  /* turn off watchdog if in debug mode */
2126  if (debug)
2127  cm_set_watchdog_params(TRUE, 0);
2128 
2129  /* increase RPC timeout to 2min for logger with exabyte or blocked disk */
2130  rpc_set_option(-1, RPC_OTIMEOUT, 120000);
2131 
2132  /* set own message print function */
2133  if (display_period)
2134  cm_set_msg_print(MT_ALL, MT_ALL, message_print);
2135 
2136  /* call user init function */
2137  if (display_period)
2138  printf("Init hardware...");
2139  if (frontend_init() != SUCCESS) {
2140  if (display_period)
2141  printf("\n");
2142  cm_disconnect_experiment();
2143  dm_buffer_release();
2144 
2145  /* let user read message before window might close */
2146  ss_sleep(5000);
2147  return 1;
2148  }
2149 
2150  /* reqister equipment in ODB */
2151  if (register_equipment() != SUCCESS) {
2152  if (display_period)
2153  printf("\n");
2154  cm_disconnect_experiment();
2155  dm_buffer_release();
2156 
2157  /* let user read message before window might close */
2158  ss_sleep(5000);
2159  return 1;
2160  }
2161 
2162  if (display_period)
2163  printf("OK\n");
2164 
2165  /* initialize screen display */
2166  if (display_period) {
2167  ss_sleep(1000);
2168  display(TRUE);
2169  }
2170 
2171  /* switch on interrupts if running */
2172  if (interrupt_eq && run_state == STATE_RUNNING)
2174 
2175  /* initialize ss_getchar */
2176  ss_getchar(0);
2177 
2178  /* call main scheduler loop */
2179  status = scheduler();
2180 
2181  /* reset terminal */
2182  ss_getchar(TRUE);
2183 
2184  /* switch off interrupts */
2185  if (interrupt_eq) {
2186  interrupt_configure(CMD_INTERRUPT_DISABLE, 0, 0);
2187  interrupt_configure(CMD_INTERRUPT_DETACH, 0, 0);
2189  free(interrupt_odb_buffer);
2190  }
2191 
2192  /* detach interrupts */
2193  if (interrupt_eq != NULL)
2194  interrupt_configure(CMD_INTERRUPT_DETACH, interrupt_eq->info.source, 0);
2195 
2196  /* call user exit function */
2197  frontend_exit();
2198 
2199  /* close slow control drivers */
2200  for (i = 0; equipment[i].name[0]; i++)
2201  if ((equipment[i].info.eq_type & EQ_SLOW) && equipment[i].status == FE_SUCCESS)
2202  equipment[i].cd(CMD_EXIT, &equipment[i]);
2203 
2204  /* close network connection to server */
2205  cm_disconnect_experiment();
2206 
2207  if (display_period) {
2208  if (status == RPC_SHUTDOWN) {
2209  ss_clear_screen();
2210  ss_printf(0, 0, "Frontend shut down.");
2211  ss_printf(0, 1, "");
2212  }
2213  }
2214 
2215  if (status != RPC_SHUTDOWN)
2216  printf("Network connection aborted.\n");
2217 
2218  dm_buffer_release();
2219 
2220  return 0;
2221 }
INT manual_trigger ( INT  index,
void *  prpc_param[] 
)

Definition at line 520 of file mfe_mucap.c.

References manual_trigger_event_id, and SUCCESS.

521 {
522  manual_trigger_event_id = CWORD(0);
523  return SUCCESS;
524 }
int message_print ( const char *  msg)

Definition at line 1246 of file mfe_mucap.c.

1247 {
1248  char str[160];
1249 
1250  memset(str, ' ', 159);
1251  str[159] = 0;
1252 
1253  if (msg[0] == '[')
1254  msg = strchr(msg, ']') + 2;
1255 
1256  memcpy(str, msg, strlen(msg));
1257  ss_printf(0, 20, str);
1258 
1259  return 0;
1260 }
INT pause_run ( INT  run_number,
char *  error 
)

Definition at line 362 of file crate.cpp.

References SUCCESS.

Referenced by tr_pause(), and tr_prepause().

363 {
364  return SUCCESS;
365 }
INT poll_event ( INT  source,
INT  count,
BOOL  test 
)

Definition at line 486 of file crate.cpp.

References count, frontend_loop(), and i.

Referenced by register_equipment(), and scheduler().

487 {
488  INT retval = false;
489 
490  if(!test) {
491  count = 1;
492  }
493 
494  for (int i = 0; i < count; i++) {
495  frontend_loop();
496  if(event_avail) {
497  retval = true;
498  }
499  }
500 
501  return retval;
502 }
INT register_equipment ( void  )

Definition at line 528 of file mfe_mucap.c.

References count, display_period, equipment, EQUIPMENT_COMMON_STR, EQUIPMENT_STATISTICS_STR, FALSE, frontend_file_name, frontend_index, full_frontend_name, hDB, hKey, i, interrupt_configure(), interrupt_eq, interrupt_odb_buffer, interrupt_routine(), manual_trigger(), poll_event(), printf(), run_number, run_state, SERVER_CACHE_SIZE, size, sprintf(), start_time, status, SUCCESS, and TRUE.

529 {
530  INT index, count, size, status, i, j, k, n;
531  char str[256];
532  EQUIPMENT_INFO *eq_info;
533  EQUIPMENT_STATS *eq_stats;
534  DWORD start_time, delta_time;
535  HNDLE hKey;
536  BOOL manual_trig_flag = FALSE;
537  BANK_LIST *bank_list;
538  DWORD dummy;
539 
540  /* get current ODB run state */
541  size = sizeof(run_state);
542  run_state = STATE_STOPPED;
543  db_get_value(hDB, 0, "/Runinfo/State", &run_state, &size, TID_INT, TRUE);
544  size = sizeof(run_number);
545  run_number = 1;
546  status =
547  db_get_value(hDB, 0, "/Runinfo/Run number", &run_number, &size, TID_INT, TRUE);
548  assert(status == SUCCESS);
549 
550  /* scan EQUIPMENT table from FRONTEND.C */
551  for (index = 0; equipment[index].name[0]; index++) {
552  eq_info = &equipment[index].info;
553  eq_stats = &equipment[index].stats;
554 
555  if (eq_info->event_id == 0) {
556  printf("\nEvent ID 0 for %s not allowed\n", equipment[index].name);
557  cm_disconnect_experiment();
558  ss_sleep(5000);
559  exit(0);
560  }
561 
562  /* init status */
563  equipment[index].status = FE_SUCCESS;
564 
565  /* check for event builder event */
566  if (eq_info->eq_type & EQ_EB) {
567 
568  if (frontend_index == -1) {
569  printf("\nEquipment \"%s\" has EQ_EB set, but no", equipment[index].name);
570  printf(" index specified via \"-i\" flag.\nExiting.");
571  cm_disconnect_experiment();
572  ss_sleep(5000);
573  exit(0);
574  }
575 
576  /* modify equipment name to <name>xx where xx is the frontend index*/
577  sprintf(equipment[index].name+strlen(equipment[index].name), "%02d", frontend_index);
578 
579  /* modify event buffer name to <name>xx where xx is the frontend index*/
580  sprintf(eq_info->buffer+strlen(eq_info->buffer), "%02d", frontend_index);
581  }
582 
583  sprintf(str, "/Equipment/%s/Common", equipment[index].name);
584 
585  /* get last event limit from ODB */
586  if (eq_info->eq_type != EQ_SLOW) {
587  db_find_key(hDB, 0, str, &hKey);
588  size = sizeof(double);
589  if (hKey)
590  db_get_value(hDB, hKey, "Event limit", &eq_info->event_limit, &size,
591  TID_DOUBLE, TRUE);
592  }
593 
594  /* Create common subtree */
595  status = db_check_record(hDB, 0, str, EQUIPMENT_COMMON_STR, TRUE);
596  if (status != DB_SUCCESS) {
597  printf("Cannot check equipment record, status = %d\n", status);
598  ss_sleep(3000);
599  }
600  db_find_key(hDB, 0, str, &hKey);
601 
602  if (equal_ustring(eq_info->format, "YBOS"))
603  equipment[index].format = FORMAT_YBOS;
604  else if (equal_ustring(eq_info->format, "FIXED"))
605  equipment[index].format = FORMAT_FIXED;
606  else /* default format is MIDAS */
607  equipment[index].format = FORMAT_MIDAS;
608 
609  gethostname(eq_info->frontend_host, sizeof(eq_info->frontend_host));
610  strcpy(eq_info->frontend_name, full_frontend_name);
611  strcpy(eq_info->frontend_file_name, frontend_file_name);
612 
613  /* set record from equipment[] table in frontend.c */
614  db_set_record(hDB, hKey, eq_info, sizeof(EQUIPMENT_INFO), 0);
615 
616  /* open hot link to equipment info */
617  db_open_record(hDB, hKey, eq_info, sizeof(EQUIPMENT_INFO), MODE_READ, NULL, NULL);
618 
619  /*---- Create variables record ---------------------------------*/
620  sprintf(str, "/Equipment/%s/Variables", equipment[index].name);
621  if (equipment[index].event_descrip) {
622  if (equipment[index].format == FORMAT_FIXED)
623  db_check_record(hDB, 0, str, (char *) equipment[index].event_descrip, TRUE);
624  else {
625  /* create bank descriptions */
626  bank_list = (BANK_LIST *) equipment[index].event_descrip;
627 
628  for (; bank_list->name[0]; bank_list++) {
629  /* mabye needed later...
630  if (bank_list->output_flag == 0)
631  continue;
632  */
633 
634  if (bank_list->type == TID_STRUCT) {
635  sprintf(str, "/Equipment/%s/Variables/%s", equipment[index].name,
636  bank_list->name);
637  status =
638  db_check_record(hDB, 0, str, strcomb(bank_list->init_str), TRUE);
639  if (status != DB_SUCCESS) {
640  printf("Cannot check/create record \"%s\", status = %d\n", str,
641  status);
642  ss_sleep(3000);
643  }
644  } else {
645  sprintf(str, "/Equipment/%s/Variables/%s", equipment[index].name,
646  bank_list->name);
647  dummy = 0;
648  db_set_value(hDB, 0, str, &dummy, rpc_tid_size(bank_list->type), 1,
649  bank_list->type);
650  }
651  }
652  }
653  } else
654  db_create_key(hDB, 0, str, TID_KEY);
655 
656  sprintf(str, "/Equipment/%s/Variables", equipment[index].name);
657  db_find_key(hDB, 0, str, &hKey);
658  equipment[index].hkey_variables = hKey;
659 
660  /*---- Create and initialize statistics tree -------------------*/
661 
662  sprintf(str, "/Equipment/%s/Statistics", equipment[index].name);
663 
664  status = db_check_record(hDB, 0, str, EQUIPMENT_STATISTICS_STR, TRUE);
665  if (status != DB_SUCCESS) {
666  printf("Cannot create/check statistics record, error %d\n", status);
667  ss_sleep(3000);
668  }
669 
670  status = db_find_key(hDB, 0, str, &hKey);
671  if (status != DB_SUCCESS) {
672  printf("Cannot find statistics record, error %d\n", status);
673  ss_sleep(3000);
674  }
675 
676  eq_stats->events_sent = 0;
677  eq_stats->events_per_sec = 0;
678  eq_stats->kbytes_per_sec = 0;
679 
680  /* open hot link to statistics tree */
681  status =
682  db_open_record(hDB, hKey, eq_stats, sizeof(EQUIPMENT_STATS), MODE_WRITE, NULL,
683  NULL);
684  if (status != DB_SUCCESS) {
685  cm_msg(MERROR, "register_equipment",
686  "Cannot open statistics record, error %d. Probably other FE is using it",
687  status);
688  ss_sleep(3000);
689  }
690 
691  /*---- open event buffer ---------------------------------------*/
692 
693  if (eq_info->buffer[0]) {
694  status =
695  bm_open_buffer(eq_info->buffer, EVENT_BUFFER_SIZE,
696  &equipment[index].buffer_handle);
697  if (status != BM_SUCCESS && status != BM_CREATED) {
698  cm_msg(MERROR, "register_equipment",
699  "Cannot open event buffer. Try to reduce EVENT_BUFFER_SIZE in midas.h \
700 and rebuild the system.");
701  return 0;
702  }
703 
704  /* set the default buffer cache size */
705  bm_set_cache_size(equipment[index].buffer_handle, 0, SERVER_CACHE_SIZE);
706  } else
707  equipment[index].buffer_handle = 0;
708 
709  /*---- evaluate polling count ----------------------------------*/
710  if (eq_info->eq_type & EQ_POLLED) {
711  if (display_period)
712  printf("\nCalibrating");
713 
714  count = 1;
715  do {
716  if (display_period)
717  printf(".");
718 
719  start_time = ss_millitime();
720 
721  poll_event(equipment[index].info.source, count, TRUE);
722 
723  delta_time = ss_millitime() - start_time;
724 
725  if (delta_time > 0)
726  count = (INT) ((double) count * 100 / delta_time);
727  else
728  count *= 100;
729  } while (delta_time > 120 || delta_time < 80);
730 
731  equipment[index].poll_count = (INT) ((double) eq_info->period / 100 * count);
732 
733  if (display_period)
734  printf("OK\n");
735  }
736 
737  /*---- initialize interrupt events -----------------------------*/
738  if (eq_info->eq_type & EQ_INTERRUPT) {
739  /* install interrupt for interrupt events */
740 
741  for (i = 0; equipment[i].name[0]; i++)
742  if (equipment[i].info.eq_type & EQ_POLLED) {
743  equipment[index].status = FE_ERR_DISABLED;
744  cm_msg(MINFO, "register_equipment",
745  "Interrupt readout cannot be combined with polled readout");
746  }
747 
748  if (equipment[index].status != FE_ERR_DISABLED) {
749  if (eq_info->enabled) {
750  if (interrupt_eq) {
751  equipment[index].status = FE_ERR_DISABLED;
752  cm_msg(MINFO, "register_equipment",
753  "Defined more than one equipment with interrupt readout");
754  } else {
755  interrupt_configure(CMD_INTERRUPT_ATTACH, eq_info->source,
756  (PTYPE) interrupt_routine);
757  interrupt_eq = &equipment[index];
758  interrupt_odb_buffer = malloc(MAX_EVENT_SIZE + sizeof(EVENT_HEADER));
759  }
760  } else {
761  equipment[index].status = FE_ERR_DISABLED;
762  cm_msg(MINFO, "register_equipment",
763  "Equipment %s disabled in file \"frontend.c\"",
764  equipment[index].name);
765  }
766  }
767  }
768 
769  /*---- initialize slow control equipment -----------------------*/
770  if (eq_info->eq_type & EQ_SLOW) {
771  /* resolve duplicate device names */
772  for (i = 0; equipment[index].driver[i].name[0]; i++)
773  for (j = i + 1; equipment[index].driver[j].name[0]; j++)
774  if (equal_ustring(equipment[index].driver[i].name,
775  equipment[index].driver[j].name)) {
776  strcpy(str, equipment[index].driver[i].name);
777  for (k = 0, n = 0; equipment[index].driver[k].name[0]; k++)
778  if (equal_ustring(str, equipment[index].driver[k].name))
779  sprintf(equipment[index].driver[k].name, "%s_%d", str, n++);
780 
781  break;
782  }
783 
784  /* loop over equipment list and call class driver's init method */
785  if (eq_info->enabled)
786  equipment[index].status = equipment[index].cd(CMD_INIT, &equipment[index]);
787  else {
788  equipment[index].status = FE_ERR_DISABLED;
789  cm_msg(MINFO, "register_equipment",
790  "Equipment %s disabled in file \"frontend.c\"", equipment[index].name);
791  }
792 
793  /* let user read error messages */
794  if (equipment[index].status != FE_SUCCESS)
795  ss_sleep(3000);
796  }
797 
798  /*---- register callback for manual triggered events -----------*/
799  if (eq_info->eq_type & EQ_MANUAL_TRIG) {
800  if (!manual_trig_flag)
801  cm_register_function(RPC_MANUAL_TRIG, manual_trigger);
802 
803  manual_trig_flag = TRUE;
804  }
805  }
806 
807  return SUCCESS;
808 }
INT resume_run ( INT  run_number,
char *  error 
)

Definition at line 371 of file crate.cpp.

References SUCCESS.

Referenced by tr_resume().

372 {
373  return SUCCESS;
374 }
INT scheduler ( void  )

Definition at line 1362 of file mfe_mucap.c.

References actual_millitime, actual_time, auto_restart, display(), display_period, eq, equipment, FALSE, fe_stop, frontend_call_loop, frontend_loop(), hDB, i, interrupt_enable(), interrupt_eq, interrupt_odb_buffer, interrupt_odb_buffer_valid, logger_root(), manual_trigger_event_id, MAX, max_bytes_per_sec, ODB_UPDATE_TIME, optimize, poll_event(), run_number, run_state, send_event(), SERVER_CACHE_SIZE, size, status, SUCCESS, TRUE, and update_odb().

1363 {
1364  EQUIPMENT_INFO *eq_info;
1365  EQUIPMENT *eq;
1366  EVENT_HEADER *pevent;
1367  DWORD last_time_network = 0, last_time_display = 0, last_time_flush = 0, readout_start;
1368  INT i, j, index, status, ch, source, size, state;
1369  char str[80];
1370  BOOL buffer_done, flag, force_update = FALSE;
1371 
1372  INT opt_max = 0, opt_index = 0, opt_tcp_size = 128, opt_cnt = 0;
1373  INT err;
1374 
1375 #ifdef OS_VXWORKS
1376  rpc_set_opt_tcp_size(1024);
1377 #ifdef PPCxxx
1378  rpc_set_opt_tcp_size(NET_TCP_SIZE);
1379 #endif
1380 #endif
1381 
1382  /*----------------- MAIN equipment loop ------------------------------*/
1383 
1384  do {
1385  actual_millitime = ss_millitime();
1386  actual_time = ss_time();
1387 
1388  /*---- loop over equipment table -------------------------------*/
1389  for (index = 0;; index++) {
1390  eq = &equipment[index];
1391  eq_info = &eq->info;
1392 
1393  /* check if end of equipment list */
1394  if (!eq->name[0])
1395  break;
1396 
1397  if (!eq_info->enabled)
1398  continue;
1399 
1400  if (eq->status != FE_SUCCESS)
1401  continue;
1402 
1403  /*---- call idle routine for slow control equipment ----*/
1404  if ((eq_info->eq_type & EQ_SLOW) && eq->status == FE_SUCCESS) {
1405  if (eq_info->event_limit > 0 && run_state == STATE_RUNNING) {
1406  if (actual_time - eq->last_idle >= (DWORD) eq_info->event_limit) {
1407  eq->cd(CMD_IDLE, eq);
1408  eq->last_idle = actual_time;
1409  }
1410  } else
1411  eq->cd(CMD_IDLE, eq);
1412  }
1413 
1414  if (run_state == STATE_STOPPED && (eq_info->read_on & RO_STOPPED) == 0)
1415  continue;
1416  if (run_state == STATE_PAUSED && (eq_info->read_on & RO_PAUSED) == 0)
1417  continue;
1418  if (run_state == STATE_RUNNING && (eq_info->read_on & RO_RUNNING) == 0)
1419  continue;
1420 
1421  /*---- check periodic events ----*/
1422  if ((eq_info->eq_type & EQ_PERIODIC) || (eq_info->eq_type & EQ_SLOW)) {
1423  if (eq_info->period == 0)
1424  continue;
1425 
1426  /* check if period over */
1427  if (actual_millitime - eq->last_called >= (DWORD) eq_info->period) {
1428  /* disable interrupts during readout */
1430 
1431  /* readout and send event */
1432  status = send_event(index);
1433 
1434  if (status != CM_SUCCESS) {
1435  cm_msg(MERROR, "scheduler", "send_event error %d", status);
1436  goto net_error;
1437  }
1438 
1439  /* re-enable the interrupt after periodic */
1441  }
1442  }
1443 
1444  /* end of periodic equipments */
1445  /*---- check polled events ----*/
1446  if (eq_info->eq_type & EQ_POLLED) {
1447  readout_start = actual_millitime;
1448  pevent = NULL;
1449 
1450  while ((source = poll_event(eq_info->source, eq->poll_count, FALSE)) > 0) {
1451  pevent = dm_pointer_get();
1452  if (pevent == NULL) {
1453  cm_msg(MERROR, "scheduler",
1454  "polled, dm_pointer_get not returning valid pointer");
1455  status = SS_NO_MEMORY;
1456  goto net_error;
1457  }
1458 
1459  /* compose MIDAS event header */
1460  pevent->event_id = eq_info->event_id;
1461  pevent->trigger_mask = eq_info->trigger_mask;
1462  pevent->data_size = 0;
1463  pevent->time_stamp = actual_time;
1464  pevent->serial_number = eq->serial_number;
1465 
1466  /* put source at beginning of event, will be overwritten by
1467  user readout code, just a special feature used by some
1468  multi-source applications */
1469  *(INT *) (pevent + 1) = source;
1470 
1471  if (eq->info.num_subevents) {
1472  eq->subevent_number = 0;
1473  do {
1474  *(INT *) ((char *) (pevent + 1) + pevent->data_size) = source;
1475 
1476  /* call user readout routine for subevent indicating offset */
1477  size = eq->readout((char *) (pevent + 1), pevent->data_size);
1478  pevent->data_size += size;
1479  if (size > 0) {
1480  if (pevent->data_size + sizeof(EVENT_HEADER) >
1481  (DWORD) max_event_size) {
1482  cm_msg(MERROR, "scheduler",
1483  "Event size %ld larger than maximum size %d",
1484  (long) (pevent->data_size + sizeof(EVENT_HEADER)),
1485  max_event_size);
1486  }
1487 
1488  eq->subevent_number++;
1489  eq->serial_number++;
1490  }
1491 
1492  /* wait for next event */
1493  do {
1494  source = poll_event(eq_info->source, eq->poll_count, FALSE);
1495 
1496  if (source == FALSE) {
1497  actual_millitime = ss_millitime();
1498 
1499  /* repeat no more than period */
1500  if (actual_millitime - readout_start > (DWORD) eq_info->period)
1501  break;
1502  }
1503  } while (source == FALSE);
1504 
1505  } while (eq->subevent_number < eq->info.num_subevents && source);
1506 
1507  /* notify readout routine about end of super-event */
1508  pevent->data_size = eq->readout((char *) (pevent + 1), -1);
1509  } else {
1510  /* call user readout routine indicating event source */
1511  pevent->data_size = eq->readout((char *) (pevent + 1), 0);
1512 
1513  /* check event size */
1514  if (pevent->data_size + sizeof(EVENT_HEADER) > (DWORD) max_event_size) {
1515  cm_msg(MERROR, "scheduler",
1516  "Event size %ld larger than maximum size %d",
1517  (long) (pevent->data_size + sizeof(EVENT_HEADER)),
1518  max_event_size);
1519  }
1520 
1521  /* increment serial number if event read out sucessfully */
1522  if (pevent->data_size)
1523  eq->serial_number++;
1524  }
1525 
1526  /* send event */
1527  if (pevent->data_size) {
1528  if (eq->buffer_handle) {
1529  /* send first event to ODB if logger writes in root format */
1530  if (pevent->serial_number == 1)
1531  if (logger_root())
1532  update_odb(pevent, eq->hkey_variables, eq->format);
1533 
1534 #ifdef USE_EVENT_CHANNEL
1535  dm_pointer_increment(eq->buffer_handle,
1536  pevent->data_size + sizeof(EVENT_HEADER));
1537 #else
1538  status = rpc_send_event(eq->buffer_handle, pevent,
1539  pevent->data_size + sizeof(EVENT_HEADER),
1540  SYNC);
1541 
1542  if (status != SUCCESS) {
1543  cm_msg(MERROR, "scheduler", "rpc_send_event error %d", status);
1544  goto net_error;
1545  }
1546 #endif
1547 
1548  eq->bytes_sent += pevent->data_size + sizeof(EVENT_HEADER);
1549 
1550  if (eq->info.num_subevents)
1551  eq->events_sent += eq->subevent_number;
1552  else
1553  eq->events_sent++;
1554  }
1555  }
1556 
1557  actual_millitime = ss_millitime();
1558 
1559  /* repeat no more than period */
1560  if (actual_millitime - readout_start > (DWORD) eq_info->period)
1561  break;
1562 
1563  /* quit if event limit is reached */
1564  if (eq_info->event_limit > 0 &&
1565  eq->stats.events_sent + eq->events_sent >= eq_info->event_limit)
1566  break;
1567  }
1568 
1569  /* send event to ODB */
1570  if (pevent && (eq_info->read_on & RO_ODB || eq_info->history)) {
1571  if (actual_millitime - eq->last_called > ODB_UPDATE_TIME && pevent != NULL) {
1572  eq->last_called = actual_millitime;
1573  update_odb(pevent, eq->hkey_variables, eq->format);
1574  eq->odb_out++;
1575  }
1576  }
1577  }
1578 
1579  /*---- send interrupt events ----*/
1580  if (eq_info->eq_type & EQ_INTERRUPT) {
1581  /* not much to do as work being done independently in interrupt_routine() */
1582 
1583  /* update ODB */
1585  update_odb(interrupt_odb_buffer, interrupt_eq->hkey_variables,
1586  interrupt_eq->format);
1588  }
1589 
1590  }
1591 
1592  /*---- check if event limit is reached ----*/
1593  if (eq_info->eq_type != EQ_SLOW &&
1594  eq_info->event_limit > 0 &&
1595  eq->stats.events_sent + eq->events_sent >= eq_info->event_limit &&
1596  run_state == STATE_RUNNING) {
1597  /* stop run */
1598  if (cm_transition(TR_STOP, 0, str, sizeof(str), SYNC, FALSE) != CM_SUCCESS)
1599  cm_msg(MERROR, "scheduler", "cannot stop run: %s", str);
1600 
1601  /* check if autorestart, main loop will take care of it */
1602  size = sizeof(BOOL);
1603  flag = FALSE;
1604  db_get_value(hDB, 0, "/Logger/Auto restart", &flag, &size, TID_BOOL, TRUE);
1605 
1606  if (flag)
1607  auto_restart = ss_time() + 20; /* restart in 20 sec. */
1608 
1609  /* update event display correctly */
1610  force_update = TRUE;
1611  }
1612  }
1613 
1614  /*---- call frontend_loop periodically -------------------------*/
1615  if (frontend_call_loop) {
1616  status = frontend_loop();
1617  if (status != CM_SUCCESS)
1618  status = RPC_SHUTDOWN;
1619  }
1620 
1621  /*---- check for deferred transitions --------------------------*/
1622  cm_check_deferred_transition();
1623 
1624  /*---- check for manual triggered events -----------------------*/
1627 
1628  /* readout and send event */
1629  status = BM_INVALID_PARAM;
1630  for (i = 0; equipment[i].name[0]; i++)
1631  if (equipment[i].info.event_id == manual_trigger_event_id) {
1632  status = send_event(i);
1633  break;
1634  }
1635 
1637 
1638  if (status != CM_SUCCESS) {
1639  cm_msg(MERROR, "scheduler", "send_event error %d", status);
1640  goto net_error;
1641  }
1642 
1643  /* re-enable the interrupt after periodic */
1645  }
1646 
1647  /*---- calculate rates and update status page periodically -----*/
1648  if (force_update ||
1650  && actual_millitime - last_time_display > (DWORD) display_period)
1651  || (!display_period && actual_millitime - last_time_display > 3000)) {
1652  force_update = FALSE;
1653 
1654  /* calculate rates */
1655  if (actual_millitime != last_time_display) {
1656  max_bytes_per_sec = 0;
1657  for (i = 0; equipment[i].name[0]; i++) {
1658  eq = &equipment[i];
1659  eq->stats.events_sent += eq->events_sent;
1660  eq->stats.events_per_sec =
1661  eq->events_sent / ((actual_millitime - last_time_display) / 1000.0);
1662  eq->stats.kbytes_per_sec =
1663  eq->bytes_sent / 1024.0 / ((actual_millitime - last_time_display) /
1664  1000.0);
1665 
1666  if ((INT) eq->bytes_sent > max_bytes_per_sec)
1667  max_bytes_per_sec = eq->bytes_sent;
1668 
1669  eq->bytes_sent = 0;
1670  eq->events_sent = 0;
1671  }
1672 
1674  ((double) max_bytes_per_sec /
1675  ((actual_millitime - last_time_display) / 1000.0));
1676 
1677  /* tcp buffer size evaluation */
1678  if (optimize) {
1679  opt_max = MAX(opt_max, (INT) max_bytes_per_sec);
1680  ss_printf(0, opt_index, "%6d : %5.1lf %5.1lf", opt_tcp_size,
1681  opt_max / 1024.0, max_bytes_per_sec / 1024.0);
1682  if (++opt_cnt == 10) {
1683  opt_cnt = 0;
1684  opt_max = 0;
1685  opt_index++;
1686  opt_tcp_size = 1 << (opt_index + 7);
1687  rpc_set_opt_tcp_size(opt_tcp_size);
1688  if (1 << (opt_index + 7) > 0x8000) {
1689  opt_index = 0;
1690  opt_tcp_size = 1 << 7;
1691  rpc_set_opt_tcp_size(opt_tcp_size);
1692  }
1693  }
1694  }
1695 
1696  }
1697 
1698  /* propagate changes in equipment to ODB */
1699  rpc_set_option(-1, RPC_OTRANSPORT, RPC_FTCP);
1700  db_send_changed_records();
1701  rpc_set_option(-1, RPC_OTRANSPORT, RPC_TCP);
1702 
1703  if (display_period) {
1704  display(FALSE);
1705 
1706  /* check keyboard */
1707  ch = 0;
1708  status = 0;
1709  while (ss_kbhit()) {
1710  ch = ss_getchar(0);
1711  if (ch == -1)
1712  ch = getchar();
1713 
1714  if (ch == '!')
1715  status = RPC_SHUTDOWN;
1716  }
1717 
1718  if (ch > 0)
1719  display(TRUE);
1720  if (status == RPC_SHUTDOWN)
1721  break;
1722  }
1723 
1724  last_time_display = actual_millitime;
1725  }
1726 
1727  /*---- check to flush cache ------------------------------------*/
1728  if (actual_millitime - last_time_flush > 1000) {
1729  last_time_flush = actual_millitime;
1730 
1731  /* if cache on server is not filled in one second at current
1732  data rate, flush it now to make events available to consumers */
1733 
1736 
1737 #ifdef USE_EVENT_CHANNEL
1738  if ((status = dm_area_flush()) != CM_SUCCESS)
1739  cm_msg(MERROR, "scheduler", "dm_area_flush: %i", status);
1740 #endif
1741 
1742  for (i = 0; equipment[i].name[0]; i++) {
1743  if (equipment[i].buffer_handle) {
1744  /* check if buffer already flushed */
1745  buffer_done = FALSE;
1746  for (j = 0; j < i; j++)
1747  if (equipment[i].buffer_handle == equipment[j].buffer_handle) {
1748  buffer_done = TRUE;
1749  break;
1750  }
1751 
1752  if (!buffer_done) {
1753  rpc_set_option(-1, RPC_OTRANSPORT, RPC_FTCP);
1754  rpc_flush_event();
1755  err = bm_flush_cache(equipment[i].buffer_handle, ASYNC);
1756  if (err != BM_SUCCESS) {
1757  cm_msg(MERROR, "scheduler", "bm_flush_cache(ASYNC) error %d",
1758  err);
1759  return err;
1760  }
1761  rpc_set_option(-1, RPC_OTRANSPORT, RPC_TCP);
1762  }
1763  }
1764  }
1766  }
1767  }
1768 
1769  /*---- check for auto restart --------------------------------*/
1770  if (auto_restart > 0 && ss_time() > auto_restart) {
1771  /* check if really stopped */
1772  size = sizeof(state);
1773  status = db_get_value(hDB, 0, "Runinfo/State", &state, &size, TID_INT, TRUE);
1774  if (status != DB_SUCCESS)
1775  cm_msg(MERROR, "scheduler", "cannot get Runinfo/State in database");
1776 
1777  if (state == STATE_STOPPED) {
1778  auto_restart = 0;
1779  size = sizeof(run_number);
1780  status =
1781  db_get_value(hDB, 0, "/Runinfo/Run number", &run_number, &size, TID_INT,
1782  TRUE);
1783  assert(status == SUCCESS);
1784 
1785  if (run_number <= 0) {
1786  cm_msg(MERROR, "main", "aborting on attempt to use invalid run number %d",
1787  run_number);
1788  abort();
1789  }
1790 
1791  cm_msg(MTALK, "main", "starting new run");
1792  status = cm_transition(TR_START, run_number + 1, NULL, 0, SYNC, FALSE);
1793  if (status != CM_SUCCESS)
1794  cm_msg(MERROR, "main", "cannot restart run");
1795  }
1796  }
1797 
1798  /*---- check network messages ----------------------------------*/
1799  if (run_state == STATE_RUNNING && interrupt_eq == NULL) {
1800  /* only call yield once every 100ms when running */
1801  if (actual_millitime - last_time_network > 100) {
1802  status = cm_yield(0);
1803  last_time_network = actual_millitime;
1804  } else
1805  status = RPC_SUCCESS;
1806  } else
1807  /* when run is stopped or interrupts used,
1808  call yield with 100ms timeout */
1809  status = cm_yield(100);
1810 
1811  /* exit for VxWorks */
1812  if (fe_stop)
1813  status = RPC_SHUTDOWN;
1814 
1815  } while (status != RPC_SHUTDOWN && status != SS_ABORT);
1816 
1817  net_error:
1818 
1819  return status;
1820 }
void send_all_periodic_events ( INT  transition)
int send_event ( INT  index)
INT tr_pause ( INT  rn,
char *  error 
)

Definition at line 471 of file mfe_mucap.c.

References display_period, FALSE, interrupt_enable(), pause_run(), run_number, run_state, send_all_periodic_events(), status, and TRUE.

Referenced by main().

472 {
473  INT status;
474 
475  /* disable interrupts */
477 
478  status = pause_run(rn, error);
479 
480  if (status == CM_SUCCESS) {
481  run_state = STATE_PAUSED;
482  run_number = rn;
483 
484  send_all_periodic_events(TR_PAUSE);
485 
486  if (display_period)
487  ss_printf(14, 2, "Paused ");
488  } else
490 
491  return status;
492 }
INT tr_resume ( INT  rn,
char *  error 
)

Definition at line 496 of file mfe_mucap.c.

References display_period, interrupt_enable(), resume_run(), run_number, run_state, send_all_periodic_events(), status, and TRUE.

497 {
498  INT status;
499 
500  status = resume_run(rn, error);
501 
502  if (status == CM_SUCCESS) {
503  run_state = STATE_RUNNING;
504  run_number = rn;
505 
506  send_all_periodic_events(TR_RESUME);
507 
508  if (display_period)
509  ss_printf(14, 2, "Running ");
510 
511  /* enable interrupts */
513  }
514 
515  return status;
516 }
INT tr_start ( INT  rn,
char *  error 
)

Definition at line 388 of file mfe_mucap.c.

References begin_of_run(), display_period, equipment, i, interrupt_enable(), run_number, run_state, send_all_periodic_events(), status, and TRUE.

389 {
390  INT i, status;
391 
392  /* reset serial numbers */
393  for (i = 0; equipment[i].name[0]; i++) {
394  equipment[i].serial_number = 1;
395  equipment[i].subevent_number = 0;
396  equipment[i].stats.events_sent = 0;
397  equipment[i].odb_in = equipment[i].odb_out = 0;
398  }
399 
400  status = begin_of_run(rn, error);
401 
402  if (status == CM_SUCCESS) {
403  run_state = STATE_RUNNING;
404  run_number = rn;
405 
406  send_all_periodic_events(TR_START);
407 
408  if (display_period) {
409  ss_printf(14, 2, "Running ");
410  ss_printf(36, 2, "%d", rn);
411  }
412 
413  /* enable interrupts */
415  }
416 
417  return status;
418 }
INT tr_stop ( INT  rn,
char *  error 
)

Definition at line 422 of file mfe_mucap.c.

References display_period, end_of_run(), eq, equipment, FALSE, i, interrupt_enable(), run_number, run_state, send_all_periodic_events(), status, and TRUE.

423 {
424  INT status, i;
425  EQUIPMENT *eq;
426 
427  /* disable interrupts */
429 
430  status = end_of_run(rn, error);
431 
432  if (status == CM_SUCCESS) {
433  /* don't send events if already stopped */
434  if (run_state != STATE_STOPPED)
435  send_all_periodic_events(TR_STOP);
436 
437  run_state = STATE_STOPPED;
438  run_number = rn;
439 
440  if (display_period)
441  ss_printf(14, 2, "Stopped ");
442  } else
444 
445  /* flush remaining buffered events */
446  rpc_flush_event();
447  for (i = 0; equipment[i].name[0]; i++)
448  if (equipment[i].buffer_handle) {
449  INT err = bm_flush_cache(equipment[i].buffer_handle, SYNC);
450  if (err != BM_SUCCESS) {
451  cm_msg(MERROR, "tr_prestop", "bm_flush_cache(SYNC) error %d", err);
452  return err;
453  }
454  }
455 
456  /* update final statistics record in ODB */
457  for (i = 0; equipment[i].name[0]; i++) {
458  eq = &equipment[i];
459  eq->stats.events_sent += eq->events_sent;
460  eq->bytes_sent = 0;
461  eq->events_sent = 0;
462  }
463 
464  db_send_changed_records();
465 
466  return status;
467 }
void update_odb ( EVENT_HEADER *  pevent,
HNDLE  hKey,
INT  format 
)

Definition at line 812 of file mfe_mucap.c.

References hDB, i, key, MIN, printf(), size, and status.

813 {
814  INT size, i, ni4, tsize, status, n_data;
815  void *pdata;
816  char name[5];
817  BANK_HEADER *pbh;
818  BANK *pbk;
819  BANK32 *pbk32;
820  void *pydata;
821  DWORD odb_type;
822  DWORD *pyevt, bkname;
823  WORD bktype;
824  HNDLE hKeyRoot, hKeyl;
825  KEY key;
826 
827  /* outcommented sind db_find_key does not work in FTCP mode, SR 25.4.03
828  rpc_set_option(-1, RPC_OTRANSPORT, RPC_FTCP); */
829 
830  if (format == FORMAT_FIXED) {
831  if (db_set_record(hDB, hKey, (char *) (pevent + 1),
832  pevent->data_size, 0) != DB_SUCCESS)
833  cm_msg(MERROR, "update_odb", "event #%d size mismatch", pevent->event_id);
834  } else if (format == FORMAT_MIDAS) {
835  pbh = (BANK_HEADER *) (pevent + 1);
836  pbk = NULL;
837  pbk32 = NULL;
838  do {
839  /* scan all banks */
840  if (bk_is32(pbh)) {
841  size = bk_iterate32(pbh, &pbk32, &pdata);
842  if (pbk32 == NULL)
843  break;
844  bkname = *((DWORD *) pbk32->name);
845  bktype = (WORD) pbk32->type;
846  } else {
847  size = bk_iterate(pbh, &pbk, &pdata);
848  if (pbk == NULL)
849  break;
850  bkname = *((DWORD *) pbk->name);
851  bktype = (WORD) pbk->type;
852  }
853 
854  n_data = size;
855  if (rpc_tid_size(bktype & 0xFF))
856  n_data /= rpc_tid_size(bktype & 0xFF);
857 
858  /* get bank key */
859  *((DWORD *) name) = bkname;
860  name[4] = 0;
861 
862  if (bktype == TID_STRUCT) {
863  status = db_find_key(hDB, hKey, name, &hKeyRoot);
864  if (status != DB_SUCCESS) {
865  cm_msg(MERROR, "update_odb",
866  "please define bank %s in BANK_LIST in frontend.c", name);
867  continue;
868  }
869 
870  /* write structured bank */
871  for (i = 0;; i++) {
872  status = db_enum_key(hDB, hKeyRoot, i, &hKeyl);
873  if (status == DB_NO_MORE_SUBKEYS)
874  break;
875 
876  db_get_key(hDB, hKeyl, &key);
877 
878  /* adjust for alignment */
879  if (key.type != TID_STRING && key.type != TID_LINK)
880  pdata =
881  (void *) VALIGN(pdata, MIN(ss_get_struct_align(), key.item_size));
882 
883  status = db_set_data(hDB, hKeyl, pdata, key.item_size * key.num_values,
884  key.num_values, key.type);
885  if (status != DB_SUCCESS) {
886  cm_msg(MERROR, "update_odb", "cannot write %s to ODB", name);
887  continue;
888  }
889 
890  /* shift data pointer to next item */
891  pdata = (char *) pdata + key.item_size * key.num_values;
892  }
893  } else {
894  /* write variable length bank */
895  if (n_data > 0)
896  db_set_value(hDB, hKey, name, pdata, size, n_data, bktype & 0xFF);
897  }
898 
899  } while (1);
900  } else if (format == FORMAT_YBOS) {
901 #ifdef YBOS_SUPPORT
902  YBOS_BANK_HEADER *pybkh;
903 
904  /* skip the lrl (4 bytes per event) */
905  pyevt = (DWORD *) (pevent + 1);
906  pybkh = NULL;
907  do {
908  /* scan all banks */
909  ni4 = ybk_iterate(pyevt, &pybkh, &pydata);
910  if (pybkh == NULL || ni4 == 0)
911  break;
912 
913  /* find the corresponding odb type */
914  tsize = odb_type = 0;
915  for (i = 0; id_map[0].ybos_type > 0; i++) {
916  if (pybkh->type == id_map[i].ybos_type) {
917  odb_type = id_map[i].odb_type;
918  tsize = id_map[i].tsize;
919  break;
920  }
921  }
922 
923  /* extract bank name (key name) */
924  *((DWORD *) name) = pybkh->name;
925  name[4] = 0;
926 
927  /* reject EVID bank */
928  if (strncmp(name, "EVID", 4) == 0)
929  continue;
930 
931  /* correct YBS number of entries */
932  if (pybkh->type == D8_BKTYPE)
933  ni4 /= 2;
934  if (pybkh->type == I2_BKTYPE)
935  ni4 *= 2;
936  if (pybkh->type == I1_BKTYPE || pybkh->type == A1_BKTYPE)
937  ni4 *= 4;
938 
939  /* write bank to ODB, ni4 always in I*4 */
940  size = ni4 * tsize;
941  if ((status =
942  db_set_value(hDB, hKey, name, pydata, size, ni4,
943  odb_type & 0xFF)) != DB_SUCCESS) {
944  printf("status:%i odb_type:%li name:%s ni4:%i size:%i tsize:%i\n", status,
945  odb_type, name, ni4, size, tsize);
946  for (i = 0; i < 6; i++) {
947  float * fpydata = (float *) pydata;
948  printf("data: %f\n", *(fpydata)++);
949  }
950  }
951  } while (1);
952 #endif /* YBOS_SUPPORT */
953  }
954 
955  rpc_set_option(-1, RPC_OTRANSPORT, RPC_TCP);
956 }

Variable Documentation

DWORD actual_millitime

Definition at line 302 of file mfe_mucap.c.

DWORD actual_time

Definition at line 301 of file mfe_mucap.c.

DWORD auto_restart = 0

Definition at line 312 of file mfe_mucap.c.

int crate_number
BOOL debug

Definition at line 311 of file mfe_mucap.c.

INT display_period

Definition at line 43 of file crate.cpp.

EQUIPMENT equipment[]

Definition at line 72 of file crate.cpp.

INT event_buffer_size

Definition at line 53 of file crate.cpp.

char exp_name[NAME_LENGTH]

Definition at line 305 of file mfe_mucap.c.

INT fe_stop = 0

Definition at line 310 of file mfe_mucap.c.

BOOL frontend_call_loop

Definition at line 39 of file crate.cpp.

char* frontend_file_name

Definition at line 36 of file crate.cpp.

INT frontend_index = -1

Definition at line 314 of file mfe_mucap.c.

Referenced by frontend_early_init(), get_frontend_index(), main(), and register_equipment().

char* frontend_name

Definition at line 33 of file crate.cpp.

char full_frontend_name[256]
HNDLE hDB

Definition at line 316 of file mfe_mucap.c.

char host_name[HOST_NAME_LENGTH]

Definition at line 304 of file mfe_mucap.c.

BOOL interrupt_enabled

Definition at line 1179 of file mfe_mucap.c.

EQUIPMENT* interrupt_eq = NULL

Definition at line 337 of file mfe_mucap.c.

EVENT_HEADER* interrupt_odb_buffer

Definition at line 338 of file mfe_mucap.c.

BOOL interrupt_odb_buffer_valid

Definition at line 339 of file mfe_mucap.c.

INT manual_trigger_event_id = 0

Definition at line 313 of file mfe_mucap.c.

Referenced by manual_trigger(), and scheduler().

INT max_bytes_per_sec

Definition at line 308 of file mfe_mucap.c.

INT max_event_size

Definition at line 47 of file crate.cpp.

INT max_event_size_frag

Definition at line 50 of file crate.cpp.

INT optimize = 0

Definition at line 309 of file mfe_mucap.c.

INT run_number

Definition at line 300 of file mfe_mucap.c.

INT run_state

PROGRAM: crate.cpp DESCRIPTION: Control and readout of CAEN V1724 digitizers. author: V.Tishchenko date: 12-Aug-2012

Modifications:

Definition at line 299 of file mfe_mucap.c.