📄 gateserver.cc
字号:
stat_table[i].precision=0; break; case statInactive: stat_table[i].name="inactive"; stat_table[i].desc="Inactive PVs"; stat_table[i].init_value=&total_inactive; stat_table[i].units=""; stat_table[i].precision=0; break; case statUnconnected: stat_table[i].name="unconnected"; stat_table[i].desc="Unconnected PVs"; stat_table[i].init_value=&total_unconnected; stat_table[i].units=""; stat_table[i].precision=0; break; case statDead: stat_table[i].name="dead"; stat_table[i].desc="Dead PVs"; stat_table[i].init_value=&total_dead; stat_table[i].units=""; stat_table[i].precision=0; break; case statConnecting: stat_table[i].name="connecting"; stat_table[i].desc="Connecting PVs"; stat_table[i].init_value=&total_connecting; stat_table[i].units=""; stat_table[i].precision=0; break; case statDisconnected: stat_table[i].name="disconnected"; stat_table[i].desc="Disconnected PVs"; stat_table[i].init_value=&total_disconnected; stat_table[i].units=""; stat_table[i].precision=0; break;# ifdef USE_FDS case statFd: stat_table[i].name="fd"; stat_table[i].desc="FDs"; stat_table[i].init_value=&total_fd; stat_table[i].units=""; stat_table[i].precision=0; break;# endif#endif#ifdef RATE_STATS case statClientEventRate: stat_table[i].name="clientEventRate"; stat_table[i].desc="Client Event Rate"; stat_table[i].init_value=&zero; stat_table[i].units="Hz"; stat_table[i].precision=2; break; case statPostEventRate: stat_table[i].name="clientPostRate"; stat_table[i].desc="Client Post Rate"; stat_table[i].init_value=&zero; stat_table[i].units="Hz"; stat_table[i].precision=2; break; case statExistTestRate: stat_table[i].name="existTestRate"; stat_table[i].desc="Exist Test Rate"; stat_table[i].init_value=&zero; stat_table[i].units="Hz"; stat_table[i].precision=2; break; case statLoopRate: stat_table[i].name="loopRate"; stat_table[i].desc="Loop Rate"; stat_table[i].init_value=&zero; stat_table[i].units="Hz"; stat_table[i].precision=2; break; case statCPUFract: stat_table[i].name="cpuFract"; stat_table[i].desc="CPU Fraction"; stat_table[i].init_value=&zero; stat_table[i].units=""; stat_table[i].precision=3; break; case statLoad: stat_table[i].name="load"; stat_table[i].desc="Load"; stat_table[i].init_value=&zero; stat_table[i].units=""; stat_table[i].precision=3; break;#endif#ifdef CAS_DIAGNOSTICS case statServerEventRate: stat_table[i].name="serverEventRate"; stat_table[i].desc="Server Event Rate"; stat_table[i].init_value=&zero; stat_table[i].units="Hz"; stat_table[i].precision=2; break; case statServerEventRequestRate: stat_table[i].name="serverPostRate"; stat_table[i].desc="Server Post Rate"; stat_table[i].init_value=&zero; stat_table[i].units="Hz"; stat_table[i].precision=2; break;#endif#ifdef CONTROL_PVS case statCommandFlag: stat_table[i].name="commandFlag"; stat_table[i].desc="Command Flag"; stat_table[i].init_value=&command_flag; stat_table[i].units=""; stat_table[i].precision=0; break; case statReport1Flag: stat_table[i].name="report1Flag"; stat_table[i].desc="Report 1 Flag"; stat_table[i].init_value=&report1_flag; stat_table[i].units=""; stat_table[i].precision=0; break; case statReport2Flag: stat_table[i].name="report2Flag"; stat_table[i].desc="Report 2 Flag"; stat_table[i].init_value=&report2_flag; stat_table[i].units=""; stat_table[i].precision=0; break; case statReport3Flag: stat_table[i].name="report3Flag"; stat_table[i].desc="Report 3 Flag"; stat_table[i].init_value=&report3_flag; stat_table[i].units=""; stat_table[i].precision=0; break; case statNewAsFlag: stat_table[i].name="newAsFlag"; stat_table[i].desc="New AS Flag"; stat_table[i].init_value=&newAs_flag; stat_table[i].units=""; stat_table[i].precision=0; break; case statQuitFlag: stat_table[i].name="quitFlag"; stat_table[i].desc="Quit Flag"; stat_table[i].init_value=&quit_flag; stat_table[i].units=""; stat_table[i].precision=0; break; case statQuitServerFlag: stat_table[i].name="quitServerFlag"; stat_table[i].desc="Quit Server Flag"; stat_table[i].init_value=&quitserver_flag; stat_table[i].units=""; stat_table[i].precision=0; break;#endif } stat_table[i].pvName=new char[stat_prefix_len+1+strlen(stat_table[i].name)+1]; sprintf(stat_table[i].pvName,"%s:%s",stat_prefix,stat_table[i].name); stat_table[i].pv=NULL; stat_table[i].descPvName=new char[stat_prefix_len+1+strlen(stat_table[i].name)+6]; sprintf(stat_table[i].descPvName,"%s:%s.DESC",stat_prefix,stat_table[i].name); stat_table[i].descPv=NULL; }}// KE: Only used in gateStat destructorvoid gateServer::clearStat(int type, gateStatType statType){ if(statType == GATE_STAT_TYPE_DESC) { stat_table[type].descPv=NULL; } else { stat_table[type].pv=NULL; }}#if defined(RATE_STATS) || defined(CAS_DIAGNOSTICS)// Rate statisticsepicsTimerNotify:: expireStatusgateRateStatsTimer::expire(const epicsTime &curTime){ static int first=1; static epicsTime prevTime; double delTime;#ifdef RATE_STATS static unsigned long cePrevCount,etPrevCount,mlPrevCount,pePrevCount ; static unsigned long cpuPrevCount; unsigned long ceCurCount=mrg->client_event_count; unsigned long peCurCount=mrg->post_event_count; unsigned long etCurCount=mrg->exist_count; unsigned long mlCurCount=mrg->loop_count; // clock really returns clock_t, which should be long#ifdef __linux__# ifndef USE_LINUX_PROC_FOR_CPU // Use clock from main process for Linux unsigned long cpuCurCount=mainClock;# endif#else // Use clock for other systems. For WIN32, clock returns wall // clock so cpuFract always is 1. unsigned long cpuCurCount=(unsigned long)clock();#endif double ceRate,peRate,etRate,mlRate,cpuFract;#endif#ifdef CAS_DIAGNOSTICS static unsigned long sePrevCount,srPrevCount; unsigned long seCurCount=mrg->subscriptionEventsProcessed(); unsigned long srCurCount=mrg->subscriptionEventsPosted(); double seRate,srRate;#endif // Initialize the first time if(first) { prevTime=curTime;#ifdef RATE_STATS cePrevCount=ceCurCount; pePrevCount=peCurCount; etPrevCount=etCurCount; mlPrevCount=mlCurCount; cpuPrevCount=cpuCurCount;#endif#ifdef CAS_DIAGNOSTICS sePrevCount=seCurCount; srPrevCount=srCurCount;#endif first=0; } delTime=(double)(curTime-prevTime);#if DEBUG_CLOCK static int second=1; if(second) { if(cpuCurCount > 0 && cpuPrevCount != cpuCurCount) { printf("%s %d cpuPrevCount=%lu cpuCurCount=%lu\n", timeStamp(),second++,cpuPrevCount,cpuCurCount); if(second > 25) second=0; } else if(cpuCurCount == (unsigned long)((clock_t)(-1))) { printf("%s %d cpuCurCount=%ld\n",timeStamp(),second++, (clock_t)cpuCurCount); if(second > 25) second=0; } }#endif#ifdef RATE_STATS // Calculate the client event rate ceRate=(delTime > 0)?(double)(ULONG_DIFF(ceCurCount,cePrevCount))/ delTime:0.0; mrg->setStat(statClientEventRate,ceRate); // Calculate the post event rate peRate=(delTime > 0)?(double)(ULONG_DIFF(peCurCount,pePrevCount))/ delTime:0.0; mrg->setStat(statPostEventRate,peRate); // Calculate the exist test rate etRate=(delTime > 0)?(double)(ULONG_DIFF(etCurCount,etPrevCount))/ delTime:0.0; mrg->setStat(statExistTestRate,etRate); // Calculate the main loop rate mlRate=(delTime > 0)?(double)(ULONG_DIFF(mlCurCount,mlPrevCount))/ delTime:0.0; mrg->setStat(statLoopRate,mlRate); // Calculate the CPU Fract // Note: clock() returns (long)-1 if it can't find the time; // however, we can't distinguish that -1 from a -1 owing to // wrapping. So treat the return value as an unsigned long and // don't check the return value.#ifdef USE_LINUX_PROC_FOR_CPU double timeDiff=linuxCpuTimeDiff(); if(timeDiff < 0.0) { // Error cpuFract=-1.0; } else { cpuFract=(delTime > 0)?timeDiff/delTime:0.0; }#else cpuFract=(delTime > 0)?(double)(ULONG_DIFF(cpuCurCount,cpuPrevCount))/ delTime/CLOCKS_PER_SEC:0.0;#endif mrg->setStat(statCPUFract,cpuFract);#ifndef WIN32 // Calculate the load using average over last minute. Does not // exist for WIN32. double load[N_LOAD]; int nProcesses; nProcesses=getloadavg(load,N_LOAD); mrg->setStat(statLoad,load[N_LOAD-1]);#endif#endif #ifdef CAS_DIAGNOSTICS // Calculate the server event rate seRate=(delTime > 0)?(double)(ULONG_DIFF(seCurCount,sePrevCount))/ delTime:0.0; mrg->setStat(statServerEventRate,seRate); // Calculate the server event request rate srRate=(delTime > 0)?(double)(ULONG_DIFF(srCurCount,srPrevCount))/ delTime:0.0; mrg->setStat(statServerEventRequestRate,srRate);#endif#if 0 printf("gateRateStatsTimer::expire(): ceCurCount=%ld cePrevCount=%ld ceRate=%g\n", ceCurCount,cePrevCount,ceRate); printf(" deltime=%g etCurCount=%ld etPrevCount=%ld etRate=%g\n", delTime,etCurCount,etPrevCount,etRate); fflush(stdout);#endif // Reset the previous values prevTime=curTime;#ifdef RATE_STATS cePrevCount=ceCurCount; pePrevCount=peCurCount; etPrevCount=etCurCount; mlPrevCount=mlCurCount; cpuPrevCount=cpuCurCount;#endif#ifdef CAS_DIAGNOSTICS sePrevCount=seCurCount; srPrevCount=srCurCount;#endif // Set to continue return epicsTimerNotify::expireStatus(restart,interval);}#endif // #if defined(RATE_STATS) || defined(CAS_DIAGNOSTICS)#endif // #if stat_count#ifdef USE_LINUX_PROC_FOR_CPU// A clock routine for Linux// From Man pages for Red Hat Linux 8.0 3.2-7// This data may change// pid %d The process id.// comm %s// The filename of the executable, in parentheses.// This is visible whether or not the executable is// swapped out.// state %c// One character from the string "RSDZTW" where R is// running, S is sleeping in an interruptible wait,// D is waiting in uninterruptible disk sleep, Z is// zombie, T is traced or stopped (on a signal), and// W is paging.// ppid %d// The PID of the parent.// pgrp %d// The process group ID of the process.// session %d// The session ID of the process.// tty_nr %d// The tty the process uses.// tpgid %d// The process group ID of the process which cur-// rently owns the tty that the process is connected// to.// flags %lu// The flags of the process. The math bit is deci-// mal 4, and the traced bit is decimal 10.// minflt %lu// The number of minor faults the process has made// which have not required loading a memory page// from disk.// cminflt %lu// The number of minor faults that the process and// its children have made.// majflt %lu// The number of major faults the process has made// which have required loading a memory page from// disk.// cmajflt %lu// The number of major faults that the process and// its children have made.// utime %lu// The number of jiffies that this process has been// scheduled in user mode.// stime %lu// The number of jiffies that this process has been// scheduled in kernel mode.// cutime %ld// The number of jiffies that this process and its// children have been scheduled in user mode.// cstime %ld// The number of jiffies that this process and its// children have been scheduled in kernel mode.// ...// jiffie is .01 sec#define SEC_PER_JIFFIE .01static double linuxCpuTimeDiff(void){ static unsigned long prevutime=0; static unsigned long prevstime=0; double retVal=-1.0; if(gate_pid > 0) { static char statfile[80]=""; // Create the file name once if(!*statfile) { sprintf(statfile,"/proc/%d/stat",gate_pid); } FILE *fp=fopen(statfile,"r"); if(fp) { int pid=0; char comm[1024]; // Should use MAX_PATH or PATH_MAX char state; int ppid,pgrp,session,tty_nr,tpgid; unsigned long flags,minflt,cminflt,majflt,cmajflt,utime=0,stime=0; long cutime=0,cstime=0; // Remove cutime and cstime for efficiency int count=fscanf(fp,"%d %s %c %d %d %d %d %d " "%lu %lu %lu %lu %lu " "%lu %lu %ld %ld", &pid,comm,&state,&ppid,&pgrp,&session,&tty_nr,&tpgid, &flags,&minflt,&cminflt,&majflt,&cmajflt, &utime,&stime,&cutime,&cstime); fclose(fp); if(count == 17 ) { double utimediff=(double)ULONG_DIFF(utime,prevutime); double stimediff=(double)ULONG_DIFF(stime,prevstime); retVal=(utimediff+stimediff)*SEC_PER_JIFFIE;#if DEBUG_CLOCK if(prevstime > stime) { printf("prevstime=%lu > stime=%lu\n",prevstime,stime); } if(prevutime > utime) { printf("prevutime=%lu > utime=%lu\n",prevutime,utime); }#endif prevstime=stime; prevutime=utime; }#if DEBUG_CLOCK static int nprint=0; if(nprint == 0) { printf("SEC_PER_JIFFIE=%g ULONG_MAX=%lu\n", SEC_PER_JIFFIE,ULONG_MAX); } if(nprint < 1000) { printf("%2d utime=%lu stime=%lu cutime=%ld cstime=%ld " "retVal=%g\n", ++nprint,utime,stime,cutime,cstime,retVal); }#endif } } return retVal;}#endif#ifndef WIN32void gateServer::sig_usr1(int /*x*/){ gateServer::command_flag=1; signal(SIGUSR1,::sig_usr1);}void gateServer::sig_usr2(int /*x*/){ gateServer::report2_flag=1; signal(SIGUSR2,::sig_usr2);}#endif/* **************************** Emacs Editing Sequences ***************** *//* Local Variables: *//* tab-width: 4 *//* c-basic-offset: 4 *//* c-comment-only-line-offset: 0 *//* c-file-offsets: ((substatement-open . 0) (label . 0)) *//* End: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -