Go to the source code of this file.
Defines | |
#define | SERVER_CACHE_SIZE 100000 |
#define | ODB_UPDATE_TIME 1000 |
#define | DEFAULT_FE_TIMEOUT 60000 |
#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\Status = STRING : [256] \n\Status color = STRING : [32] \n\" |
#define | EQUIPMENT_STATISTICS_STR "\Events sent = DOUBLE : 0\n\Events per sec. = DOUBLE : 0\n\kBytes per sec. = DOUBLE : 0\n\" |
#define | MFE_ERROR_SIZE 10 |
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, POINTER_T adr) |
int | readout_thread (void *param) |
void | mfe_error_check (void) |
int | send_event (INT idx, BOOL manual_trig) |
int | receive_trigger_event (EQUIPMENT *eq) |
void | send_all_periodic_events (INT transition) |
void | interrupt_routine (void) |
void | readout_enable (BOOL flag) |
int | readout_enabled (void) |
void | display (BOOL bInit) |
void | rotate_wheel (void) |
BOOL | logger_root () |
INT | check_polled_events (void) |
void | set_rate_period (int ms) |
int | get_rate_period () |
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 idx, void *prpc_param[]) |
int | sc_thread (void *info) |
INT | device_driver (DEVICE_DRIVER *device_drv, INT cmd,...) |
INT | register_equipment (void) |
INT | initialize_equipment (void) |
int | set_equipment_status (const char *name, const char *eqipment_status, const char *status_color) |
void | update_odb (EVENT_HEADER *pevent, HNDLE hKey, INT format) |
int | message_print (const char *msg) |
INT | scheduler (void) |
INT | get_frontend_index () |
void | mfe_set_error (void(*dispatcher)(const char *)) |
void | mfe_error (const char *error) |
int | main (int argc, char *argv[]) |
Variables | |
char * | frontend_name |
char * | frontend_file_name |
BOOL | frontend_call_loop |
INT | max_event_size |
INT | max_event_size_frag |
INT | event_buffer_size |
INT | display_period |
INT | rpc_mode = 1 |
INT | run_state |
INT | run_number |
DWORD | actual_time |
DWORD | actual_millitime |
DWORD | rate_period |
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 |
BOOL | lockout_readout_thread = TRUE |
HNDLE | hDB |
EQUIPMENT | equipment [] |
EQUIPMENT * | interrupt_eq = NULL |
EQUIPMENT * | multithread_eq = NULL |
BOOL | slowcont_eq = FALSE |
void * | event_buffer |
void * | frag_buffer = NULL |
int * | n_events |
int | rbh1 = 0 |
int | rbh2 = 0 |
int | rbh1_next = 0 |
int | rbh2_next = 0 |
volatile int | stop_all_threads = 0 |
volatile int | readout_thread_active = 0 |
static int | _readout_enabled_flag = 0 |
void(*) | mfe_error_dispatcher (const char *) = NULL |
char | mfe_error_str [MFE_ERROR_SIZE][256] |
int | mfe_error_r |
int | mfe_error_w |
MUTEX_T * | mfe_mutex = NULL |
#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\Status = STRING : [256] \n\Status color = STRING : [32] \n\" |
#define MFE_ERROR_SIZE 10 |
#define SERVER_CACHE_SIZE 100000 |
INT check_polled_events | ( | void | ) |
Definition at line 1605 of file mfe.c.
Referenced by tr_stop().
01606 { 01607 EQUIPMENT_INFO *eq_info; 01608 EQUIPMENT *eq; 01609 EVENT_HEADER *pevent, *pfragment; 01610 DWORD readout_start, sent, size; 01611 INT i, idx, source, events_sent, status; 01612 char *pdata; 01613 unsigned char *pd; 01614 01615 events_sent = 0; 01616 actual_millitime = ss_millitime(); 01617 01618 /*---- loop over equipment table -------------------------------*/ 01619 for (idx = 0;; idx++) { 01620 eq = &equipment[idx]; 01621 eq_info = &eq->info; 01622 01623 /* check if end of equipment list */ 01624 if (!eq->name[0]) 01625 break; 01626 01627 if (!eq_info->enabled) 01628 continue; 01629 01630 if (eq->status != FE_SUCCESS) 01631 continue; 01632 01633 if ((eq_info->eq_type & EQ_POLLED) == 0) 01634 continue; 01635 01636 /*---- check polled events ----*/ 01637 readout_start = actual_millitime; 01638 pevent = NULL; 01639 01640 while ((source = poll_event(eq_info->source, eq->poll_count, FALSE)) > 0) { 01641 01642 if (eq_info->eq_type & EQ_FRAGMENTED) 01643 pevent = frag_buffer; 01644 else 01645 pevent = (EVENT_HEADER *)event_buffer; 01646 01647 /* compose MIDAS event header */ 01648 pevent->event_id = eq_info->event_id; 01649 pevent->trigger_mask = eq_info->trigger_mask; 01650 pevent->data_size = 0; 01651 pevent->time_stamp = actual_time; 01652 pevent->serial_number = eq->serial_number; 01653 01654 /* put source at beginning of event, will be overwritten by 01655 user readout code, just a special feature used by some 01656 multi-source applications */ 01657 *(INT *) (pevent + 1) = source; 01658 01659 if (eq->info.num_subevents) { 01660 eq->subevent_number = 0; 01661 do { 01662 *(INT *) ((char *) (pevent + 1) + pevent->data_size) = source; 01663 01664 /* call user readout routine for subevent indicating offset */ 01665 size = eq->readout((char *) (pevent + 1), pevent->data_size); 01666 pevent->data_size += size; 01667 if (size > 0) { 01668 if (pevent->data_size + sizeof(EVENT_HEADER) > 01669 (DWORD) max_event_size) { 01670 cm_msg(MERROR, "check_polled_events", 01671 "Event size %ld larger than maximum size %d", 01672 (long) (pevent->data_size + sizeof(EVENT_HEADER)), 01673 max_event_size); 01674 } 01675 01676 eq->subevent_number++; 01677 eq->serial_number++; 01678 } 01679 01680 /* wait for next event */ 01681 do { 01682 source = poll_event(eq_info->source, eq->poll_count, FALSE); 01683 01684 if (source == FALSE) { 01685 actual_millitime = ss_millitime(); 01686 01687 /* repeat no more than period */ 01688 if (actual_millitime - readout_start > (DWORD) eq_info->period) 01689 break; 01690 } 01691 } while (source == FALSE); 01692 01693 } while (eq->subevent_number < eq->info.num_subevents && source); 01694 01695 /* notify readout routine about end of super-event */ 01696 pevent->data_size = eq->readout((char *) (pevent + 1), -1); 01697 } else { 01698 /* call user readout routine indicating event source */ 01699 pevent->data_size = eq->readout((char *) (pevent + 1), 0); 01700 01701 /* check event size */ 01702 if (eq_info->eq_type & EQ_FRAGMENTED) { 01703 if (pevent->data_size + sizeof(EVENT_HEADER) > (DWORD) max_event_size_frag) { 01704 cm_msg(MERROR, "check_polled_events", 01705 "Event size %ld larger than maximum size %d for frag. ev.", 01706 (long) (pevent->data_size + sizeof(EVENT_HEADER)), 01707 max_event_size_frag); 01708 assert(FALSE); 01709 } 01710 } else { 01711 if (pevent->data_size + sizeof(EVENT_HEADER) > (DWORD) max_event_size) { 01712 cm_msg(MERROR, "check_polled_events", 01713 "Event size %ld larger than maximum size %d", 01714 (long) (pevent->data_size + sizeof(EVENT_HEADER)), 01715 max_event_size); 01716 assert(FALSE); 01717 } 01718 } 01719 01720 /* increment serial number if event read out sucessfully */ 01721 if (pevent->data_size) 01722 eq->serial_number++; 01723 } 01724 01725 /* send event */ 01726 if (pevent->data_size) { 01727 01728 /* check for fragmented event */ 01729 if (eq_info->eq_type & EQ_FRAGMENTED) { 01730 /* compose fragments */ 01731 pfragment = event_buffer; 01732 01733 /* compose MIDAS event header */ 01734 memcpy(pfragment, pevent, sizeof(EVENT_HEADER)); 01735 pfragment->event_id |= EVENTID_FRAG1; 01736 01737 /* store total event size */ 01738 pd = (unsigned char *) (pfragment + 1); 01739 size = pevent->data_size; 01740 for (i = 0; i < 4; i++) { 01741 pd[i] = (unsigned char) (size & 0xFF); /* little endian, please! */ 01742 size >>= 8; 01743 } 01744 01745 pfragment->data_size = sizeof(DWORD); 01746 01747 pdata = (char *) (pevent + 1); 01748 01749 for (i = 0, sent = 0; sent < pevent->data_size; i++) { 01750 if (i > 0) { 01751 pfragment = event_buffer; 01752 01753 /* compose MIDAS event header */ 01754 memcpy(pfragment, pevent, sizeof(EVENT_HEADER)); 01755 pfragment->event_id |= EVENTID_FRAG; 01756 01757 /* copy portion of event */ 01758 size = pevent->data_size - sent; 01759 if (size > max_event_size - sizeof(EVENT_HEADER)) 01760 size = max_event_size - sizeof(EVENT_HEADER); 01761 01762 memcpy(pfragment + 1, pdata, size); 01763 pfragment->data_size = size; 01764 sent += size; 01765 pdata += size; 01766 } 01767 01768 /* send event to buffer */ 01769 if (equipment[idx].buffer_handle) { 01770 status = rpc_send_event(equipment[idx].buffer_handle, pfragment, 01771 pfragment->data_size + sizeof(EVENT_HEADER), SYNC, rpc_mode); 01772 if (status != RPC_SUCCESS) { 01773 cm_msg(MERROR, "check_polled_events", "rpc_send_event(SYNC) error %d", status); 01774 return status; 01775 } 01776 01777 /* flush events from buffer */ 01778 rpc_flush_event(); 01779 } 01780 } 01781 01782 } else { /*-------------------*/ 01783 01784 /* send unfragmented event */ 01785 01786 /* send first event to ODB if logger writes in root format */ 01787 if (pevent->serial_number == 0) 01788 if (logger_root()) 01789 update_odb(pevent, eq->hkey_variables, eq->format); 01790 01791 status = rpc_send_event(eq->buffer_handle, pevent, 01792 pevent->data_size + sizeof(EVENT_HEADER), 01793 SYNC, rpc_mode); 01794 01795 if (status != SUCCESS) { 01796 cm_msg(MERROR, "check_polled_events", "rpc_send_event error %d", status); 01797 break; 01798 } 01799 } 01800 01801 eq->bytes_sent += pevent->data_size + sizeof(EVENT_HEADER); 01802 01803 if (eq->info.num_subevents) { 01804 eq->events_sent += eq->subevent_number; 01805 events_sent += eq->subevent_number; 01806 } else { 01807 eq->events_sent++; 01808 events_sent++; 01809 } 01810 01811 rotate_wheel(); 01812 } 01813 01814 actual_millitime = ss_millitime(); 01815 01816 /* repeat no more than period */ 01817 if (actual_millitime - readout_start > (DWORD) eq_info->period) 01818 break; 01819 01820 /* quit if event limit is reached */ 01821 if (eq_info->event_limit > 0 && 01822 eq->stats.events_sent + eq->events_sent >= eq_info->event_limit) 01823 break; 01824 } 01825 } 01826 01827 return events_sent; 01828 }
void display | ( | BOOL | bInit | ) |
Definition at line 1489 of file mfe.c.
01490 { 01491 INT i, status; 01492 time_t full_time; 01493 char str[30]; 01494 01495 if (bInit) { 01496 ss_clear_screen(); 01497 01498 if (host_name[0]) 01499 strcpy(str, host_name); 01500 else 01501 strcpy(str, "<local>"); 01502 01503 ss_printf(0, 0, "%s connected to %s. Press \"!\" to exit", full_frontend_name, str); 01504 ss_printf(0, 1, 01505 "================================================================================"); 01506 ss_printf(0, 2, "Run status: %s", 01507 run_state == STATE_STOPPED ? "Stopped" : run_state == 01508 STATE_RUNNING ? "Running" : "Paused"); 01509 ss_printf(25, 2, "Run number %d ", run_number); 01510 ss_printf(0, 3, 01511 "================================================================================"); 01512 ss_printf(0, 4, 01513 "Equipment Status Events Events/sec Rate[kB/s] ODB->FE FE->ODB"); 01514 ss_printf(0, 5, 01515 "--------------------------------------------------------------------------------"); 01516 for (i = 0; equipment[i].name[0]; i++) 01517 ss_printf(0, i + 6, "%s", equipment[i].name); 01518 } 01519 01520 /* display time */ 01521 time(&full_time); 01522 strcpy(str, ctime(&full_time) + 11); 01523 str[8] = 0; 01524 ss_printf(72, 0, "%s", str); 01525 01526 for (i = 0; equipment[i].name[0]; i++) { 01527 status = equipment[i].status; 01528 01529 if ((status == 0 || status == FE_SUCCESS) && equipment[i].info.enabled) 01530 ss_printf(14, i + 6, "OK "); 01531 else if (!equipment[i].info.enabled) 01532 ss_printf(14, i + 6, "Disabled "); 01533 else if (status == FE_ERR_ODB) 01534 ss_printf(14, i + 6, "ODB Error"); 01535 else if (status == FE_ERR_HW) 01536 ss_printf(14, i + 6, "HW Error "); 01537 else if (status == FE_ERR_DISABLED) 01538 ss_printf(14, i + 6, "Disabled "); 01539 else if (status == FE_ERR_DRIVER) 01540 ss_printf(14, i + 6, "Driver err"); 01541 else 01542 ss_printf(14, i + 6, "Unknown "); 01543 01544 if (equipment[i].stats.events_sent > 1E9) 01545 ss_printf(25, i + 6, "%1.3lfG ", equipment[i].stats.events_sent / 1E9); 01546 else if (equipment[i].stats.events_sent > 1E6) 01547 ss_printf(25, i + 6, "%1.3lfM ", equipment[i].stats.events_sent / 1E6); 01548 else 01549 ss_printf(25, i + 6, "%1.0lf ", equipment[i].stats.events_sent); 01550 ss_printf(36, i + 6, "%1.1lf ", equipment[i].stats.events_per_sec); 01551 ss_printf(47, i + 6, "%1.1lf ", equipment[i].stats.kbytes_per_sec); 01552 ss_printf(58, i + 6, "%ld ", equipment[i].odb_in); 01553 ss_printf(69, i + 6, "%ld ", equipment[i].odb_out); 01554 } 01555 01556 /* go to next line */ 01557 ss_printf(0, i + 6, ""); 01558 }
INT frontend_exit | ( | void | ) |
INT frontend_init | ( | void | ) |
INT frontend_loop | ( | void | ) |
INT get_frontend_index | ( | ) |
int get_rate_period | ( | ) |
INT initialize_equipment | ( | void | ) |
Definition at line 755 of file mfe.c.
Referenced by main().
00756 { 00757 INT idx, i, j, k, n, count; 00758 char str[256]; 00759 DWORD start_time, delta_time; 00760 EQUIPMENT_INFO *eq_info; 00761 EQUIPMENT_STATS *eq_stats; 00762 BOOL manual_trig_flag = FALSE; 00763 00764 /* scan EQUIPMENT table from FRONTEND.C */ 00765 for (idx = 0; equipment[idx].name[0]; idx++) { 00766 eq_info = &equipment[idx].info; 00767 eq_stats = &equipment[idx].stats; 00768 00769 /*---- initialize interrupt events -----------------------------*/ 00770 00771 if (eq_info->eq_type & EQ_INTERRUPT) { 00772 /* install interrupt for interrupt events */ 00773 00774 for (i = 0; equipment[i].name[0]; i++) 00775 if (equipment[i].info.eq_type & EQ_POLLED) { 00776 equipment[idx].status = FE_ERR_DISABLED; 00777 cm_msg(MINFO, "initialize_equipment", 00778 "Interrupt readout cannot be combined with polled readout"); 00779 } 00780 00781 if (equipment[idx].status != FE_ERR_DISABLED) { 00782 if (eq_info->enabled) { 00783 if (interrupt_eq) { 00784 equipment[idx].status = FE_ERR_DISABLED; 00785 cm_msg(MINFO, "initialize_equipment", 00786 "Defined more than one equipment with interrupt readout"); 00787 } else { 00788 interrupt_eq = &equipment[idx]; 00789 00790 /* create ring buffer for inter-thread data transfer */ 00791 if (!rbh1) { 00792 rb_create(event_buffer_size, max_event_size, &rbh1); 00793 rbh2 = rbh1; 00794 } 00795 00796 /* establish interrupt handler */ 00797 interrupt_configure(CMD_INTERRUPT_ATTACH, eq_info->source, 00798 (POINTER_T) interrupt_routine); 00799 } 00800 } else { 00801 equipment[idx].status = FE_ERR_DISABLED; 00802 cm_msg(MINFO, "initialize_equipment", 00803 "Equipment %s disabled in file \"frontend.c\"", 00804 equipment[idx].name); 00805 } 00806 } 00807 } 00808 00809 /*---- evaluate polling count ----------------------------------*/ 00810 00811 if (eq_info->eq_type & (EQ_POLLED | EQ_MULTITHREAD)) { 00812 if (eq_info->eq_type & EQ_INTERRUPT) { 00813 if (eq_info->eq_type & EQ_POLLED) 00814 cm_msg(MERROR, "register_equipment", 00815 "Equipment \"%s\" cannot be of type EQ_INTERRUPT and EQ_POLLED at the same time", 00816 equipment[idx].name); 00817 else 00818 cm_msg(MERROR, "register_equipment", 00819 "Equipment \"%s\" cannot be of type EQ_INTERRUPT and EQ_MULTITHREAD at the same time", 00820 equipment[idx].name); 00821 return 0; 00822 } 00823 00824 if (display_period) 00825 printf("\nCalibrating"); 00826 00827 count = 1; 00828 do { 00829 if (display_period) 00830 printf("."); 00831 00832 start_time = ss_millitime(); 00833 00834 poll_event(equipment[idx].info.source, count, TRUE); 00835 00836 delta_time = ss_millitime() - start_time; 00837 00838 if (count == 1 && delta_time > eq_info->period * 1.2) { 00839 cm_msg(MERROR, "register_equipment", "Polling routine with count=1 takes %d ms", delta_time); 00840 ss_sleep(3000); 00841 break; 00842 } 00843 00844 if (delta_time > 0) 00845 count = (INT) ((double) count * eq_info->period / delta_time); 00846 else 00847 count *= 100; 00848 00849 } while (delta_time > eq_info->period * 1.2 || delta_time < eq_info->period * 0.8); 00850 00851 equipment[idx].poll_count = count; 00852 } 00853 00854 /*---- initialize multithread events -------------------------*/ 00855 00856 if (eq_info->eq_type & EQ_MULTITHREAD) { 00857 /* install interrupt for interrupt events */ 00858 00859 for (i = 0; equipment[i].name[0]; i++) 00860 if (equipment[i].info.eq_type & EQ_POLLED) { 00861 equipment[idx].status = FE_ERR_DISABLED; 00862 cm_msg(MINFO, "initialize_equipment", 00863 "Multi-threaded readout cannot be combined with polled readout for equipment \'%s\'", equipment[i].name); 00864 } 00865 00866 if (equipment[idx].status != FE_ERR_DISABLED) { 00867 if (eq_info->enabled) { 00868 if (multithread_eq) { 00869 equipment[idx].status = FE_ERR_DISABLED; 00870 cm_msg(MINFO, "initialize_equipment", 00871 "Defined more than one equipment with multi-threaded readout for equipment \'%s\'", equipment[i].name); 00872 } else { 00873 multithread_eq = &equipment[idx]; 00874 00875 /* create ring buffer for inter-thread data transfer */ 00876 if (!rbh1) { 00877 rb_create(event_buffer_size, max_event_size, &rbh1); 00878 rbh2 = rbh1; 00879 } 00880 00881 /* create hardware reading thread */ 00882 readout_enable(FALSE); 00883 ss_thread_create(readout_thread, multithread_eq); 00884 } 00885 } else { 00886 equipment[idx].status = FE_ERR_DISABLED; 00887 cm_msg(MINFO, "initialize_equipment", 00888 "Equipment %s disabled in file \"frontend.c\"", 00889 equipment[idx].name); 00890 } 00891 } 00892 } 00893 00894 /*---- initialize slow control equipment ---------------------*/ 00895 00896 if (eq_info->eq_type & EQ_SLOW) { 00897 00898 set_equipment_status(equipment[idx].name, "Initializing...", "yellow"); 00899 00900 /* resolve duplicate device names */ 00901 for (i = 0; equipment[idx].driver[i].name[0]; i++) 00902 for (j = i + 1; equipment[idx].driver[j].name[0]; j++) 00903 if (equal_ustring(equipment[idx].driver[i].name, 00904 equipment[idx].driver[j].name)) { 00905 strcpy(str, equipment[idx].driver[i].name); 00906 for (k = 0, n = 0; equipment[idx].driver[k].name[0]; k++) 00907 if (equal_ustring(str, equipment[idx].driver[k].name)) 00908 sprintf(equipment[idx].driver[k].name, "%s_%d", str, n++); 00909 00910 break; 00911 } 00912 00913 /* loop over equipment list and call class driver's init method */ 00914 if (eq_info->enabled) { 00915 printf("%s:\n", equipment[idx].name); 00916 equipment[idx].status = equipment[idx].cd(CMD_INIT, &equipment[idx]); 00917 00918 if (equipment[idx].status == FE_SUCCESS) 00919 set_equipment_status(equipment[idx].name, "Ok", "#00FF00"); 00920 else if (equipment[idx].status == FE_ERR_HW) 00921 set_equipment_status(equipment[idx].name, "Hardware error", "#FF0000"); 00922 else if (equipment[idx].status == FE_ERR_ODB) 00923 set_equipment_status(equipment[idx].name, "ODB error", "#FF0000"); 00924 else if (equipment[idx].status == FE_ERR_DRIVER) 00925 set_equipment_status(equipment[idx].name, "Driver error", "#FF0000"); 00926 else 00927 set_equipment_status(equipment[idx].name, "Error", "#FF0000"); 00928 00929 } else { 00930 equipment[idx].status = FE_ERR_DISABLED; 00931 set_equipment_status(equipment[idx].name, "Disbled", "yellow"); 00932 } 00933 00934 /* now start threads if requested */ 00935 if (equipment[idx].status == FE_SUCCESS) 00936 equipment[idx].cd(CMD_START, &equipment[idx]); /* start threads for this equipment */ 00937 00938 /* remember that we have slowcontrol equipment (needed later for scheduler) */ 00939 slowcont_eq = TRUE; 00940 00941 /* let user read error messages */ 00942 if (equipment[idx].status != FE_SUCCESS && 00943 equipment[idx].status != FE_ERR_DISABLED) 00944 ss_sleep(3000); 00945 } 00946 00947 /*---- register callback for manual triggered events -----------*/ 00948 if (eq_info->eq_type & EQ_MANUAL_TRIG) { 00949 if (!manual_trig_flag) 00950 cm_register_function(RPC_MANUAL_TRIG, manual_trigger); 00951 00952 manual_trig_flag = TRUE; 00953 } 00954 } 00955 00956 if (slowcont_eq) 00957 cm_msg(MINFO, "initialize_equipment", "Slow control equipment initialized"); 00958 00959 return SUCCESS; 00960 }
Definition at line 252 of file frontend.c.
00253 { 00254 switch (cmd) { 00255 case CMD_INTERRUPT_ENABLE: 00256 break; 00257 case CMD_INTERRUPT_DISABLE: 00258 break; 00259 case CMD_INTERRUPT_ATTACH: 00260 break; 00261 case CMD_INTERRUPT_DETACH: 00262 break; 00263 } 00264 return SUCCESS; 00265 }
void interrupt_routine | ( | void | ) |
Definition at line 1295 of file mfe.c.
Referenced by initialize_equipment().
01296 { 01297 int status; 01298 EVENT_HEADER *pevent; 01299 void *p; 01300 01301 /* get pointer for upcoming event. 01302 This is a blocking call if no space available */ 01303 status = rb_get_wp(rbh1, &p, 100000); 01304 01305 if (status == DB_SUCCESS) { 01306 pevent = (EVENT_HEADER *)p; 01307 01308 /* compose MIDAS event header */ 01309 pevent->event_id = interrupt_eq->info.event_id; 01310 pevent->trigger_mask = interrupt_eq->info.trigger_mask; 01311 pevent->data_size = 0; 01312 pevent->time_stamp = actual_time; 01313 pevent->serial_number = interrupt_eq->serial_number++; 01314 01315 /* call user readout routine */ 01316 pevent->data_size = interrupt_eq->readout((char *) (pevent + 1), 0); 01317 01318 /* send event */ 01319 if (pevent->data_size) { 01320 01321 /* put event into ring buffer */ 01322 rb_increment_wp(rbh1, sizeof(EVENT_HEADER) + pevent->data_size); 01323 01324 } else 01325 interrupt_eq->serial_number--; 01326 } 01327 }
BOOL logger_root | ( | ) |
Definition at line 1578 of file mfe.c.
Referenced by receive_trigger_event().
01580 { 01581 int size, i, status; 01582 char str[80]; 01583 HNDLE hKeyRoot, hKey; 01584 01585 if (db_find_key(hDB, 0, "/Logger/Channels", &hKeyRoot) == DB_SUCCESS) { 01586 for (i = 0;; i++) { 01587 status = db_enum_key(hDB, hKeyRoot, i, &hKey); 01588 if (status == DB_NO_MORE_SUBKEYS) 01589 break; 01590 01591 strcpy(str, "MIDAS"); 01592 size = sizeof(str); 01593 db_get_value(hDB, hKey, "Settings/Format", str, &size, TID_STRING, TRUE); 01594 01595 if (equal_ustring(str, "ROOT")) 01596 return TRUE; 01597 } 01598 } 01599 01600 return FALSE; 01601 }
int main | ( | int | argc, | |
char * | argv[] | |||
) |
Definition at line 2464 of file mfe.c.
02466 { 02467 INT status, i, j, size; 02468 INT daemon_flag; 02469 int sys_max_event_size = MAX_EVENT_SIZE; 02470 02471 host_name[0] = 0; 02472 exp_name[0] = 0; 02473 debug = FALSE; 02474 daemon_flag = 0; 02475 02476 setbuf(stdout, 0); 02477 setbuf(stderr, 0); 02478 02479 #ifdef SIGPIPE 02480 signal(SIGPIPE, SIG_IGN); 02481 #endif 02482 02483 #ifdef OS_VXWORKS 02484 if (ahost_name) 02485 strcpy(host_name, ahost_name); 02486 if (aexp_name) 02487 strcpy(exp_name, aexp_name); 02488 debug = adebug; 02489 #else 02490 02491 /* get default from environment */ 02492 cm_get_environment(host_name, sizeof(host_name), exp_name, sizeof(exp_name)); 02493 02494 /* parse command line parameters */ 02495 for (i = 1; i < argc; i++) { 02496 if (argv[i][0] == '-' && argv[i][1] == 'd') 02497 debug = TRUE; 02498 else if (argv[i][0] == '-' && argv[i][1] == 'D') 02499 daemon_flag = 1; 02500 else if (argv[i][0] == '-' && argv[i][1] == 'O') 02501 daemon_flag = 2; 02502 else if (argv[i][0] == '-') { 02503 if (i + 1 >= argc || argv[i + 1][0] == '-') 02504 goto usage; 02505 if (argv[i][1] == 'e') 02506 strcpy(exp_name, argv[++i]); 02507 else if (argv[i][1] == 'h') 02508 strcpy(host_name, argv[++i]); 02509 else if (argv[i][1] == 'i') 02510 frontend_index = atoi(argv[++i]); 02511 else { 02512 usage: 02513 printf 02514 ("usage: frontend [-h Hostname] [-e Experiment] [-d] [-D] [-O] [-i n]\n"); 02515 printf(" [-d] Used to debug the frontend\n"); 02516 printf(" [-D] Become a daemon\n"); 02517 printf(" [-O] Become a daemon but keep stdout\n"); 02518 printf(" [-i n] Set frontend index (used for event building)\n"); 02519 return 0; 02520 } 02521 } 02522 } 02523 #endif 02524 02525 /* check event and buffer sizes */ 02526 if (event_buffer_size < 2 * max_event_size) { 02527 cm_msg(MERROR, "mainFE", "event_buffer_size %d too small for max. event size %d\n", event_buffer_size, max_event_size); 02528 ss_sleep(5000); 02529 return 1; 02530 } 02531 02532 #ifdef OS_VXWORKS 02533 /* override event_buffer_size in case of VxWorks 02534 take remaining free memory and use 20% of it for rb_ */ 02535 event_buffer_size = 2 * 10 * (max_event_size + sizeof(EVENT_HEADER) + sizeof(INT)); 02536 if (event_buffer_size > memFindMax()) { 02537 cm_msg(MERROR, "mainFE", "Not enough mem space for event size"); 02538 return 0; 02539 } 02540 /* takes overall 20% of the available memory resource for rb_() */ 02541 event_buffer_size = 0.2 * memFindMax(); 02542 #endif 02543 02544 /* retrieve frontend index from environment if defined */ 02545 if (getenv("MIDAS_FRONTEND_INDEX")) 02546 frontend_index = atoi(getenv("MIDAS_FRONTEND_INDEX")); 02547 02548 /* add frontend index to frontend name if present */ 02549 strcpy(full_frontend_name, frontend_name); 02550 if (frontend_index >= 0) 02551 sprintf(full_frontend_name + strlen(full_frontend_name), "%02d", frontend_index); 02552 02553 /* inform user of settings */ 02554 printf("Frontend name : %s\n", full_frontend_name); 02555 printf("Event buffer size : %d\n", event_buffer_size); 02556 printf("User max event size : %d\n", max_event_size); 02557 if (max_event_size_frag > 0) 02558 printf("User max frag. size : %d\n", max_event_size_frag); 02559 printf("# of events per buffer : %d\n\n", event_buffer_size / max_event_size); 02560 02561 if (daemon_flag) { 02562 printf("\nBecoming a daemon...\n"); 02563 ss_daemon_init(daemon_flag == 2); 02564 } 02565 02566 /* set default rate period */ 02567 set_rate_period(3000); 02568 02569 /* now connect to server */ 02570 if (display_period) { 02571 if (host_name[0]) { 02572 if (exp_name[0]) 02573 printf("Connect to experiment %s on host %s...\n", exp_name, host_name); 02574 else 02575 printf("Connect to experiment on host %s...\n", host_name); 02576 } else if (exp_name[0]) 02577 printf("Connect to experiment %s...\n", exp_name); 02578 else 02579 printf("Connect to experiment...\n"); 02580 } 02581 02582 status = cm_connect_experiment1(host_name, exp_name, full_frontend_name, 02583 NULL, DEFAULT_ODB_SIZE, DEFAULT_FE_TIMEOUT); 02584 if (status != CM_SUCCESS) { 02585 cm_msg(MERROR, "mainFE", "Cannot connect to experiment \'%s\' on host \'%s\', status %d", exp_name, host_name, status); 02586 /* let user read message before window might close */ 02587 ss_sleep(5000); 02588 return 1; 02589 } 02590 02591 if (display_period) 02592 printf("OK\n"); 02593 02594 /* allocate buffer space */ 02595 event_buffer = malloc(max_event_size); 02596 if (event_buffer == NULL) { 02597 cm_msg(MERROR, "mainFE", "mfe: Cannot allocate event buffer of max_event_size %d\n", max_event_size); 02598 return 1; 02599 } 02600 02601 /* remomve any dead frontend */ 02602 cm_cleanup(full_frontend_name, FALSE); 02603 02604 /* shutdown previous frontend */ 02605 status = cm_shutdown(full_frontend_name, FALSE); 02606 if (status == CM_SUCCESS && display_period) { 02607 printf("Previous frontend stopped\n"); 02608 02609 /* let user read message */ 02610 ss_sleep(3000); 02611 } 02612 02613 /* register transition callbacks */ 02614 if (cm_register_transition(TR_START, tr_start, 500) != CM_SUCCESS || 02615 cm_register_transition(TR_STOP, tr_stop, 500) != CM_SUCCESS || 02616 cm_register_transition(TR_PAUSE, tr_pause, 500) != CM_SUCCESS || 02617 cm_register_transition(TR_RESUME, tr_resume, 500) != CM_SUCCESS) { 02618 printf("Failed to start local RPC server"); 02619 cm_disconnect_experiment(); 02620 02621 /* let user read message before window might close */ 02622 ss_sleep(5000); 02623 return 1; 02624 } 02625 02626 cm_get_experiment_database(&hDB, &status); 02627 /* set time from server */ 02628 #ifdef OS_VXWORKS 02629 cm_synchronize(NULL); 02630 #endif 02631 02632 size = sizeof(sys_max_event_size); 02633 status = db_get_value(hDB, 0, "/Experiment/MAX_EVENT_SIZE", &sys_max_event_size, &size, TID_DWORD, TRUE); 02634 02635 if (max_event_size > sys_max_event_size) { 02636 cm_msg(MERROR, "mainFE", "Requested max_event_size (%d) exceeds max. system event size (%d)", 02637 max_event_size, sys_max_event_size); 02638 return 1; 02639 } 02640 02641 /* turn off watchdog if in debug mode */ 02642 if (debug) 02643 cm_set_watchdog_params(FALSE, 0); 02644 02645 /* increase RPC timeout to 2min for logger with exabyte or blocked disk */ 02646 rpc_set_option(-1, RPC_OTIMEOUT, 120000); 02647 02648 /* set own message print function */ 02649 if (display_period) 02650 cm_set_msg_print(MT_ALL, MT_ALL, message_print); 02651 02652 /* reqister equipment in ODB */ 02653 if (register_equipment() != SUCCESS) { 02654 if (display_period) 02655 printf("\n"); 02656 cm_disconnect_experiment(); 02657 02658 /* let user read message before window might close */ 02659 ss_sleep(5000); 02660 return 1; 02661 } 02662 02663 /* call user init function */ 02664 if (display_period) 02665 printf("Init hardware...\n"); 02666 if (frontend_init() != SUCCESS) { 02667 if (display_period) 02668 printf("\n"); 02669 cm_disconnect_experiment(); 02670 02671 /* let user read message before window might close */ 02672 ss_sleep(5000); 02673 return 1; 02674 } 02675 02676 initialize_equipment(); 02677 02678 if (display_period) 02679 printf("OK\n"); 02680 02681 /* initialize screen display */ 02682 if (display_period) { 02683 ss_sleep(300); 02684 display(TRUE); 02685 } 02686 02687 /* switch on interrupts or readout thread if running */ 02688 if (run_state == STATE_RUNNING) 02689 readout_enable(TRUE); 02690 02691 /* initialize ss_getchar */ 02692 ss_getchar(0); 02693 02694 /* call main scheduler loop */ 02695 status = scheduler(); 02696 02697 /* stop readout thread */ 02698 stop_all_threads = 1; 02699 rb_set_nonblocking(); 02700 while (readout_thread_active) 02701 ss_sleep(100); 02702 02703 /* reset terminal */ 02704 ss_getchar(TRUE); 02705 02706 /* switch off interrupts */ 02707 if (interrupt_eq) { 02708 interrupt_configure(CMD_INTERRUPT_DISABLE, 0, 0); 02709 interrupt_configure(CMD_INTERRUPT_DETACH, 0, 0); 02710 } 02711 02712 /* detach interrupts */ 02713 if (interrupt_eq != NULL) 02714 interrupt_configure(CMD_INTERRUPT_DETACH, interrupt_eq->info.source, 0); 02715 02716 /* call user exit function */ 02717 frontend_exit(); 02718 02719 /* close slow control drivers */ 02720 for (i = 0; equipment[i].name[0]; i++) 02721 if ((equipment[i].info.eq_type & EQ_SLOW) && equipment[i].status == FE_SUCCESS) { 02722 02723 for (j = 0; equipment[i].driver[j].name[0]; j++) 02724 if (equipment[i].driver[j].flags & DF_MULTITHREAD) 02725 break; 02726 02727 /* stop all threads if multithreaded */ 02728 if (equipment[i].driver[j].name[0] && equipment[i].status == FE_SUCCESS) 02729 equipment[i].cd(CMD_STOP, &equipment[i]); /* stop all threads */ 02730 } 02731 for (i = 0; equipment[i].name[0]; i++) 02732 if ((equipment[i].info.eq_type & EQ_SLOW) && equipment[i].status == FE_SUCCESS) 02733 equipment[i].cd(CMD_EXIT, &equipment[i]); /* close physical connections */ 02734 02735 free(n_events); 02736 02737 /* close network connection to server */ 02738 cm_disconnect_experiment(); 02739 02740 if (display_period) { 02741 if (status == RPC_SHUTDOWN) { 02742 ss_clear_screen(); 02743 ss_printf(0, 0, "Frontend shut down."); 02744 ss_printf(0, 1, ""); 02745 } 02746 } 02747 02748 if (status != RPC_SHUTDOWN) 02749 printf("Network connection aborted.\n"); 02750 02751 return 0; 02752 }
Definition at line 296 of file mfe.c.
00297 { 00298 int i; 00299 00300 i = idx; /* avoid compiler warning */ 00301 manual_trigger_event_id = CWORD(0); 00302 return SUCCESS; 00303 }
int message_print | ( | const char * | msg | ) |
Definition at line 1471 of file mfe.c.
Referenced by main().
01472 { 01473 char str[160]; 01474 01475 memset(str, ' ', 159); 01476 str[159] = 0; 01477 01478 if (msg[0] == '[') 01479 msg = strchr(msg, ']') + 2; 01480 01481 memcpy(str, msg, strlen(msg)); 01482 ss_printf(0, 20, str); 01483 01484 return 0; 01485 }
void mfe_error | ( | const char * | error | ) |
Definition at line 2435 of file mfe.c.
02438 { 02439 /* put error into FIFO */ 02440 ss_mutex_wait_for(mfe_mutex, 1000); 02441 strlcpy(mfe_error_str[mfe_error_w], error, 256); 02442 mfe_error_w = (mfe_error_w + 1) % MFE_ERROR_SIZE; 02443 ss_mutex_release(mfe_mutex); 02444 }
void mfe_error_check | ( | void | ) |
Definition at line 2446 of file mfe.c.
02447 { 02448 if (mfe_mutex != NULL) { 02449 ss_mutex_wait_for(mfe_mutex, 1000); 02450 if (mfe_error_w != mfe_error_r) { 02451 if (mfe_error_dispatcher != NULL) 02452 mfe_error_dispatcher(mfe_error_str[mfe_error_r]); 02453 mfe_error_r = (mfe_error_r + 1) % MFE_ERROR_SIZE; 02454 } 02455 ss_mutex_release(mfe_mutex); 02456 } 02457 }
void mfe_set_error | ( | void(*)(const char *) | dispatcher | ) |
Definition at line 2419 of file mfe.c.
02420 { 02421 int status; 02422 02423 mfe_error_dispatcher = dispatcher; 02424 mfe_error_r = mfe_error_w = 0; 02425 memset(mfe_error_str, 0, sizeof(mfe_error_str)); 02426 02427 if (mfe_mutex == NULL) { 02428 status = ss_mutex_create(&mfe_mutex); 02429 if (status != SS_SUCCESS && status != SS_CREATED) 02430 cm_msg(MERROR, "mfe_set_error", "Cannot create mutex\n"); 02431 } 02432 02433 }
Definition at line 86 of file midas_macro.h.
00090 { 00091 INT i, lam; 00092 00093 for (i = 0; i < count; i++) { 00094 cam_lam_read(source >> 24, &lam); 00095 if (lam) 00096 if (!test) 00097 return TRUE; 00098 } 00099 00100 return FALSE; 00101 }
void readout_enable | ( | BOOL | flag | ) |
Definition at line 1274 of file mfe.c.
Referenced by main(), tr_pause(), tr_resume(), tr_start(), and tr_stop().
01275 { 01276 _readout_enabled_flag = flag; 01277 01278 if (interrupt_eq) { 01279 if (flag) 01280 interrupt_configure(CMD_INTERRUPT_ENABLE, 0, 0); 01281 else 01282 interrupt_configure(CMD_INTERRUPT_DISABLE, 0, 0); 01283 } 01284 01285 if (multithread_eq) { 01286 /* readout thread might still be in readout, so wait until finished */ 01287 if (flag == 0) 01288 while (readout_thread_active) 01289 ss_sleep(10); 01290 } 01291 }
int readout_enabled | ( | void | ) |
Definition at line 1269 of file mfe.c.
Referenced by readout_thread().
01270 { 01271 return _readout_enabled_flag; 01272 }
int readout_thread | ( | void * | param | ) |
Definition at line 1331 of file mfe.c.
01332 { 01333 int status, source; 01334 EVENT_HEADER *pevent; 01335 void *p; 01336 01337 p = param; /* avoid compiler warning */ 01338 while (!stop_all_threads) { 01339 /* obtain buffer space */ 01340 if (rbh1_next) // if set by user code, use it 01341 rbh1 = rbh1_next; 01342 01343 status = rb_get_wp(rbh1, &p, 0); 01344 if (stop_all_threads) 01345 break; 01346 if (status == DB_TIMEOUT) { 01347 // printf("readout_thread: Ring buffer is full, waiting for space!\n"); 01348 ss_sleep(10); 01349 continue; 01350 } 01351 if (status != DB_SUCCESS) 01352 break; 01353 01354 if (readout_enabled()) { 01355 01356 /* indicate activity for readout_enable() */ 01357 readout_thread_active = 1; 01358 01359 /* check for new event */ 01360 source = poll_event(multithread_eq->info.source, multithread_eq->poll_count, FALSE); 01361 01362 if (source > 0) { 01363 01364 if (stop_all_threads) 01365 break; 01366 01367 pevent = (EVENT_HEADER *)p; 01368 /* put source at beginning of event, will be overwritten by 01369 user readout code, just a special feature used by some 01370 multi-source applications */ 01371 *(INT *) (pevent + 1) = source; 01372 01373 /* compose MIDAS event header */ 01374 pevent->event_id = multithread_eq->info.event_id; 01375 pevent->trigger_mask = multithread_eq->info.trigger_mask; 01376 pevent->data_size = 0; 01377 pevent->time_stamp = actual_time; 01378 pevent->serial_number = multithread_eq->serial_number++; 01379 01380 /* call user readout routine */ 01381 pevent->data_size = multithread_eq->readout((char *) (pevent + 1), 0); 01382 01383 /* check event size */ 01384 if (pevent->data_size + sizeof(EVENT_HEADER) > (DWORD) max_event_size) { 01385 cm_msg(MERROR, "readout_thread", 01386 "Event size %ld larger than maximum size %d", 01387 (long) (pevent->data_size + sizeof(EVENT_HEADER)), 01388 max_event_size); 01389 assert(FALSE); 01390 } 01391 01392 if (pevent->data_size > 0) { 01393 /* put event into ring buffer */ 01394 rb_increment_wp(rbh1, sizeof(EVENT_HEADER) + pevent->data_size); 01395 } else 01396 multithread_eq->serial_number--; 01397 } 01398 01399 readout_thread_active = 0; 01400 01401 } else // readout_enabled 01402 ss_sleep(10); 01403 01404 } 01405 01406 readout_thread_active = 0; 01407 01408 return 0; 01409 }
int receive_trigger_event | ( | EQUIPMENT * | eq | ) |
Definition at line 1413 of file mfe.c.
Referenced by tr_stop().
01414 { 01415 int status; 01416 EVENT_HEADER *prb, *pevent; 01417 void *p; 01418 int nbytes; 01419 01420 if (0) { 01421 static int count = 0; 01422 if (((count++) % 100) == 0) { 01423 rb_get_buffer_level(rbh2, &nbytes); 01424 if (nbytes != 0) 01425 printf("mfe: ring buffer contains %d bytes\n", nbytes); 01426 } 01427 } 01428 01429 status = rb_get_rp(rbh2, &p, 10); 01430 prb = (EVENT_HEADER *)p; 01431 if (status == DB_TIMEOUT) 01432 return 0; 01433 01434 pevent = prb; 01435 01436 /* send event */ 01437 if (pevent->data_size) { 01438 if (eq->buffer_handle) { 01439 /* send first event to ODB if logger writes in root format */ 01440 if (pevent->serial_number == 0) 01441 if (logger_root()) 01442 update_odb(pevent, eq->hkey_variables, eq->format); 01443 01444 status = rpc_send_event(eq->buffer_handle, pevent, 01445 pevent->data_size + sizeof(EVENT_HEADER), 01446 SYNC, rpc_mode); 01447 01448 if (status != SUCCESS) { 01449 cm_msg(MERROR, "receive_trigger_event", "rpc_send_event error %d", status); 01450 return -1; 01451 } 01452 01453 eq->bytes_sent += pevent->data_size + sizeof(EVENT_HEADER); 01454 01455 if (eq->info.num_subevents) 01456 eq->events_sent += eq->subevent_number; 01457 else 01458 eq->events_sent++; 01459 01460 rotate_wheel(); 01461 } 01462 } 01463 01464 rb_increment_rp(rbh2, sizeof(EVENT_HEADER) + prb->data_size); 01465 01466 return prb->data_size; 01467 }
INT register_equipment | ( | void | ) |
Definition at line 541 of file mfe.c.
Referenced by main().
00542 { 00543 INT idx, size, status; 00544 char str[256]; 00545 EQUIPMENT_INFO *eq_info; 00546 EQUIPMENT_STATS *eq_stats; 00547 HNDLE hKey; 00548 BANK_LIST *bank_list; 00549 DWORD dummy; 00550 00551 /* get current ODB run state */ 00552 size = sizeof(run_state); 00553 run_state = STATE_STOPPED; 00554 db_get_value(hDB, 0, "/Runinfo/State", &run_state, &size, TID_INT, TRUE); 00555 size = sizeof(run_number); 00556 run_number = 1; 00557 status = 00558 db_get_value(hDB, 0, "/Runinfo/Run number", &run_number, &size, TID_INT, TRUE); 00559 assert(status == SUCCESS); 00560 00561 /* scan EQUIPMENT table from FRONTEND.C */ 00562 for (idx = 0; equipment[idx].name[0]; idx++) { 00563 eq_info = &equipment[idx].info; 00564 eq_stats = &equipment[idx].stats; 00565 00566 if (eq_info->event_id == 0) { 00567 printf("\nEvent ID 0 for %s not allowed\n", equipment[idx].name); 00568 cm_disconnect_experiment(); 00569 ss_sleep(5000); 00570 exit(0); 00571 } 00572 00573 /* init status */ 00574 equipment[idx].status = FE_SUCCESS; 00575 00576 /* check for % in equipment (needed for event building) */ 00577 if (frontend_index != -1) { 00578 /* modify equipment name to <name>xx where xx is the frontend index */ 00579 if (strchr(equipment[idx].name, '%')) { 00580 strcpy(str, equipment[idx].name); 00581 sprintf(equipment[idx].name, str, frontend_index); 00582 } 00583 00584 /* modify event buffer name to <name>xx where xx is the frontend index */ 00585 if (strchr(eq_info->buffer, '%')) { 00586 strcpy(str, eq_info->buffer); 00587 sprintf(eq_info->buffer, str, frontend_index); 00588 } 00589 } else { 00590 /* stip %.. */ 00591 if (strchr(equipment[idx].name, '%')) 00592 *strchr(equipment[idx].name, '%') = 0; 00593 if (strchr(eq_info->buffer, '%')) 00594 *strchr(eq_info->buffer, '%') = 0; 00595 } 00596 00597 sprintf(str, "/Equipment/%s/Common", equipment[idx].name); 00598 00599 /* get last event limit from ODB */ 00600 if (eq_info->eq_type != EQ_SLOW) { 00601 db_find_key(hDB, 0, str, &hKey); 00602 size = sizeof(double); 00603 if (hKey) 00604 db_get_value(hDB, hKey, "Event limit", &eq_info->event_limit, &size, 00605 TID_DOUBLE, TRUE); 00606 } 00607 00608 /* Create common subtree */ 00609 status = db_check_record(hDB, 0, str, EQUIPMENT_COMMON_STR, FALSE); 00610 if (status == DB_NO_KEY || status == DB_STRUCT_MISMATCH) { 00611 db_create_record(hDB, 0, str, EQUIPMENT_COMMON_STR); 00612 db_find_key(hDB, 0, str, &hKey); 00613 db_set_record(hDB, hKey, eq_info, sizeof(EQUIPMENT_INFO), 0); 00614 } else if (status != DB_SUCCESS) { 00615 printf("Cannot check equipment record, status = %d\n", status); 00616 ss_sleep(3000); 00617 } 00618 db_find_key(hDB, 0, str, &hKey); 00619 assert(hKey); 00620 00621 /* set fixed parameters from user structure */ 00622 db_set_value(hDB, hKey, "Event ID", &eq_info->event_id, sizeof(WORD), 1, TID_WORD); 00623 db_set_value(hDB, hKey, "Type", &eq_info->eq_type, sizeof(INT), 1, TID_INT); 00624 db_set_value(hDB, hKey, "Source", &eq_info->source, sizeof(INT), 1, TID_INT); 00625 00626 /* open hot link to equipment info */ 00627 db_open_record(hDB, hKey, eq_info, sizeof(EQUIPMENT_INFO), MODE_READ, NULL, NULL); 00628 00629 if (equal_ustring(eq_info->format, "YBOS")) 00630 assert(!"YBOS not supported anymore"); 00631 else if (equal_ustring(eq_info->format, "FIXED")) 00632 equipment[idx].format = FORMAT_FIXED; 00633 else /* default format is MIDAS */ 00634 equipment[idx].format = FORMAT_MIDAS; 00635 00636 gethostname(eq_info->frontend_host, sizeof(eq_info->frontend_host)); 00637 strcpy(eq_info->frontend_name, full_frontend_name); 00638 strcpy(eq_info->frontend_file_name, frontend_file_name); 00639 sprintf(eq_info->status, "%s@%s", full_frontend_name, eq_info->frontend_host); 00640 strcpy(eq_info->status_color, "#00FF00"); 00641 00642 /* update variables in ODB */ 00643 db_set_record(hDB, hKey, eq_info, sizeof(EQUIPMENT_INFO), 0); 00644 00645 /*---- Create variables record ---------------------------------*/ 00646 00647 sprintf(str, "/Equipment/%s/Variables", equipment[idx].name); 00648 if (equipment[idx].event_descrip) { 00649 if (equipment[idx].format == FORMAT_FIXED) 00650 db_check_record(hDB, 0, str, (char *) equipment[idx].event_descrip, TRUE); 00651 else { 00652 /* create bank descriptions */ 00653 bank_list = (BANK_LIST *) equipment[idx].event_descrip; 00654 00655 for (; bank_list->name[0]; bank_list++) { 00656 /* mabye needed later... 00657 if (bank_list->output_flag == 0) 00658 continue; 00659 */ 00660 00661 if (bank_list->type == TID_STRUCT) { 00662 sprintf(str, "/Equipment/%s/Variables/%s", equipment[idx].name, 00663 bank_list->name); 00664 status = 00665 db_check_record(hDB, 0, str, strcomb((const char**)bank_list->init_str), TRUE); 00666 if (status != DB_SUCCESS) { 00667 printf("Cannot check/create record \"%s\", status = %d\n", str, 00668 status); 00669 ss_sleep(3000); 00670 } 00671 } else { 00672 sprintf(str, "/Equipment/%s/Variables/%s", equipment[idx].name, 00673 bank_list->name); 00674 dummy = 0; 00675 db_set_value(hDB, 0, str, &dummy, rpc_tid_size(bank_list->type), 1, 00676 bank_list->type); 00677 } 00678 } 00679 } 00680 } else 00681 db_create_key(hDB, 0, str, TID_KEY); 00682 00683 sprintf(str, "/Equipment/%s/Variables", equipment[idx].name); 00684 db_find_key(hDB, 0, str, &hKey); 00685 equipment[idx].hkey_variables = hKey; 00686 00687 /*---- Create and initialize statistics tree -------------------*/ 00688 00689 sprintf(str, "/Equipment/%s/Statistics", equipment[idx].name); 00690 00691 status = db_check_record(hDB, 0, str, EQUIPMENT_STATISTICS_STR, TRUE); 00692 if (status != DB_SUCCESS) { 00693 printf("Cannot create/check statistics record \'%s\', error %d\n", str, status); 00694 ss_sleep(3000); 00695 } 00696 00697 status = db_find_key(hDB, 0, str, &hKey); 00698 if (status != DB_SUCCESS) { 00699 printf("Cannot find statistics record \'%s\', error %d\n", str, status); 00700 ss_sleep(3000); 00701 } 00702 00703 eq_stats->events_sent = 0; 00704 eq_stats->events_per_sec = 0; 00705 eq_stats->kbytes_per_sec = 0; 00706 00707 /* open hot link to statistics tree */ 00708 status = 00709 db_open_record(hDB, hKey, eq_stats, sizeof(EQUIPMENT_STATS), MODE_WRITE, NULL, 00710 NULL); 00711 if (status != DB_SUCCESS) { 00712 cm_msg(MERROR, "register_equipment", 00713 "Cannot open statistics record \'%s\', error %d. Probably other FE is using it", 00714 str, status); 00715 ss_sleep(3000); 00716 } 00717 00718 /*---- open event buffer ---------------------------------------*/ 00719 00720 /* check for fragmented event */ 00721 if (eq_info->eq_type & EQ_FRAGMENTED) { 00722 if (frag_buffer == NULL) 00723 frag_buffer = malloc(max_event_size_frag); 00724 00725 if (frag_buffer == NULL) { 00726 cm_msg(MERROR, "register_equipment", 00727 "Not enough memory to allocate buffer for fragmented events"); 00728 return SS_NO_MEMORY; 00729 } 00730 } 00731 00732 if (eq_info->buffer[0]) { 00733 status = 00734 bm_open_buffer(eq_info->buffer, 2*MAX_EVENT_SIZE, 00735 &equipment[idx].buffer_handle); 00736 if (status != BM_SUCCESS && status != BM_CREATED) { 00737 cm_msg(MERROR, "register_equipment", 00738 "Cannot open event buffer \"%s\" size %d, bm_open_buffer() status %d", eq_info->buffer, 2*MAX_EVENT_SIZE, status); 00739 return 0; 00740 } 00741 00742 /* set the default buffer cache size */ 00743 bm_set_cache_size(equipment[idx].buffer_handle, 0, SERVER_CACHE_SIZE); 00744 } else 00745 equipment[idx].buffer_handle = 0; 00746 } 00747 00748 n_events = calloc(sizeof(int), idx); 00749 00750 return SUCCESS; 00751 }
void rotate_wheel | ( | void | ) |
Definition at line 1562 of file mfe.c.
Referenced by receive_trigger_event().
01563 { 01564 static DWORD last_wheel = 0, wheel_index = 0; 01565 static char wheel_char[] = { '-', '\\', '|', '/' }; 01566 01567 if (display_period) { 01568 if (ss_millitime() - last_wheel > 300) { 01569 last_wheel = ss_millitime(); 01570 ss_printf(79, 2, "%c", wheel_char[wheel_index]); 01571 wheel_index = (wheel_index + 1) % 4; 01572 } 01573 } 01574 }
int sc_thread | ( | void * | info | ) |
Definition at line 307 of file mfe.c.
Referenced by device_driver().
00308 { 00309 DEVICE_DRIVER *device_drv = info; 00310 int i, status, cmd; 00311 int current_channel = 0; 00312 int current_priority_channel = 0; 00313 float value; 00314 int *last_update; 00315 unsigned int current_time; 00316 DWORD last_time; 00317 00318 last_update = calloc(device_drv->channels, sizeof(int)); 00319 last_time = ss_millitime(); 00320 00321 do { 00322 /* read one channel from device */ 00323 for (cmd = CMD_GET_FIRST; cmd <= CMD_GET_LAST; cmd++) { 00324 value = (float)ss_nan(); 00325 status = device_drv->dd(cmd, device_drv->dd_info, current_channel, &value); 00326 00327 ss_semaphore_wait_for(device_drv->semaphore, 1000); 00328 device_drv->mt_buffer->channel[current_channel].variable[cmd] = value; 00329 device_drv->mt_buffer->status = status; 00330 ss_semaphore_release(device_drv->semaphore); 00331 00332 // printf("TID %d: channel %d, value %f\n", ss_gettid(), current_channel, value); 00333 } 00334 00335 /* switch to next channel in next loop */ 00336 current_channel = (current_channel + 1) % device_drv->channels; 00337 00338 /* check for priority channel */ 00339 current_time = ss_millitime(); 00340 i = (current_priority_channel + 1) % device_drv->channels; 00341 while (!(current_time - last_update[i] < 10000)) { 00342 i = (i + 1) % device_drv->channels; 00343 if (i == current_priority_channel) { 00344 /* non found, so finish */ 00345 break; 00346 } 00347 } 00348 00349 /* updated channel found, so read it additionally */ 00350 if (current_time - last_update[i] < 10000) { 00351 current_priority_channel = i; 00352 00353 for (cmd = CMD_GET_FIRST; cmd <= CMD_GET_LAST; cmd++) { 00354 status = device_drv->dd(cmd, device_drv->dd_info, i, &value); 00355 00356 ss_semaphore_wait_for(device_drv->semaphore, 1000); 00357 device_drv->mt_buffer->channel[i].variable[cmd] = value; 00358 device_drv->mt_buffer->status = status; 00359 ss_semaphore_release(device_drv->semaphore); 00360 } 00361 } 00362 00363 /* check if anything to write to device */ 00364 for (i = 0; i < device_drv->channels; i++) { 00365 00366 for (cmd = CMD_SET_FIRST; cmd <= CMD_SET_LAST; cmd++) { 00367 if (!ss_isnan(device_drv->mt_buffer->channel[i].variable[cmd])) { 00368 ss_semaphore_wait_for(device_drv->semaphore, 1000); 00369 value = device_drv->mt_buffer->channel[i].variable[cmd]; 00370 device_drv->mt_buffer->channel[i].variable[cmd] = (float) ss_nan(); 00371 device_drv->mt_buffer->status = status; 00372 ss_semaphore_release(device_drv->semaphore); 00373 00374 status = device_drv->dd(cmd, device_drv->dd_info, i, value); 00375 last_update[i] = ss_millitime(); 00376 } 00377 } 00378 } 00379 00380 /* limit data rate if defined in equipment list */ 00381 if (current_channel == 0) 00382 if (device_drv->pequipment && device_drv->pequipment->event_limit) { 00383 while (ss_millitime() - last_time < (DWORD)device_drv->pequipment->event_limit && 00384 !device_drv->stop_thread) 00385 ss_sleep(10); 00386 last_time = ss_millitime(); 00387 } 00388 00389 } while (device_drv->stop_thread == 0); 00390 00391 free(last_update); 00392 00393 /* signal stopped thread */ 00394 device_drv->stop_thread = 2; 00395 00396 return SUCCESS; 00397 }
INT scheduler | ( | void | ) |
Definition at line 1832 of file mfe.c.
Referenced by main().
01833 { 01834 EQUIPMENT_INFO *eq_info; 01835 EQUIPMENT *eq; 01836 EVENT_HEADER *pevent, *pfragment; 01837 DWORD last_time_network = 0, last_time_display = 0, last_time_flush = 0, 01838 readout_start, sent, size, last_time_rate = 0; 01839 INT i, j, idx, status = 0, ch, source, state, old_flag; 01840 char str[80], *pdata; 01841 unsigned char *pd; 01842 BOOL buffer_done, flag, force_update = FALSE; 01843 01844 INT opt_max = 0, opt_index = 0, opt_tcp_size = 128, opt_cnt = 0; 01845 INT err; 01846 01847 #ifdef OS_VXWORKS 01848 rpc_set_opt_tcp_size(1024); 01849 #ifdef PPCxxx 01850 rpc_set_opt_tcp_size(NET_TCP_SIZE); 01851 #endif 01852 #endif 01853 01854 /*----------------- MAIN equipment loop ------------------------------*/ 01855 01856 last_time_rate = ss_millitime(); 01857 01858 do { 01859 actual_millitime = ss_millitime(); 01860 actual_time = ss_time(); 01861 01862 /*---- loop over equipment table -------------------------------*/ 01863 for (idx = 0;; idx++) { 01864 eq = &equipment[idx]; 01865 eq_info = &eq->info; 01866 01867 /* check if end of equipment list */ 01868 if (!eq->name[0]) 01869 break; 01870 01871 if (!eq_info->enabled) 01872 continue; 01873 01874 if (eq->status != FE_SUCCESS) 01875 continue; 01876 01877 /*---- call idle routine for slow control equipment ----*/ 01878 if ((eq_info->eq_type & EQ_SLOW) && eq->status == FE_SUCCESS) { 01879 /* if equipment is multi-threaded, read all channel in one loop */ 01880 01881 if (eq_info->event_limit > 0) { 01882 if (actual_millitime - eq->last_idle >= (DWORD) eq_info->event_limit) { 01883 eq->cd(CMD_IDLE, eq); 01884 eq->last_idle = actual_millitime; 01885 } 01886 } else 01887 eq->cd(CMD_IDLE, eq); 01888 } 01889 01890 if (run_state == STATE_STOPPED && (eq_info->read_on & RO_STOPPED) == 0) 01891 continue; 01892 if (run_state == STATE_PAUSED && (eq_info->read_on & RO_PAUSED) == 0) 01893 continue; 01894 if (run_state == STATE_RUNNING && (eq_info->read_on & RO_RUNNING) == 0) 01895 continue; 01896 01897 /*---- check periodic events ----*/ 01898 if ((eq_info->eq_type & EQ_PERIODIC) || (eq_info->eq_type & EQ_SLOW)) { 01899 if (eq_info->period == 0) 01900 continue; 01901 01902 /* check if period over */ 01903 if (actual_millitime - eq->last_called >= (DWORD) eq_info->period) { 01904 /* disable interrupts or readout thread during this event */ 01905 old_flag = readout_enabled(); 01906 if (old_flag && lockout_readout_thread) 01907 readout_enable(FALSE); 01908 01909 /* readout and send event */ 01910 status = send_event(idx, FALSE); 01911 01912 if (status != CM_SUCCESS) { 01913 cm_msg(MERROR, "scheduler", "send_event error %d", status); 01914 goto net_error; 01915 } 01916 01917 /* re-enable the interrupt or readout thread after periodic */ 01918 if (old_flag) 01919 readout_enable(TRUE); 01920 } 01921 } 01922 01923 /*---- check polled events ----*/ 01924 if (eq_info->eq_type & EQ_POLLED) { 01925 readout_start = actual_millitime; 01926 pevent = NULL; 01927 01928 while ((source = poll_event(eq_info->source, eq->poll_count, FALSE)) > 0) { 01929 01930 if (eq_info->eq_type & EQ_FRAGMENTED) 01931 pevent = frag_buffer; 01932 else 01933 pevent = (EVENT_HEADER *)event_buffer; 01934 01935 /* compose MIDAS event header */ 01936 pevent->event_id = eq_info->event_id; 01937 pevent->trigger_mask = eq_info->trigger_mask; 01938 pevent->data_size = 0; 01939 pevent->time_stamp = actual_time; 01940 pevent->serial_number = eq->serial_number; 01941 01942 /* put source at beginning of event, will be overwritten by 01943 user readout code, just a special feature used by some 01944 multi-source applications */ 01945 *(INT *) (pevent + 1) = source; 01946 01947 if (eq->info.num_subevents) { 01948 eq->subevent_number = 0; 01949 do { 01950 *(INT *) ((char *) (pevent + 1) + pevent->data_size) = source; 01951 01952 /* call user readout routine for subevent indicating offset */ 01953 size = eq->readout((char *) (pevent + 1), pevent->data_size); 01954 pevent->data_size += size; 01955 if (size > 0) { 01956 if (pevent->data_size + sizeof(EVENT_HEADER) > 01957 (DWORD) max_event_size) { 01958 cm_msg(MERROR, "scheduler", 01959 "Event size %ld larger than maximum size %d", 01960 (long) (pevent->data_size + sizeof(EVENT_HEADER)), 01961 max_event_size); 01962 } 01963 01964 eq->subevent_number++; 01965 eq->serial_number++; 01966 } 01967 01968 /* wait for next event */ 01969 do { 01970 source = poll_event(eq_info->source, eq->poll_count, FALSE); 01971 01972 if (source == FALSE) { 01973 actual_millitime = ss_millitime(); 01974 01975 /* repeat no more than period */ 01976 if (actual_millitime - readout_start > (DWORD) eq_info->period) 01977 break; 01978 } 01979 } while (source == FALSE); 01980 01981 } while (eq->subevent_number < eq->info.num_subevents && source); 01982 01983 /* notify readout routine about end of super-event */ 01984 pevent->data_size = eq->readout((char *) (pevent + 1), -1); 01985 } else { 01986 /* call user readout routine indicating event source */ 01987 pevent->data_size = eq->readout((char *) (pevent + 1), 0); 01988 01989 /* check event size */ 01990 if (eq_info->eq_type & EQ_FRAGMENTED) { 01991 if (pevent->data_size + sizeof(EVENT_HEADER) > (DWORD) max_event_size_frag) { 01992 cm_msg(MERROR, "send_event", 01993 "Event size %ld larger than maximum size %d for frag. ev.", 01994 (long) (pevent->data_size + sizeof(EVENT_HEADER)), 01995 max_event_size_frag); 01996 assert(FALSE); 01997 } 01998 } else { 01999 if (pevent->data_size + sizeof(EVENT_HEADER) > (DWORD) max_event_size) { 02000 cm_msg(MERROR, "scheduler", 02001 "Event size %ld larger than maximum size %d", 02002 (long) (pevent->data_size + sizeof(EVENT_HEADER)), 02003 max_event_size); 02004 assert(FALSE); 02005 } 02006 } 02007 02008 /* increment serial number if event read out sucessfully */ 02009 if (pevent->data_size) 02010 eq->serial_number++; 02011 } 02012 02013 /* send event */ 02014 if (pevent->data_size) { 02015 02016 /* check for fragmented event */ 02017 if (eq_info->eq_type & EQ_FRAGMENTED) { 02018 /* compose fragments */ 02019 pfragment = event_buffer; 02020 02021 /* compose MIDAS event header */ 02022 memcpy(pfragment, pevent, sizeof(EVENT_HEADER)); 02023 pfragment->event_id |= EVENTID_FRAG1; 02024 02025 /* store total event size */ 02026 pd = (unsigned char *) (pfragment + 1); 02027 size = pevent->data_size; 02028 for (i = 0; i < 4; i++) { 02029 pd[i] = (unsigned char) (size & 0xFF); /* little endian, please! */ 02030 size >>= 8; 02031 } 02032 02033 pfragment->data_size = sizeof(DWORD); 02034 02035 pdata = (char *) (pevent + 1); 02036 02037 for (i = 0, sent = 0; sent < pevent->data_size; i++) { 02038 if (i > 0) { 02039 pfragment = event_buffer; 02040 02041 /* compose MIDAS event header */ 02042 memcpy(pfragment, pevent, sizeof(EVENT_HEADER)); 02043 pfragment->event_id |= EVENTID_FRAG; 02044 02045 /* copy portion of event */ 02046 size = pevent->data_size - sent; 02047 if (size > max_event_size - sizeof(EVENT_HEADER)) 02048 size = max_event_size - sizeof(EVENT_HEADER); 02049 02050 memcpy(pfragment + 1, pdata, size); 02051 pfragment->data_size = size; 02052 sent += size; 02053 pdata += size; 02054 } 02055 02056 /* send event to buffer */ 02057 if (equipment[idx].buffer_handle) { 02058 status = rpc_send_event(equipment[idx].buffer_handle, pfragment, 02059 pfragment->data_size + sizeof(EVENT_HEADER), SYNC, rpc_mode); 02060 if (status != RPC_SUCCESS) { 02061 cm_msg(MERROR, "scheduler", "rpc_send_event(SYNC) error %d", status); 02062 return status; 02063 } 02064 02065 /* flush events from buffer */ 02066 rpc_flush_event(); 02067 } 02068 } 02069 02070 } else { /*-------------------*/ 02071 02072 /* send unfragmented event */ 02073 02074 /* send first event to ODB if logger writes in root format */ 02075 if (pevent->serial_number == 0) 02076 if (logger_root()) 02077 update_odb(pevent, eq->hkey_variables, eq->format); 02078 02079 status = rpc_send_event(eq->buffer_handle, pevent, 02080 pevent->data_size + sizeof(EVENT_HEADER), 02081 SYNC, rpc_mode); 02082 02083 if (status != SUCCESS) { 02084 cm_msg(MERROR, "scheduler", "rpc_send_event error %d", status); 02085 goto net_error; 02086 } 02087 } 02088 02089 eq->bytes_sent += pevent->data_size + sizeof(EVENT_HEADER); 02090 02091 if (eq->info.num_subevents) 02092 eq->events_sent += eq->subevent_number; 02093 else 02094 eq->events_sent++; 02095 02096 rotate_wheel(); 02097 } 02098 02099 actual_millitime = ss_millitime(); 02100 02101 /* send event to ODB */ 02102 if (pevent->data_size && (eq_info->read_on & RO_ODB)) { 02103 if (actual_millitime - eq->last_called > ODB_UPDATE_TIME) { 02104 eq->last_called = actual_millitime; 02105 update_odb(pevent, eq->hkey_variables, eq->format); 02106 eq->odb_out++; 02107 } 02108 } 02109 02110 /* repeat no more than period */ 02111 if (actual_millitime - readout_start > (DWORD) eq_info->period) 02112 break; 02113 02114 /* quit if event limit is reached */ 02115 if (eq_info->event_limit > 0 && 02116 eq->stats.events_sent + eq->events_sent >= eq_info->event_limit) 02117 break; 02118 } 02119 02120 } 02121 02122 /*---- send interrupt events ----*/ 02123 if (eq_info->eq_type & (EQ_INTERRUPT | EQ_MULTITHREAD)) { 02124 readout_start = actual_millitime; 02125 02126 do { 02127 size = receive_trigger_event(eq); 02128 if ((int)size == -1) 02129 goto net_error; 02130 02131 actual_millitime = ss_millitime(); 02132 02133 /* repeat no more than period */ 02134 if (actual_millitime - readout_start > (DWORD) eq_info->period) 02135 break; 02136 02137 /* quit if event limit is reached */ 02138 if (eq_info->event_limit > 0 && 02139 eq->stats.events_sent + eq->events_sent >= eq_info->event_limit) 02140 break; 02141 02142 } while (size > 0); 02143 02144 /* send event to ODB */ 02145 pevent = (EVENT_HEADER *)event_buffer; 02146 if (size > 0 && pevent->data_size && (eq_info->read_on & RO_ODB || eq_info->history)) { 02147 if (actual_millitime - eq->last_called > ODB_UPDATE_TIME && pevent != NULL) { 02148 eq->last_called = actual_millitime; 02149 update_odb(pevent, eq->hkey_variables, eq->format); 02150 eq->odb_out++; 02151 } 02152 } 02153 } 02154 02155 /*---- check if event limit is reached ----*/ 02156 if (eq_info->eq_type != EQ_SLOW && 02157 eq_info->event_limit > 0 && 02158 eq->stats.events_sent + eq->events_sent >= eq_info->event_limit && 02159 run_state == STATE_RUNNING) { 02160 /* stop run */ 02161 if (cm_transition(TR_STOP, 0, str, sizeof(str), SYNC, FALSE) != CM_SUCCESS) 02162 cm_msg(MERROR, "scheduler", "cannot stop run: %s", str); 02163 02164 /* check if autorestart, main loop will take care of it */ 02165 size = sizeof(BOOL); 02166 flag = FALSE; 02167 db_get_value(hDB, 0, "/Logger/Auto restart", &flag, (INT *)&size, TID_BOOL, TRUE); 02168 02169 if (flag) 02170 auto_restart = ss_time() + 20; /* restart in 20 sec. */ 02171 02172 /* update event display correctly */ 02173 force_update = TRUE; 02174 } 02175 } 02176 02177 /*---- check for error messages periodically -------------------*/ 02178 mfe_error_check(); 02179 02180 /*---- call frontend_loop periodically -------------------------*/ 02181 if (frontend_call_loop) { 02182 status = frontend_loop(); 02183 if (status == RPC_SHUTDOWN || status == SS_ABORT) { 02184 status = RPC_SHUTDOWN; 02185 break; 02186 } 02187 } 02188 02189 /*---- check for deferred transitions --------------------------*/ 02190 cm_check_deferred_transition(); 02191 02192 /*---- check for manual triggered events -----------------------*/ 02193 if (manual_trigger_event_id) { 02194 old_flag = readout_enabled(); 02195 if (old_flag && lockout_readout_thread) 02196 readout_enable(FALSE); 02197 02198 /* readout and send event */ 02199 status = BM_INVALID_PARAM; 02200 for (i = 0; equipment[i].name[0]; i++) 02201 if (equipment[i].info.event_id == manual_trigger_event_id) { 02202 status = send_event(i, TRUE); 02203 break; 02204 } 02205 02206 manual_trigger_event_id = 0; 02207 02208 if (status != CM_SUCCESS) { 02209 cm_msg(MERROR, "scheduler", "send_event error %d", status); 02210 goto net_error; 02211 } 02212 02213 /* re-enable the interrupt after periodic */ 02214 if (old_flag) 02215 readout_enable(TRUE); 02216 } 02217 02218 /*---- calculate rates and update status page periodically -----*/ 02219 if (force_update || 02220 (display_period 02221 && actual_millitime - last_time_display > (DWORD) display_period) 02222 || (!display_period && actual_millitime - last_time_display > 3000)) { 02223 force_update = FALSE; 02224 02225 for (i = 0; equipment[i].name[0]; i++) { 02226 eq = &equipment[i]; 02227 eq->stats.events_sent += eq->events_sent; 02228 n_events[i] += eq->events_sent; 02229 eq->events_sent = 0; 02230 } 02231 02232 /* calculate rates after requested period */ 02233 if (actual_millitime - last_time_rate > (DWORD)get_rate_period()) { 02234 max_bytes_per_sec = 0; 02235 for (i = 0; equipment[i].name[0]; i++) { 02236 eq = &equipment[i]; 02237 eq->stats.events_per_sec = 02238 n_events[i] / ((actual_millitime - last_time_rate) / 1000.0); 02239 eq->stats.kbytes_per_sec = 02240 eq->bytes_sent / 1024.0 / ((actual_millitime - last_time_rate) / 02241 1000.0); 02242 02243 if ((INT) eq->bytes_sent > max_bytes_per_sec) 02244 max_bytes_per_sec = eq->bytes_sent; 02245 02246 eq->bytes_sent = 0; 02247 n_events[i] = 0; 02248 } 02249 02250 max_bytes_per_sec = (DWORD) 02251 ((double) max_bytes_per_sec / 02252 ((actual_millitime - last_time_rate) / 1000.0)); 02253 02254 last_time_rate = actual_millitime; 02255 } 02256 02257 /* tcp buffer size evaluation */ 02258 if (optimize) { 02259 opt_max = MAX(opt_max, (INT) max_bytes_per_sec); 02260 ss_printf(0, opt_index, "%6d : %5.1lf %5.1lf", opt_tcp_size, 02261 opt_max / 1024.0, max_bytes_per_sec / 1024.0); 02262 if (++opt_cnt == 10) { 02263 opt_cnt = 0; 02264 opt_max = 0; 02265 opt_index++; 02266 opt_tcp_size = 1 << (opt_index + 7); 02267 rpc_set_opt_tcp_size(opt_tcp_size); 02268 if (1 << (opt_index + 7) > 0x8000) { 02269 opt_index = 0; 02270 opt_tcp_size = 1 << 7; 02271 rpc_set_opt_tcp_size(opt_tcp_size); 02272 } 02273 } 02274 } 02275 02276 /* propagate changes in equipment to ODB */ 02277 rpc_set_option(-1, RPC_OTRANSPORT, RPC_FTCP); 02278 db_send_changed_records(); 02279 rpc_set_option(-1, RPC_OTRANSPORT, RPC_TCP); 02280 02281 if (display_period) { 02282 display(FALSE); 02283 02284 /* check keyboard */ 02285 ch = 0; 02286 status = 0; 02287 while (ss_kbhit()) { 02288 ch = ss_getchar(0); 02289 if (ch == -1) 02290 ch = getchar(); 02291 02292 if (ch == '!') 02293 status = RPC_SHUTDOWN; 02294 } 02295 02296 if (ch > 0) 02297 display(TRUE); 02298 if (status == RPC_SHUTDOWN) 02299 break; 02300 } 02301 02302 last_time_display = actual_millitime; 02303 } 02304 02305 /*---- check to flush cache ------------------------------------*/ 02306 if (actual_millitime - last_time_flush > 1000) { 02307 last_time_flush = actual_millitime; 02308 02309 /* if cache on server is not filled in one second at current 02310 data rate, flush it now to make events available to consumers */ 02311 02312 if (max_bytes_per_sec < SERVER_CACHE_SIZE) { 02313 old_flag = readout_enabled(); 02314 if (old_flag && lockout_readout_thread) 02315 readout_enable(FALSE); 02316 02317 for (i = 0; equipment[i].name[0]; i++) { 02318 if (equipment[i].buffer_handle) { 02319 /* check if buffer already flushed */ 02320 buffer_done = FALSE; 02321 for (j = 0; j < i; j++) 02322 if (equipment[i].buffer_handle == equipment[j].buffer_handle) { 02323 buffer_done = TRUE; 02324 break; 02325 } 02326 02327 if (!buffer_done) { 02328 rpc_set_option(-1, RPC_OTRANSPORT, RPC_FTCP); 02329 rpc_flush_event(); 02330 err = bm_flush_cache(equipment[i].buffer_handle, ASYNC); 02331 if ((err != BM_SUCCESS) && (err != BM_ASYNC_RETURN)) { 02332 cm_msg(MERROR, "scheduler", "bm_flush_cache(ASYNC) error %d", 02333 err); 02334 return err; 02335 } 02336 rpc_set_option(-1, RPC_OTRANSPORT, RPC_TCP); 02337 } 02338 } 02339 } 02340 02341 if (old_flag) 02342 readout_enable(TRUE); 02343 } 02344 } 02345 02346 /*---- check for auto restart --------------------------------*/ 02347 if (auto_restart > 0 && ss_time() > auto_restart) { 02348 /* check if really stopped */ 02349 size = sizeof(state); 02350 status = db_get_value(hDB, 0, "Runinfo/State", &state, (INT *)&size, TID_INT, TRUE); 02351 if (status != DB_SUCCESS) 02352 cm_msg(MERROR, "scheduler", "cannot get Runinfo/State in database"); 02353 02354 if (state == STATE_STOPPED) { 02355 auto_restart = 0; 02356 size = sizeof(run_number); 02357 status = 02358 db_get_value(hDB, 0, "/Runinfo/Run number", &run_number, (INT*)&size, TID_INT, 02359 TRUE); 02360 assert(status == SUCCESS); 02361 02362 if (run_number <= 0) { 02363 cm_msg(MERROR, "main", "aborting on attempt to use invalid run number %d", 02364 run_number); 02365 abort(); 02366 } 02367 02368 cm_msg(MTALK, "main", "starting new run"); 02369 status = cm_transition(TR_START, run_number + 1, NULL, 0, SYNC, FALSE); 02370 if (status != CM_SUCCESS) 02371 cm_msg(MERROR, "main", "cannot restart run"); 02372 } 02373 } 02374 02375 /*---- check network messages ----------------------------------*/ 02376 if ((run_state == STATE_RUNNING && interrupt_eq == NULL) || slowcont_eq) { 02377 /* only call yield once every 100ms when running */ 02378 if (actual_millitime - last_time_network > 100) { 02379 status = cm_yield(0); 02380 last_time_network = actual_millitime; 02381 } else 02382 status = RPC_SUCCESS; 02383 } else 02384 /* when run is stopped or interrupts used, 02385 call yield with 100ms timeout */ 02386 status = cm_yield(100); 02387 02388 /* exit for VxWorks */ 02389 if (fe_stop) 02390 status = RPC_SHUTDOWN; 02391 02392 /* exit if CTRL-C pressed */ 02393 if (cm_is_ctrlc_pressed()) 02394 status = RPC_SHUTDOWN; 02395 02396 } while (status != RPC_SHUTDOWN && status != SS_ABORT); 02397 02398 net_error: 02399 02400 return status; 02401 }
void send_all_periodic_events | ( | INT | transition | ) |
Definition at line 1241 of file mfe.c.
Referenced by tr_pause(), tr_resume(), tr_start(), tr_start_fal(), tr_stop(), and tr_stop_fal().
01242 { 01243 EQUIPMENT_INFO *eq_info; 01244 INT i; 01245 01246 for (i = 0; equipment[i].name[0]; i++) { 01247 eq_info = &equipment[i].info; 01248 01249 if (!eq_info->enabled || equipment[i].status != FE_SUCCESS) 01250 continue; 01251 01252 if (transition == TR_START && (eq_info->read_on & RO_BOR) == 0) 01253 continue; 01254 if (transition == TR_STOP && (eq_info->read_on & RO_EOR) == 0) 01255 continue; 01256 if (transition == TR_PAUSE && (eq_info->read_on & RO_PAUSE) == 0) 01257 continue; 01258 if (transition == TR_RESUME && (eq_info->read_on & RO_RESUME) == 0) 01259 continue; 01260 01261 send_event(i, FALSE); 01262 } 01263 }
Definition at line 1086 of file mfe.c.
Referenced by manual_trigger(), and send_all_periodic_events().
01087 { 01088 EQUIPMENT_INFO *eq_info; 01089 EVENT_HEADER *pevent, *pfragment; 01090 char *pdata; 01091 unsigned char *pd; 01092 INT i, status; 01093 DWORD sent, size; 01094 01095 eq_info = &equipment[idx].info; 01096 01097 /* check for fragmented event */ 01098 if (eq_info->eq_type & EQ_FRAGMENTED) 01099 pevent = frag_buffer; 01100 else 01101 pevent = (EVENT_HEADER *)event_buffer; 01102 01103 /* compose MIDAS event header */ 01104 pevent->event_id = eq_info->event_id; 01105 pevent->trigger_mask = eq_info->trigger_mask; 01106 pevent->data_size = (INT) manual_trig; 01107 pevent->time_stamp = ss_time(); 01108 pevent->serial_number = equipment[idx].serial_number++; 01109 01110 equipment[idx].last_called = ss_millitime(); 01111 01112 /* call user readout routine */ 01113 *((EQUIPMENT **) (pevent + 1)) = &equipment[idx]; 01114 pevent->data_size = equipment[idx].readout((char *) (pevent + 1), 0); 01115 01116 /* send event */ 01117 if (pevent->data_size) { 01118 if (eq_info->eq_type & EQ_FRAGMENTED) { 01119 /* fragment event */ 01120 if (pevent->data_size + sizeof(EVENT_HEADER) > (DWORD) max_event_size_frag) { 01121 cm_msg(MERROR, "send_event", 01122 "Event size %ld larger than maximum size %d for frag. ev.", 01123 (long) (pevent->data_size + sizeof(EVENT_HEADER)), 01124 max_event_size_frag); 01125 return SS_NO_MEMORY; 01126 } 01127 01128 /* compose fragments */ 01129 pfragment = event_buffer; 01130 01131 /* compose MIDAS event header */ 01132 memcpy(pfragment, pevent, sizeof(EVENT_HEADER)); 01133 pfragment->event_id |= EVENTID_FRAG1; 01134 01135 /* store total event size */ 01136 pd = (unsigned char *) (pfragment + 1); 01137 size = pevent->data_size; 01138 for (i = 0; i < 4; i++) { 01139 pd[i] = (unsigned char) (size & 0xFF); /* little endian, please! */ 01140 size >>= 8; 01141 } 01142 01143 pfragment->data_size = sizeof(DWORD); 01144 01145 pdata = (char *) (pevent + 1); 01146 01147 for (i = 0, sent = 0; sent < pevent->data_size; i++) { 01148 if (i > 0) { 01149 pfragment = event_buffer; 01150 01151 /* compose MIDAS event header */ 01152 memcpy(pfragment, pevent, sizeof(EVENT_HEADER)); 01153 pfragment->event_id |= EVENTID_FRAG; 01154 01155 /* copy portion of event */ 01156 size = pevent->data_size - sent; 01157 if (size > max_event_size - sizeof(EVENT_HEADER)) 01158 size = max_event_size - sizeof(EVENT_HEADER); 01159 01160 memcpy(pfragment + 1, pdata, size); 01161 pfragment->data_size = size; 01162 sent += size; 01163 pdata += size; 01164 } 01165 01166 /* send event to buffer */ 01167 if (equipment[idx].buffer_handle) { 01168 status = rpc_send_event(equipment[idx].buffer_handle, pfragment, 01169 pfragment->data_size + sizeof(EVENT_HEADER), SYNC, rpc_mode); 01170 if (status != RPC_SUCCESS) { 01171 cm_msg(MERROR, "send_event", "rpc_send_event(SYNC) error %d", status); 01172 return status; 01173 } 01174 01175 /* flush events from buffer */ 01176 rpc_flush_event(); 01177 } 01178 } 01179 01180 if (equipment[idx].buffer_handle) { 01181 /* flush buffer cache on server side */ 01182 status = bm_flush_cache(equipment[idx].buffer_handle, SYNC); 01183 if (status != BM_SUCCESS) { 01184 cm_msg(MERROR, "send_event", "bm_flush_cache(SYNC) error %d", status); 01185 return status; 01186 } 01187 } 01188 } else { 01189 /* send unfragmented event */ 01190 01191 if (pevent->data_size + sizeof(EVENT_HEADER) > (DWORD) max_event_size) { 01192 cm_msg(MERROR, "send_event", "Event size %ld larger than maximum size %d", 01193 (long) (pevent->data_size + sizeof(EVENT_HEADER)), max_event_size); 01194 return SS_NO_MEMORY; 01195 } 01196 01197 /* send event to buffer */ 01198 if (equipment[idx].buffer_handle) { 01199 status = rpc_send_event(equipment[idx].buffer_handle, pevent, 01200 pevent->data_size + sizeof(EVENT_HEADER), SYNC, rpc_mode); 01201 if (status != BM_SUCCESS) { 01202 cm_msg(MERROR, "send_event", "bm_send_event(SYNC) error %d", status); 01203 return status; 01204 } 01205 rpc_flush_event(); 01206 status = bm_flush_cache(equipment[idx].buffer_handle, SYNC); 01207 if (status != BM_SUCCESS) { 01208 cm_msg(MERROR, "send_event", "bm_flush_cache(SYNC) error %d", status); 01209 return status; 01210 } 01211 } 01212 01213 /* send event to ODB if RO_ODB flag is set or history is on. Do not 01214 send SLOW events since the class driver does that */ 01215 if ((eq_info->read_on & RO_ODB) || 01216 (eq_info->history > 0 && (eq_info->eq_type & ~EQ_SLOW))) { 01217 update_odb(pevent, equipment[idx].hkey_variables, equipment[idx].format); 01218 equipment[idx].odb_out++; 01219 } 01220 } 01221 01222 equipment[idx].bytes_sent += pevent->data_size + sizeof(EVENT_HEADER); 01223 equipment[idx].events_sent++; 01224 } else 01225 equipment[idx].serial_number--; 01226 01227 for (i = 0; equipment[i].name[0]; i++) 01228 if (equipment[i].buffer_handle) { 01229 status = bm_flush_cache(equipment[i].buffer_handle, SYNC); 01230 if (status != BM_SUCCESS) { 01231 cm_msg(MERROR, "send_event", "bm_flush_cache(SYNC) error %d", status); 01232 return status; 01233 } 01234 } 01235 01236 return CM_SUCCESS; 01237 }
int set_equipment_status | ( | const char * | name, | |
const char * | eqipment_status, | |||
const char * | status_color | |||
) |
Definition at line 964 of file mfe.c.
00965 { 00966 int status, idx; 00967 char str[256]; 00968 HNDLE hKey; 00969 00970 for (idx = 0; equipment[idx].name[0]; idx++) 00971 if (equal_ustring(equipment[idx].name, name)) 00972 break; 00973 00974 if (equal_ustring(equipment[idx].name, name)) { 00975 sprintf(str, "/Equipment/%s/Common", name); 00976 db_find_key(hDB, 0, str, &hKey); 00977 assert(hKey); 00978 00979 status = db_set_value(hDB, hKey, "Status", eqipment_status, 256, 1, TID_STRING); 00980 assert(status == DB_SUCCESS); 00981 status = db_set_value(hDB, hKey, "Status color", status_color, 32, 1, TID_STRING); 00982 assert(status == DB_SUCCESS); 00983 } 00984 00985 return SUCCESS; 00986 }
void set_rate_period | ( | int | ms | ) |
Definition at line 247 of file mfe.c.
Referenced by main().
00248 { 00249 INT status; 00250 00251 /* disable interrupts or readout thread */ 00252 readout_enable(FALSE); 00253 00254 status = pause_run(rn, error); 00255 00256 if (status == CM_SUCCESS) { 00257 run_state = STATE_PAUSED; 00258 run_number = rn; 00259 00260 send_all_periodic_events(TR_PAUSE); 00261 00262 if (display_period) 00263 ss_printf(14, 2, "Paused "); 00264 } else 00265 readout_enable(TRUE); 00266 00267 return status; 00268 }
Definition at line 272 of file mfe.c.
Referenced by main().
00273 { 00274 INT status; 00275 00276 status = resume_run(rn, error); 00277 00278 if (status == CM_SUCCESS) { 00279 run_state = STATE_RUNNING; 00280 run_number = rn; 00281 00282 send_all_periodic_events(TR_RESUME); 00283 00284 if (display_period) 00285 ss_printf(14, 2, "Running "); 00286 00287 /* enable interrupts or readout thread */ 00288 readout_enable(TRUE); 00289 } 00290 00291 return status; 00292 }
Definition at line 145 of file mfe.c.
Referenced by main(), and tr_start_fal().
00146 { 00147 INT i, status; 00148 00149 /* disable interrupts or readout thread 00150 * if somehow it was not stopped from previous run */ 00151 readout_enable(FALSE); 00152 00153 /* reset serial numbers */ 00154 for (i = 0; equipment[i].name[0]; i++) { 00155 equipment[i].serial_number = 0; 00156 equipment[i].subevent_number = 0; 00157 equipment[i].stats.events_sent = 0; 00158 equipment[i].odb_in = equipment[i].odb_out = 0; 00159 n_events[i] = 0; 00160 } 00161 00162 status = begin_of_run(rn, error); 00163 00164 if (status == CM_SUCCESS) { 00165 run_state = STATE_RUNNING; 00166 run_number = rn; 00167 00168 send_all_periodic_events(TR_START); 00169 00170 if (display_period) { 00171 ss_printf(14, 2, "Running "); 00172 ss_printf(36, 2, "%d", rn); 00173 } 00174 00175 /* enable interrupts or readout thread */ 00176 readout_enable(TRUE); 00177 } 00178 00179 return status; 00180 }
Definition at line 184 of file mfe.c.
Referenced by main(), and tr_stop_fal().
00185 { 00186 INT status, i; 00187 EQUIPMENT *eq; 00188 00189 /* disable interrupts or readout thread */ 00190 readout_enable(FALSE); 00191 00192 status = end_of_run(rn, error); 00193 00194 /* check if event(s) happened just before disabling the trigger */ 00195 if ((i = check_polled_events()) > 0) { 00196 // cm_msg(MINFO, "tr_stop", "sent remaining %d polled events", i); 00197 } 00198 00199 if (status == CM_SUCCESS) { 00200 /* don't send events if already stopped */ 00201 if (run_state != STATE_STOPPED) 00202 send_all_periodic_events(TR_STOP); 00203 00204 run_state = STATE_STOPPED; 00205 run_number = rn; 00206 00207 if (display_period) 00208 ss_printf(14, 2, "Stopped "); 00209 } else 00210 readout_enable(TRUE); 00211 00212 for (i = 0; equipment[i].name[0]; i++) { 00213 /* read remaining events from ring buffers */ 00214 if (equipment[i].info.eq_type & (EQ_MULTITHREAD | EQ_INTERRUPT)) { 00215 while (receive_trigger_event(equipment+i) > 0); 00216 } 00217 00218 /* flush remaining buffered events */ 00219 rpc_flush_event(); 00220 if (equipment[i].buffer_handle) { 00221 INT err = bm_flush_cache(equipment[i].buffer_handle, SYNC); 00222 if (err != BM_SUCCESS) { 00223 cm_msg(MERROR, "tr_stop", "bm_flush_cache(SYNC) error %d", err); 00224 return err; 00225 } 00226 } 00227 } 00228 00229 /* update final statistics record in ODB */ 00230 for (i = 0; equipment[i].name[0]; i++) { 00231 eq = &equipment[i]; 00232 eq->stats.events_sent += eq->events_sent; 00233 eq->stats.events_per_sec = 0; 00234 eq->stats.kbytes_per_sec = 0; 00235 eq->bytes_sent = 0; 00236 eq->events_sent = 0; 00237 n_events[i] = 0; 00238 } 00239 00240 db_send_changed_records(); 00241 00242 return status; 00243 }
void update_odb | ( | EVENT_HEADER * | pevent, | |
HNDLE | hKey, | |||
INT | format | |||
) |
Definition at line 990 of file mfe.c.
Referenced by receive_trigger_event(), and send_event().
00991 { 00992 INT size, i, status, n_data; 00993 char *pdata; 00994 char name[5]; 00995 BANK_HEADER *pbh; 00996 BANK *pbk; 00997 BANK32 *pbk32; 00998 DWORD bkname; 00999 WORD bktype; 01000 HNDLE hKeyRoot, hKeyl; 01001 KEY key; 01002 01003 01004 /* outcommented since db_find_key does not work in FTCP mode, SR 25.4.03 01005 rpc_set_option(-1, RPC_OTRANSPORT, RPC_FTCP); */ 01006 01007 if (format == FORMAT_FIXED) { 01008 if (db_set_record(hDB, hKey, (char *) (pevent + 1), 01009 pevent->data_size, 0) != DB_SUCCESS) 01010 cm_msg(MERROR, "update_odb", "event #%d size mismatch", pevent->event_id); 01011 } else if (format == FORMAT_MIDAS) { 01012 pbh = (BANK_HEADER *) (pevent + 1); 01013 pbk = NULL; 01014 pbk32 = NULL; 01015 do { 01016 /* scan all banks */ 01017 if (bk_is32(pbh)) { 01018 size = bk_iterate32(pbh, &pbk32, &pdata); 01019 if (pbk32 == NULL) 01020 break; 01021 bkname = *((DWORD *) pbk32->name); 01022 bktype = (WORD) pbk32->type; 01023 } else { 01024 size = bk_iterate(pbh, &pbk, &pdata); 01025 if (pbk == NULL) 01026 break; 01027 bkname = *((DWORD *) pbk->name); 01028 bktype = (WORD) pbk->type; 01029 } 01030 01031 n_data = size; 01032 if (rpc_tid_size(bktype & 0xFF)) 01033 n_data /= rpc_tid_size(bktype & 0xFF); 01034 01035 /* get bank key */ 01036 *((DWORD *) name) = bkname; 01037 name[4] = 0; 01038 01039 if (bktype == TID_STRUCT) { 01040 status = db_find_key(hDB, hKey, name, &hKeyRoot); 01041 if (status != DB_SUCCESS) { 01042 cm_msg(MERROR, "update_odb", 01043 "please define bank %s in BANK_LIST in frontend.c", name); 01044 continue; 01045 } 01046 01047 /* write structured bank */ 01048 for (i = 0;; i++) { 01049 status = db_enum_key(hDB, hKeyRoot, i, &hKeyl); 01050 if (status == DB_NO_MORE_SUBKEYS) 01051 break; 01052 01053 db_get_key(hDB, hKeyl, &key); 01054 01055 /* adjust for alignment */ 01056 if (key.type != TID_STRING && key.type != TID_LINK) 01057 pdata = 01058 (void *) VALIGN(pdata, MIN(ss_get_struct_align(), key.item_size)); 01059 01060 status = db_set_data(hDB, hKeyl, pdata, key.item_size * key.num_values, 01061 key.num_values, key.type); 01062 if (status != DB_SUCCESS) { 01063 cm_msg(MERROR, "update_odb", "cannot write %s to ODB", name); 01064 continue; 01065 } 01066 01067 /* shift data pointer to next item */ 01068 pdata += key.item_size * key.num_values; 01069 } 01070 } else { 01071 /* write variable length bank */ 01072 if (n_data > 0) 01073 db_set_value(hDB, hKey, name, pdata, size, n_data, bktype & 0xFF); 01074 } 01075 01076 } while (1); 01077 } else if (format == FORMAT_YBOS) { 01078 assert(!"YBOS not supported anymore"); 01079 } 01080 01081 rpc_set_option(-1, RPC_OTRANSPORT, RPC_TCP); 01082 }
int _readout_enabled_flag = 0 [static] |
Definition at line 55 of file mfe.c.
Referenced by check_polled_events(), scan_fragment(), and scheduler().
Definition at line 54 of file mfe.c.
Referenced by check_polled_events(), interrupt_routine(), log_write(), process_event(), readout_thread(), scheduler(), and update_stats().
DWORD auto_restart = 0 |
Definition at line 66 of file mfe.c.
Referenced by log_write(), main(), start_the_run(), stop_the_run(), and tr_stop().
Definition at line 65 of file mfe.c.
Referenced by cmp_names(), eb_user(), handFlush(), lazy_main(), lazy_maintain_free_space(), lazy_select_purge(), load_fragment(), main(), open_history(), scan_fragment(), set_history_path(), source_booking(), source_unbooking(), and vf48_ParameterRead().
Definition at line 32 of file ebuser.c.
Referenced by manual_trigger(), rotate_wheel(), tr_pause(), tr_resume(), tr_start(), and tr_stop().
void* event_buffer |
Definition at line 78 of file mfe.c.
Referenced by check_polled_events(), main(), scheduler(), and send_event().
void* frag_buffer = NULL |
Definition at line 20 of file midas_macro.h.
char* frontend_file_name |
INT frontend_index = -1 |
Definition at line 68 of file mfe.c.
Referenced by get_frontend_index(), main(), and register_equipment().
char* frontend_name |
Definition at line 23 of file ebuser.c.
Referenced by load_fragment(), main(), register_equipment(), scan_fragment(), and tr_stop().
char full_frontend_name[256] |
HNDLE hDB |
Definition at line 71 of file mfe.c.
Referenced by add_data_dir(), add_event(), ana_end_of_run(), analyze_run(), analyzer_init(), ascii_write(), assemble_prompt(), book_ntuples(), bor(), build_done_list(), build_done_list_odb(), close_history(), cm_connect_client(), cm_connect_experiment1(), cm_disconnect_experiment(), cm_get_client_info(), cm_msg_log(), cm_msg_log1(), cm_msg_retrieve(), cm_set_watchdog_params(), cmd_dir(), command_loop(), condition_test(), convert_done_list(), db_get_event_definition(), do_jrpc_rev0(), dump_write(), el_submit(), evaluate_src(), exec_script(), gen_odb_attachment(), get_elog_url(), get_event_id(), get_variable_id(), get_variable_id_tags(), MidasHistory::GetEventsFromEquipment(), MidasHistory::GetEventsFromOdbEvents(), MidasHistory::GetEventsFromOdbTags(), MidasHistory::GetTagsFromEquipment(), MidasHistory::GetTagsFromOdb(), MidasHistory::hs_connect(), MidasHistory::hs_get_events(), init_module_parameters(), is_editable(), lazy_main(), lazy_maintain_check(), lazy_maintain_free_space(), lazy_select_purge(), load_fragment(), log_callback(), log_odb_dump(), log_write(), logger_init(), logger_root(), main(), mana_init(), odb_load(), odb_save(), open_history(), process_event(), register_equipment(), register_requests(), save_done_list(), set_equipment_status(), show_cnaf_page(), show_custom_gif(), show_custom_page(), show_elog_delete(), show_elog_new(), show_elog_page(), show_elog_query(), show_elog_submit_query(), show_form_query(), show_messages_page(), show_odb_tag(), show_rawfile(), show_sc_page(), show_status_page(), start_the_run(), stop_the_run(), submit_elog(), submit_form(), test_write(), tr_start(), tr_start_fal(), tr_stop(), tr_stop_fal(), update_odb(), write_event_ascii(), write_event_hbook(), and write_event_odb().
char host_name[HOST_NAME_LENGTH] |
Definition at line 58 of file mfe.c.
Referenced by display(), ftp_data(), ftp_open(), main(), mftp_open(), sendmail(), server_loop(), and submit_elog().
EQUIPMENT* interrupt_eq = NULL |
Definition at line 75 of file mfe.c.
Referenced by initialize_equipment(), interrupt_enable(), interrupt_routine(), main(), and readout_enable().
BOOL lockout_readout_thread = TRUE |
Definition at line 35 of file ebuser.c.
Referenced by check_polled_events(), handFlush(), initialize_equipment(), load_fragment(), readout_thread(), send_event(), source_booking(), and source_scan().
void(*) mfe_error_dispatcher(const char *) = NULL |
int mfe_error_r |
char mfe_error_str[MFE_ERROR_SIZE][256] |
int mfe_error_w |
EQUIPMENT* multithread_eq = NULL |
int* n_events |
int rbh1 = 0 |
Definition at line 84 of file mfe.c.
Referenced by initialize_equipment(), interrupt_routine(), and readout_thread().
int rbh1_next = 0 |
int rbh2 = 0 |
Definition at line 84 of file mfe.c.
Referenced by initialize_equipment(), and receive_trigger_event().
volatile int readout_thread_active = 0 |
Definition at line 53 of file mfe.c.
Referenced by display(), el_submit(), export_hist(), generate_hist_graph(), loop_runs_offline(), register_equipment(), show_elog_new(), show_form_query(), tr_pause(), tr_resume(), tr_start(), and tr_stop().
Definition at line 52 of file mfe.c.
Referenced by display(), interprete(), lazy_condition_check(), main(), register_equipment(), scan_fragment(), scheduler(), tr_pause(), tr_resume(), tr_start(), tr_start_fal(), tr_stop(), and tr_stop_fal().
BOOL slowcont_eq = FALSE |
volatile int stop_all_threads = 0 |