まーにゃ@エンタメ系火事場エンジニアの日々

数々の「火だるまプロジェクト」を安請け合いし何度でも復活する 「自称・不死身のエンジニア」の物欲まみれの日々をつづる

【PC編】「2020-07-05 ★完成★これでどうでしょう?★」と「CPUメータ@LINUX」と私

【PC編】「★完成★これでどうでしょう?★」と「CPUメータ@LINUX」と私
と題しまして小話を1つ。
以下の形で、ほぼ完成イメージに至りました。
2次元配列はA「」「」をやめて属性を意味するATTR「」「」に変えました。
コマンドラインの引数で縦、横切り替えは、そのうちやります。
LINUXからCPUの数を取得して、画面表示に反映してるので
CPUの数に関係なく、動くはずですが、コードミスってたら直してください。
BIOSでSMT(ハイパースレッディング)をOFFにしてCPUの数を
24から12に減らしたら、ヘッダーとフッターの表示がCPUの数に
対応できてませんでした。すんません。
BIOSでハイパースレッドをOFFにした場合、CPUは12個に減る>
が、グラフのヘッダーとフッターの表示は24このまま残っている。あちゃー。
Screenshot from 2020-07-05 21-50-36.png
内部で使う配列等は、関数が何回も呼び出されるので、STATICにして
ヒープエリアに置き、だいぶ余裕持たせて固定配列を割り当ててます。
Screenshot from 2020-07-05 11-27-22.png
#define GYOU_SIZE (13)
#define RETSU_SIZE (61)
void DisplayLevelBAR2(int NUMCORE, float *data){
static int ATTR[GYOU_SIZE][RETSU_SIZE];/*ATTRIBUTE ARRAY*/
int i ;/*NUMOFCORE*/
int j ;/*LEVEL BAR */
static int val2[128];/*MAX 128 PROCESSORS*/
/*INITIALIZE GAMEN ARRAY DATA*/
for(i=0;i<GYOU_SIZE;i++){
for(j=0;j<RETSU_SIZE;j++) ATTR[i][j]= -1;/*SPACE */
}
/*WRITE LEVEL DATA TO ARRAY*/
/*ASSGNING -1 IS SPACE ,OTHER IS REAL FREQ INFO*/
#define OFFSET_GHZ (34)
for(i=0;i<NUMCORE;i++){
val2[i] = (int)(data[i]/100.0);/*MEMORIZE GHz TO %2d ARRAY*/
int val3 = (int)val2[i] - OFFSET_GHZ ; /*GHz - 34GHz*/
for(j=0;j<val3;j++) ATTR[j][i] = val2[i];
}
/*DISPLAY CHAR GRAPHIC IMAGE */
//SET_GREEN_BACK;
SET_BLACK_BACK;
RESET_CURSOR;
CLS;
SET_WHITE;
/**PRINT HEADER*/
printf(
" +------------------------------------------------------------------------+\n");
printf(
"[GHz]::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::|\n");
float fval=4.7;/*MAX GHz*/
#define MAXFREQ_RANGE (12)
for(int i=MAXFREQ_RANGE;i>=0;i--){
SET_BLACK_BACK;
printf("%1.1fG|",fval);
for(j=0;j<NUMCORE;j++){
switch(ATTR[i][j]){
/*SET CHARCTOR COLOR*/
case 34:
case 35:
case 36:
case 37:SET_REV_CYAN;break;
case 38:
case 39:SET_REV_YELLOW;break;
case 40:
case 41:
case 42:
case 43:SET_REV_MAZENTA;break;
case 44:
case 45:
case 46:SET_REV_RED;break;
case -1:/*SPACE */
default:SET_BLACK_BACK;break;
}
#ifdef OLD
//従来の表示
// -1 (空白)でなければ、周波数値を表示
if(ATTR[i][j] !=-1)printf("|%2d",ATTR[i][j]);
else printf(":::");
#else
//今回改善した表示部分
if(ATTR[i][j] != -1 && ATTR[i+1][j] == -1){
//バーグラフの頭のてっぺんだけに周波数を表示
printf("|%2d",ATTR[i][j]);
}
else if(ATTR[i][j] != -1)printf("| ");//その他は棒だけ
else printf(":::");//空白部は":::"で埋める。
#endif
RESET_MODE;
}
RESET_MODE;
SET_WHITE;
SET_BLACK_BACK;
printf("|\n");/*End of LINE*/
fval = fval - (0.1);
}
SET_WHITE;
/**PRINT FUTTER*/
printf(
" +---+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n");
printf(
"[CPU] 00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|16|17|18|19|20|21|22|23|\n");
}/*End of function*/
################################################
##上記を含む全ソースコードです。
##レベルバーの頭の数字を整数2桁から 少数2桁に変えました。
##隣り合ったCPUの周波数が同じ場合の表示が見苦しいので、やっぱ整数2桁にしときますわ。
###ifdef #else #endifで囲ってあるのでもどせますし。
##例によって、インデントなし、すべての変数値は、半角に統一が必要です。
################################################
Screenshot from 2020-07-05 12-06-23.png
Screenshot from 2020-07-05 11-27-22.png
#include <stdio.h>
#include <stdlib.h>
/*****************************************/
/*2020.06/30 */
/*2020.07/01 */
/*2020.07/03 */
/*2020.07/04 */
/* Reference ESCAPE SEQUENCE SITE
http://7ujm.net/etc/esc.html */
/*COLOR SETTINGS */
#define SET_BLACK printf("\033[30m")
#define SET_RED printf("\033[31m")
#define SET_GREEN printf("\033[32m")
#define SET_YELLOW printf("\033[33m")
#define SET_BLUE printf("\033[34m")
#define SET_MAZENTA printf("\033[35m")
#define SET_CYAN printf("\033[36m")
#define SET_WHITE printf("\033[37m")
#define SET_DEFAULT printf("\033[39m")
#define CLS printf("\033[2J")
#define SET_BLACK_BACK printf("\033[40m")
#define SET_RED_BACK printf("\033[41m")
#define SET_GREEN_BACK printf("\033[42m")
#define SET_BACK_DEFAULT printf("\033[49m")
#define RESET_CURSOR printf("\033[1;1H")
#define SET_FUTO_MOJI printf("\033[1m")
#define SET_REVERT printf("\033[7m")
#define SET_UNDER_LINE printf("\033[4m")
#define SET_STANDARD printf("\033[m")
#define RESET_MODE printf("\33[0m")
#define SET_REV_RED printf("\33[41m")
#define SET_REV_GREEN printf("\33[42m")
#define SET_REV_YELLOW printf("\33[43m")
#define SET_REV_BLUE printf("\33[44m")
#define SET_REV_MAZENTA printf("\33[45m")
#define SET_REV_CYAN printf("\33[46m")
/*****************************************/
int GetNumOfCORE(void);
void DisplayLevelBAR(int,int, float *);
void DisplayLevelBAR1(int, float *);
void DisplayLevelBAR2(int, float *);
int ReadFreqDataFromPIPE(int, float *);
/************************/
/*Get Num of CPU CORE's */
/************************/
int GetNumOfCORE()
{
FILE *fp;
int NUMCORE;
/*OPEN PIPE AS READ MODE */
fp = popen("grep \"cpu MHz\" /proc/cpuinfo | wc -l", "r");
if (fp == (FILE *) NULL) {
SET_RED_BACK;
printf("[%s:%d]PIPE for COUNT CORE's Open Failed\n",
__FILE__, __LINE__);
exit(1);
}
/*GET NUM OF CORE */
fscanf(fp, "%d", &NUMCORE);
/*CLOSE PIPE */
pclose(fp);
printf("[%s:%d:GetNumOfCORE]NumOfCore = %d\n",
__FILE__, __LINE__, NUMCORE);
/*RETURN*/ return (NUMCORE);
} /*end of GetNumOfCORE */
/*****************************/
/* DISPLAY LEVEL BAR */
/*****************************/
void DisplayLevelBAR(int mode, int NUMCORE,float *data){
switch (mode){
case 1: DisplayLevelBAR1(NUMCORE,data);break;
case 2: DisplayLevelBAR2(NUMCORE,data);break;
default: DisplayLevelBAR1(NUMCORE,data);break;
}
}
/*完成イメージ
GHz +------------------------------------------------------------------------
4.4G|
|
4.2G+
|
4.0G+
| @
3.8G+ @ |
| * @ |
3.5G+ * @ |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+---
CPU |00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|16|17|18|19|20|21|22|23|
*/
#define GYOU_SIZE (13)
#define RETSU_SIZE (61)
void DisplayLevelBAR2(int NUMCORE, float *data){
static int ATTR[GYOU_SIZE][RETSU_SIZE];/*ATTRIBUTE ARRAY*/
int i ;/*NUMOFCORE*/
int j ;/*LEVEL BAR */
static int val2[128];/*MAX 128 PROCESSORS*/
/*INITIALIZE GAMEN ARRAY DATA*/
for(i=0;i<GYOU_SIZE;i++){
for(j=0;j<RETSU_SIZE;j++) ATTR[i][j]= -1;/*SPACE */
}
/*WRITE LEVEL DATA TO ARRAY*/
/*ASSGNING -1 IS SPACE ,OTHER IS REAL FREQ INFO*/
#define OFFSET_GHZ (34)
for(i=0;i<NUMCORE;i++){
val2[i] = (int)(data[i]/100.0);/*MEMORIZE GHz TO %2d ARRAY*/
int val3 = (int)val2[i] - OFFSET_GHZ ; /*GHz - 34GHz*/
for(j=0;j<val3;j++) ATTR[j][i] = val2[i];
}
/*DISPLAY CHAR GRAPHIC IMAGE */
//SET_GREEN_BACK;
SET_BLACK_BACK;
RESET_CURSOR;
CLS;
SET_WHITE;
/**PRINT HEADER*/
printf(
" +------------------------------------------------------------------------+\n");
printf(
"[GHz]::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::|\n");
float fval=4.7;/*MAX GHz*/
#define MAXFREQ_RANGE (12)
for(int i=MAXFREQ_RANGE;i>=0;i--){
SET_BLACK_BACK;
printf("%1.1fG|",fval);
for(j=0;j<NUMCORE;j++){
switch(ATTR[i][j]){
/*SET CHARCTOR COLOR*/
case 34:
case 35:
case 36:
case 37:SET_REV_CYAN;break;
case 38:
case 39:SET_REV_YELLOW;break;
case 40:
case 41:
case 42:
case 43:SET_REV_MAZENTA;break;
case 44:
case 45:
case 46:SET_REV_RED;break;
case -1:/*SPACE */
default:SET_BLACK_BACK;break;
}
if(ATTR[i][j] != -1 && ATTR[i+1][j] == -1){
/* DISPLAY GHZ at the TOP of the LEVEL_BAR*/
#ifdef OLD
printf("|%2d",ATTR[i][j]);
#else
printf("%1.1f",*1;
#endif
}
else if (ATTR[i][j] != -1){
/* LEVEL BAR but no TOP*/
printf("| ");
}
else {
/* BLANK SPACE*/
printf(":::");/* SPACE */
}
RESET_MODE;
}
RESET_MODE;
SET_WHITE;
SET_BLACK_BACK;
printf("|\n");/*End of LINE*/
fval = fval - (0.1);
}
SET_WHITE;
/**PRINT FUTTER*/
printf(
" +---+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n");
printf(
"[CPU] 00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|16|17|18|19|20|21|22|23|\n");
}/*End of function*/
void DisplayLevelBAR1(int NUMCORE, float *data)
{
/* READ FROM ARRAY AND DISPLAY */
for (int j = 0; j < NUMCORE; j++) {
int val = (int)(data[j]);
int val2 = *2 == -1) {
SET_RED_BACK;
printf("[%s:%d] GetNumOfCORE Failed\n",
__FILE__, __LINE__);
exit(1);
}
while (1) {
/* CLEAR SCREEN and RESET CURSOR */
SET_BLACK_BACK;
CLS;
RESET_CURSOR;
/* READ FROM PIPE to ARRAY */
ReadFreqDataFromPIPE(NUMCORE, data);
/* READ FROM ARRAY AND DISPLAY */
DisplayLevelBAR(2,NUMCORE, data);
/*WAIT*/ system("sleep 2");
}/*End of while */
}/* End of main */
####################################
★追記★
BLOGからLINUXのエディタへCOPY&PASTEの
実験をしてみました。
BLOGからCOPYして、VIで開いたエディッタ画面に
PASTEしてみました。
PRINTF文で空白が3文字とか入れてる部分が
勝手に1文字になっちゃったりしてます。
ですが、元々空白1文字のところで空白がなくなったりは
してないようです。
気になる方は、エディタでPASTEしたあとで、
ファイルをセーブして
「indent ファイル名」 でコマンドを実行されれば、
ぐちゃぐちゃのコードが少しは見やすくなります。
<訂正必要箇所#たぶん以下の3箇所ぐらいだと思います。>
・グラフのヘッダーの”+ーーーー+”部分
・グラフのヘッダー直下の「GHz」文字を描画してる部分の”:”
・グラフのフッター部分の”+ーーー+ーーーー;;;;;;;”の部分
※「CPU」で始まるコア番号のPRINTF文は、空白が1つ入ってますが、
 ここは、変になってないので、このPRINT文に合わせる形で上記3箇所を
 修正すれば、うまく、調整できると思います。
あくまでも自分のLINUX環境ですが、
PRINTFに入っている”空白”の数の微調整 のみで、
全角半角の問題は、発生してないみたいです。
コンパイルもエラーなしで通りました。
####################################
では・・また・・:_;)/

*1:float)ATTR[i][j]/10.0

*2:int)(val+50) /100);

if (val2 < 36) { /*LOWER 3.6GHz */
SET_CYAN;
} else if (val2 < 39) { /*LOWER 3.8GHz */
SET_BLUE;
} else {
SET_RED;
}
/*PRINT BASE CORE and GHz INFO */
printf("CORE[%2d] %4d[MHz]", j, val);
/*PRINT LEVEL BAR INFO */
switch (val2) {
case 30: printf("\n"); break;
case 31: printf("\n"); break;
case 33: printf("\n"); break;
case 34: printf("\n"); break;
case 35: printf("\n"); break;
case 36: printf(":\n"); break;
case 37: printf("::\n"); break;
case 38: printf(":::\n"); break;
case 39: printf("::::\n"); break;
case 40: printf("=====\n"); break;
case 41: printf("======\n"); break;
case 42: printf("=======\n"); break;
case 43: printf("********X\n"); break;
case 44: printf("*********X\n"); break;
case 45: printf("**********X\n"); break;
case 46: printf("@@@@@@@@@@@X\n"); break;
default: printf("\n"); break;
}/*End of switch */
}/*End of for */
return;
}/* end of Fuction */
/**************************/
/*READ FREQ DATA FROM PIPE*/
/**************************/
int ReadFreqDataFromPIPE(int NUMCORE, float *data)
{
FILE *fp = (FILE *) NULL;
/*OPEN PIPE as RESULT OF "grep command" OUTPUT */
fp = popen("grep \"cpu MHz\" /proc/cpuinfo", "r");
if (fp == (FILE *) NULL) {
SET_RED_BACK;
printf("[%s:%d] PIPE Open Failed \n", __FILE__, __LINE__);
system("date");
return (-1);
}
/* READ DATA FROM PIPE */
for (int j = 0; j < NUMCORE; j++) {
fscanf(fp, "cpu MHz : %f ", &data[j]);
}
/*CLOSE PIPE */
pclose(fp);
/* FINISHED */
return (0);
}
/***************/
/*main function*/
/***************/
/* HOMEWORK*/
/* (1) data ARRAY to allocated memory*/
/* (2) sleep time change using sprintf*/
void main()
{
FILE *fp;
float data[128];
int NUMCORE = -1;
if ((NUMCORE = GetNumOfCORE(