From 58f7a41c1cdefb0efe038ce5ebf2c9fc098b5bd7 Mon Sep 17 00:00:00 2001 From: Martin Konrad Date: Fri, 10 Aug 2018 14:09:23 -0400 Subject: [PATCH 1/2] Add scanOnce/callback queue status Reports data about scanOnce and callback queue size and usage. --- devIocStats/devIocStats.h | 5 +- devIocStats/devIocStatsAnalog.c | 124 ++++++++++++++++++++++++++++++++ iocAdmin/Db/ioc.template | 25 +++++++ iocAdmin/Db/iocQueue.db | 45 ++++++++++++ 4 files changed, 197 insertions(+), 2 deletions(-) create mode 100644 iocAdmin/Db/iocQueue.db diff --git a/devIocStats/devIocStats.h b/devIocStats/devIocStats.h index 1d1b85c..1a76ef8 100644 --- a/devIocStats/devIocStats.h +++ b/devIocStats/devIocStats.h @@ -38,8 +38,9 @@ #define LOAD_TYPE 1 #define FD_TYPE 2 #define CA_TYPE 3 -#define STATIC_TYPE 4 -#define TOTAL_TYPES 5 +#define QUEUE_TYPE 4 +#define STATIC_TYPE 5 +#define TOTAL_TYPES 6 /* Names of environment variables (may be redefined in OSD include) */ #define STARTUP "STARTUP" diff --git a/devIocStats/devIocStatsAnalog.c b/devIocStats/devIocStatsAnalog.c index f668d1d..c6fe512 100644 --- a/devIocStats/devIocStatsAnalog.c +++ b/devIocStats/devIocStatsAnalog.c @@ -112,6 +112,7 @@ #include #include #include +#include #include #include @@ -124,6 +125,7 @@ #include #include #include +#include #include "devIocStats.h" @@ -213,6 +215,20 @@ static void statsIFOErrs(double *); static void statsRecords(double *); static void statsPID(double *); static void statsPPID(double *); +static void statsScanOnceQHiWtrMrk(double*); +static void statsScanOnceQUsed(double*); +static void statsScanOnceQSize(double*); +static void statsScanOnceQOverruns(double*); +static void statsCbQSize(double*); +static void statsCbLowQHiWtrMrk(double*); +static void statsCbLowQUsed(double*); +static void statsCbLowQOverruns(double*); +static void statsCbMediumQHiWtrMrk(double*); +static void statsCbMediumQUsed(double*); +static void statsCbMediumQOverruns(double*); +static void statsCbHighQHiWtrMrk(double*); +static void statsCbHighQUsed(double*); +static void statsCbHighQOverruns(double*); struct { char *name; @@ -222,6 +238,7 @@ struct { { "cpu_scan_rate", 20.0 }, { "fd_scan_rate", 10.0 }, { "ca_scan_rate", 15.0 }, + { "queue_scan_rate", 1.0 }, { NULL, 0.0 }, }; @@ -253,6 +270,20 @@ static validGetParms statsGetParms[]={ { "records", statsRecords, STATIC_TYPE }, { "proc_id", statsPID, STATIC_TYPE }, { "parent_proc_id", statsPPID, STATIC_TYPE }, + { "scanOnceQueueHiWtrMrk", statsScanOnceQHiWtrMrk, QUEUE_TYPE }, + { "scanOnceQueueUsed", statsScanOnceQUsed, QUEUE_TYPE }, + { "scanOnceQueueSize", statsScanOnceQSize, STATIC_TYPE }, + { "scanOnceQueueOverruns", statsScanOnceQOverruns, QUEUE_TYPE }, + { "cbQueueSize", statsCbQSize, STATIC_TYPE }, + { "cbLowQueueHiWtrMrk", statsCbLowQHiWtrMrk, QUEUE_TYPE }, + { "cbLowQueueUsed", statsCbLowQUsed, QUEUE_TYPE }, + { "cbLowQueueOverruns", statsCbLowQOverruns, QUEUE_TYPE }, + { "cbMediumQueueHiWtrMrk", statsCbMediumQHiWtrMrk, QUEUE_TYPE }, + { "cbMediumQueueUsed", statsCbMediumQUsed, QUEUE_TYPE }, + { "cbMediumQueueOverruns", statsCbMediumQOverruns, QUEUE_TYPE }, + { "cbHighQueueHiWtrMrk", statsCbHighQHiWtrMrk, QUEUE_TYPE }, + { "cbHighQueueUsed", statsCbHighQUsed, QUEUE_TYPE }, + { "cbHighQueueOverruns", statsCbHighQOverruns, QUEUE_TYPE }, { NULL,NULL,0 } }; @@ -265,6 +296,9 @@ epicsExportAddress(dset,devAiClusts); static memInfo meminfo = {0.0,0.0,0.0,0.0,0.0,0.0}; static memInfo workspaceinfo = {0.0,0.0,0.0,0.0,0.0,0.0}; +static scanOnceQueueStats scanOnceQStatus; +static callbackQueueStats callbackQStatus; +static int queueDataInitialized; static scanInfo scan[TOTAL_TYPES] = {{0}}; static fdInfo fdusage = {0,0}; static loadInfo loadinfo = {1,0.,0.}; @@ -310,6 +344,14 @@ static void notifyOnCaServInit(initHookState state) } } +static void getQueueData() { + if(EPICS_VERSION_INT >= VERSION_INT(3, 16, 2, 0)) { + scanOnceQueueStatus(0, &scanOnceQStatus); + callbackQueueStatus(0, &callbackQStatus); + } + queueDataInitialized = 1; +} + static void scan_time(int type) { switch(type) { @@ -374,6 +416,13 @@ static void scan_time(int type) epicsMutexUnlock(scan_mutex); break; } + case QUEUE_TYPE: + { + epicsMutexLock(scan_mutex); + getQueueData(); + epicsMutexUnlock(scan_mutex); + break; + } default: break; } @@ -756,3 +805,78 @@ static void statsPPID(double *val) *val = 0; devIocStatsGetPPID(val); } + +static void statsScanOnceQHiWtrMrk(double *val) +{ + if(!queueDataInitialized) getQueueData(); + *val = scanOnceQStatus.maxUsed; +} +static void statsScanOnceQUsed(double *val) +{ + if(!queueDataInitialized) getQueueData(); + *val = scanOnceQStatus.numUsed; +} +static void statsScanOnceQSize(double *val) +{ + if(!queueDataInitialized) getQueueData(); + *val = scanOnceQStatus.size; +} +static void statsScanOnceQOverruns(double *val) +{ + if(!queueDataInitialized) getQueueData(); + *val = scanOnceQStatus.numOverflow; +} + +static void statsCbQSize(double *val) +{ + if(!queueDataInitialized) getQueueData(); + *val = callbackQStatus.size; +} + +static void statsCbLowQHiWtrMrk(double *val) +{ + if(!queueDataInitialized) getQueueData(); + *val = callbackQStatus.maxUsed[priorityLow]; +} +static void statsCbLowQUsed(double *val) +{ + if(!queueDataInitialized) getQueueData(); + *val = callbackQStatus.numUsed[priorityLow]; +} +static void statsCbLowQOverruns(double *val) +{ + if(!queueDataInitialized) getQueueData(); + *val = callbackQStatus.numOverflow[priorityLow]; +} + +static void statsCbMediumQHiWtrMrk(double *val) +{ + if(!queueDataInitialized) getQueueData(); + *val = callbackQStatus.maxUsed[priorityMedium]; +} +static void statsCbMediumQUsed(double *val) +{ + if(!queueDataInitialized) getQueueData(); + *val = callbackQStatus.numUsed[priorityMedium]; +} +static void statsCbMediumQOverruns(double *val) +{ + if(!queueDataInitialized) getQueueData(); + *val = callbackQStatus.numOverflow[priorityMedium]; +} + +static void statsCbHighQHiWtrMrk(double *val) +{ + if(!queueDataInitialized) getQueueData(); + *val = callbackQStatus.maxUsed[priorityHigh]; +} +static void statsCbHighQUsed(double *val) +{ + if(!queueDataInitialized) getQueueData(); + *val = callbackQStatus.numUsed[priorityHigh]; +} +static void statsCbHighQOverruns(double *val) +{ + if(!queueDataInitialized) getQueueData(); + *val = callbackQStatus.numOverflow[priorityHigh]; +} diff --git a/iocAdmin/Db/ioc.template b/iocAdmin/Db/ioc.template index 47e9c8a..eaa06ab 100644 --- a/iocAdmin/Db/ioc.template +++ b/iocAdmin/Db/ioc.template @@ -361,3 +361,28 @@ record(ai, "$(IOCNAME):PARENT_ID") { field(DTYP, "IOC stats") field(INP, "@parent_proc_id") } + +record(ai, "$(IOCNAME):SCANONCE_Q_SIZE") { + field(DESC, "max # entries in IOC scanOnce queue") + field(DTYP, "IOC stats") + field(INP, "@scanOnceQueueSize") + field(PINI, "YES") +} +record(ai, "$(IOCNAME):CB_Q_SIZE") { + field(DESC, "max # entries in IOC callback queues") + field(DTYP, "IOC stats") + field(INP, "@cbQueueSize") + field(PINI, "YES") +} + +substitute "QUEUE=scanOnce, QUEUE_CAPS=SCANONCE, QUEUE_TYPE=SCANONCE" +include "iocQueue.db" + +substitute "QUEUE=cbLow, QUEUE_CAPS=CBLOW, QUEUE_TYPE=CB" +include "iocQueue.db" + +substitute "QUEUE=cbMedium, QUEUE_CAPS=CBMEDIUM, QUEUE_TYPE=CB" +include "iocQueue.db" + +substitute "QUEUE=cbHigh, QUEUE_CAPS=CBHIGH, QUEUE_TYPE=CB" +include "iocQueue.db" diff --git a/iocAdmin/Db/iocQueue.db b/iocAdmin/Db/iocQueue.db new file mode 100644 index 0000000..ab49b88 --- /dev/null +++ b/iocAdmin/Db/iocQueue.db @@ -0,0 +1,45 @@ +record(ai, "$(IOCNAME):$(QUEUE_CAPS)_Q_HIGH") { + field(DESC, "max # of elmts in IOC's $(QUEUE) queue") + field(SCAN, "I/O Intr") + field(DTYP, "IOC stats") + field(INP, "@$(QUEUE)QueueHiWtrMrk") + field(PINI, "YES") + field(FLNK, "$(IOCNAME):$(QUEUE_CAPS)_Q_HIGHPER") +} + +record(calc, "$(IOCNAME):$(QUEUE_CAPS)_Q_HIGHPER") { + field(DESC, "Max. usage of IOC's $(QUEUE) queue") + field(INPA, "$(IOCNAME):$(QUEUE_CAPS)_Q_HIGH NPP MS") + field(INPB, "$(IOCNAME):$(QUEUE_TYPE)_Q_SIZE NPP MS") + field(CALC, "100*A/B") + field(LOPR, "0") + field(HOPR, "100") + field(EGU, "%") +} + +record(ai, "$(IOCNAME):$(QUEUE_CAPS)_Q_USED") { + field(DESC, "# of entries in IOC's $(QUEUE) queue") + field(SCAN, "I/O Intr") + field(DTYP, "IOC stats") + field(INP, "@$(QUEUE)QueueUsed") + field(PINI, "YES") + field(FLNK, "$(IOCNAME):$(QUEUE_CAPS)_Q_USEDPER") +} + +record(calc, "$(IOCNAME):$(QUEUE_CAPS)_Q_USEDPER") { + field(DESC, "Percentage of IOC's $(QUEUE) queue used") + field(INPA, "$(IOCNAME):$(QUEUE_CAPS)_Q_USED NPP MS") + field(INPB, "$(IOCNAME):$(QUEUE_TYPE)_Q_SIZE NPP MS") + field(CALC, "100*A/B") + field(LOPR, "0") + field(HOPR, "100") + field(EGU, "%") +} + +record(ai, "$(IOCNAME):$(QUEUE_CAPS)_Q_OVERRUNS") { + field(DESC, "# of overruns of IOC's $(QUEUE) queue") + field(SCAN, "I/O Intr") + field(DTYP, "IOC stats") + field(INP, "@$(QUEUE)QueueOverruns") + field(PINI, "YES") +} From 719b73ca6a1c4bb622db497270f1b09ede257ee0 Mon Sep 17 00:00:00 2001 From: Martin Konrad Date: Thu, 13 Dec 2018 15:28:22 -0500 Subject: [PATCH 2/2] Disable queue status code when used with old Base version --- devIocStats/devIocStatsAnalog.c | 64 +++++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 2 deletions(-) diff --git a/devIocStats/devIocStatsAnalog.c b/devIocStats/devIocStatsAnalog.c index c6fe512..543edef 100644 --- a/devIocStats/devIocStatsAnalog.c +++ b/devIocStats/devIocStatsAnalog.c @@ -129,6 +129,8 @@ #include "devIocStats.h" +#define BASE_HAS_QUEUE_STATUS (EPICS_VERSION_INT == VERSION_INT(3, 16, 2, 0)) || (EPICS_VERSION_INT >= VERSION_INT(7, 0, 2, 0)) + struct aStats { long number; @@ -296,8 +298,10 @@ epicsExportAddress(dset,devAiClusts); static memInfo meminfo = {0.0,0.0,0.0,0.0,0.0,0.0}; static memInfo workspaceinfo = {0.0,0.0,0.0,0.0,0.0,0.0}; +#if BASE_HAS_QUEUE_STATUS static scanOnceQueueStats scanOnceQStatus; static callbackQueueStats callbackQStatus; +#endif static int queueDataInitialized; static scanInfo scan[TOTAL_TYPES] = {{0}}; static fdInfo fdusage = {0,0}; @@ -345,10 +349,10 @@ static void notifyOnCaServInit(initHookState state) } static void getQueueData() { - if(EPICS_VERSION_INT >= VERSION_INT(3, 16, 2, 0)) { + #if BASE_HAS_QUEUE_STATUS scanOnceQueueStatus(0, &scanOnceQStatus); callbackQueueStatus(0, &callbackQStatus); - } + #endif queueDataInitialized = 1; } @@ -808,75 +812,131 @@ static void statsPPID(double *val) static void statsScanOnceQHiWtrMrk(double *val) { +#if BASE_HAS_QUEUE_STATUS if(!queueDataInitialized) getQueueData(); *val = scanOnceQStatus.maxUsed; +#else + *val = 0; +#endif } static void statsScanOnceQUsed(double *val) { +#if BASE_HAS_QUEUE_STATUS if(!queueDataInitialized) getQueueData(); *val = scanOnceQStatus.numUsed; +#else + *val = 0; +#endif } static void statsScanOnceQSize(double *val) { +#if BASE_HAS_QUEUE_STATUS if(!queueDataInitialized) getQueueData(); *val = scanOnceQStatus.size; +#else + *val = 0; +#endif } static void statsScanOnceQOverruns(double *val) { +#if BASE_HAS_QUEUE_STATUS if(!queueDataInitialized) getQueueData(); *val = scanOnceQStatus.numOverflow; +#else + *val = 0; +#endif } static void statsCbQSize(double *val) { +#if BASE_HAS_QUEUE_STATUS if(!queueDataInitialized) getQueueData(); *val = callbackQStatus.size; +#else + *val = 0; +#endif } static void statsCbLowQHiWtrMrk(double *val) { +#if BASE_HAS_QUEUE_STATUS if(!queueDataInitialized) getQueueData(); *val = callbackQStatus.maxUsed[priorityLow]; +#else + *val = 0; +#endif } static void statsCbLowQUsed(double *val) { +#if BASE_HAS_QUEUE_STATUS if(!queueDataInitialized) getQueueData(); *val = callbackQStatus.numUsed[priorityLow]; +#else + *val = 0; +#endif } static void statsCbLowQOverruns(double *val) { +#if BASE_HAS_QUEUE_STATUS if(!queueDataInitialized) getQueueData(); *val = callbackQStatus.numOverflow[priorityLow]; +#else + *val = 0; +#endif } static void statsCbMediumQHiWtrMrk(double *val) { +#if BASE_HAS_QUEUE_STATUS if(!queueDataInitialized) getQueueData(); *val = callbackQStatus.maxUsed[priorityMedium]; +#else + *val = 0; +#endif } static void statsCbMediumQUsed(double *val) { +#if BASE_HAS_QUEUE_STATUS if(!queueDataInitialized) getQueueData(); *val = callbackQStatus.numUsed[priorityMedium]; +#else + *val = 0; +#endif } static void statsCbMediumQOverruns(double *val) { +#if BASE_HAS_QUEUE_STATUS if(!queueDataInitialized) getQueueData(); *val = callbackQStatus.numOverflow[priorityMedium]; +#else + *val = 0; +#endif } static void statsCbHighQHiWtrMrk(double *val) { +#if BASE_HAS_QUEUE_STATUS if(!queueDataInitialized) getQueueData(); *val = callbackQStatus.maxUsed[priorityHigh]; +#else + *val = 0; +#endif } static void statsCbHighQUsed(double *val) { +#if BASE_HAS_QUEUE_STATUS if(!queueDataInitialized) getQueueData(); *val = callbackQStatus.numUsed[priorityHigh]; +#else + *val = 0; +#endif } static void statsCbHighQOverruns(double *val) { +#if BASE_HAS_QUEUE_STATUS if(!queueDataInitialized) getQueueData(); *val = callbackQStatus.numOverflow[priorityHigh]; +#else + *val = 0; +#endif }