66#include "util/stringUtils.h"
77
88#define FF_CPUUSAGE_DISPLAY_NAME "CPU Usage"
9- #define FF_CPUUSAGE_NUM_FORMAT_ARGS 1
9+ #define FF_CPUUSAGE_NUM_FORMAT_ARGS 5
1010
1111void ffPrintCPUUsage (FFCPUUsageOptions * options )
1212{
13- double percentage = 0.0 / 0.0 ;
14- const char * error = ffGetCpuUsageResult (& percentage );
13+ FF_LIST_AUTO_DESTROY percentages = ffListCreate ( sizeof ( double )) ;
14+ const char * error = ffGetCpuUsageResult (& percentages );
1515
1616 if (error )
1717 {
1818 ffPrintError (FF_CPUUSAGE_DISPLAY_NAME , 0 , & options -> moduleArgs , "%s" , error );
1919 return ;
2020 }
2121
22+ double maxValue = -999 , minValue = 999 , sumValue = 0 ;
23+ uint32_t maxIndex = 999 , minIndex = 999 ;
24+
25+ uint32_t index = 0 ;
26+ FF_LIST_FOR_EACH (double , percent , percentages )
27+ {
28+ sumValue += * percent ;
29+ if (* percent > maxValue )
30+ {
31+ maxValue = * percent ;
32+ maxIndex = index ;
33+ }
34+ if (* percent < minValue )
35+ {
36+ minValue = * percent ;
37+ minIndex = index ;
38+ }
39+ ++ index ;
40+ }
41+ double avgValue = sumValue / (double ) percentages .length ;
42+
2243 if (options -> moduleArgs .outputFormat .length == 0 )
2344 {
2445 ffPrintLogoAndKey (FF_CPUUSAGE_DISPLAY_NAME , 0 , & options -> moduleArgs , FF_PRINT_TYPE_DEFAULT );
2546
2647 FF_STRBUF_AUTO_DESTROY str = ffStrbufCreate ();
27- if (instance .config .percentType & FF_PERCENTAGE_TYPE_BAR_BIT )
28- ffAppendPercentBar (& str , percentage , 0 , 50 , 80 );
29- if (instance .config .percentType & FF_PERCENTAGE_TYPE_NUM_BIT )
48+ if (options -> displayType == FF_CPUUSAGE_DISPLAY_TYPE_DEFAULT )
3049 {
31- if (str .length > 0 )
32- ffStrbufAppendC (& str , ' ' );
33- ffAppendPercentNum (& str , percentage , 50 , 80 , str .length > 0 );
50+ if (instance .config .percentType & FF_PERCENTAGE_TYPE_BAR_BIT )
51+ ffAppendPercentBar (& str , avgValue , 0 , 50 , 80 );
52+ if (instance .config .percentType & FF_PERCENTAGE_TYPE_NUM_BIT )
53+ {
54+ if (str .length > 0 )
55+ ffStrbufAppendC (& str , ' ' );
56+ ffAppendPercentNum (& str , avgValue , 50 , 80 , str .length > 0 );
57+ }
58+ }
59+ else
60+ {
61+ FF_LIST_FOR_EACH (double , percent , percentages )
62+ {
63+ if (str .length > 0 )
64+ ffStrbufAppendC (& str , ' ' );
65+ ffAppendPercentNum (& str , * percent , 50 , 80 , false);
66+ }
3467 }
3568 ffStrbufPutTo (& str , stdout );
3669 }
3770 else
3871 {
39- FF_STRBUF_AUTO_DESTROY percentageStr = ffStrbufCreate ();
40- ffAppendPercentNum (& percentageStr , percentage , 50 , 80 , false);
72+ FF_STRBUF_AUTO_DESTROY avgStr = ffStrbufCreate ();
73+ ffAppendPercentNum (& avgStr , avgValue , 50 , 80 , false);
74+ FF_STRBUF_AUTO_DESTROY minStr = ffStrbufCreate ();
75+ ffAppendPercentNum (& minStr , minValue , 50 , 80 , false);
76+ FF_STRBUF_AUTO_DESTROY maxStr = ffStrbufCreate ();
77+ ffAppendPercentNum (& maxStr , maxValue , 50 , 80 , false);
4178 ffPrintFormat (FF_CPUUSAGE_DISPLAY_NAME , 0 , & options -> moduleArgs , FF_CPUUSAGE_NUM_FORMAT_ARGS , (FFformatarg []){
42- {FF_FORMAT_ARG_TYPE_STRBUF , & percentageStr }
79+ {FF_FORMAT_ARG_TYPE_STRBUF , & avgStr },
80+ {FF_FORMAT_ARG_TYPE_STRBUF , & maxStr },
81+ {FF_FORMAT_ARG_TYPE_UINT , & maxIndex },
82+ {FF_FORMAT_ARG_TYPE_STRBUF , & minStr },
83+ {FF_FORMAT_ARG_TYPE_UINT , & minIndex },
4384 });
4485 }
4586}
@@ -57,6 +98,16 @@ bool ffParseCPUUsageCommandOptions(FFCPUUsageOptions* options, const char* key,
5798 if (ffOptionParseModuleArgs (key , subKey , value , & options -> moduleArgs ))
5899 return true;
59100
101+ if (ffStrEqualsIgnCase (subKey , "display-type" ))
102+ {
103+ options -> displayType = (FFCPUUsageDisplayType ) ffOptionParseEnum (key , value , (FFKeyValuePair []) {
104+ { "default" , FF_CPUUSAGE_DISPLAY_TYPE_DEFAULT },
105+ { "separate" , FF_CPUUSAGE_DISPLAY_TYPE_SEPARATE },
106+ {},
107+ });
108+ return true;
109+ }
110+
60111 return false;
61112}
62113
@@ -78,26 +129,49 @@ void ffParseCPUUsageJsonObject(FFCPUUsageOptions* options, yyjson_val* module)
78129 if (ffJsonConfigParseModuleArgs (key , val , & options -> moduleArgs ))
79130 continue ;
80131
132+ if (ffStrEqualsIgnCase (key , "display-type" ))
133+ {
134+ int value ;
135+ const char * error = ffJsonConfigParseEnum (val , & value , (FFKeyValuePair []) {
136+ { "default" , FF_CPUUSAGE_DISPLAY_TYPE_DEFAULT },
137+ { "separate" , FF_CPUUSAGE_DISPLAY_TYPE_SEPARATE },
138+ {},
139+ });
140+ if (error )
141+ ffPrintErrorString (FF_CPUUSAGE_MODULE_NAME , 0 , NULL , FF_PRINT_TYPE_NO_CUSTOM_KEY , "Invalid %s value: %s" , key , error );
142+ else
143+ options -> displayType = (FFCPUUsageDisplayType ) value ;
144+ continue ;
145+ }
146+
81147 ffPrintError (FF_CPUUSAGE_MODULE_NAME , 0 , & options -> moduleArgs , "Unknown JSON key %s" , key );
82148 }
83149}
84150
85151void ffGenerateCPUUsageJson (FF_MAYBE_UNUSED FFCPUUsageOptions * options , yyjson_mut_doc * doc , yyjson_mut_val * module )
86152{
87- double percentage = 0.0 / 0.0 ;
88- const char * error = ffGetCpuUsageResult (& percentage );
153+ FF_LIST_AUTO_DESTROY percentages = ffListCreate ( sizeof ( double )) ;
154+ const char * error = ffGetCpuUsageResult (& percentages );
89155
90156 if (error )
91157 {
92158 yyjson_mut_obj_add_str (doc , module , "error" , error );
93159 return ;
94160 }
95- yyjson_mut_obj_add_real (doc , module , "result" , percentage );
161+ yyjson_mut_val * result = yyjson_mut_obj_add_arr (doc , module , "result" );
162+ FF_LIST_FOR_EACH (double , percent , percentages )
163+ {
164+ yyjson_mut_arr_add_real (doc , result , * percent );
165+ }
96166}
97167
98168void ffPrintCPUUsageHelpFormat (void )
99169{
100170 ffPrintModuleFormatHelp (FF_CPUUSAGE_MODULE_NAME , "{1}" , FF_CPUUSAGE_NUM_FORMAT_ARGS , (const char * []) {
101- "CPU usage (percentage)"
171+ "CPU usage (percentage, average)" ,
172+ "CPU usage (percentage, maximum)" ,
173+ "CPU core index of maximum usage" ,
174+ "CPU usage (percentage, minimum)" ,
175+ "CPU core index of minimum usage" ,
102176 });
103177}
0 commit comments