From 7c273b3d1543ae973b7d48422ed1308ed1581bc2 Mon Sep 17 00:00:00 2001 From: Florian Feldbauer Date: Tue, 7 Jun 2022 09:20:08 +0200 Subject: [PATCH 1/2] Add support to monitor CPU temperature Added support to monitor the CPU temperature on Linux. New function uses the LOAD_TYPE scan rate like all the other CPU related informations. --- devIocStats/Makefile | 1 + devIocStats/devIocStats.h | 3 +++ devIocStats/devIocStatsAnalog.c | 11 +++++++- devIocStats/os/Linux/osdCpuTemp.c | 40 +++++++++++++++++++++++++++++ devIocStats/os/default/osdCpuTemp.c | 21 +++++++++++++++ 5 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 devIocStats/os/Linux/osdCpuTemp.c create mode 100644 devIocStats/os/default/osdCpuTemp.c diff --git a/devIocStats/Makefile b/devIocStats/Makefile index 5acd089..10fd9e1 100644 --- a/devIocStats/Makefile +++ b/devIocStats/Makefile @@ -44,6 +44,7 @@ SRCS += osdBootInfo.c SRCS += osdSystemInfo.c SRCS += osdHostInfo.c SRCS += osdPIDInfo.c +SRCS += osdCpuTemp.c OBJS_vxWorks += osdCpuUsageTest.o diff --git a/devIocStats/devIocStats.h b/devIocStats/devIocStats.h index 1a76ef8..1e2dd32 100644 --- a/devIocStats/devIocStats.h +++ b/devIocStats/devIocStats.h @@ -131,4 +131,7 @@ extern int devIocStatsGetHostname (char **pval); extern int devIocStatsGetPID (double *proc_id); extern int devIocStatsGetPPID (double *proc_id); +/* CPU Temperature */ +extern int devIocStatsGetCpuTemp (int *pval); + #endif /* devIocStats_H */ diff --git a/devIocStats/devIocStatsAnalog.c b/devIocStats/devIocStatsAnalog.c index 7f4ea6e..58b1bb0 100644 --- a/devIocStats/devIocStatsAnalog.c +++ b/devIocStats/devIocStatsAnalog.c @@ -202,6 +202,7 @@ static void statsWSAllocBytes(double*); static void statsWSTotalBytes(double*); static void statsCpuUsage(double*); static void statsCpuUtilization(double*); +static void statsCpuTemperature(double*); static void statsNoOfCpus(double*); static void statsSuspendedTasks(double*); static void statsFdUsage(double*); @@ -231,7 +232,6 @@ static void statsCbMediumQOverruns(double*); static void statsCbHighQHiWtrMrk(double*); static void statsCbHighQUsed(double*); static void statsCbHighQOverruns(double*); - struct { char *name; double scan_rate; @@ -286,6 +286,7 @@ static validGetParms statsGetParms[]={ { "cbHighQueueHiWtrMrk", statsCbHighQHiWtrMrk, QUEUE_TYPE }, { "cbHighQueueUsed", statsCbHighQUsed, QUEUE_TYPE }, { "cbHighQueueOverruns", statsCbHighQOverruns, QUEUE_TYPE }, + { "cpu_temperature", statsCpuTemperature, LOAD_TYPE }, { NULL,NULL,0 } }; @@ -307,6 +308,7 @@ static scanInfo scan[TOTAL_TYPES] = {{0}}; static fdInfo fdusage = {0,0}; static loadInfo loadinfo = {1,0.,0.}; static int susptasknumber = 0; +static int cputemperature = 0; static int recordnumber = 0; static clustInfo clustinfo[2] = {{{0}},{{0}}}; static int mbufnumber[2] = {0,0}; @@ -385,12 +387,15 @@ static void scan_time(int type) { loadInfo loadinfo_local = {1,0.,0.}; int susptasknumber_local = 0; + int cputemperature_local = 0; devIocStatsGetCpuUsage(&loadinfo_local); devIocStatsGetCpuUtilization(&loadinfo_local); devIocStatsGetSuspTasks(&susptasknumber_local); + devIocStatsGetCpuTemp(&cputemperature_local); epicsMutexLock(scan_mutex); loadinfo = loadinfo_local; susptasknumber = susptasknumber_local; + cputemperature = cputemperature_local; epicsMutexUnlock(scan_mutex); break; } @@ -747,6 +752,10 @@ static void statsCpuUtilization(double* val) { *val = loadinfo.iocLoad; } +static void statsCpuTemperature(double* val) +{ + *val = (double)cputemperature/1000.; +} static void statsNoOfCpus(double* val) { *val = (double)loadinfo.noOfCpus; diff --git a/devIocStats/os/Linux/osdCpuTemp.c b/devIocStats/os/Linux/osdCpuTemp.c new file mode 100644 index 0000000..ff5d974 --- /dev/null +++ b/devIocStats/os/Linux/osdCpuTemp.c @@ -0,0 +1,40 @@ +/*************************************************************************\ +* Copyright (c) 2009 Helmholtz-Zentrum Berlin fuer Materialien und Energie. +* Copyright (c) 2002 The University of Chicago, as Operator of Argonne +* National Laboratory. +* Copyright (c) 2002 The Regents of the University of California, as +* Operator of Los Alamos National Laboratory. +* EPICS BASE Versions 3.13.7 +* and higher are distributed subject to a Software License Agreement found +* in file LICENSE that is included with this distribution. +\*************************************************************************/ + +/* osdCpuTemp.c - Temperature of the CPU: default implementation = do nothing */ + +/* + * Author: Florian Feldbauer (RUB) + * + */ + +#include +#include +#include +#include + +#include + +int devIocStatsGetCpuTemp (int *pval) { + FILE *pFile = fopen ( "/sys/class/thermal/thermal_zone0/temp", "r" ); + if( !pFile ) { + //fprintf( stderr, "\033[31;1m: Could not open file '/sys/class/thermal/thermal_zone0/temp': %s\033[0m\n", + // strerror( errno ) ); + return -1; + } + + unsigned num = fscanf( pFile, "%d", pval ); + if ( 1 != num ) { + //fprintf( stderr, "\033[31;1mCould not parse value\033[0m\n" ); + } + fclose( pFile ); + return 0; +} diff --git a/devIocStats/os/default/osdCpuTemp.c b/devIocStats/os/default/osdCpuTemp.c new file mode 100644 index 0000000..341565a --- /dev/null +++ b/devIocStats/os/default/osdCpuTemp.c @@ -0,0 +1,21 @@ +/*************************************************************************\ +* Copyright (c) 2009 Helmholtz-Zentrum Berlin fuer Materialien und Energie. +* Copyright (c) 2002 The University of Chicago, as Operator of Argonne +* National Laboratory. +* Copyright (c) 2002 The Regents of the University of California, as +* Operator of Los Alamos National Laboratory. +* EPICS BASE Versions 3.13.7 +* and higher are distributed subject to a Software License Agreement found +* in file LICENSE that is included with this distribution. +\*************************************************************************/ + +/* osdCpuTemp.c - Temperature of the CPU: default implementation = do nothing */ + +/* + * Author: Florian Feldbauer (RUB) + * + */ + +#include + +int devIocStatsGetCpuTemp (int *pval) { return -1; } From b7ee5a29332c4641c5d0acbc60d05a3fd88ad41f Mon Sep 17 00:00:00 2001 From: Florian Feldbauer Date: Fri, 10 Mar 2023 11:13:53 +0100 Subject: [PATCH 2/2] Incorporated comments from PullRequest - Replaced blanks by tab for intendation in `devIocStats/devIocStatsAnalog.c` - Added the new entry in `README_devIocStats` --- README_devIocStats | 1 + devIocStats/devIocStatsAnalog.c | 2 +- devIocStats/os/Linux/osdCpuTemp.c | 6 +++--- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/README_devIocStats b/README_devIocStats index e1e1eab..124ac82 100644 --- a/README_devIocStats +++ b/README_devIocStats @@ -85,6 +85,7 @@ Analog In (ai) Records (DTYP = "IOC stats"), INP = @one of the following: no_of_cpus - number of CPU cores on the system ioc_cpuload - estimated percent CPU utilization by this IOC + cpu_temperature - Measured CPU temperature (implemented for Linux IOC only) fd - number of file descriptors currently in use max_fd - max number of file descriptors Note - free_bytes, total_bytes, sys_cpuload, no_of_cpus diff --git a/devIocStats/devIocStatsAnalog.c b/devIocStats/devIocStatsAnalog.c index 58b1bb0..4a44867 100644 --- a/devIocStats/devIocStatsAnalog.c +++ b/devIocStats/devIocStatsAnalog.c @@ -286,7 +286,7 @@ static validGetParms statsGetParms[]={ { "cbHighQueueHiWtrMrk", statsCbHighQHiWtrMrk, QUEUE_TYPE }, { "cbHighQueueUsed", statsCbHighQUsed, QUEUE_TYPE }, { "cbHighQueueOverruns", statsCbHighQOverruns, QUEUE_TYPE }, - { "cpu_temperature", statsCpuTemperature, LOAD_TYPE }, + { "cpu_temperature", statsCpuTemperature, LOAD_TYPE }, { NULL,NULL,0 } }; diff --git a/devIocStats/os/Linux/osdCpuTemp.c b/devIocStats/os/Linux/osdCpuTemp.c index ff5d974..639a66d 100644 --- a/devIocStats/os/Linux/osdCpuTemp.c +++ b/devIocStats/os/Linux/osdCpuTemp.c @@ -26,14 +26,14 @@ int devIocStatsGetCpuTemp (int *pval) { FILE *pFile = fopen ( "/sys/class/thermal/thermal_zone0/temp", "r" ); if( !pFile ) { - //fprintf( stderr, "\033[31;1m: Could not open file '/sys/class/thermal/thermal_zone0/temp': %s\033[0m\n", - // strerror( errno ) ); + fprintf( stderr, "\033[31;1m: Could not open file '/sys/class/thermal/thermal_zone0/temp': %s\033[0m\n", + strerror( errno ) ); return -1; } unsigned num = fscanf( pFile, "%d", pval ); if ( 1 != num ) { - //fprintf( stderr, "\033[31;1mCould not parse value\033[0m\n" ); + fprintf( stderr, "\033[31;1mCould not parse value\033[0m\n" ); } fclose( pFile ); return 0;