Skip to content

Commit

Permalink
Merge pull request #30 from mark0n/callbackQueueStatus
Browse files Browse the repository at this point in the history
Add scanOnce/callback queue status
  • Loading branch information
anjohnson authored Apr 30, 2019
2 parents 109598d + 719b73c commit 4df9e87
Show file tree
Hide file tree
Showing 4 changed files with 257 additions and 2 deletions.
5 changes: 3 additions & 2 deletions devIocStats/devIocStats.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
184 changes: 184 additions & 0 deletions devIocStats/devIocStatsAnalog.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@
#include <epicsThread.h>
#include <epicsTimer.h>
#include <epicsMutex.h>
#include <epicsVersion.h>

#include <rsrv.h>
#include <dbAccess.h>
Expand All @@ -124,9 +125,12 @@
#include <recGbl.h>
#include <epicsExport.h>
#include <initHooks.h>
#include <callback.h>

#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;
Expand Down Expand Up @@ -213,6 +217,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;
Expand All @@ -222,6 +240,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 },
};

Expand Down Expand Up @@ -253,6 +272,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 }
};

Expand All @@ -265,6 +298,11 @@ 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};
static loadInfo loadinfo = {1,0.,0.};
Expand Down Expand Up @@ -310,6 +348,14 @@ static void notifyOnCaServInit(initHookState state)
}
}

static void getQueueData() {
#if BASE_HAS_QUEUE_STATUS
scanOnceQueueStatus(0, &scanOnceQStatus);
callbackQueueStatus(0, &callbackQStatus);
#endif
queueDataInitialized = 1;
}

static void scan_time(int type)
{
switch(type) {
Expand Down Expand Up @@ -374,6 +420,13 @@ static void scan_time(int type)
epicsMutexUnlock(scan_mutex);
break;
}
case QUEUE_TYPE:
{
epicsMutexLock(scan_mutex);
getQueueData();
epicsMutexUnlock(scan_mutex);
break;
}
default:
break;
}
Expand Down Expand Up @@ -756,3 +809,134 @@ static void statsPPID(double *val)
*val = 0;
devIocStatsGetPPID(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
}
25 changes: 25 additions & 0 deletions iocAdmin/Db/ioc.template
Original file line number Diff line number Diff line change
Expand Up @@ -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"
45 changes: 45 additions & 0 deletions iocAdmin/Db/iocQueue.db
Original file line number Diff line number Diff line change
@@ -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")
}

0 comments on commit 4df9e87

Please sign in to comment.