Files
CoreFreq/corefreq-cli.c
2017-11-30 20:33:32 +01:00

6619 lines
186 KiB
C

/*
* CoreFreq
* Copyright (C) 2015-2017 CYRIL INGENIERIE
* Licenses: GPL2
*/
#define _GNU_SOURCE
#include <math.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include <poll.h>
#include <termios.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libgen.h>
#include <sched.h>
#include "bitasm.h"
#include "coretypes.h"
#include "corefreq.h"
static Bit64 Shutdown __attribute__ ((aligned (64))) = 0x0;
void Emergency(int caught)
{
switch (caught) {
case SIGINT:
case SIGQUIT:
case SIGTERM:
case SIGTSTP:
BITSET(LOCKLESS, Shutdown, 0);
break;
}
}
void TrapSignal(void)
{
signal(SIGINT, Emergency);
signal(SIGQUIT, Emergency);
signal(SIGTERM, Emergency);
signal(SIGTSTP, Emergency); // [CTRL] + [Z]
}
// VT100 requirements.
#define SCP "\033[s"
#define RCP "\033[u"
#define HIDE "\033[?25l"
#define SHOW "\033[?25h"
#define RESET "\033c"
#define SCR1 "\033[?47h"
#define SCR0 "\033[?47l"
#define CLS "\033[J"
#define CUH "\033[H"
#define CUP(col, row) "\033["#row";"#col"H"
#define BLACK 0
#define RED 1
#define GREEN 2
#define YELLOW 3
#define BLUE 4
#define MAGENTA 5
#define CYAN 6
#define WHITE 7
#define _COLOR(_mod, _fg, _bg) "\033["#_mod";3"#_fg";4"#_bg"m"
#define COLOR(mod, fg, bg) _COLOR(mod, fg, bg)
#define AoK COLOR(0, WHITE, BLACK)
#define DoK COLOR(1, BLACK, BLACK)
#define RoK COLOR(1, RED, BLACK)
#define GoK COLOR(1, GREEN, BLACK)
#define YoK COLOR(1, YELLOW, BLACK)
#define BoK COLOR(1, BLUE, BLACK)
#define MoK COLOR(1, MAGENTA, BLACK)
#define CoK COLOR(1, CYAN, BLACK)
#define WoK COLOR(1, WHITE, BLACK)
const char lcd[10][3][3] = {
{// 0
" _ ",
"| |",
"|_|"
},
{// 1
" ",
" | ",
" | "
},
{// 2
" _ ",
" _|",
"|_ "
},
{// 3
" _ ",
" _|",
" _|"
},
{// 4
" ",
"|_|",
" |"
},
{// 5
" _ ",
"|_ ",
" _|"
},
{// 6
" _ ",
"|_ ",
"|_|"
},
{// 7
" _ ",
" |",
" |"
},
{// 8
" _ ",
"|_|",
"|_|"
},
{// 9
" _ ",
"|_|",
" _|"
}
};
#define TOP_HEADER_ROW 3
#define TOP_FOOTER_ROW 2
#define TOP_SEPARATOR 3
#define MAX_CPU_ROW 48
#define MAX_HEIGHT ((2 * MAX_CPU_ROW) \
+ TOP_HEADER_ROW \
+ TOP_SEPARATOR \
+ TOP_FOOTER_ROW)
#define MAX_WIDTH 132
#define MIN_WIDTH 80
#define LEADING_LEFT 1
#define LEADING_TOP 1
#define MARGIN_WIDTH 2
#define MARGIN_HEIGHT 1
#define INTER_WIDTH 3
#define INTER_HEIGHT (3 + 1)
char hSpace[] = " "" "" "" "" " \
" "" "" "" "" " \
" "" "" "" "" " \
" "" ";
char hBar[] = "||||||||""||||||||""||||||||""||||||||""||||||||" \
"||||||||""||||||||""||||||||""||||||||""||||||||" \
"||||||||""||||||||""||||||||""||||||||""||||||||" \
"||||||||""||||";
char hLine[] = "--------""--------""--------""--------""--------" \
"--------""--------""--------""--------""--------" \
"--------""--------""--------""--------""--------" \
"--------""----";
typedef union {
unsigned long long key;
unsigned char code[8];
} SCANKEY;
#define SCANKEY_VOID 0x8000000000000000
#define SCANKEY_NULL 0x0000000000000000
#define SCANKEY_TAB 0x0000000000000009
#define SCANKEY_ENTER 0x000000000000000a
#define SCANKEY_ESC 0x000000000000001b
#define SCANKEY_PLUS 0x000000000000002b
#define SCANKEY_MINUS 0x000000000000002d
#define SCANKEY_UP 0x0000000000415b1b
#define SCANKEY_DOWN 0x0000000000425b1b
#define SCANKEY_RIGHT 0x0000000000435b1b
#define SCANKEY_LEFT 0x0000000000445b1b
#define SCANKEY_HOME 0x0000000000485b1b
#define SCANKEY_END 0x0000000000465b1b
#define SCANKEY_F1 0x0000000000504f1b
#define SCANKEY_F2 0x0000000000514f1b
#define SCANKEY_F3 0x0000000000524f1b
#define SCANKEY_F4 0x0000000000534f1b
#define SCANKEY_F10 0x0000000031325b1b
#define SCANKEY_SHIFT_TAB 0x00000000005a5b1b
#define SCANKEY_PGUP 0x000000007e355b1b
#define SCANKEY_PGDW 0x000000007e365b1b
#define SCANKEY_PERCENT 0x0000000000000025
#define SCANKEY_SHIFT_a 0x0000000000000041
#define SCANKEY_SHIFT_d 0x0000000000000044
#define SCANKEY_SHIFT_i 0x0000000000000049
#define SCANKEY_SHIFT_m 0x000000000000004d
#define SCANKEY_SHIFT_q 0x0000000000000051
#define SCANKEY_SHIFT_s 0x0000000000000053
#define SCANKEY_SHIFT_v 0x0000000000000056
#define SCANKEY_SHIFT_w 0x0000000000000057
#define SCANKEY_SHIFT_z 0x000000000000005a
#define SCANKEY_a 0x0000000000000061
#define SCANKEY_b 0x0000000000000062
#define SCANKEY_c 0x0000000000000063
#define SCANKEY_d 0x0000000000000064
#define SCANKEY_e 0x0000000000000065
#define SCANKEY_f 0x0000000000000066
#define SCANKEY_g 0x0000000000000067
#define SCANKEY_h 0x0000000000000068
#define SCANKEY_i 0x0000000000000069
#define SCANKEY_k 0x000000000000006b
#define SCANKEY_l 0x000000000000006c
#define SCANKEY_m 0x000000000000006d
#define SCANKEY_n 0x000000000000006e
#define SCANKEY_o 0x000000000000006f
#define SCANKEY_p 0x0000000000000070
#define SCANKEY_q 0x0000000000000071
#define SCANKEY_r 0x0000000000000072
#define SCANKEY_s 0x0000000000000073
#define SCANKEY_t 0x0000000000000074
#define SCANKEY_u 0x0000000000000075
#define SCANKEY_v 0x0000000000000076
#define SCANKEY_w 0x0000000000000077
#define SCANKEY_x 0x0000000000000078
#define SCANKEY_z 0x000000000000007a
#define SCANCON_HOME 0x000000007e315b1b
#define SCANCON_END 0x000000007e345b1b
#define SCANCON_F1 0x00000000415b5b1b
#define SCANCON_F2 0x00000000425b5b1b
#define SCANCON_F3 0x00000000435b5b1b
#define SCANCON_F4 0x00000000445b5b1b
#define SCANCON_SHIFT_TAB 0x000000000000091b
#define SORTBY_STATE 0x400000000000000e
#define SORTBY_RTIME 0x400000000000000d
#define SORTBY_UTIME 0x400000000000000c
#define SORTBY_STIME 0x400000000000000b
#define SORTBY_PID 0x400000000000000a
#define SORTBY_COMM 0x4000000000000009
#define BOXKEY_EIST 0x3000000000000004
#define BOXKEY_EIST_OFF 0x3000000000000005
#define BOXKEY_EIST_ON 0x3000000000000006
#define BOXKEY_C1E 0x3000000000000008
#define BOXKEY_C1E_OFF 0x3000000000000009
#define BOXKEY_C1E_ON 0x300000000000000a
#define BOXKEY_TURBO 0x3000000000000010
#define BOXKEY_TURBO_OFF 0x3000000000000011
#define BOXKEY_TURBO_ON 0x3000000000000012
#define BOXKEY_C1A 0x3000000000000020
#define BOXKEY_C1A_OFF 0x3000000000000021
#define BOXKEY_C1A_ON 0x3000000000000022
#define BOXKEY_C3A 0x3000000000000040
#define BOXKEY_C3A_OFF 0x3000000000000041
#define BOXKEY_C3A_ON 0x3000000000000042
#define BOXKEY_C1U 0x3000000000000080
#define BOXKEY_C1U_OFF 0x3000000000000081
#define BOXKEY_C1U_ON 0x3000000000000082
#define BOXKEY_C3U 0x3000000000000100
#define BOXKEY_C3U_OFF 0x3000000000000101
#define BOXKEY_C3U_ON 0x3000000000000102
#define BOXKEY_PKGCST 0x3000000000000200
#define BOXKEY_PKGCST_C0 0x3000000000000201
#define BOXKEY_PKGCST_C1 0x3000000000000211
#define BOXKEY_PKGCST_C2 0x3000000000000221
#define BOXKEY_PKGCST_C3 0x3000000000000231
#define BOXKEY_PKGCST_C6 0x3000000000000261
#define BOXKEY_PKGCST_C7 0x3000000000000271
#define BOXKEY_IOMWAIT 0x3000000000000400
#define BOXKEY_IOMWAIT_OFF 0x3000000000000401
#define BOXKEY_IOMWAIT_ON 0x3000000000000402
#define BOXKEY_IORCST 0x3000000000000800
#define BOXKEY_IORCST_C0 0x3000000000000801
#define BOXKEY_IORCST_C3 0x3000000000000831
#define BOXKEY_IORCST_C4 0x3000000000000841
#define BOXKEY_IORCST_C6 0x3000000000000861
#define BOXKEY_IORCST_C7 0x3000000000000871
#define BOXKEY_ODCM 0x3000000000001000
#define BOXKEY_ODCM_OFF 0x3000000000001001
#define BOXKEY_ODCM_ON 0x3000000000001002
#define BOXKEY_DUTYCYCLE 0x3000000000002000
#define BOXKEY_ODCM_DC00 0x3000000000002001
#define BOXKEY_ODCM_DC01 0x3000000000002011
#define BOXKEY_ODCM_DC02 0x3000000000002021
#define BOXKEY_ODCM_DC03 0x3000000000002031
#define BOXKEY_ODCM_DC04 0x3000000000002041
#define BOXKEY_ODCM_DC05 0x3000000000002051
#define BOXKEY_ODCM_DC06 0x3000000000002061
#define BOXKEY_ODCM_DC07 0x3000000000002071
#define BOXKEY_ODCM_DC08 0x3000000000002081
#define BOXKEY_ODCM_DC09 0x3000000000002091
#define BOXKEY_ODCM_DC10 0x30000000000020a1
#define BOXKEY_ODCM_DC11 0x30000000000020b1
#define BOXKEY_ODCM_DC12 0x30000000000020c1
#define BOXKEY_ODCM_DC13 0x30000000000020d1
#define BOXKEY_ODCM_DC14 0x30000000000020e1
#define TRACK_TASK 0x2000000000000000
#define TRACK_MASK 0x0000000000007fff
int GetKey(SCANKEY *scan, struct timespec *tsec)
{
struct pollfd fds = {.fd = STDIN_FILENO, .events = POLLIN};
int rp = 0, rz = 0;
if ((rp=ppoll(&fds, 1, tsec, NULL)) > 0)
if (fds.revents == POLLIN) {
size_t lc = fread(&scan->key, 1, 8, stdin);
for (rz = lc; rz < 8; rz++)
scan->code[rz] = 0;
}
return(rp);
}
typedef struct {
int width,
height;
} SCREEN_SIZE;
SCREEN_SIZE GetScreenSize(void)
{
SCREEN_SIZE _screenSize = {.width = 0, .height = 0};
struct winsize ts;
ioctl(STDIN_FILENO, TIOCGWINSZ, &ts);
_screenSize.width = (int) ts.ws_col;
_screenSize.height = (int) ts.ws_row;
return(_screenSize);
}
unsigned int Dec2Digit(unsigned int decimal, unsigned int thisDigit[])
{
memset(thisDigit, 0, 9 * sizeof(unsigned int));
unsigned int j = 9;
while (decimal > 0) {
thisDigit[--j] = decimal % 10;
decimal /= 10;
}
return(9 - j);
}
void printv( void(*OutFunc)(unsigned long long key, char *output),
unsigned long long key, CUINT width, int tab, char *fmt, ...)
{
const char *indent[2][4] = {
{"", "|", "|- ", " |- "},
{"", " ", " ", " "}
};
char *line = malloc(width + 1);
va_list ap;
va_start(ap, fmt);
vsprintf(line, fmt, ap);
if (OutFunc == NULL)
printf("%s%s%.*s\n", indent[0][tab], line,
(int)(width - strlen(line) - strlen(indent[0][tab])), hSpace);
else {
char *output = malloc(width + 1);
sprintf(output, "%s%s%.*s", indent[1][tab], line,
(int)(width - strlen(line) - strlen(indent[1][tab])), hSpace);
OutFunc(key, output);
free(output);
}
va_end(ap);
free(line);
}
void SysInfoCPUID(SHM_STRUCT *Shm, CUINT width,
void(*OutFunc)(unsigned long long key, char *output) )
{
char format[] = "%08x:%08x%.*s%08x %08x %08x %08x";
unsigned int cpu;
for (cpu = 0; cpu < Shm->Proc.CPU.Count; cpu++) {
if (OutFunc == NULL) {
printv(OutFunc, SCANKEY_NULL, width, 0,
"CPU #%-2u function" \
" EAX EBX ECX EDX",
cpu);
} else {
printv(OutFunc, SCANKEY_NULL, width, 0, "CPU #%-2u", cpu);
}
printv(OutFunc, SCANKEY_NULL, width, 2, format,
0x00000000, 0x00000000,
4, hSpace,
Shm->Cpu[cpu].Query.StdFunc.LargestStdFunc,
Shm->Cpu[cpu].Query.StdFunc.BX,
Shm->Cpu[cpu].Query.StdFunc.CX,
Shm->Cpu[cpu].Query.StdFunc.DX);
printv(OutFunc, SCANKEY_NULL, width, 3,
"Largest Standard Function=%08x",
Shm->Cpu[cpu].Query.StdFunc.LargestStdFunc);
printv(OutFunc, SCANKEY_NULL, width, 2, format,
0x80000000, 0x00000000,
4, hSpace,
Shm->Cpu[cpu].Query.ExtFunc.LargestExtFunc,
Shm->Cpu[cpu].Query.ExtFunc.EBX,
Shm->Cpu[cpu].Query.ExtFunc.ECX,
Shm->Cpu[cpu].Query.ExtFunc.EDX);
printv(OutFunc, SCANKEY_NULL, width, 3,
"Largest Extended Function=%08x",
Shm->Cpu[cpu].Query.ExtFunc.LargestExtFunc);
int i;
for (i = 0; i < CPUID_MAX_FUNC; i++)
if (Shm->Cpu[cpu].CpuID[i].func) {
printv(OutFunc, SCANKEY_NULL, width, 2, format,
Shm->Cpu[cpu].CpuID[i].func,
Shm->Cpu[cpu].CpuID[i].sub,
4, hSpace,
Shm->Cpu[cpu].CpuID[i].reg[0],
Shm->Cpu[cpu].CpuID[i].reg[1],
Shm->Cpu[cpu].CpuID[i].reg[2],
Shm->Cpu[cpu].CpuID[i].reg[3]);
}
}
}
void SysInfoProc(SHM_STRUCT *Shm,
CUINT width,
void(*OutFunc)(unsigned long long key, char *output))
{
char *str = malloc(width + 1), symb[2][2] = {{'[', ']'}, {'<', '>'}};
int activeCores, boost = 0;
void PrintBoost(char *pfx, int _boost, int syc, unsigned long long _key)
{
if (Shm->Proc.Boost[_boost] > 0) {
sprintf(str, "%.*s""%s""%.*s""%7.2f""%.*s""%c%4d %c",
17, hSpace, pfx, 3, hSpace,
(double) ( Shm->Proc.Boost[_boost]
* Shm->Cpu[0].Clock.Hz) / 1000000.0,
20, hSpace,
symb[syc][0],
Shm->Proc.Boost[_boost],
symb[syc][1]);
printv(OutFunc, _key, width, 0, str);
}
}
printv(OutFunc, SCANKEY_NULL, width, 0, "Processor%.*s[%s]",
width - 11 - strlen(Shm->Proc.Brand), hSpace, Shm->Proc.Brand);
printv(OutFunc, SCANKEY_NULL, width, 2, "Architecture%.*s[%s]",
width - 17 - strlen(Shm->Proc.Architecture), hSpace,
Shm->Proc.Architecture);
printv(OutFunc, SCANKEY_NULL, width, 2, "Vendor ID%.*s[%s]",
width - 14 - strlen(Shm->Proc.Features.Info.Vendor.ID), hSpace,
Shm->Proc.Features.Info.Vendor.ID);
printv(OutFunc, SCANKEY_NULL, width, 2, "Signature%.*s[%1X%1X_%1X%1X]",
width - 19, hSpace,
Shm->Proc.Features.Std.EAX.ExtFamily,
Shm->Proc.Features.Std.EAX.Family,
Shm->Proc.Features.Std.EAX.ExtModel,
Shm->Proc.Features.Std.EAX.Model);
printv(OutFunc, SCANKEY_NULL, width, 2, "Stepping%.*s[%5u]",
width - 18, hSpace, Shm->Proc.Features.Std.EAX.Stepping);
printv(OutFunc, SCANKEY_NULL, width, 2, "Microcode%.*s[%5u]",
width - 19, hSpace, Shm->Cpu[0].Query.Microcode);
printv(OutFunc, SCANKEY_NULL, width, 2, "Online CPU%.*s[%2u/%-2u]",
width - 20, hSpace, Shm->Proc.CPU.OnLine, Shm->Proc.CPU.Count);
printv(OutFunc, SCANKEY_NULL, width, 2, "Base Clock%.*s[%5.1f]",
width - 20, hSpace, Shm->Cpu[0].Clock.Hz / 1000000.0);
printv(OutFunc, SCANKEY_NULL, width, 2, "TDP Limited%.*s[%6s]",
width - 22, hSpace,
Shm->Proc.Features.TDP_Unlock ? "UNLOCK" : "LOCK");
printv(OutFunc, SCANKEY_NULL, width, 2, "Ratio Limited%.*s[%6s]",
width - 24, hSpace,
Shm->Proc.Features.Ratio_Unlock ? "UNLOCK" : "LOCK");
printv(OutFunc, SCANKEY_NULL, width, 2, "Frequency%.*s(Mhz)%.*sRatio",
12, hSpace, 23 - (OutFunc == NULL), hSpace);
PrintBoost("Min", 0, 0, SCANKEY_NULL);
PrintBoost("Max", 1, 0, SCANKEY_NULL);
printv(OutFunc, SCANKEY_NULL, width, 2, "Turbo Boost");
for (boost = LAST_BOOST, activeCores = 1;
boost > LAST_BOOST - Shm->Proc.Features.SpecTurboRatio;
boost--, activeCores++)
{
char pfx[4];
sprintf(pfx, "%2dC", activeCores);
PrintBoost(pfx,boost,Shm->Proc.Features.Ratio_Unlock,SCANKEY_NULL);
}
free(str);
}
void SysInfoISA(SHM_STRUCT *Shm,
CUINT width,
void(*OutFunc)(unsigned long long key, char *output))
{
size_t len = 0;
char *row[2] = {malloc(width + 1), malloc(width + 1)},
*str = malloc(width + 1),
*pad = NULL;
/* Row Mark */
len = 3;
len += sprintf(str, "3DNow!/Ext [%c,%c]",
Shm->Proc.Features.ExtInfo.EDX._3DNow ? 'Y' : 'N',
Shm->Proc.Features.ExtInfo.EDX._3DNowEx ? 'Y' : 'N');
strcpy(row[0], str);
len += sprintf(str, "%.*s", 11, hSpace);
strcat(row[0], str);
len += sprintf(str, "AES [%c]",
Shm->Proc.Features.Std.ECX.AES ? 'Y' : 'N');
strcat(row[0], str);
len += sprintf(str, "%.*s", 6, hSpace);
strcat(row[0], str);
len += sprintf(str, "AVX/AVX2 [%c/%c]",
Shm->Proc.Features.Std.ECX.AVX ? 'Y' : 'N',
Shm->Proc.Features.ExtFeature.EBX.AVX2 ? 'Y' : 'N');
strcat(row[0], str);
len += sprintf(str, "BMI1/BMI2 [%c/%c]",
Shm->Proc.Features.ExtFeature.EBX.BMI1 ? 'Y' : 'N',
Shm->Proc.Features.ExtFeature.EBX.BMI2 ? 'Y' : 'N');
pad = realloc(pad, (width - len) + 1);
sprintf(pad, "%.*s", (int)(width - len), hSpace);
strcat(row[0], pad);
strcat(row[0], str);
printv(OutFunc, SCANKEY_NULL, width, 2, row[0]);
/* Row Mark */
len = 3;
len += sprintf(str, "CLFSH [%c]",
Shm->Proc.Features.Std.EDX.CLFSH ? 'Y' : 'N');
strcpy(row[0], str);
len += sprintf(str, "%.*s", 10, hSpace);
strcat(row[0], str);
len += sprintf(str, "CMOV [%c]",
Shm->Proc.Features.Std.EDX.CMOV ? 'Y' : 'N');
strcat(row[0], str);
len += sprintf(str, "%.*s", 7, hSpace);
strcat(row[0], str);
len += sprintf(str, "CMPXCH8 [%c]",
Shm->Proc.Features.Std.EDX.CMPXCH8 ? 'Y' : 'N');
strcat(row[0], str);
len += sprintf(str, "CMPXCH16 [%c]",
Shm->Proc.Features.Std.ECX.CMPXCH16 ? 'Y' : 'N');
pad = realloc(pad, (width - len) + 1);
sprintf(pad, "%.*s", (int)(width - len), hSpace);
strcat(row[0], pad);
strcat(row[0], str);
printv(OutFunc, SCANKEY_NULL, width, 2, row[0]);
/* Row Mark */
len = 3;
len += sprintf(str, "F16C [%c]",
Shm->Proc.Features.Std.ECX.F16C ? 'Y' : 'N');
strcpy(row[0], str);
len += sprintf(str, "%.*s", 11, hSpace);
strcat(row[0], str);
len += sprintf(str, "FPU [%c]",
Shm->Proc.Features.Std.EDX.FPU ? 'Y' : 'N');
strcat(row[0], str);
len += sprintf(str, "%.*s", 10, hSpace);
strcat(row[0], str);
len += sprintf(str, "FXSR [%c]",
Shm->Proc.Features.Std.EDX.FXSR ? 'Y' : 'N');
strcat(row[0], str);
len += sprintf(str, "LAHF/SAHF [%c]",
Shm->Proc.Features.ExtInfo.ECX.LAHFSAHF ? 'Y' : 'N');
pad = realloc(pad, (width - len) + 1);
sprintf(pad, "%.*s", (int)(width - len), hSpace);
strcat(row[0], pad);
strcat(row[0], str);
printv(OutFunc, SCANKEY_NULL, width, 2, row[0]);
/* Row Mark */
len = 3;
len += sprintf(str, "MMX/Ext [%c/%c]",
Shm->Proc.Features.Std.EDX.MMX ? 'Y' : 'N',
Shm->Proc.Features.ExtInfo.EDX.MMX_Ext ? 'Y' : 'N');
strcpy(row[0], str);
len += sprintf(str, "%.*s", 7, hSpace);
strcat(row[0], str);
len += sprintf(str, "MONITOR [%c]",
Shm->Proc.Features.Std.ECX.MONITOR ? 'Y' : 'N');
strcat(row[0], str);
len += sprintf(str, "%.*s", 9, hSpace);
strcat(row[0], str);
len += sprintf(str, "MOVBE [%c]",
Shm->Proc.Features.Std.ECX.MOVBE ? 'Y' : 'N');
strcat(row[0], str);
len += sprintf(str, "PCLMULDQ [%c]",
Shm->Proc.Features.Std.ECX.PCLMULDQ ? 'Y' : 'N');
pad = realloc(pad, (width - len) + 1);
sprintf(pad, "%.*s", (int)(width - len), hSpace);
strcat(row[0], pad);
strcat(row[0], str);
printv(OutFunc, SCANKEY_NULL, width, 2, row[0]);
/* Row Mark */
len = 3;
len += sprintf(str, "POPCNT [%c]",
Shm->Proc.Features.Std.ECX.POPCNT ? 'Y' : 'N');
strcpy(row[0], str);
len += sprintf(str, "%.*s", 8, hSpace);
strcat(row[0], str);
len += sprintf(str, "RDRAND [%c]",
Shm->Proc.Features.Std.ECX.RDRAND ? 'Y' : 'N');
strcat(row[0], str);
len += sprintf(str, "%.*s", 8, hSpace);
strcat(row[0], str);
len += sprintf(str, "RDTSCP [%c]",
Shm->Proc.Features.ExtInfo.EDX.RDTSCP ? 'Y' : 'N');
strcat(row[0], str);
len += sprintf(str, "SEP [%c]",
Shm->Proc.Features.Std.EDX.SEP ? 'Y' : 'N');
pad = realloc(pad, (width - len) + 1);
sprintf(pad, "%.*s", (int)(width - len), hSpace);
strcat(row[0], pad);
strcat(row[0], str);
printv(OutFunc, SCANKEY_NULL, width, 2, row[0]);
/* Row Mark */
len = 3;
len += sprintf(str, "SSE [%c]",
Shm->Proc.Features.Std.EDX.SSE ? 'Y' : 'N');
strcpy(row[0], str);
len += sprintf(str, "%.*s", 10, hSpace);
strcat(row[0], str);
len += sprintf(str, "SSE2 [%c]",
Shm->Proc.Features.Std.EDX.SSE2 ? 'Y' : 'N');
strcat(row[0], str);
len += sprintf(str, "%.*s", 10, hSpace);
strcat(row[0], str);
len += sprintf(str, "SSE3 [%c]",
Shm->Proc.Features.Std.ECX.SSE3 ? 'Y' : 'N');
strcat(row[0], str);
len += sprintf(str, "SSSE3 [%c]",
Shm->Proc.Features.Std.ECX.SSSE3 ? 'Y' : 'N');
pad = realloc(pad, (width - len) + 1);
sprintf(pad, "%.*s", (int)(width - len), hSpace);
strcat(row[0], pad);
strcat(row[0], str);
printv(OutFunc, SCANKEY_NULL, width, 2, row[0]);
/* Row Mark */
len = 3;
len += sprintf(str, "SSE4.1/4A [%c/%c]",
Shm->Proc.Features.Std.ECX.SSE41 ? 'Y' : 'N',
Shm->Proc.Features.ExtInfo.ECX.SSE4A ? 'Y' : 'N');
strcpy(row[0], str);
len += sprintf(str, "%.*s", 8, hSpace);
strcat(row[0], str);
len += sprintf(str, "SSE4.2 [%c]",
Shm->Proc.Features.Std.ECX.SSE42 ? 'Y' : 'N');
strcat(row[0], str);
len += sprintf(str, "%.*s", 7, hSpace);
strcat(row[0], str);
len += sprintf(str, "SYSCALL [%c]",
Shm->Proc.Features.ExtInfo.EDX.SYSCALL ? 'Y' : 'N');
pad = realloc(pad, (width - len) + 1);
sprintf(pad, "%.*s", (int)(width - len), hSpace);
strcat(row[0], str);
strcat(row[0], pad);
printv(OutFunc, SCANKEY_NULL, width, 2, row[0]);
free(row[0]);
free(row[1]);
free(str);
free(pad);
}
void SysInfoFeatures( SHM_STRUCT *Shm, CUINT width,
void(*OutFunc)(unsigned long long key, char *output) )
{
/* Section Mark */
const char *TSC[] = {
"Missing",
"Variant",
"Invariant"
};
const char *x2APIC[] = {
"Missing",
" xAPIC",
" x2APIC"
};
/* Section Mark */
printv(OutFunc, SCANKEY_NULL, width, 2,
"1 GB Pages Support%.*s1GB-PAGES [%7s]",
width - 42, hSpace,
powered(Shm->Proc.Features.ExtInfo.EDX.PG_1GB));
printv(OutFunc, SCANKEY_NULL, width, 2,
"100 MHz multiplier Control%.*s100MHzSteps [%7s]",
width - 52, hSpace,
powered(Shm->Proc.Features.AdvPower.EDX._100MHz));
printv(OutFunc, SCANKEY_NULL, width, 2,
"Advanced Configuration & Power Interface" \
"%.*sACPI [%7s]",
width - 59, hSpace,
powered(Shm->Proc.Features.Std.EDX.ACPI // Intel
| Shm->Proc.Features.AdvPower.EDX.HwPstate) ); // AMD
printv(OutFunc, SCANKEY_NULL, width, 2,
"Advanced Programmable Interrupt Controller" \
"%.*sAPIC [%7s]",
width - 61, hSpace, powered(Shm->Proc.Features.Std.EDX.APIC));
printv(OutFunc, SCANKEY_NULL, width, 2,
"Core Multi-Processing%.*sCMP Legacy [%7s]",
width - 46, hSpace,
powered(Shm->Proc.Features.ExtInfo.ECX.MP_Mode));
printv(OutFunc, SCANKEY_NULL, width, 2,
"L1 Data Cache Context ID%.*sCNXT-ID [%7s]",
width - 46,hSpace, powered(Shm->Proc.Features.Std.ECX.CNXT_ID));
printv(OutFunc, SCANKEY_NULL, width, 2,
"Direct Cache Access%.*sDCA [%7s]",
width - 37, hSpace, powered(Shm->Proc.Features.Std.ECX.DCA));
printv(OutFunc, SCANKEY_NULL, width, 2,
"Debugging Extension%.*sDE [%7s]",
width - 36, hSpace, powered(Shm->Proc.Features.Std.EDX.DE));
printv(OutFunc, SCANKEY_NULL, width, 2,
"Debug Store & Precise Event Based Sampling" \
"%.*sDS, PEBS [%7s]",
width - 65,hSpace, powered(Shm->Proc.Features.Std.EDX.DS_PEBS));
printv(OutFunc, SCANKEY_NULL, width, 2,
"CPL Qualified Debug Store%.*sDS-CPL [%7s]",
width - 46, hSpace, powered(Shm->Proc.Features.Std.ECX.DS_CPL));
printv(OutFunc, SCANKEY_NULL, width, 2,
"64-Bit Debug Store%.*sDTES64 [%7s]",
width - 39, hSpace, powered(Shm->Proc.Features.Std.ECX.DTES64));
printv(OutFunc, SCANKEY_NULL, width, 2,
"Fast-String Operation%.*sFast-Strings [%7s]",
width - 48,hSpace,
powered(Shm->Proc.Features.ExtFeature.EBX.FastStrings));
printv(OutFunc, SCANKEY_NULL, width, 2,
"Fused Multiply Add%.*sFMA|FMA4 [%7s]",
width - 41, hSpace,
powered( Shm->Proc.Features.Std.ECX.FMA
| Shm->Proc.Features.ExtInfo.ECX.FMA4 ));
printv(OutFunc, SCANKEY_NULL, width, 2,
"Hardware Lock Elision%.*sHLE [%7s]",
width - 39, hSpace,
powered(Shm->Proc.Features.ExtFeature.EBX.HLE));
printv(OutFunc, SCANKEY_NULL, width, 2,
"Long Mode 64 bits%.*sIA64|LM [%7s]",
width - 39, hSpace,
powered(Shm->Proc.Features.ExtInfo.EDX.IA64));
printv(OutFunc, SCANKEY_NULL, width, 2,
"LightWeight Profiling%.*sLWP [%7s]",
width - 39, hSpace,
powered(Shm->Proc.Features.ExtInfo.ECX.LWP));
printv(OutFunc, SCANKEY_NULL, width, 2,
"Machine-Check Architecture%.*sMCA [%7s]",
width - 44, hSpace,
powered(Shm->Proc.Features.Std.EDX.MCA));
printv(OutFunc, SCANKEY_NULL, width, 2,
"Model Specific Registers%.*sMSR [%7s]",
width - 42, hSpace, powered(Shm->Proc.Features.Std.EDX.MSR));
printv(OutFunc, SCANKEY_NULL, width, 2,
"Memory Type Range Registers%.*sMTRR [%7s]",
width - 46, hSpace, powered(Shm->Proc.Features.Std.EDX.MTRR));
printv(OutFunc, SCANKEY_NULL, width, 2,
"OS-Enabled Ext. State Management%.*sOSXSAVE [%7s]",
width - 54,hSpace, powered(Shm->Proc.Features.Std.ECX.OSXSAVE));
printv(OutFunc, SCANKEY_NULL, width, 2,
"Physical Address Extension%.*sPAE [%7s]",
width - 44, hSpace, powered(Shm->Proc.Features.Std.EDX.PAE));
printv(OutFunc, SCANKEY_NULL, width, 2,
"Page Attribute Table%.*sPAT [%7s]",
width - 38, hSpace, powered(Shm->Proc.Features.Std.EDX.PAT));
printv(OutFunc, SCANKEY_NULL, width, 2,
"Pending Break Enable%.*sPBE [%7s]",
width - 38, hSpace, powered(Shm->Proc.Features.Std.EDX.PBE));
printv(OutFunc, SCANKEY_NULL, width, 2,
"Process Context Identifiers%.*sPCID [%7s]",
width - 46, hSpace, powered(Shm->Proc.Features.Std.ECX.PCID));
printv(OutFunc, SCANKEY_NULL, width, 2,
"Perfmon and Debug Capability%.*sPDCM [%7s]",
width - 47, hSpace, powered(Shm->Proc.Features.Std.ECX.PDCM));
printv(OutFunc, SCANKEY_NULL, width, 2,
"Page Global Enable%.*sPGE [%7s]",
width - 36, hSpace, powered(Shm->Proc.Features.Std.EDX.PGE));
printv(OutFunc, SCANKEY_NULL, width, 2,
"Page Size Extension%.*sPSE [%7s]",
width - 37, hSpace, powered(Shm->Proc.Features.Std.EDX.PSE));
printv(OutFunc, SCANKEY_NULL, width, 2,
"36-bit Page Size Extension%.*sPSE36 [%7s]",
width - 46, hSpace, powered(Shm->Proc.Features.Std.EDX.PSE36));
printv(OutFunc, SCANKEY_NULL, width, 2,
"Processor Serial Number%.*sPSN [%7s]",
width - 41, hSpace, powered(Shm->Proc.Features.Std.EDX.PSN));
printv(OutFunc, SCANKEY_NULL, width, 2,
"Restricted Transactional Memory%.*sRTM [%7s]",
width - 49, hSpace,
powered(Shm->Proc.Features.ExtFeature.EBX.RTM));
printv(OutFunc, SCANKEY_NULL, width, 2,
"Safer Mode Extensions%.*sSMX [%7s]",
width - 39, hSpace, powered(Shm->Proc.Features.Std.ECX.SMX));
printv(OutFunc, SCANKEY_NULL, width, 2,
"Self-Snoop%.*sSS [%7s]",
width - 27, hSpace, powered(Shm->Proc.Features.Std.EDX.SS));
printv(OutFunc, SCANKEY_NULL, width, 2,
"Time Stamp Counter%.*sTSC [%9s]",
width - 36, hSpace, TSC[Shm->Proc.Features.InvariantTSC]);
printv(OutFunc, SCANKEY_NULL, width, 2,
"Time Stamp Counter Deadline%.*sTSC-DEADLINE [%7s]",
width - 54,hSpace, powered(Shm->Proc.Features.Std.ECX.TSCDEAD));
printv(OutFunc, SCANKEY_NULL, width, 2,
"Virtual Mode Extension%.*sVME [%7s]",
width - 40, hSpace, powered(Shm->Proc.Features.Std.EDX.VME));
printv(OutFunc, SCANKEY_NULL, width, 2,
"Virtual Machine Extensions%.*sVMX [%7s]",
width - 44, hSpace, powered(Shm->Proc.Features.Std.ECX.VMX));
printv(OutFunc, SCANKEY_NULL, width, 2,
"Extended xAPIC Support%.*sx2APIC [%7s]",
width - 43, hSpace, x2APIC[Shm->Cpu[0].Topology.MP.x2APIC]);
printv(OutFunc, SCANKEY_NULL, width, 2,
"Execution Disable Bit Support%.*sXD-Bit [%7s]",
width - 50, hSpace,
powered(Shm->Proc.Features.ExtInfo.EDX.XD_Bit));
printv(OutFunc, SCANKEY_NULL, width, 2,
"XSAVE/XSTOR States%.*sXSAVE [%7s]",
width - 38, hSpace, powered(Shm->Proc.Features.Std.ECX.XSAVE));
printv(OutFunc, SCANKEY_NULL, width, 2,
"xTPR Update Control%.*sxTPR [%7s]",
width - 38, hSpace, powered(Shm->Proc.Features.Std.ECX.xTPR));
}
void SysInfoTech(SHM_STRUCT *Shm, CUINT width,
void(*OutFunc)(unsigned long long key, char *output) )
{
const unsigned int
isTurbo = !BITWISEXOR(LOCKLESS, Shm->Proc.TurboBoost,
Shm->Proc.TurboBoost_Mask),
isEIST = !BITWISEXOR(LOCKLESS, Shm->Proc.SpeedStep,
Shm->Proc.SpeedStep_Mask);
/* Section Mark */
printv(OutFunc, SCANKEY_NULL, width, 2,
"Hyper-Threading%.*sHTT [%3s]", width - 33, hSpace,
enabled(Shm->Proc.Features.HyperThreading));
printv(OutFunc, BOXKEY_EIST, width, 2,
"SpeedStep%.*sEIST <%3s>", width - 28, hSpace,
enabled(isEIST));
printv(OutFunc, SCANKEY_NULL, width, 2,
"PowerNow!%.*sPowerNow [%3s]", width - 32, hSpace,
enabled(Shm->Proc.PowerNow == 0b11)); // VID + FID
printv(OutFunc, SCANKEY_NULL, width, 2,
"Dynamic Acceleration%.*sIDA [%3s]", width - 38, hSpace,
enabled(Shm->Proc.Features.Power.EAX.TurboIDA));
printv(OutFunc, BOXKEY_TURBO, width, 2,
"Turbo Boost/CPB%.*sTURBO <%3s>", width - 35, hSpace,
enabled(isTurbo|Shm->Proc.Features.AdvPower.EDX.CPB));
printv(OutFunc, SCANKEY_NULL, width, 2,
"Virtualization%.*sHYPERVISOR [%3s]", width - 39, hSpace,
enabled(Shm->Proc.Features.Std.ECX.Hyperv));
}
void SysInfoPerfMon( SHM_STRUCT *Shm, CUINT width,
void(*OutFunc)(unsigned long long key, char *output) )
{
const unsigned int
isC1E = !BITWISEXOR(LOCKLESS,Shm->Proc.C1E, Shm->Proc.C1E_Mask),
isC3A = !BITWISEXOR(LOCKLESS,Shm->Proc.C3A, Shm->Proc.C3A_Mask),
isC1A = !BITWISEXOR(LOCKLESS,Shm->Proc.C1A, Shm->Proc.C1A_Mask),
isC3U = !BITWISEXOR(LOCKLESS,Shm->Proc.C3U, Shm->Proc.C3U_Mask),
isC1U = !BITWISEXOR(LOCKLESS,Shm->Proc.C1U, Shm->Proc.C1U_Mask);
/* Section Mark */
printv(OutFunc, SCANKEY_NULL, width, 2,
"Version%.*sPM [%3d]",
width - 24, hSpace, Shm->Proc.PM_version);
printv(OutFunc, SCANKEY_NULL, width, 2,
"Counters:%.*sGeneral%.*sFixed",
10, hSpace, width - 61, hSpace);
if (OutFunc == NULL) {
printv(OutFunc, SCANKEY_NULL, width, 1,
"%.*s%3u x%3u bits%.*s%3u x%3u bits",
19, hSpace, Shm->Proc.Features.PerfMon.EAX.MonCtrs,
Shm->Proc.Features.PerfMon.EAX.MonWidth,
11, hSpace, Shm->Proc.Features.PerfMon.EDX.FixCtrs,
Shm->Proc.Features.PerfMon.EDX.FixWidth);
} else {
printv(OutFunc, SCANKEY_NULL, width, 0,
"%.*s%3u x%3u bits%.*s%3u x%3u bits",
19, hSpace, Shm->Proc.Features.PerfMon.EAX.MonCtrs,
Shm->Proc.Features.PerfMon.EAX.MonWidth,
5, hSpace, Shm->Proc.Features.PerfMon.EDX.FixCtrs,
Shm->Proc.Features.PerfMon.EDX.FixWidth);
}
printv(OutFunc, BOXKEY_C1E, width, 2,
"Enhanced Halt State%.*sC1E <%3s>",
width - 37, hSpace, enabled(isC1E));
printv(OutFunc, BOXKEY_C1A, width, 2,
"C1 Auto Demotion%.*sC1A <%3s>",
width - 34, hSpace, enabled(isC1A));
printv(OutFunc, BOXKEY_C3A, width, 2,
"C3 Auto Demotion%.*sC3A <%3s>",
width - 34, hSpace, enabled(isC3A));
printv(OutFunc, BOXKEY_C1U, width, 2,
"C1 UnDemotion%.*sC1U <%3s>",
width - 31, hSpace, enabled(isC1U));
printv(OutFunc, BOXKEY_C3U, width, 2,
"C3 UnDemotion%.*sC3U <%3s>",
width - 31, hSpace, enabled(isC3U));
printv(OutFunc, SCANKEY_NULL, width, 2,
"Frequency ID control%.*sFID [%3s]",
width - 38, hSpace,
enabled(Shm->Proc.Features.AdvPower.EDX.FID));
printv(OutFunc, SCANKEY_NULL, width, 2,
"Voltage ID control%.*sVID [%3s]",
width - 36, hSpace,
enabled(Shm->Proc.Features.AdvPower.EDX.VID));
printv(OutFunc, SCANKEY_NULL, width, 2,
"P-State Hardware Coordination Feedback" \
"%.*sMPERF/APERF [%3s]",
width - 64, hSpace,
enabled(Shm->Proc.Features.Power.ECX.HCF_Cap));
printv(OutFunc, SCANKEY_NULL, width, 2,
"Hardware-Controlled Performance States%.*sHWP [%3s]",
width - 56, hSpace,
enabled( Shm->Proc.Features.Power.EAX.HWP_Reg
| Shm->Proc.Features.AdvPower.EDX.HwPstate));
printv(OutFunc, SCANKEY_NULL, width, 2,
"Hardware Duty Cycling%.*sHDC [%3s]",
width - 39, hSpace,
enabled(Shm->Proc.Features.Power.EAX.HDC_Reg));
printv(OutFunc, SCANKEY_NULL, width, 2, "Package C-State");
printv(OutFunc, SCANKEY_NULL, width, 3,
"Configuration Control%.*sCONFIG [%7s]",
width - (OutFunc == NULL ? 45 : 43), hSpace,
!Shm->Cpu[0].Query.CfgLock? "UNLOCK":"LOCK");
if (!Shm->Cpu[0].Query.CfgLock) {
printv(OutFunc, BOXKEY_PKGCST, width, 3,
"Lowest C-State%.*sLIMIT <%7d>",
width - (OutFunc == NULL ? 37 : 35), hSpace,
Shm->Cpu[0].Query.CStateLimit);
printv(OutFunc, BOXKEY_IOMWAIT, width, 3,
"I/O MWAIT Redirection%.*sIOMWAIT <%7s>",
width - (OutFunc == NULL ? 46 : 44), hSpace,
Shm->Cpu[0].Query.IORedir? " ENABLE":"DISABLE");
printv(OutFunc, BOXKEY_IORCST, width, 3,
"Max C-State Inclusion%.*sRANGE <%7d>",
width - (OutFunc == NULL ? 44 : 42), hSpace,
Shm->Cpu[0].Query.CStateInclude);
} else {
printv(OutFunc, SCANKEY_NULL, width, 3,
"Lowest C-State%.*sLIMIT [%7d]",
width - (OutFunc == NULL ? 37 : 35), hSpace,
Shm->Cpu[0].Query.CStateLimit);
printv(OutFunc, SCANKEY_NULL, width, 3,
"I/O MWAIT Redirection%.*sIOMWAIT [%7s]",
width - (OutFunc == NULL ? 46 : 44), hSpace,
Shm->Cpu[0].Query.IORedir? " ENABLE":"DISABLE");
printv(OutFunc, SCANKEY_NULL, width, 3,
"Max C-State Inclusion%.*sRANGE [%7d]",
width - (OutFunc == NULL ? 44 : 42), hSpace,
Shm->Cpu[0].Query.CStateInclude);
}
printv(OutFunc, SCANKEY_NULL, width, 2,
"MWAIT States:%.*sC0 C1 C2 C3 C4",
06, hSpace);
printv(OutFunc, SCANKEY_NULL, width, (OutFunc == NULL) ? 1 : 0,
"%.*s%2d %2d %2d %2d %2d",
21, hSpace,
Shm->Proc.Features.MWait.EDX.Num_C0_MWAIT,
Shm->Proc.Features.MWait.EDX.Num_C1_MWAIT,
Shm->Proc.Features.MWait.EDX.Num_C2_MWAIT,
Shm->Proc.Features.MWait.EDX.Num_C3_MWAIT,
Shm->Proc.Features.MWait.EDX.Num_C4_MWAIT);
printv(OutFunc, SCANKEY_NULL, width, 2,
"Core Cycles%.*s[%7s]",
width - 23, hSpace,
powered(!Shm->Proc.Features.PerfMon.EBX.CoreCycles));
printv(OutFunc, SCANKEY_NULL, width, 2,
"Instructions Retired%.*s[%7s]",
width - 32, hSpace,
powered(!Shm->Proc.Features.PerfMon.EBX.InstrRetired));
printv(OutFunc, SCANKEY_NULL, width, 2,
"Reference Cycles%.*s[%7s]",
width - 28, hSpace,
powered(!Shm->Proc.Features.PerfMon.EBX.RefCycles));
printv(OutFunc, SCANKEY_NULL, width, 2,
"Last Level Cache References%.*s[%7s]",
width - 39, hSpace,
powered(!Shm->Proc.Features.PerfMon.EBX.LLC_Ref));
printv(OutFunc, SCANKEY_NULL, width, 2,
"Last Level Cache Misses%.*s[%7s]",
width - 35, hSpace,
powered(!Shm->Proc.Features.PerfMon.EBX.LLC_Misses));
printv(OutFunc, SCANKEY_NULL, width, 2,
"Branch Instructions Retired%.*s[%7s]",
width - 39, hSpace,
powered(!Shm->Proc.Features.PerfMon.EBX.BranchRetired));
printv(OutFunc, SCANKEY_NULL, width, 2,
"Branch Mispredicts Retired%.*s[%7s]",
width - 38, hSpace,
powered(!Shm->Proc.Features.PerfMon.EBX.BranchMispred));
}
void SysInfoPwrThermal( SHM_STRUCT *Shm, CUINT width,
void(*OutFunc)(unsigned long long key, char *output) )
{
const char *TM[] = {
"Missing",
"Present",
"Disable",
" Enable",
}, *Unlock[] = {
" LOCK",
"UNLOCK",
};
const unsigned int
isODCM = !BITWISEXOR(LOCKLESS, Shm->Proc.ODCM,
Shm->Proc.ODCM_Mask),
isPowerMgmt = !BITWISEXOR(LOCKLESS, Shm->Proc.PowerMgmt,
Shm->Proc.PowerMgmt_Mask);
/* Section Mark */
printv(OutFunc, BOXKEY_ODCM, width, 2,
"Clock Modulation%.*sODCM <%7s>",
width - 35, hSpace, isODCM ? " Enable" : "Disable");
printv(OutFunc, BOXKEY_DUTYCYCLE, width, 3,
"DutyCycle%.*s<%6.2f%%>",
width - (OutFunc == NULL ? 24: 22), hSpace,
(Shm->Cpu[0].PowerThermal.DutyCycle.Extended ?
6.25f : 12.5f
* Shm->Cpu[0].PowerThermal.DutyCycle.ClockMod));
printv(OutFunc, SCANKEY_NULL, width, 2,
"Power Management%.*sPWR MGMT [%7s]",
width - 39, hSpace, Unlock[isPowerMgmt]);
printv(OutFunc, SCANKEY_NULL, width, 3,
"Energy Policy%.*sBias Hint [%7u]",
width - (OutFunc == NULL ? 40 : 38),
hSpace, Shm->Cpu[0].PowerThermal.PowerPolicy);
printv(OutFunc, SCANKEY_NULL, width, 2,
"Junction Temperature%.*sTjMax [%7u]",
width - 40, hSpace, Shm->Cpu[0].PowerThermal.Target);
printv(OutFunc, SCANKEY_NULL, width, 2,
"Digital Thermal Sensor%.*sDTS [%7s]",
width - 40, hSpace,
powered( Shm->Proc.Features.Power.EAX.DTS
|Shm->Proc.Features.AdvPower.EDX.TS));
printv(OutFunc, SCANKEY_NULL, width, 2,
"Power Limit Notification%.*sPLN [%7s]",
width - 42, hSpace, powered(Shm->Proc.Features.Power.EAX.PLN));
printv(OutFunc, SCANKEY_NULL, width, 2,
"Package Thermal Management%.*sPTM [%7s]",
width - 44, hSpace, powered(Shm->Proc.Features.Power.EAX.PTM));
printv(OutFunc, SCANKEY_NULL, width, 2,
"Thermal Monitor 1%.*sTM1|TTP [%7s]",
width - 39, hSpace, TM[ Shm->Cpu[0].PowerThermal.TM1
|Shm->Proc.Features.AdvPower.EDX.TTP ]);
printv(OutFunc, SCANKEY_NULL, width, 2,
"Thermal Monitor 2%.*sTM2|HTC [%7s]",
width - 39, hSpace, TM[ Shm->Cpu[0].PowerThermal.TM2
|Shm->Proc.Features.AdvPower.EDX.TM ]);
}
void SysInfoKernel( SHM_STRUCT *Shm, CUINT width,
void(*OutFunc)(unsigned long long key, char *output) )
{
size_t len = 0;
char *row = malloc(width + 1),
*str = malloc(width + 1);
int i = 0;
/* Section Mark */
printv(OutFunc, SCANKEY_NULL, width, 0, "%s:", Shm->SysGate.sysname);
printv(OutFunc, SCANKEY_NULL, width, 2, "Release%.*s[%s]",
width - 12 - strlen(Shm->SysGate.release), hSpace,
Shm->SysGate.release);
printv(OutFunc, SCANKEY_NULL, width, 2, "Version%.*s[%s]",
width - 12 - strlen(Shm->SysGate.version), hSpace,
Shm->SysGate.version);
printv(OutFunc, SCANKEY_NULL, width, 2, "Machine%.*s[%s]",
width - 12 - strlen(Shm->SysGate.machine), hSpace,
Shm->SysGate.machine);
/* Section Mark */
printv(OutFunc, SCANKEY_NULL, width, 0, "Memory:%.*s",
width - 7, hSpace);
len = sprintf(str, "%lu", Shm->SysGate.memInfo.totalram);
printv(OutFunc, SCANKEY_NULL, width, 2, "Total RAM" "%.*s" "%s KB",
width - 15 - len, hSpace, str);
len = sprintf(str, "%lu", Shm->SysGate.memInfo.sharedram);
printv(OutFunc, SCANKEY_NULL, width, 2, "Shared RAM" "%.*s" "%s KB",
width - 16 - len, hSpace, str);
len = sprintf(str, "%lu", Shm->SysGate.memInfo.freeram);
printv(OutFunc, SCANKEY_NULL, width, 2, "Free RAM" "%.*s" "%s KB",
width - 14 - len, hSpace, str);
len = sprintf(str, "%lu", Shm->SysGate.memInfo.bufferram);
printv(OutFunc, SCANKEY_NULL, width, 2, "Buffer RAM" "%.*s" "%s KB",
width - 16 - len, hSpace, str);
len = sprintf(str, "%lu", Shm->SysGate.memInfo.totalhigh);
printv(OutFunc, SCANKEY_NULL, width, 2, "Total High" "%.*s" "%s KB",
width - 16 - len, hSpace, str);
len = sprintf(str, "%lu", Shm->SysGate.memInfo.freehigh);
printv(OutFunc, SCANKEY_NULL, width, 2, "Free High" "%.*s" "%s KB",
width - 15 - len, hSpace, str);
/* Section Mark */
if ((len = strlen(Shm->SysGate.IdleDriver.Name)
+ strlen(Shm->SysGate.IdleDriver.Governor)) > 0) {
printv(OutFunc, SCANKEY_NULL, width, 0, "Idle driver%.*s[%s@%s]",
width - 14 - len, hSpace,
Shm->SysGate.IdleDriver.Governor, Shm->SysGate.IdleDriver.Name);
/* Row Mark */
len = sprintf(row, "States:%.*s", 9, hSpace);
for (i = 0; i < Shm->SysGate.IdleDriver.stateCount; i++) {
len += sprintf(str, "%-8s",
Shm->SysGate.IdleDriver.State[i].Name);
strcat(row, str);
}
printv(OutFunc, SCANKEY_NULL, width, 3, row);
/* Row Mark */
len = sprintf(row, "Power:%.*s", 10, hSpace);
for (i = 0; i < Shm->SysGate.IdleDriver.stateCount; i++) {
len += sprintf(str, "%-8d",
Shm->SysGate.IdleDriver.State[i].powerUsage);
strcat(row, str);
}
printv(OutFunc, SCANKEY_NULL, width, 3, row);
/* Row Mark */
len = sprintf(row, "Latency:%.*s", 8, hSpace);
for (i = 0; i < Shm->SysGate.IdleDriver.stateCount; i++) {
len += sprintf(str, "%-8u",
Shm->SysGate.IdleDriver.State[i].exitLatency);
strcat(row, str);
}
printv(OutFunc, SCANKEY_NULL, width, 3, row);
/* Row Mark */
len = sprintf(row, "Residency:%.*s", 6, hSpace);
for (i = 0; i < Shm->SysGate.IdleDriver.stateCount; i++) {
len += sprintf(str, "%-8u",
Shm->SysGate.IdleDriver.State[i].targetResidency);
strcat(row, str);
}
printv(OutFunc, SCANKEY_NULL, width, 3, row);
}
free(row);
free(str);
}
void Counters(SHM_STRUCT *Shm)
{
unsigned int cpu = 0;
while (!BITVAL(Shutdown, 0)) {
while (!BITVAL(Shm->Proc.Sync, 0) && !BITVAL(Shutdown, 0))
nanosleep(&Shm->Proc.BaseSleep, NULL);
BITCLR(LOCKLESS, Shm->Proc.Sync, 0);
if (BITVAL(Shm->Proc.Sync, 63))
BITCLR(LOCKLESS, Shm->Proc.Sync, 63);
printf("CPU Freq(MHz) Ratio Turbo" \
" C0(%%) C1(%%) C3(%%) C6(%%) C7(%%)" \
" Min TMP:TS Max\n");
for (cpu = 0; (cpu < Shm->Proc.CPU.Count) && !BITVAL(Shutdown,0); cpu++)
if (!BITVAL(Shm->Cpu[cpu].OffLine, HW)) {
struct FLIP_FLOP *Flop =
&Shm->Cpu[cpu].FlipFlop[!Shm->Cpu[cpu].Toggle];
if (!BITVAL(Shm->Cpu[cpu].OffLine, OS))
printf("#%02u %7.2f (%5.2f)" \
" %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f" \
" %-3u/%3u:%-3u/%3u\n",
cpu,
Flop->Relative.Freq,
Flop->Relative.Ratio,
100.f * Flop->State.Turbo,
100.f * Flop->State.C0,
100.f * Flop->State.C1,
100.f * Flop->State.C3,
100.f * Flop->State.C6,
100.f * Flop->State.C7,
Shm->Cpu[cpu].PowerThermal.Limit[0],
Flop->Thermal.Temp,
Flop->Thermal.Sensor,
Shm->Cpu[cpu].PowerThermal.Limit[1]);
else
printf("#%02u OFF\n", cpu);
}
printf("\n" \
"%.*s" "Averages:" \
"%.*s" "Turbo C0(%%) C1(%%) C3(%%) C6(%%) C7(%%)" \
"%.*s" "TjMax:\n" \
"%.*s" "%6.2f %6.2f %6.2f %6.2f %6.2f %6.2f" \
"%.*s" "%3u C\n\n",
4, hSpace,
8, hSpace,
7, hSpace,
20, hSpace,
100.f * Shm->Proc.Avg.Turbo,
100.f * Shm->Proc.Avg.C0,
100.f * Shm->Proc.Avg.C1,
100.f * Shm->Proc.Avg.C3,
100.f * Shm->Proc.Avg.C6,
100.f * Shm->Proc.Avg.C7,
8, hSpace,
Shm->Cpu[0].PowerThermal.Target);
}
}
void Voltage(SHM_STRUCT *Shm)
{
unsigned int cpu = 0;
while (!BITVAL(Shutdown, 0)) {
while (!BITVAL(Shm->Proc.Sync, 0) && !BITVAL(Shutdown, 0))
nanosleep(&Shm->Proc.BaseSleep, NULL);
BITCLR(LOCKLESS, Shm->Proc.Sync, 0);
if (BITVAL(Shm->Proc.Sync, 63))
BITCLR(LOCKLESS, Shm->Proc.Sync, 63);
printf("CPU Freq(MHz) VID Vcore\n");
for (cpu = 0; (cpu < Shm->Proc.CPU.Count) && !BITVAL(Shutdown,0); cpu++)
if (!BITVAL(Shm->Cpu[cpu].OffLine, HW)) {
struct FLIP_FLOP *Flop =
&Shm->Cpu[cpu].FlipFlop[!Shm->Cpu[cpu].Toggle];
if (!BITVAL(Shm->Cpu[cpu].OffLine, OS))
printf("#%02u %7.2f %5d %5.4f\n",
cpu,
Flop->Relative.Freq,
Flop->Voltage.VID,
Flop->Voltage.Vcore);
else
printf("#%02u OFF\n", cpu);
}
}
}
void Instructions(SHM_STRUCT *Shm)
{
unsigned int cpu = 0;
while (!BITVAL(Shutdown, 0)) {
while (!BITVAL(Shm->Proc.Sync, 0) && !BITVAL(Shutdown, 0))
nanosleep(&Shm->Proc.BaseSleep, NULL);
BITCLR(LOCKLESS, Shm->Proc.Sync, 0);
if (BITVAL(Shm->Proc.Sync, 63))
BITCLR(LOCKLESS, Shm->Proc.Sync, 63);
printf("CPU IPS IPC CPI\n");
for (cpu=0; (cpu < Shm->Proc.CPU.Count) && !BITVAL(Shutdown,0); cpu++)
if (!BITVAL(Shm->Cpu[cpu].OffLine, HW)) {
struct FLIP_FLOP *Flop =
&Shm->Cpu[cpu].FlipFlop[!Shm->Cpu[cpu].Toggle];
if (!BITVAL(Shm->Cpu[cpu].OffLine, OS))
printf("#%02u %12.6f/s %12.6f/c %12.6f/i\n",
cpu,
Flop->State.IPS,
Flop->State.IPC,
Flop->State.CPI);
else
printf("#%02u\n", cpu);
}
printf("\n");
}
}
void Topology(SHM_STRUCT *Shm, void(*OutFunc)(char *output))
{
unsigned int cpu = 0, level = 0, nl = 6;
char line[16];
void printv(char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vsprintf(line, fmt, ap);
if (OutFunc == NULL)
if (!--nl) {
nl = 6;
printf("%s\n", line);
}
else
printf("%s", line);
else
OutFunc(line);
va_end(ap);
}
printv("CPU Apic ");printv(" Core Thread");printv(" Caches ");
printv(" (w)rite-Back");printv(" (i)nclusive ");printv(" ");
printv(" # ID ");printv(" ID ID ");printv(" L1-Inst Way ");
printv(" L1-Data Way ");printv(" L2 Way ");printv(" L3 Way ");
for (cpu = 0; cpu < Shm->Proc.CPU.Count; cpu++) {
printv("%02u%-4s%6d ",
cpu,
(Shm->Cpu[cpu].Topology.MP.BSP) ? ":BSP" : ":AP",
Shm->Cpu[cpu].Topology.ApicID);
printv("%6d %6d",
Shm->Cpu[cpu].Topology.CoreID,
Shm->Cpu[cpu].Topology.ThreadID);
for (level = 0; level < CACHE_MAX_LEVEL; level++) {
printv("%8u%3u%c%c",
Shm->Cpu[cpu].Topology.Cache[level].Size,
Shm->Cpu[cpu].Topology.Cache[level].Way,
Shm->Cpu[cpu].Topology.Cache[level].Feature.WriteBack?
'w' : 0x20,
Shm->Cpu[cpu].Topology.Cache[level].Feature.Inclusive?
'i' : 0x20);
}
}
}
void MemoryController(SHM_STRUCT *Shm, void(*OutFunc)(char *output))
{
unsigned int nl = 14;
unsigned short mc, cha, slot;
char line[8], fInt[16], hInt[2][8];
void printv(char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vsprintf(line, fmt, ap);
if (OutFunc == NULL)
if (!--nl) {
nl = 14;
printf("%s\n", line);
}
else
printf("%s", line);
else
OutFunc(line);
va_end(ap);
}
void iSplit(unsigned int sInt) {
sprintf(fInt, "%10u", sInt);
strncpy(hInt[0], &fInt[0], 5); hInt[0][5] = '\0';
strncpy(hInt[1], &fInt[5], 5); hInt[1][5] = '\0';
}
for (mc = 0; mc < Shm->Uncore.CtrlCount; mc++) {
printv("Contr"); printv("oller");
printv(" #%-3u", mc); printv(" "); printv(" ");
printv(" "); printv(" "); printv(" "); printv(" ");
printv(" "); printv(" ");
switch (Shm->Uncore.MC[mc].ChannelCount) {
case 1:
printv("Singl"); printv("e Cha"); printv("nnel ");
break;
case 2:
printv(" Dual"); printv(" Chan"); printv("nel ");
break;
case 3:
printv("Tripl"); printv("e Cha"); printv("nnel ");
break;
case 4:
printv(" Quad"); printv(" Chan"); printv("nel ");
break;
case 6:
printv(" Hexa"); printv(" Chan"); printv("nel ");
break;
case 8:
printv(" Octa"); printv(" Chan"); printv("nel ");
break;
default:
printv(" "); printv(" "); printv(" ");
break;
}
printv(" Bus "); printv("Rate ");
printv("%5llu", Shm->Uncore.Bus.Rate);
switch (Shm->Uncore.Unit.Bus_Rate) {
case 0b00:
printv(" MHz ");
break;
case 0b01:
printv(" MT/s");
break;
case 0b10:
printv(" MB/s");
break;
case 0b11:
printv(" ");
break;
}
printv(" ");
printv(" Bus "); printv("Speed");
printv("%5llu", Shm->Uncore.Bus.Speed);
switch (Shm->Uncore.Unit.BusSpeed) {
case 0b00:
printv(" MHz ");
break;
case 0b01:
printv(" MT/s");
break;
case 0b10:
printv(" MB/s");
break;
case 0b11:
printv(" ");
break;
}
printv(" ");
printv("DRAM "); printv("Speed");
printv("%5llu", Shm->Uncore.CtrlSpeed);
switch (Shm->Uncore.Unit.DDRSpeed) {
case 0b00:
printv(" MHz ");
break;
case 0b01:
printv(" MT/s");
break;
case 0b10:
printv(" MB/s");
break;
case 0b11:
printv(" ");
break;
}
printv(" "); printv(" ");
printv(" "); printv(" "); printv(" "); printv(" ");
printv(" "); printv(" "); printv(" "); printv(" ");
printv(" "); printv(" "); printv(" "); printv(" ");
printv(" Cha ");
printv(" CL");printv(" RCD");printv(" RP");printv(" RAS");
printv(" RRD");printv(" RFC");printv(" WR");printv(" RTPr");
printv(" WTPr");printv(" FAW");printv(" B2B");printv(" CWL");
printv(" Rate");
for (cha = 0; cha < Shm->Uncore.MC[mc].ChannelCount; cha++) {
printv("\x20\x20#%-2u", cha);
printv("%5u", Shm->Uncore.MC[mc].Channel[cha].Timing.tCL);
printv("%5u", Shm->Uncore.MC[mc].Channel[cha].Timing.tRCD);
printv("%5u", Shm->Uncore.MC[mc].Channel[cha].Timing.tRP);
printv("%5u", Shm->Uncore.MC[mc].Channel[cha].Timing.tRAS);
printv("%5u", Shm->Uncore.MC[mc].Channel[cha].Timing.tRRD);
printv("%5u", Shm->Uncore.MC[mc].Channel[cha].Timing.tRFC);
printv("%5u", Shm->Uncore.MC[mc].Channel[cha].Timing.tWR);
printv("%5u", Shm->Uncore.MC[mc].Channel[cha].Timing.tRTPr);
printv("%5u", Shm->Uncore.MC[mc].Channel[cha].Timing.tWTPr);
printv("%5u", Shm->Uncore.MC[mc].Channel[cha].Timing.tFAW);
printv("%5u", Shm->Uncore.MC[mc].Channel[cha].Timing.B2B);
printv("%5u", Shm->Uncore.MC[mc].Channel[cha].Timing.tCWL);
printv("%4uN",Shm->Uncore.MC[mc].Channel[cha].Timing.CMD_Rate);
}
printv(" ");
printv(" ddWR"); printv(" drWR"); printv(" srWR");
printv(" ddRW"); printv(" drRW"); printv(" srRW");
printv(" ddRR"); printv(" drRR"); printv(" srRR");
printv(" ddWW"); printv(" drWW"); printv(" srWW");
printv(" ECC");
for (cha = 0; cha < Shm->Uncore.MC[mc].ChannelCount; cha++) {
printv("\x20\x20#%-2u", cha);
printv("%5u", Shm->Uncore.MC[mc].Channel[cha].Timing.tddWrTRd);
printv("%5u", Shm->Uncore.MC[mc].Channel[cha].Timing.tdrWrTRd);
printv("%5u", Shm->Uncore.MC[mc].Channel[cha].Timing.tsrWrTRd);
printv("%5u", Shm->Uncore.MC[mc].Channel[cha].Timing.tddRdTWr);
printv("%5u", Shm->Uncore.MC[mc].Channel[cha].Timing.tdrRdTWr);
printv("%5u", Shm->Uncore.MC[mc].Channel[cha].Timing.tsrRdTWr);
printv("%5u", Shm->Uncore.MC[mc].Channel[cha].Timing.tddRdTRd);
printv("%5u", Shm->Uncore.MC[mc].Channel[cha].Timing.tdrRdTRd);
printv("%5u", Shm->Uncore.MC[mc].Channel[cha].Timing.tsrRdTRd);
printv("%5u", Shm->Uncore.MC[mc].Channel[cha].Timing.tddWrTWr);
printv("%5u", Shm->Uncore.MC[mc].Channel[cha].Timing.tdrWrTWr);
printv("%5u", Shm->Uncore.MC[mc].Channel[cha].Timing.tsrWrTWr);
printv("%4u ", Shm->Uncore.MC[mc].Channel[cha].Timing.ECC);
}
printv(" "); printv(" ");
printv(" "); printv(" "); printv(" "); printv(" ");
printv(" "); printv(" "); printv(" "); printv(" ");
printv(" "); printv(" "); printv(" "); printv(" ");
for (cha = 0; cha < Shm->Uncore.MC[mc].ChannelCount; cha++) {
printv(" DIMM"); printv(" Geom"); printv("etry ");printv("for c");
printv("hanne"); printv("l #%-2u", cha);
printv(" "); printv(" "); printv(" ");printv(" ");
printv(" "); printv(" "); printv(" ");printv(" ");
printv(" ");
printv(" Slot"); printv(" Bank"); printv(" Rank");
printv(" "); printv("Rows "); printv(" Col");printv("umns ");
printv(" Me"); printv("mory "); printv("Size ");printv("(MB) ");
printv(" "); printv(" ");
for (slot = 0; slot < Shm->Uncore.MC[mc].SlotCount; slot++) {
printv(" ");
printv("\x20\x20#%-2u", slot);
printv("%5u", Shm->Uncore.MC[mc].Channel[cha].DIMM[slot].Banks);
printv("%5u", Shm->Uncore.MC[mc].Channel[cha].DIMM[slot].Ranks);
iSplit(Shm->Uncore.MC[mc].Channel[cha].DIMM[slot].Rows);
printv("%5s", hInt[0]);
printv("%5s", hInt[1]);
iSplit(Shm->Uncore.MC[mc].Channel[cha].DIMM[slot].Cols);
printv("%5s", hInt[0]);
printv("%5s", hInt[1]);
printv(" ");
iSplit(Shm->Uncore.MC[mc].Channel[cha].DIMM[slot].Size);
printv("%5s", hInt[0]);
printv("%5s", hInt[1]);
printv(" "); printv(" "); printv(" ");
}
}
}
}
typedef struct {
CUINT col,
row;
} Coordinate;
typedef struct {
CSINT horz,
vert;
} CoordShift;
typedef struct {
CUINT wth,
hth;
} CoordSize;
typedef union {
unsigned char value;
struct {
unsigned char fg: 3-0,
un: 4-3,
bg: 7-4,
bf: 8-7;
};
} Attribute;
#define MakeAttr(_fg, _un, _bg, _bf) \
({Attribute _attr={.fg = _fg,.un = _un,.bg = _bg,.bf = _bf}; _attr;})
#define HDK {.fg = BLACK, .bg = BLACK, .bf = 1}
#define HBK {.fg = BLUE, .bg = BLACK, .bf = 1}
#define HRK {.fg = RED, .bg = BLACK, .bf = 1}
#define HGK {.fg = GREEN, .bg = BLACK, .bf = 1}
#define HYK {.fg = YELLOW, .bg = BLACK, .bf = 1}
#define HWK {.fg = WHITE, .bg = BLACK, .bf = 1}
#define HKB {.fg = BLACK, .bg = BLUE, .bf = 1}
#define HWB {.fg = WHITE, .bg = BLUE, .bf = 1}
#define HKW {.fg = BLACK, .bg = WHITE, .bf = 1}
#define HCK {.fg = CYAN, .bg = BLACK, .bf = 1}
#define HWC {.fg = WHITE, .bg = CYAN, .bf = 1}
#define _HWK {.fg = WHITE, .bg = BLACK, .un = 1, .bf = 1}
#define _HWB {.fg = WHITE, .bg = BLUE, .un = 1, .bf = 1}
#define _HKW {.fg = BLACK, .bg = WHITE, .un = 1, .bf = 1}
#define _HCK {.fg = CYAN, .bg = BLACK, .un = 1, .bf = 1}
#define LDK {.fg = BLACK, .bg = BLACK}
#define LKW {.fg = BLACK, .bg = WHITE}
#define LRK {.fg = RED, .bg = BLACK}
#define LYK {.fg = YELLOW, .bg = BLACK}
#define LBK {.fg = BLUE, .bg = BLACK}
#define LBW {.fg = BLUE, .bg = WHITE}
#define LCK {.fg = CYAN, .bg = BLACK}
#define LWK {.fg = WHITE, .bg = BLACK}
#define LWB {.fg = WHITE, .bg = BLUE}
#define LKC {.fg = BLACK, .bg = CYAN}
#define _LKW {.fg = BLACK, .bg = WHITE, .un = 1}
#define _LBW {.fg = BLUE, .bg = WHITE, .un = 1}
#define _LWK {.fg = WHITE, .bg = BLACK, .un = 1}
#define _LCK {.fg = CYAN, .bg = BLACK, .un = 1}
#define MAKE_TITLE_UNFOCUS MakeAttr(BLACK, 0, BLUE, 1)
#define MAKE_TITLE_FOCUS MakeAttr(WHITE, 0, CYAN, 1)
#define MAKE_BORDER_UNFOCUS MakeAttr(BLACK, 0, BLUE, 1)
#define MAKE_BORDER_FOCUS MakeAttr(WHITE, 0, BLUE, 1)
#define MAKE_SELECT_UNFOCUS MakeAttr(WHITE, 0, BLACK, 0)
#define MAKE_SELECT_FOCUS MakeAttr(BLACK, 0, CYAN, 0)
#define MAKE_PRINT_UNFOCUS MakeAttr(WHITE, 0, BLACK, 0)
#define MAKE_PRINT_FOCUS MakeAttr(WHITE, 0, BLACK, 1)
#define MAKE_PRINT_DROP MakeAttr(BLACK, 0, WHITE, 0)
typedef unsigned char ASCII;
#define LayerDeclare(_len) \
struct { \
Coordinate origin; \
size_t length; \
Attribute attr[_len]; \
ASCII code[_len]; \
}
typedef struct {
ASCII *code;
Attribute *attr;
CoordSize size;
} Layer;
typedef struct {
CoordSize size;
Coordinate origin,
select;
CoordShift scroll;
} Matrix;
typedef struct {
SCANKEY quick;
Attribute *attr;
ASCII *item;
size_t length;
} TCell;
typedef struct _Win {
Layer *layer;
unsigned long long id;
struct _Win *prev,
*next;
struct {
void (*Print)(struct _Win *win, void *list);
struct {
int (*Enter)(SCANKEY *scan, struct _Win *win);
void (*Escape)(struct _Win *win);
void (*Left)(struct _Win *win);
void (*Right)(struct _Win *win);
void (*Down)(struct _Win *win);
void (*Up)(struct _Win *win);
void (*Home)(struct _Win *win);
void (*End)(struct _Win *win);
void (*PgUp)(struct _Win *win);
void (*PgDw)(struct _Win *win);
void (*WinLeft)(struct _Win *win);
void (*WinRight)(struct _Win *win);
void (*WinDown)(struct _Win *win);
void (*WinUp)(struct _Win *win);
} key;
struct {
Attribute select,
border,
title;
} color[2];
char *title;
} hook;
Matrix matrix;
TCell *cell;
size_t dim;
struct {
size_t rowLen,
titleLen;
CUINT bottomRow;
} lazyComp;
} Window;
typedef struct {
Window *head;
} WinList;
typedef void (*TCELLFUNC)(Window*, void*);
typedef int (*KEYFUNC)(SCANKEY*, Window*);
typedef void (*WINFUNC)(Window*);
typedef char REGSTR[];
typedef char *REGPTR;
void HookCellFunc(TCELLFUNC *with, TCELLFUNC what) { *with=what; }
void HookKeyFunc(KEYFUNC *with, KEYFUNC what) { *with=what; }
void HookWinFunc(WINFUNC *with, WINFUNC what) { *with=what; }
void HookAttrib(Attribute *with, Attribute what) { with->value=what.value; }
void HookString(REGSTR *with, REGSTR what) { strcpy(*with, what); }
void HookPointer(REGPTR *with, REGPTR what)
{
if ((*with = realloc(*with, 1 + strlen(what))) != NULL)
strcpy(*with, what);
}
#define StoreWindow(win, with, what) \
( \
__builtin_choose_expr(__builtin_types_compatible_p( \
typeof(win->hook with), typeof(TCELLFUNC)), HookCellFunc, \
__builtin_choose_expr(__builtin_types_compatible_p( \
typeof(win->hook with), typeof(KEYFUNC)), HookKeyFunc, \
__builtin_choose_expr(__builtin_types_compatible_p( \
typeof(win->hook with), typeof(WINFUNC)), HookWinFunc, \
__builtin_choose_expr(__builtin_types_compatible_p( \
typeof(win->hook with), typeof(Attribute)), HookAttrib, \
__builtin_choose_expr(__builtin_types_compatible_p( \
typeof(win->hook with), typeof(REGSTR)), HookString, \
__builtin_choose_expr(__builtin_types_compatible_p( \
typeof(win->hook with), typeof(REGPTR)), HookPointer, \
(void)0)))))) \
(&(win->hook with), what) \
)
#define LayerAt(layer, plane, col, row) \
layer->plane[col + (row * layer->size.wth)]
#define LayerFillAt(layer, col, row, len, source, attrib) \
({ \
memset(&LayerAt(layer, attr, col, row), attrib.value, len); \
memcpy(&LayerAt(layer, code, col, row), source, len); \
})
#define LayerCopyAt(layer, col, row, len, attrib, source) \
({ \
memcpy(&LayerAt(layer, attr, col, row), attrib, len); \
memcpy(&LayerAt(layer, code, col, row), source, len); \
})
#define TCellAt(win, col, row) \
win->cell[col + (row * win->matrix.size.wth)]
#define GetHead(list) (list)->head
#define SetHead(list, win) GetHead(list) = win
#define SetDead(list) SetHead(list, NULL)
#define IsHead(list, win) (GetHead(list) == win)
#define IsDead(list) (GetHead(list) == NULL)
#define IsCycling(win) ((win->next == win) && (win->prev == win))
#define GetFocus(list) GetHead(list)
void DestroyLayer(Layer *layer)
{
if (layer != NULL) {
if (layer->attr != NULL) {
free(layer->attr);
layer->attr = NULL;
}
if (layer->code != NULL) {
free(layer->code);
layer->code = NULL;
}
}
}
void CreateLayer(Layer *layer, CoordSize size)
{
if (layer != NULL) {
layer->size.wth = size.wth;
layer->size.hth = size.hth;
size_t len = layer->size.wth * layer->size.hth;
layer->attr = calloc(len, sizeof(Attribute));
layer->code = calloc(len, sizeof(ASCII));
}
}
#define ResetLayer(layer) \
memset(layer->attr, 0, layer->size.wth * layer->size.hth); \
memset(layer->code, 0, layer->size.wth * layer->size.hth);
void FreeAllTCells(Window *win)
{
if (win->cell != NULL) {
CUINT i;
for (i = 0; i < win->dim; i++)
{
free(win->cell[i].attr);
free(win->cell[i].item);
}
free(win->cell);
win->cell = NULL;
}
}
void AllocCopyAttr(TCell *cell, Attribute attrib[])
{
if ((attrib != NULL) && (cell->attr = malloc(cell->length)) != NULL)
memcpy(&cell->attr->value, &attrib->value, cell->length);
}
void AllocFillAttr(TCell *cell, Attribute attrib)
{
if ((cell->attr = malloc(cell->length)) != NULL)
memset(&cell->attr->value, attrib.value, cell->length);
}
void AllocCopyItem(TCell *cell, ASCII *item)
{
if ((cell->item = malloc(cell->length)) != NULL)
strncpy((char *)cell->item, (char *)item, cell->length);
}
#define StoreTCell(win, shortkey, item, attrib) \
({ \
if (item != NULL) { \
win->dim++; \
win->lazyComp.bottomRow = (win->dim / win->matrix.size.wth) \
- win->matrix.size.hth; \
\
if ((win->cell = realloc(win->cell,sizeof(TCell) * win->dim)) != NULL)\
{ \
win->cell[win->dim - 1].quick.key = shortkey; \
win->cell[win->dim - 1].length = strlen((char *)item); \
\
__builtin_choose_expr(__builtin_types_compatible_p( \
typeof(attrib), typeof(Attribute[])), AllocCopyAttr, \
__builtin_choose_expr(__builtin_types_compatible_p( \
typeof(attrib), typeof(Attribute)), AllocFillAttr, \
(void)0)) \
(&(win->cell[win->dim - 1]), attrib); \
\
AllocCopyItem(&win->cell[win->dim - 1], (ASCII *)item); \
} \
} \
})
void DestroyWindow(Window *win)
{
if (win != NULL) {
if (win->hook.title != NULL) {
free(win->hook.title);
win->hook.title = NULL;
win->lazyComp.titleLen = 0;
}
FreeAllTCells(win);
free(win);
win = NULL;
}
}
Window *CreateWindow( Layer *layer, unsigned long long id,
CUINT width, CUINT height,
CUINT oCol, CUINT oRow)
{
Window *win = calloc(1, sizeof(Window));
if (win != NULL) {
win->layer = layer;
win->id = id;
win->matrix.size.wth = width;
win->matrix.size.hth = height;
win->matrix.origin.col = oCol;
win->matrix.origin.row = oRow;
Attribute select[2] = {
MAKE_SELECT_UNFOCUS,
MAKE_SELECT_FOCUS
},
border[2] = {
MAKE_BORDER_UNFOCUS,
MAKE_BORDER_FOCUS
},
title[2] = {
MAKE_TITLE_UNFOCUS,
MAKE_TITLE_FOCUS
};
int i;
for (i = 0; i < 2; i++) {
win->hook.color[i].select = select[i];
win->hook.color[i].border = border[i];
win->hook.color[i].title = title[i];
}
}
return(win);
}
#define RemoveWinList(win, list) \
({ \
win->prev->next = win->next; \
win->next->prev = win->prev; \
})
#define AppendWinList(win, list) \
({ \
win->prev = GetHead(list); \
win->next = GetHead(list)->next; \
GetHead(list)->next->prev = win; \
GetHead(list)->next = win; \
})
void RemoveWindow(Window *win, WinList *list)
{
RemoveWinList(win, list);
if (IsCycling(GetHead(list)))
SetDead(list);
else if (IsHead(list, win))
/*Auto shift*/ SetHead(list, win->next);
DestroyWindow(win);
}
void AppendWindow(Window *win, WinList *list)
{
if (win != NULL) {
if (!IsDead(list))
AppendWinList(win, list);
else {
// Dead head, now cycling
win->prev = win;
win->next = win;
}
SetHead(list, win);
}
}
void DestroyAllWindows(WinList *list)
{
while (!IsDead(list))
RemoveWindow(GetHead(list), list);
}
void AnimateWindow(int rotate, WinList *list)
{
if (!IsDead(list))
SetHead(list, rotate == 1 ? GetHead(list)->next : GetHead(list)->prev);
}
Window *SearchWinListById(unsigned long long id, WinList *list)
{
Window *win = NULL;
if (!IsDead(list)) {
Window *walker = GetHead(list);
do {
if (walker->id == id)
win = walker;
walker = walker->prev;
} while (!IsHead(list, walker) && (win == NULL));
}
return(win);
}
void PrintContent(Window *win, WinList *list, CUINT col, CUINT row)
{
if ((win->matrix.select.col == col)
&& (win->matrix.select.row == row))
LayerFillAt(win->layer,
(win->matrix.origin.col
+ (col * TCellAt(win,
(win->matrix.scroll.horz + col),
(win->matrix.scroll.vert + row)).length)),
(win->matrix.origin.row + row),
TCellAt(win,
(win->matrix.scroll.horz + col),
(win->matrix.scroll.vert + row)).length,
TCellAt(win,
(win->matrix.scroll.horz + col),
(win->matrix.scroll.vert + row)).item,
win->hook.color[(GetFocus(list) == win)].select);
else if (GetFocus(list) == win)
LayerCopyAt(win->layer,
(win->matrix.origin.col
+ (col * TCellAt(win,
(win->matrix.scroll.horz + col),
(win->matrix.scroll.vert + row)).length)),
(win->matrix.origin.row + row),
TCellAt(win,
(win->matrix.scroll.horz + col),
(win->matrix.scroll.vert + row)).length,
TCellAt(win,
(win->matrix.scroll.horz + col),
(win->matrix.scroll.vert + row)).attr,
TCellAt(win,
(win->matrix.scroll.horz + col),
(win->matrix.scroll.vert + row)).item);
else {
LayerFillAt(win->layer,
(win->matrix.origin.col
+ (col * TCellAt(win,
(win->matrix.scroll.horz + col),
(win->matrix.scroll.vert + row)).length)),
(win->matrix.origin.row + row),
TCellAt(win,
(win->matrix.scroll.horz + col),
(win->matrix.scroll.vert + row)).length,
TCellAt(win,
(win->matrix.scroll.horz + col),
(win->matrix.scroll.vert + row)).item,
win->hook.color[0].select);
}
}
void ForEachCellPrint(Window *win, WinList *list)
{
CUINT col, row;
Attribute border = win->hook.color[(GetFocus(list) == win)].border;
if (win->lazyComp.rowLen == 0)
for (col=0, win->lazyComp.rowLen=2; col < win->matrix.size.wth; col++)
win->lazyComp.rowLen += TCellAt(win, col, 0).length;
// Top, Left Border Corner
LayerAt(win->layer, attr,
(win->matrix.origin.col - 1),
(win->matrix.origin.row - 1)) = border;
LayerAt(win->layer, code,
(win->matrix.origin.col - 1),
(win->matrix.origin.row - 1)) = 0x20;
// Top Border Line
if (win->hook.title == NULL)
LayerFillAt(win->layer,
win->matrix.origin.col,
(win->matrix.origin.row - 1),
(win->lazyComp.rowLen - 2), hLine, border);
else {
if (win->lazyComp.titleLen == 0)
win->lazyComp.titleLen=strlen(win->hook.title);
size_t halfLeft=(win->lazyComp.rowLen - win->lazyComp.titleLen) / 2;
size_t halfRight = halfLeft
+ (win->lazyComp.rowLen - win->lazyComp.titleLen) % 2;
// Top, Half-Left Border Line
LayerFillAt(win->layer,
win->matrix.origin.col,
(win->matrix.origin.row - 1),
halfLeft, hLine, border);
// Top, Centered Border Title
LayerFillAt(win->layer,
(halfLeft + (win->matrix.origin.col - 1)),
(win->matrix.origin.row - 1),
win->lazyComp.titleLen, win->hook.title,
((GetFocus(list) == win) ?
win->hook.color[1].title
: win->hook.color[0].title));
// Top, Half-Right Border Line
LayerFillAt(win->layer,
(halfLeft + win->lazyComp.titleLen
+ (win->matrix.origin.col - 1)),
(win->matrix.origin.row - 1),
(halfRight - 1), hLine, border);
}
// Top, Right Border Corner
LayerAt(win->layer, attr,
(win->matrix.origin.col + win->lazyComp.rowLen - 2),
(win->matrix.origin.row - 1)) = border;
LayerAt(win->layer, code,
(win->matrix.origin.col + win->lazyComp.rowLen - 2),
(win->matrix.origin.row - 1)) = 0x20;
for (row = 0; row < win->matrix.size.hth; row++) {
// Left Side Border Column
LayerAt( win->layer, attr,
(win->matrix.origin.col - 1),
(win->matrix.origin.row + row)) = border;
LayerAt( win->layer, code,
(win->matrix.origin.col - 1),
(win->matrix.origin.row + row)) = 0x20;
for (col = 0; col < win->matrix.size.wth; col++)
PrintContent(win, list, col, row);
// Right Side Border Column
LayerAt( win->layer, attr,
(win->matrix.origin.col
+ col * TCellAt(win, 0, 0).length),
(win->matrix.origin.row + row)) = border;
LayerAt( win->layer, code,
(win->matrix.origin.col
+ col * TCellAt(win, 0, 0).length),
(win->matrix.origin.row + row)) = 0x20;
}
// Bottom, Left Border Corner
LayerAt(win->layer, attr,
(win->matrix.origin.col - 1),
(win->matrix.origin.row + win->matrix.size.hth)) = border;
LayerAt(win->layer, code,
(win->matrix.origin.col - 1),
(win->matrix.origin.row + win->matrix.size.hth)) = 0x20;
// Bottom Border Line
LayerFillAt(win->layer,
win->matrix.origin.col,
(win->matrix.origin.row + win->matrix.size.hth),
(win->lazyComp.rowLen - 2), hLine, border);
// Bottom, Right Border Corner
LayerAt(win->layer, attr,
(win->matrix.origin.col + win->lazyComp.rowLen - 2),
(win->matrix.origin.row + win->matrix.size.hth)) = border;
LayerAt(win->layer, code,
(win->matrix.origin.col + win->lazyComp.rowLen - 2),
(win->matrix.origin.row + win->matrix.size.hth)) = 0x20;
}
void EraseWindowWithBorder(Window *win)
{ // Care about the four window side borders.
CUINT row;
for (row = 0; row < win->matrix.size.hth + 2; row++) {
Coordinate origin = {
.col = win->matrix.origin.col - 1,
.row = (win->matrix.origin.row - 1) + row
};
size_t len = win->lazyComp.rowLen + 1;
memset(&LayerAt(win->layer, attr, origin.col,origin.row),0,len);
memset(&LayerAt(win->layer, code, origin.col,origin.row),0,len);
}
}
void MotionReset_Win(Window *win)
{
win->matrix.scroll.horz = win->matrix.select.col = 0;
win->matrix.scroll.vert = win->matrix.select.row = 0;
}
void MotionLeft_Win(Window *win)
{
if (win->matrix.select.col > 0)
win->matrix.select.col--;
else
win->matrix.select.col = win->matrix.size.wth - 1;
}
void MotionRight_Win(Window *win)
{
if (win->matrix.select.col < win->matrix.size.wth - 1)
win->matrix.select.col++;
else
win->matrix.select.col = 0;
}
void MotionUp_Win(Window *win)
{
if (win->matrix.select.row > 0)
win->matrix.select.row--;
else if (win->matrix.scroll.vert > 0)
win->matrix.scroll.vert--;
}
void MotionDown_Win(Window *win)
{
if (win->matrix.select.row < win->matrix.size.hth - 1)
win->matrix.select.row++;
else if (win->matrix.scroll.vert < win->lazyComp.bottomRow)
win->matrix.scroll.vert++;
}
void MotionHome_Win(Window *win)
{
win->matrix.select.col = 0;
}
void MotionEnd_Win(Window *win)
{
win->matrix.select.col = win->matrix.size.wth - 1;
}
void MotionPgUp_Win(Window *win)
{
if (win->matrix.scroll.vert >= win->matrix.size.hth)
win->matrix.scroll.vert -= win->matrix.size.hth;
else
win->matrix.scroll.vert = 0;
}
void MotionPgDw_Win(Window *win)
{
if(win->matrix.scroll.vert < (win->lazyComp.bottomRow - win->matrix.size.hth))
win->matrix.scroll.vert += win->matrix.size.hth;
else
win->matrix.scroll.vert = win->lazyComp.bottomRow;
}
void MotionOriginLeft_Win(Window *win)
{
if (win->matrix.origin.col > 1) {
EraseWindowWithBorder(win);
win->matrix.origin.col--;
}
}
void MotionOriginRight_Win(Window *win)
{ // Care about the right-side window border.
CUINT maxVisibleCol=KMIN(MAX_WIDTH - 1,GetScreenSize().width)
- win->lazyComp.rowLen;
if (win->matrix.origin.col <= maxVisibleCol) {
EraseWindowWithBorder(win);
win->matrix.origin.col++;
}
}
void MotionOriginUp_Win(Window *win)
{
if (win->matrix.origin.row > 1) {
EraseWindowWithBorder(win);
win->matrix.origin.row--;
}
}
void MotionOriginDown_Win(Window *win)
{ // Care about the bottom window border.
CUINT maxVisibleRow=KMIN(MAX_HEIGHT - 1,GetScreenSize().height)
- win->matrix.size.hth - 1;
if (win->matrix.origin.row < maxVisibleRow) {
EraseWindowWithBorder(win);
win->matrix.origin.row++;
}
}
int Motion_Trigger(SCANKEY *scan, Window *win, WinList *list)
{
switch (scan->key) {
case SCANKEY_ESC:
{
Layer *thisLayer = win->layer;
if (win->hook.key.Escape != NULL)
win->hook.key.Escape(win);
else
RemoveWindow(win, list);
ResetLayer(thisLayer);
}
break;
case SCANKEY_TAB:
AnimateWindow(1, list);
break;
case SCANKEY_SHIFT_TAB:
case SCANCON_SHIFT_TAB:
AnimateWindow(0, list);
break;
case SCANKEY_LEFT:
if (win->hook.key.Left != NULL)
win->hook.key.Left(win);
break;
case SCANKEY_RIGHT:
if (win->hook.key.Right != NULL)
win->hook.key.Right(win);
break;
case SCANKEY_DOWN:
if (win->hook.key.Down != NULL)
win->hook.key.Down(win);
break;
case SCANKEY_UP:
if (win->hook.key.Up != NULL)
win->hook.key.Up(win);
break;
case SCANKEY_HOME:
case SCANCON_HOME:
if (win->hook.key.Home != NULL)
win->hook.key.Home(win);
break;
case SCANKEY_END:
case SCANCON_END:
if (win->hook.key.End != NULL)
win->hook.key.End(win);
break;
case SCANKEY_PGUP:
if (win->hook.key.PgUp != NULL)
win->hook.key.PgUp(win);
break;
case SCANKEY_PGDW:
if (win->hook.key.PgDw != NULL)
win->hook.key.PgDw(win);
break;
case SCANKEY_SHIFT_d:
if (win->hook.key.WinRight != NULL)
win->hook.key.WinRight(win);
break;
case SCANKEY_SHIFT_a:
case SCANKEY_SHIFT_q:
if (win->hook.key.WinLeft != NULL)
win->hook.key.WinLeft(win);
break;
case SCANKEY_SHIFT_w:
case SCANKEY_SHIFT_z:
if (win->hook.key.WinUp != NULL)
win->hook.key.WinUp(win);
break;
case SCANKEY_SHIFT_s:
if (win->hook.key.WinDown != NULL)
win->hook.key.WinDown(win);
break;
case SCANKEY_ENTER:
if (win->hook.key.Enter != NULL)
return(win->hook.key.Enter(scan, win));
// fallthrough
default:
return(-1);
}
return(0);
}
enum VIEW {
V_FREQ,
V_INST,
V_CYCLES,
V_CSTATES,
V_PACKAGE,
V_TASKS,
V_INTR,
V_VOLTAGE
};
#define LOAD_LEAD 4
void Top(SHM_STRUCT *Shm, char option)
{
/*
SCREEN
__________________________
| MENU |
| T |
| L HEADER |
| R |
|--E ----------------------|
| A |
| A LOAD |
| I |
|--D ----------------------|
| L |
| I MONITOR |
| I |
|--N ----------------------|
| N |
| G FOOTER |
| G |
`__________________________'
*/
Layer *sLayer = NULL,
*dLayer = NULL,
*wLayer = NULL,
*fuze = NULL;
WinList winList = {.head = NULL};
struct {
struct {
unsigned int
layout : 1-0, // Draw layout
clear : 2-1, // Clear screen
height : 3-2, // Valid height
width : 4-3, // Valid width
daemon : 5-4, // Draw dynamic
taskVal : 6-5, // Display task's value
avgOrPC : 7-6, // C-states average || % pkg states
_pad8 : 8-7,
disposal: 16-8,
_pad16 : 32-16;
};
enum VIEW view;
} drawFlag = {
.layout = 0,
.clear = 0,
.height = 0,
.width = 0,
.daemon = 0,
.taskVal= 0,
.avgOrPC= 0,
.view = V_FREQ,
.disposal= (option == 'd') ? 1 : 0
};
SCREEN_SIZE drawSize = {.width = 0, .height = 0};
unsigned int cpu = 0, prevTopFreq = 0, digit[9], iClock = 0, ratioCount = 0;
unsigned long prevFreeRAM = 0;
int prevTaskCount = 0;
CUINT loadWidth = 0;
CUINT MIN_HEIGHT = 0,
TOP_UPPER_FIRST = 1 + TOP_HEADER_ROW,
TOP_LOWER_FIRST = 2+ TOP_HEADER_ROW + Shm->Proc.CPU.Count,
TOP_LOWER_LAST = 2 + TOP_HEADER_ROW + 2 * Shm->Proc.CPU.Count,
TOP_FOOTER_LAST = 2 + TOP_HEADER_ROW + TOP_FOOTER_ROW
+ 2 * Shm->Proc.CPU.Count;
double minRatio=Shm->Proc.Boost[0], maxRatio=Shm->Proc.Boost[LAST_BOOST],
medianRatio=(minRatio + maxRatio) / 2, availRatio[MAX_BOOST]={minRatio};
typedef char HBCLK[11 + 1];
HBCLK *hBClk;
char *buffer = NULL, *console = NULL;
Coordinate *cTask;
for (unsigned int idx = 1; idx < MAX_BOOST; idx++)
if (Shm->Proc.Boost[idx] != 0) {
int sort = Shm->Proc.Boost[idx] - availRatio[ratioCount];
if (sort < 0) {
availRatio[ratioCount + 1] = availRatio[ratioCount];
availRatio[ratioCount++] = Shm->Proc.Boost[idx];
}
else if (sort > 0)
availRatio[++ratioCount] = Shm->Proc.Boost[idx];
}
ratioCount++;
#define EraseTCell_Menu(win) \
( \
{ \
CoordShift shift = { \
.horz = win->matrix.scroll.horz + win->matrix.select.col,\
.vert = win->matrix.scroll.vert + row \
}; \
Coordinate cell = { \
.col = (win->matrix.origin.col \
+ (win->matrix.select.col \
* TCellAt(win, shift.horz, shift.vert).length)), \
(win->matrix.origin.row + row), \
.row = win->matrix.origin.row + row \
}; \
memset(&LayerAt(win->layer, attr, cell.col, cell.row), \
0, \
TCellAt(win, shift.horz, shift.vert).length); \
memset(&LayerAt(win->layer, code, cell.col, cell.row), \
0, \
TCellAt(win, shift.horz, shift.vert).length); \
} \
)
void ForEachCellPrint_Menu(Window *win, void *plist)
{
WinList *list = (WinList *) plist;
CUINT col, row;
size_t len;
if (win->lazyComp.rowLen == 0)
for (col = 0; col < win->matrix.size.wth; col++)
win->lazyComp.rowLen += TCellAt(win, col, 0).length;
if (win->matrix.origin.col > 0)
LayerFillAt( win->layer,
0,
win->matrix.origin.row,
win->matrix.origin.col, hSpace,
win->hook.color[0].title);
for (col = 0; col < win->matrix.size.wth; col++)
PrintContent(win, list, col, 0);
for (row = 1; row < win->matrix.size.hth; row++)
if (TCellAt(win,
(win->matrix.scroll.horz + win->matrix.select.col),
(win->matrix.scroll.vert + row)).quick.key != SCANKEY_VOID)
PrintContent(win, list, win->matrix.select.col, row);
if((len=drawSize.width-win->lazyComp.rowLen-win->matrix.origin.col) > 0)
LayerFillAt( win->layer,
win->matrix.origin.col + win->lazyComp.rowLen,
win->matrix.origin.row,
len, hSpace,
win->hook.color[0].title);
}
void ForEachCellPrint_Drop(Window *win, void *plist)
{
WinList *list = (WinList *) plist;
CUINT col, row;
if (win->lazyComp.rowLen == 0)
for (col = 0; col < win->matrix.size.wth; col++)
win->lazyComp.rowLen += TCellAt(win, col, 0).length;
for (row = 0; row < win->matrix.size.hth; row++)
if (TCellAt(win,
(win->matrix.scroll.horz + win->matrix.select.col),
(win->matrix.scroll.vert + row)).quick.key != SCANKEY_VOID)
PrintContent(win, list, win->matrix.select.col, row);
}
int MotionEnter_Cell(SCANKEY *scan, Window *win)
{
if ((scan->key = TCellAt(win,
( win->matrix.select.col
+ win->matrix.scroll.horz),
( win->matrix.select.row
+ win->matrix.scroll.vert)
).quick.key) != SCANKEY_NULL) {
SCANKEY closeKey = {.key = SCANKEY_ESC};
Motion_Trigger(&closeKey, win,&winList);
return(1);
} else
return(0);
}
void MotionEnd_Cell(Window *win)
{
win->matrix.scroll.vert = win->lazyComp.bottomRow;
win->matrix.select.row = win->matrix.size.hth - 1;
}
void MotionLeft_Menu(Window *win)
{
CUINT row;
for (row = 1; row < win->matrix.size.hth; row++)
EraseTCell_Menu(win);
if (win->matrix.select.col > 0)
win->matrix.select.col--;
else
win->matrix.select.col = win->matrix.size.wth - 1;
win->matrix.select.row = 0;
}
void MotionRight_Menu(Window *win)
{
CUINT row;
for (row = 1; row < win->matrix.size.hth; row++)
EraseTCell_Menu(win);
if (win->matrix.select.col < win->matrix.size.wth - 1)
win->matrix.select.col++;
else
win->matrix.select.col = 0;
win->matrix.select.row = 0;
}
void MotionUp_Menu(Window *win)
{
CUINT row = win->matrix.select.row;
if (win->matrix.select.row > 0)
row--;
if (TCellAt(win,
(win->matrix.scroll.horz + win->matrix.select.col),
(win->matrix.scroll.vert + row)).quick.key != SCANKEY_VOID)
win->matrix.select.row = row;
}
void MotionDown_Menu(Window *win)
{
CUINT row = win->matrix.select.row;
if (row < win->matrix.size.hth - 1)
row++;
if (TCellAt(win,
(win->matrix.scroll.horz + win->matrix.select.col),
(win->matrix.scroll.vert + row)).quick.key != SCANKEY_VOID)
win->matrix.select.row = row;
}
void MotionHome_Menu(Window *win)
{
if (TCellAt(win,
(win->matrix.scroll.horz + win->matrix.select.col),
(win->matrix.scroll.vert + 1)).quick.key != SCANKEY_VOID)
win->matrix.select.row = 1;
else
win->matrix.select.row = 0;
}
void MotionEnd_Menu(Window *win)
{
CUINT row = 0;
for (row = win->matrix.size.hth - 1; row > 1; row--)
if (TCellAt(win,
(win->matrix.scroll.horz + win->matrix.select.col),
(win->matrix.scroll.vert + row)).quick.key != SCANKEY_VOID)
break;
win->matrix.select.row = row;
}
Window *CreateMenu(unsigned long long id)
{
Window *wMenu = CreateWindow(wLayer, id, 3, 11, 3, 0);
if (wMenu != NULL) {
Attribute sameAttr = {.fg = BLACK, .bg = WHITE, .bf = 0},
voidAttr = {.value = 0}, gateAttr[24], ctrlAttr[24],
stopAttr[24] = {
HKW,HKW,HKW,HKW,HKW,HKW,HKW,HKW,HKW,HKW,HKW,HKW,
HKW,HKW,HKW,HKW,HKW,HKW,HKW,HKW,HKW,HKW,HKW,HKW
},
helpAttr[24] = {
LKW,LKW,LKW,LKW,LKW,LKW,LKW,LKW,LKW,LKW,_LKW,LKW,
LKW,LKW,LKW,LKW,LKW,LKW,LKW,LKW,LKW,LKW, LKW,LKW
},
quitAttr[24] = {
LKW,LKW,LKW,LKW,LKW,LKW,LKW,LKW, LKW,LKW,LKW,LKW,
LKW,LKW,LKW,LKW,LKW,LKW,LKW,HKW,_LKW,_LKW,HKW,LKW
},
skeyAttr[24] = {
LKW,LKW,LKW,LKW,LKW,LKW,LKW,LKW,LKW, LKW,LKW,LKW,
LKW,LKW,LKW,LKW,LKW,LKW,LKW,LKW,HKW,_LKW,HKW,LKW
};
memcpy(gateAttr, BITWISEAND(LOCKLESS, Shm->SysGate.Operation, 0x1) ?
skeyAttr : stopAttr, 24);
memcpy(ctrlAttr, (Shm->Uncore.CtrlCount > 0) ? skeyAttr : stopAttr, 24);
StoreTCell(wMenu, SCANKEY_h, " Help ", helpAttr);
StoreTCell(wMenu, SCANKEY_NULL, " View ", sameAttr);
StoreTCell(wMenu, SCANKEY_NULL, " Window ", sameAttr);
StoreTCell(wMenu, SCANKEY_s, " Settings [s] ", skeyAttr);
StoreTCell(wMenu, SCANKEY_d, " Dashboard [d] ", skeyAttr);
StoreTCell(wMenu, SCANKEY_p, " Processor [p] ", skeyAttr);
StoreTCell(wMenu, SCANKEY_a, " About [a] ", skeyAttr);
StoreTCell(wMenu, SCANKEY_f, " Frequency [f] ", skeyAttr);
StoreTCell(wMenu, SCANKEY_m, " Topology [m] ", skeyAttr);
StoreTCell(wMenu, SCANKEY_F4, " Quit [F4] ", quitAttr);
StoreTCell(wMenu, SCANKEY_i, " Inst cycles [i] ", skeyAttr);
StoreTCell(wMenu, SCANKEY_e, " Features [e] ", skeyAttr);
StoreTCell(wMenu, SCANKEY_VOID, "", voidAttr);
StoreTCell(wMenu, SCANKEY_c, " Core cycles [c] ", skeyAttr);
StoreTCell(wMenu, SCANKEY_SHIFT_i," ISA Extensions [I] ", skeyAttr);
StoreTCell(wMenu, SCANKEY_VOID, "", voidAttr);
StoreTCell(wMenu, SCANKEY_l, " Idle C-States [l] ", skeyAttr);
StoreTCell(wMenu, SCANKEY_t, " Technologies [t] ", skeyAttr);
StoreTCell(wMenu, SCANKEY_VOID, "", voidAttr);
StoreTCell(wMenu, SCANKEY_g, " Package cycles [g] ", skeyAttr);
StoreTCell(wMenu, SCANKEY_o, " Perf. Monitoring [o] ", skeyAttr);
StoreTCell(wMenu, SCANKEY_VOID, "", voidAttr);
StoreTCell(wMenu, SCANKEY_x, " Tasks Monitoring [x] ", gateAttr);
StoreTCell(wMenu, SCANKEY_w, " Power & Thermal [w] ", skeyAttr);
StoreTCell(wMenu, SCANKEY_VOID, "", voidAttr);
StoreTCell(wMenu, SCANKEY_q, " System Interrupts [q] ", skeyAttr);
StoreTCell(wMenu, SCANKEY_u, " CPUID Hexa Dump [u] ", skeyAttr);
StoreTCell(wMenu, SCANKEY_VOID, "", voidAttr);
StoreTCell(wMenu, SCANKEY_SHIFT_v," Voltage Vcore [V] ", skeyAttr);
StoreTCell(wMenu, SCANKEY_SHIFT_m," Memory Controller [M] ", ctrlAttr);
StoreTCell(wMenu, SCANKEY_VOID, "", voidAttr);
StoreTCell(wMenu, SCANKEY_VOID, "", voidAttr);
StoreTCell(wMenu, SCANKEY_k, " Kernel Data [k] ", gateAttr);
StoreWindow(wMenu, .color[0].select, MakeAttr(BLACK,0,WHITE,0));
StoreWindow(wMenu, .color[0].title, MakeAttr(BLACK,0,WHITE,0));
StoreWindow(wMenu, .color[1].title, MakeAttr(BLACK,0,WHITE,1));
StoreWindow(wMenu, .Print, ForEachCellPrint_Menu);
StoreWindow(wMenu, .key.Enter, MotionEnter_Cell);
StoreWindow(wMenu, .key.Left, MotionLeft_Menu);
StoreWindow(wMenu, .key.Right, MotionRight_Menu);
StoreWindow(wMenu, .key.Down, MotionDown_Menu);
StoreWindow(wMenu, .key.Up, MotionUp_Menu);
StoreWindow(wMenu, .key.Home, MotionHome_Menu);
StoreWindow(wMenu, .key.End, MotionEnd_Menu);
}
return(wMenu);
}
Window *CreateSettings(unsigned long long id)
{
Window *wSet = CreateWindow(wLayer, id, 2, 10, 8, TOP_HEADER_ROW + 3);
if (wSet != NULL) {
char intervStr[16], tickStr[16], pollStr[16], experStr[16],
cpuhpStr[16], pciRegStr[16], nmiRegStr[16];
int intervLen = sprintf(intervStr, "%13uE6",
Shm->Proc.SleepInterval),
tickLen = sprintf(tickStr, "%13uE6",
Shm->Proc.SleepInterval*Shm->SysGate.tickReset),
pollLen = sprintf(pollStr, "%13ldE6",
Shm->Proc.BaseSleep.tv_nsec / 1000000L),
experLen = sprintf(experStr, "[%3s]",
enabled(Shm->Registration.Experimental)),
cpuhpLen = sprintf(cpuhpStr, "[%3s]",
enabled(!(Shm->Registration.hotplug < 0))),
pciRegLen = sprintf(pciRegStr, "[%3s]",
enabled(!(Shm->Registration.pci < 0))),
nmiRegLen = sprintf(nmiRegStr, "[%3s]",
enabled(Shm->Registration.nmi));
size_t appLen = strlen(Shm->AppName);
StoreTCell(wSet, SCANKEY_NULL, " ", MAKE_PRINT_FOCUS);
StoreTCell(wSet, SCANKEY_NULL, " ", MAKE_PRINT_FOCUS);
StoreTCell(wSet, SCANKEY_NULL, " Daemon gate ", MAKE_PRINT_FOCUS);
StoreTCell(wSet, SCANKEY_NULL, " ", MAKE_PRINT_FOCUS);
StoreTCell(wSet, SCANKEY_NULL, " Interval(ns) ", MAKE_PRINT_FOCUS);
StoreTCell(wSet, SCANKEY_NULL, " ", MAKE_PRINT_FOCUS);
StoreTCell(wSet, SCANKEY_NULL, " Sys.Tick(ns) ", MAKE_PRINT_FOCUS);
StoreTCell(wSet, SCANKEY_NULL, " ", MAKE_PRINT_FOCUS);
StoreTCell(wSet, SCANKEY_NULL, " Polling (ns) ", MAKE_PRINT_FOCUS);
StoreTCell(wSet, SCANKEY_NULL, " ", MAKE_PRINT_FOCUS);
StoreTCell(wSet, SCANKEY_NULL, " Experimental ", MAKE_PRINT_FOCUS);
StoreTCell(wSet, SCANKEY_NULL, " ", MAKE_PRINT_FOCUS);
StoreTCell(wSet, SCANKEY_NULL, " CPU Hot-Plug ", MAKE_PRINT_FOCUS);
StoreTCell(wSet, SCANKEY_NULL, " ", MAKE_PRINT_FOCUS);
StoreTCell(wSet, SCANKEY_NULL, " PCI enablement ", MAKE_PRINT_FOCUS);
StoreTCell(wSet, SCANKEY_NULL, " ", MAKE_PRINT_FOCUS);
StoreTCell(wSet, SCANKEY_NULL, " NMI registered ", MAKE_PRINT_FOCUS);
StoreTCell(wSet, SCANKEY_NULL, " ", MAKE_PRINT_FOCUS);
StoreTCell(wSet, SCANKEY_NULL, " ", MAKE_PRINT_FOCUS);
StoreTCell(wSet, SCANKEY_NULL, " ", MAKE_PRINT_FOCUS);
memcpy(&TCellAt(wSet, 1, 1).item[15 - appLen], Shm->AppName, appLen);
memcpy(&TCellAt(wSet, 1, 2).item[15 - intervLen], intervStr, intervLen);
memcpy(&TCellAt(wSet, 1, 3).item[15 - tickLen], tickStr, tickLen);
memcpy(&TCellAt(wSet, 1, 4).item[15 - pollLen], pollStr, pollLen);
memcpy(&TCellAt(wSet, 1, 5).item[15 - experLen], experStr, experLen);
memcpy(&TCellAt(wSet, 1, 6).item[15 - cpuhpLen], cpuhpStr, cpuhpLen);
memcpy(&TCellAt(wSet, 1, 7).item[15 - pciRegLen], pciRegStr, pciRegLen);
memcpy(&TCellAt(wSet, 1, 8).item[15 - nmiRegLen], nmiRegStr, nmiRegLen);
StoreWindow(wSet, .title, " Settings ");
StoreWindow(wSet, .color[0].select, MAKE_PRINT_UNFOCUS);
StoreWindow(wSet, .color[1].select, MAKE_PRINT_FOCUS);
StoreWindow(wSet, .key.WinLeft, MotionOriginLeft_Win);
StoreWindow(wSet, .key.WinRight, MotionOriginRight_Win);
StoreWindow(wSet, .key.WinDown, MotionOriginDown_Win);
StoreWindow(wSet, .key.WinUp, MotionOriginUp_Win);
}
return(wSet);
}
Window *CreateHelp(unsigned long long id)
{
Window *wHelp = CreateWindow(wLayer, id, 2, 17, 2, TOP_HEADER_ROW + 2);
if (wHelp != NULL) {
StoreTCell(wHelp, SCANKEY_NULL, " ", MAKE_PRINT_FOCUS);
StoreTCell(wHelp, SCANKEY_NULL, " ", MAKE_PRINT_FOCUS);
StoreTCell(wHelp, SCANKEY_NULL, " [F2] ", MAKE_PRINT_FOCUS);
StoreTCell(wHelp, SCANKEY_NULL, " Menu ", MAKE_PRINT_FOCUS);
StoreTCell(wHelp, SCANKEY_NULL, " [Escape] ", MAKE_PRINT_FOCUS);
StoreTCell(wHelp, SCANKEY_NULL, " Close window ", MAKE_PRINT_FOCUS);
StoreTCell(wHelp, SCANKEY_NULL, " [Shift]+[Tab] ", MAKE_PRINT_FOCUS);
StoreTCell(wHelp, SCANKEY_NULL, " Previous window ", MAKE_PRINT_FOCUS);
StoreTCell(wHelp, SCANKEY_NULL, " [Tab] ", MAKE_PRINT_FOCUS);
StoreTCell(wHelp, SCANKEY_NULL, " Next window ", MAKE_PRINT_FOCUS);
StoreTCell(wHelp, SCANKEY_NULL, " [A|Z] ", MAKE_PRINT_FOCUS);
StoreTCell(wHelp, SCANKEY_NULL, " ", MAKE_PRINT_FOCUS);
StoreTCell(wHelp, SCANKEY_NULL, " [W|Q] [S] [D] ", MAKE_PRINT_FOCUS);
StoreTCell(wHelp, SCANKEY_NULL, " Move window ", MAKE_PRINT_FOCUS);
StoreTCell(wHelp, SCANKEY_NULL, " ", MAKE_PRINT_FOCUS);
StoreTCell(wHelp, SCANKEY_NULL, " ", MAKE_PRINT_FOCUS);
StoreTCell(wHelp, SCANKEY_NULL, " [Up] ", MAKE_PRINT_FOCUS);
StoreTCell(wHelp, SCANKEY_NULL, " ", MAKE_PRINT_FOCUS);
StoreTCell(wHelp, SCANKEY_NULL, " [Left] [Right]", MAKE_PRINT_FOCUS);
StoreTCell(wHelp, SCANKEY_NULL, " Move selection ", MAKE_PRINT_FOCUS);
StoreTCell(wHelp, SCANKEY_NULL, " [Down] ", MAKE_PRINT_FOCUS);
StoreTCell(wHelp, SCANKEY_NULL, " ", MAKE_PRINT_FOCUS);
StoreTCell(wHelp, SCANKEY_NULL, " [End] ", MAKE_PRINT_FOCUS);
StoreTCell(wHelp, SCANKEY_NULL, " Last cell ", MAKE_PRINT_FOCUS);
StoreTCell(wHelp, SCANKEY_NULL, " [Home] ", MAKE_PRINT_FOCUS);
StoreTCell(wHelp, SCANKEY_NULL, " First cell ", MAKE_PRINT_FOCUS);
StoreTCell(wHelp, SCANKEY_NULL, " [Enter] ", MAKE_PRINT_FOCUS);
StoreTCell(wHelp, SCANKEY_NULL, "Trigger selection ", MAKE_PRINT_FOCUS);
StoreTCell(wHelp, SCANKEY_NULL, " [Page-Up] ", MAKE_PRINT_FOCUS);
StoreTCell(wHelp, SCANKEY_NULL, " Previous page ", MAKE_PRINT_FOCUS);
StoreTCell(wHelp, SCANKEY_NULL, " [Page-Dw] ", MAKE_PRINT_FOCUS);
StoreTCell(wHelp, SCANKEY_NULL, " Next page ", MAKE_PRINT_FOCUS);
StoreTCell(wHelp, SCANKEY_NULL, " ", MAKE_PRINT_FOCUS);
StoreTCell(wHelp, SCANKEY_NULL, " ", MAKE_PRINT_FOCUS);
StoreWindow(wHelp, .title, " Help ");
StoreWindow(wHelp, .color[0].select, MAKE_PRINT_UNFOCUS);
StoreWindow(wHelp, .color[1].select, MAKE_PRINT_FOCUS);
StoreWindow(wHelp, .key.WinLeft, MotionOriginLeft_Win);
StoreWindow(wHelp, .key.WinRight, MotionOriginRight_Win);
StoreWindow(wHelp, .key.WinDown, MotionOriginDown_Win);
StoreWindow(wHelp, .key.WinUp, MotionOriginUp_Win);
}
return(wHelp);
}
Window *CreateAbout(unsigned long long id)
{
char *C[] = {
" "" ______ ______ "" ",
" "" / ____/___ ________ / ____/_______ ____ _"" ",
" "" / / / __ \\/ ___/ _ \\/ /_ / ___/ _ \\/ __ `/"" ",
" ""/ /___/ /_/ / / / __/ __/ / / / __/ /_/ / "" ",
" ""\\____/\\____/_/ \\___/_/ /_/ \\___/\\__, / "" ",
" "" /_/ "" "
};
char *F[] = {
" "" by CyrIng "" ",
" "" "" ",
" "" (C)2015-2017 CYRIL INGENIERIE "" "
};
size_t c = sizeof(C) / sizeof(C[0]),
f = sizeof(F) / sizeof(F[0]),
l = strlen(C[0]), v = strlen(COREFREQ_VERSION);
Window *wAbout = CreateWindow( wLayer, id,
1, c + f,
(drawSize.width-l)/2, TOP_HEADER_ROW+4);
if (wAbout != NULL) {
unsigned int i;
for (i = 0; i < c; i++)
StoreTCell(wAbout,SCANKEY_NULL, C[i], MAKE_PRINT_FOCUS);
for (i = 0; i < f; i++)
StoreTCell(wAbout,SCANKEY_NULL, F[i], MAKE_PRINT_FOCUS);
size_t pos = strlen((char*) TCellAt(wAbout, 1, 5).item) - 2 - v;
memcpy(&TCellAt(wAbout, 1, 5).item[pos], COREFREQ_VERSION, v);
wAbout->matrix.select.row = wAbout->matrix.size.hth - 1;
StoreWindow(wAbout, .title, " CoreFreq ");
StoreWindow(wAbout, .color[0].select, MAKE_PRINT_UNFOCUS);
StoreWindow(wAbout, .color[1].select, MAKE_PRINT_FOCUS);
StoreWindow(wAbout, .key.WinLeft, MotionOriginLeft_Win);
StoreWindow(wAbout, .key.WinRight, MotionOriginRight_Win);
StoreWindow(wAbout, .key.WinDown, MotionOriginDown_Win);
StoreWindow(wAbout, .key.WinUp, MotionOriginUp_Win);
}
return(wAbout);
}
Window *_CreateBox(unsigned long long id,
Coordinate origin,
Coordinate select,
char *title,
ASCII *button, ...)
{
struct PBOX {
int cnt;
struct SBOX {
unsigned long long key;
ASCII item[MIN_WIDTH];
Attribute attr;
} btn[];
} *pBox = NULL;
int cnt = 0;
va_list ap;
va_start(ap, button);
ASCII *item = button;
Attribute attr = va_arg(ap, Attribute);
unsigned long long aKey = va_arg(ap, unsigned long long);
do {
if (item != NULL) {
cnt = (pBox == NULL) ? 1: pBox->cnt + 1;
if ((pBox = realloc(pBox,
sizeof(struct PBOX)
+ cnt * sizeof(struct SBOX))) != NULL)
{
strcpy((char *) pBox->btn[cnt - 1].item, (char *) item);
pBox->btn[cnt - 1].attr = attr;
pBox->btn[cnt - 1].key = aKey;
pBox->cnt = cnt;
}
item = va_arg(ap, ASCII*);
attr = va_arg(ap, Attribute);
aKey = va_arg(ap, unsigned long long);
}
} while (item != NULL) ;
va_end(ap);
Window *wBox = NULL;
if (pBox != NULL) {
wBox = CreateWindow(wLayer, id,
1, pBox->cnt,
origin.col, origin.row);
if (wBox != NULL) {
wBox->matrix.select.col = select.col;
wBox->matrix.select.row = select.row;
for (cnt = 0; cnt < pBox->cnt; cnt++)
StoreTCell( wBox,
pBox->btn[cnt].key,
pBox->btn[cnt].item,
pBox->btn[cnt].attr);
if (title != NULL)
StoreWindow(wBox, .title, title);
StoreWindow(wBox, .key.Enter, MotionEnter_Cell);
StoreWindow(wBox, .key.Down, MotionDown_Win);
StoreWindow(wBox, .key.Up, MotionUp_Win);
StoreWindow(wBox, .key.Home, MotionReset_Win);
StoreWindow(wBox, .key.End, MotionEnd_Cell);
}
free(pBox);
}
return(wBox);
}
#define CreateBox(id, origin, select, title, button, ...) \
_CreateBox(id, origin, select, title, button, __VA_ARGS__,NULL)
Window *CreateSysInfo(unsigned long long id)
{
CoordSize matrixSize = {.wth = 1, .hth = 18};
Coordinate winOrigin = {.col = 3, .row = TOP_HEADER_ROW + 1};
CUINT winWidth = 74;
void (*SysInfoFunc) (SHM_STRUCT*, CUINT,
void(*OutFunc)(unsigned long long, char*));
char *title = NULL;
switch (id) {
case SCANKEY_p:
{
winOrigin.col = 2;
winWidth = 76;
SysInfoFunc = SysInfoProc;
title = " Processor ";
}
break;
case SCANKEY_SHIFT_i:
{
matrixSize.hth = 7;
winOrigin.col = 2;
winOrigin.row = TOP_HEADER_ROW + 3;
winWidth = 76;
SysInfoFunc = SysInfoISA;
title = " Instruction Set Extensions ";
}
break;
case SCANKEY_e:
{
winOrigin.col = 4;
winWidth = 72;
SysInfoFunc = SysInfoFeatures;
title = " Features ";
}
break;
case SCANKEY_t:
{
matrixSize.hth = 6;
winOrigin.col = 23;
winOrigin.row = TOP_HEADER_ROW + 11;
winWidth = 50;
SysInfoFunc = SysInfoTech;
title = " Technologies ";
}
break;
case SCANKEY_o:
{
SysInfoFunc = SysInfoPerfMon;
title = " Performance Monitoring ";
}
break;
case SCANKEY_w:
{
matrixSize.hth = 10;
winOrigin.col = 23;
winOrigin.row = TOP_HEADER_ROW + 2;
winWidth = 50;
SysInfoFunc = SysInfoPwrThermal;
title = " Power & Thermal ";
}
break;
case SCANKEY_u:
{
winWidth = 74;
SysInfoFunc = SysInfoCPUID;
title = " function " \
"EAX EBX ECX EDX ";
}
break;
case SCANKEY_k:
{
matrixSize.hth = 11;
winOrigin.col = 4;
winOrigin.row = TOP_HEADER_ROW + 8;
SysInfoFunc = SysInfoKernel;
title = " Kernel ";
}
break;
}
int pad = 0;
Window *wSysInfo = CreateWindow(wLayer, id,
matrixSize.wth, matrixSize.hth,
winOrigin.col, winOrigin.row);
void AddSysInfoCell(unsigned long long key, char *input)
{
pad++;
StoreTCell(wSysInfo, key, input, MAKE_PRINT_FOCUS);
}
if (wSysInfo != NULL) {
SysInfoFunc(Shm, winWidth, AddSysInfoCell);
while (pad < matrixSize.hth) { // Pad with blank rows.
pad++;
StoreTCell(wSysInfo,
SCANKEY_NULL,
&hSpace[MAX_WIDTH - winWidth],
MAKE_PRINT_FOCUS);
}
switch (id) {
case SCANKEY_u:
wSysInfo->matrix.select.row = 1;
StoreWindow(wSysInfo, .color[1].title,
wSysInfo->hook.color[1].border);
break;
default:
break;
}
StoreWindow(wSysInfo, .title, title);
StoreWindow(wSysInfo, .key.Enter, MotionEnter_Cell);
StoreWindow(wSysInfo, .key.Left, MotionLeft_Win);
StoreWindow(wSysInfo, .key.Right, MotionRight_Win);
StoreWindow(wSysInfo, .key.Down, MotionDown_Win);
StoreWindow(wSysInfo, .key.Up, MotionUp_Win);
StoreWindow(wSysInfo, .key.PgUp, MotionPgUp_Win);
StoreWindow(wSysInfo, .key.PgDw, MotionPgDw_Win);
StoreWindow(wSysInfo, .key.Home, MotionReset_Win);
StoreWindow(wSysInfo, .key.End, MotionEnd_Cell);
StoreWindow(wSysInfo, .key.WinLeft, MotionOriginLeft_Win);
StoreWindow(wSysInfo, .key.WinRight, MotionOriginRight_Win);
StoreWindow(wSysInfo, .key.WinDown, MotionOriginDown_Win);
StoreWindow(wSysInfo, .key.WinUp, MotionOriginUp_Win);
}
return(wSysInfo);
}
Window *CreateTopology(unsigned long long id)
{
Window *wTopology = CreateWindow(wLayer, id,
6, 2 + Shm->Proc.CPU.Count,
1, TOP_HEADER_ROW + 3);
wTopology->matrix.select.row = 2;
void AddTopologyCell(char *input)
{
StoreTCell(wTopology, SCANKEY_NULL, input, MAKE_PRINT_FOCUS);
}
if (wTopology != NULL) {
Topology(Shm, AddTopologyCell);
StoreWindow(wTopology, .title, " Topology ");
StoreWindow(wTopology, .key.Left, MotionLeft_Win);
StoreWindow(wTopology, .key.Right, MotionRight_Win);
StoreWindow(wTopology, .key.Down, MotionDown_Win);
StoreWindow(wTopology, .key.Up, MotionUp_Win);
StoreWindow(wTopology, .key.Home, MotionHome_Win);
StoreWindow(wTopology, .key.End, MotionEnd_Win);
StoreWindow(wTopology, .key.WinLeft, MotionOriginLeft_Win);
StoreWindow(wTopology, .key.WinRight, MotionOriginRight_Win);
StoreWindow(wTopology, .key.WinDown, MotionOriginDown_Win);
StoreWindow(wTopology, .key.WinUp, MotionOriginUp_Win);
}
return(wTopology);
}
Window *CreateMemCtrl(unsigned long long id)
{
unsigned short mc, cha, rows = 0;
for (mc = 0; mc < Shm->Uncore.CtrlCount; mc++)
for (cha = 0; cha < Shm->Uncore.MC[mc].ChannelCount; cha++)
rows++;
rows *= 2;
if (rows > 0) {
Window *wIMC = CreateWindow(wLayer, id,
14, rows + 11,
1, TOP_HEADER_ROW + 2);
wIMC->matrix.select.row = 4;
void AddMemoryControllerCell(char *input)
{
StoreTCell(wIMC, SCANKEY_NULL, input, MAKE_PRINT_FOCUS);
}
if (wIMC != NULL) {
MemoryController(Shm, AddMemoryControllerCell);
StoreWindow(wIMC, .title, " Memory Controller ");
StoreWindow(wIMC, .key.Left, MotionLeft_Win);
StoreWindow(wIMC, .key.Right, MotionRight_Win);
StoreWindow(wIMC, .key.Down, MotionDown_Win);
StoreWindow(wIMC, .key.Up, MotionUp_Win);
StoreWindow(wIMC, .key.PgUp, MotionPgUp_Win);
StoreWindow(wIMC, .key.PgDw, MotionPgDw_Win);
StoreWindow(wIMC, .key.Home, MotionHome_Win);
StoreWindow(wIMC, .key.End, MotionEnd_Win);
StoreWindow(wIMC, .key.WinLeft, MotionOriginLeft_Win);
StoreWindow(wIMC, .key.WinRight, MotionOriginRight_Win);
StoreWindow(wIMC, .key.WinDown, MotionOriginDown_Win);
StoreWindow(wIMC, .key.WinUp, MotionOriginUp_Win);
}
return(wIMC);
}
else
return(NULL);
}
Window *CreateSortByField(unsigned long long id)
{
Window *wSortBy = CreateWindow( wLayer, id,
1, SORTBYCOUNT,
33, TOP_HEADER_ROW+Shm->Proc.CPU.Count+2);
if (wSortBy != NULL) {
StoreTCell(wSortBy,SORTBY_STATE, " State ", MAKE_PRINT_DROP);
StoreTCell(wSortBy,SORTBY_RTIME, " RunTime ", MAKE_PRINT_DROP);
StoreTCell(wSortBy,SORTBY_UTIME, " UserTime ", MAKE_PRINT_DROP);
StoreTCell(wSortBy,SORTBY_STIME, " SysTime ", MAKE_PRINT_DROP);
StoreTCell(wSortBy,SORTBY_PID, " PID ", MAKE_PRINT_DROP);
StoreTCell(wSortBy,SORTBY_COMM, " Command ", MAKE_PRINT_DROP);
wSortBy->matrix.select.row = Shm->SysGate.sortByField;
StoreWindow(wSortBy, .color[0].select, MAKE_PRINT_DROP);
StoreWindow(wSortBy, .color[0].title, MAKE_PRINT_DROP);
StoreWindow(wSortBy, .color[1].title,MakeAttr(BLACK,0,WHITE,1));
StoreWindow(wSortBy, .Print, ForEachCellPrint_Drop);
StoreWindow(wSortBy, .key.Enter, MotionEnter_Cell);
StoreWindow(wSortBy, .key.Down, MotionDown_Win);
StoreWindow(wSortBy, .key.Up, MotionUp_Win);
StoreWindow(wSortBy, .key.Home, MotionReset_Win);
StoreWindow(wSortBy, .key.End, MotionEnd_Cell);
}
return(wSortBy);
}
Window *CreateTracking(unsigned long long id)
{
int SortByForest(const void *p1, const void *p2)
{
TASK_MCB *task1 = (TASK_MCB*) p1, *task2 = (TASK_MCB*) p2;
if (task1->ppid < task2->ppid)
return(-1);
else if (task1->ppid > task2->ppid)
return(1);
else if (task1->tgid < task2->tgid)
return(-1);
else if (task1->tgid > task2->tgid)
return(1);
else if (task1->pid < task2->pid)
return(-1);
else if (task1->pid > task2->pid)
return(1);
else
return(1);
}
if (BITWISEAND(LOCKLESS, Shm->SysGate.Operation, 0x1)) {
size_t tc = Shm->SysGate.taskCount;
if (tc > 0) {
const CUINT margin = 12; // @ "Freq(MHz)"
int padding = drawSize.width - margin - TASK_COMM_LEN - 7;
Window *wTrack = CreateWindow(wLayer, id,
1, TOP_HEADER_ROW+Shm->Proc.CPU.Count*2,
margin, TOP_HEADER_ROW);
if (wTrack != NULL) {
char *item = malloc(MAX_WIDTH);
TASK_MCB *trackList = malloc(tc * sizeof(TASK_MCB));
memcpy(trackList, Shm->SysGate.taskList, tc * sizeof(TASK_MCB));
qsort(trackList, tc, sizeof(TASK_MCB), SortByForest);
unsigned int ti, si = 0, qi = 0;
pid_t previd = (pid_t) -1;
for (ti = 0; ti < tc; ti++) {
if (trackList[ti].ppid == previd) {
si += (si < padding - 2) ? 1 : 0;
} else if (trackList[ti].tgid != previd) {
si -= (si > 0) ? 1 : 0;
}
previd = trackList[ti].tgid;
if (trackList[ti].pid == trackList[ti].tgid)
qi = si + 1;
else
qi = si + 2;
sprintf(item,
"%.*s" "%-16s" "%.*s" "(%5d)",
qi,
hSpace,
trackList[ti].comm,
padding - qi,
hSpace,
trackList[ti].pid);
StoreTCell(wTrack,
(TRACK_TASK | trackList[ti].pid),
item,
(trackList[ti].pid == trackList[ti].tgid) ?
MAKE_PRINT_DROP
: MakeAttr(BLACK, 0, WHITE, 1));
}
StoreWindow(wTrack, .color[0].select, MAKE_PRINT_DROP);
StoreWindow(wTrack, .color[0].title, MAKE_PRINT_DROP);
StoreWindow(wTrack, .color[1].title, MakeAttr(BLACK,0,WHITE,1));
StoreWindow(wTrack, .Print, ForEachCellPrint_Drop);
StoreWindow(wTrack, .key.Enter, MotionEnter_Cell);
StoreWindow(wTrack, .key.Down, MotionDown_Win);
StoreWindow(wTrack, .key.Up, MotionUp_Win);
StoreWindow(wTrack, .key.PgUp, MotionPgUp_Win);
StoreWindow(wTrack, .key.PgDw, MotionPgDw_Win);
StoreWindow(wTrack, .key.Home, MotionReset_Win);
StoreWindow(wTrack, .key.End, MotionEnd_Cell);
free(trackList);
free(item);
}
return(wTrack);
}
else
return(NULL);
}
else
return(NULL);
}
void PrintWindowStack(void)
{
Window *walker;
if ((walker=GetHead(&winList)) != NULL) {
do {
walker = walker->next;
if (walker->hook.Print != NULL)
walker->hook.Print(walker, &winList);
else
ForEachCellPrint(walker, &winList);
} while (!IsHead(&winList, walker)) ;
}
}
void FreeAll(void)
{
DestroyAllWindows(&winList);
free(hBClk);
free(buffer);
free(console);
free(cTask);
DestroyLayer(sLayer);
DestroyLayer(dLayer);
DestroyLayer(wLayer);
DestroyLayer(fuze);
free(sLayer);
free(dLayer);
free(wLayer);
free(fuze);
}
void AllocAll()
{
hBClk = calloc(Shm->Proc.CPU.Count, sizeof(HBCLK));
buffer = malloc(10 * MAX_WIDTH); // 10 times for ANSI cursor string.
console = malloc((10 * MAX_WIDTH) * MAX_HEIGHT);
const CoordSize layerSize = {
.wth = MAX_WIDTH,
.hth = MAX_HEIGHT
};
cTask = calloc(Shm->Proc.CPU.Count, sizeof(Coordinate));
sLayer = calloc(1, sizeof(Layer));
dLayer = calloc(1, sizeof(Layer));
wLayer = calloc(1, sizeof(Layer));
fuze = calloc(1, sizeof(Layer));
CreateLayer(sLayer, layerSize);
CreateLayer(dLayer, layerSize);
CreateLayer(wLayer, layerSize);
CreateLayer(fuze, layerSize);
}
void TrapScreenSize(int caught)
{
if (caught == SIGWINCH) {
SCREEN_SIZE currentSize = GetScreenSize();
if (currentSize.height != drawSize.height) {
if (currentSize.height > MAX_HEIGHT)
drawSize.height = MAX_HEIGHT;
else
drawSize.height = currentSize.height;
switch (drawFlag.disposal) {
case 0:
switch (drawFlag.view) {
case V_FREQ:
case V_INST:
case V_CYCLES:
case V_CSTATES:
case V_TASKS:
case V_INTR:
case V_VOLTAGE:
MIN_HEIGHT = (2 * Shm->Proc.CPU.Count) + TOP_HEADER_ROW
+ TOP_SEPARATOR + TOP_FOOTER_ROW;
break;
case V_PACKAGE:
MIN_HEIGHT = Shm->Proc.CPU.Count + 8 + TOP_HEADER_ROW
+ TOP_SEPARATOR + TOP_FOOTER_ROW;
break;
}
break;
case 1:
MIN_HEIGHT = LEADING_TOP + MARGIN_HEIGHT + INTER_HEIGHT;
break;
}
drawFlag.clear = 1;
drawFlag.height = !(drawSize.height < MIN_HEIGHT);
}
if (currentSize.width != drawSize.width) {
if (currentSize.width > MAX_WIDTH)
drawSize.width = MAX_WIDTH;
else
drawSize.width = currentSize.width;
drawFlag.clear = 1;
drawFlag.width = !(drawSize.width < MIN_WIDTH);
}
}
}
int Shortcut(SCANKEY *scan)
{
Attribute stateAttr[2] = {
MakeAttr(WHITE, 0, BLACK, 0),
MakeAttr(CYAN, 0, BLACK, 1)
},
blankAttr = MakeAttr(BLACK, 0, BLACK, 1),
descAttr = MakeAttr(CYAN, 0, BLACK, 0);
ASCII *stateStr[2][2] = {
{
(ASCII*)" Disable ",
(ASCII*)" < Disable > "
},{
(ASCII*)" Enable ",
(ASCII*)" < Enable > "
}
},
*blankStr = (ASCII*)" ",
*descStr[] = {
(ASCII*)" SpeedStep ",
(ASCII*)" Enhanced Halt State ",
(ASCII*)" Turbo Boost/Core Performance Boost ",
(ASCII*)" C1 Auto Demotion ",
(ASCII*)" C3 Auto Demotion ",
(ASCII*)" C1 UnDemotion ",
(ASCII*)" C3 UnDemotion ",
(ASCII*)" I/O MWAIT Redirection ",
(ASCII*)" Clock Modulation "
};
switch (scan->key) {
/*
case SCANKEY_PLUS:
{
if (!RING_FULL(Shm->Ring))
RING_WRITE(Shm->Ring, COREFREQ_IOCTL_MACHINE, COREFREQ_TOGGLE_ON);
}
break;
case SCANKEY_MINUS:
{
if (!RING_FULL(Shm->Ring))
RING_WRITE(Shm->Ring, COREFREQ_IOCTL_MACHINE, COREFREQ_TOGGLE_OFF);
}
break;
*/
case SCANKEY_F2:
case SCANCON_F2:
{
Window *win = SearchWinListById(SCANKEY_F2, &winList);
if (win == NULL)
AppendWindow(CreateMenu(SCANKEY_F2), &winList);
else
SetHead(&winList, win);
}
break;
case SCANKEY_F4:
case SCANCON_F4:
BITSET(LOCKLESS, Shutdown, 0);
break;
case SCANKEY_PERCENT:
{
drawFlag.avgOrPC = !drawFlag.avgOrPC;
drawFlag.clear = 1;
}
break;
case SCANKEY_a:
{
Window *win = SearchWinListById(scan->key, &winList);
if (win == NULL)
AppendWindow(CreateAbout(scan->key), &winList);
else
SetHead(&winList, win);
}
break;
case SCANKEY_b:
if (drawFlag.view == V_TASKS) {
Window *win = SearchWinListById(scan->key, &winList);
if (win == NULL)
AppendWindow(CreateSortByField(scan->key), &winList);
else
SetHead(&winList, win);
}
break;
case SCANKEY_c:
{
drawFlag.disposal = 0;
drawFlag.view = V_CYCLES;
drawSize.height = 0;
TrapScreenSize(SIGWINCH);
}
break;
case SCANKEY_d:
{
drawFlag.disposal = 1;
drawSize.height = 0;
TrapScreenSize(SIGWINCH);
}
break;
case SCANKEY_f:
{
drawFlag.disposal = 0;
drawFlag.view = V_FREQ;
drawSize.height = 0;
TrapScreenSize(SIGWINCH);
}
break;
case SCANKEY_n:
if (drawFlag.view == V_TASKS) {
Window *win = SearchWinListById(scan->key, &winList);
if (win == NULL)
AppendWindow(CreateTracking(scan->key), &winList);
else
SetHead(&winList, win);
}
break;
case SCANKEY_g:
{
drawFlag.disposal = 0;
drawFlag.view = V_PACKAGE;
drawSize.height = 0;
TrapScreenSize(SIGWINCH);
}
break;
case SCANKEY_h:
{
Window *win = SearchWinListById(scan->key, &winList);
if (win == NULL)
AppendWindow(CreateHelp(scan->key), &winList);
else
SetHead(&winList, win);
}
break;
case SCANKEY_i:
{
drawFlag.disposal = 0;
drawFlag.view = V_INST;
drawSize.height = 0;
TrapScreenSize(SIGWINCH);
}
break;
case SCANKEY_l:
{
drawFlag.view = V_CSTATES;
drawSize.height = 0;
TrapScreenSize(SIGWINCH);
}
break;
case SCANKEY_m:
{
Window *win = SearchWinListById(scan->key, &winList);
if (win == NULL)
AppendWindow(CreateTopology(scan->key), &winList);
else
SetHead(&winList, win);
}
break;
case SCANKEY_SHIFT_m:
if (Shm->Uncore.CtrlCount > 0) {
Window *win = SearchWinListById(scan->key, &winList);
if (win == NULL)
AppendWindow(CreateMemCtrl(scan->key),&winList);
else
SetHead(&winList, win);
}
break;
case SCANKEY_q:
{
drawFlag.disposal = 0;
drawFlag.view = V_INTR;
drawSize.height = 0;
TrapScreenSize(SIGWINCH);
}
break;
case SCANKEY_SHIFT_v:
{
drawFlag.disposal = 0;
drawFlag.view = V_VOLTAGE;
drawSize.height = 0;
TrapScreenSize(SIGWINCH);
}
break;
case SCANKEY_s:
{
Window *win = SearchWinListById(scan->key, &winList);
if (win == NULL)
AppendWindow(CreateSettings(scan->key), &winList);
else
SetHead(&winList, win);
}
break;
case SCANKEY_r:
if (drawFlag.view == V_TASKS) {
Shm->SysGate.reverseOrder = !Shm->SysGate.reverseOrder;
drawFlag.layout = 1;
}
break;
case SCANKEY_v:
if (drawFlag.view == V_TASKS) {
drawFlag.taskVal = !drawFlag.taskVal;
drawFlag.layout = 1;
}
break;
case SCANKEY_x:
if (BITWISEAND(LOCKLESS, Shm->SysGate.Operation, 0x1)) {
Shm->SysGate.trackTask = 0;
drawFlag.disposal = 0;
drawFlag.view = V_TASKS;
drawSize.height = 0;
TrapScreenSize(SIGWINCH);
}
break;
case SORTBY_STATE:
{
Shm->SysGate.sortByField = F_STATE;
drawFlag.layout = 1;
}
break;
case SORTBY_RTIME:
{
Shm->SysGate.sortByField = F_RTIME;
drawFlag.layout = 1;
}
break;
case SORTBY_UTIME:
{
Shm->SysGate.sortByField = F_UTIME;
drawFlag.layout = 1;
}
break;
case SORTBY_STIME:
{
Shm->SysGate.sortByField = F_STIME;
drawFlag.layout = 1;
}
break;
case SORTBY_PID:
{
Shm->SysGate.sortByField = F_PID;
drawFlag.layout = 1;
}
break;
case SORTBY_COMM:
{
Shm->SysGate.sortByField = F_COMM;
drawFlag.layout = 1;
}
break;
case BOXKEY_EIST:
{
Window *win = SearchWinListById(scan->key, &winList);
if (win == NULL)
{
const unsigned int isEIST = !BITWISEXOR(LOCKLESS,
Shm->Proc.SpeedStep,
Shm->Proc.SpeedStep_Mask);
const Coordinate origin = {
.col = (drawSize.width - strlen((char *) blankStr)) / 2,
.row = TOP_HEADER_ROW + 3
}, select = {
.col = 0,
.row = isEIST ? 4 : 3
};
AppendWindow(CreateBox(scan->key, origin, select, " EIST ",
blankStr, blankAttr, SCANKEY_NULL,
descStr[0], descAttr, SCANKEY_NULL,
blankStr, blankAttr, SCANKEY_NULL,
stateStr[1][isEIST], stateAttr[isEIST], BOXKEY_EIST_ON,
stateStr[0][!isEIST], stateAttr[!isEIST], BOXKEY_EIST_OFF,
blankStr, blankAttr, SCANKEY_NULL),
&winList);
} else
SetHead(&winList, win);
}
break;
case BOXKEY_EIST_OFF:
{
if (!RING_FULL(Shm->Ring))
RING_WRITE(Shm->Ring, COREFREQ_IOCTL_EIST, COREFREQ_TOGGLE_OFF);
}
break;
case BOXKEY_EIST_ON:
{
if (!RING_FULL(Shm->Ring))
RING_WRITE(Shm->Ring, COREFREQ_IOCTL_EIST, COREFREQ_TOGGLE_ON);
}
break;
case BOXKEY_C1E:
{
Window *win = SearchWinListById(scan->key, &winList);
if (win == NULL)
{
const unsigned int isC1E = !BITWISEXOR(LOCKLESS,
Shm->Proc.C1E,
Shm->Proc.C1E_Mask);
const Coordinate origin = {
.col = (drawSize.width - strlen((char *) blankStr)) / 2,
.row = TOP_HEADER_ROW + 2
}, select = {
.col = 0,
.row = isC1E ? 4 : 3
};
AppendWindow(CreateBox(scan->key, origin, select, " C1E ",
blankStr, blankAttr, SCANKEY_NULL,
descStr[1], descAttr, SCANKEY_NULL,
blankStr, blankAttr, SCANKEY_NULL,
stateStr[1][isC1E], stateAttr[isC1E], BOXKEY_C1E_ON,
stateStr[0][!isC1E], stateAttr[!isC1E], BOXKEY_C1E_OFF,
blankStr, blankAttr, SCANKEY_NULL),
&winList);
} else
SetHead(&winList, win);
}
break;
case BOXKEY_C1E_OFF:
{
if (!RING_FULL(Shm->Ring))
RING_WRITE(Shm->Ring, COREFREQ_IOCTL_C1E, COREFREQ_TOGGLE_OFF);
}
break;
case BOXKEY_C1E_ON:
{
if (!RING_FULL(Shm->Ring))
RING_WRITE(Shm->Ring, COREFREQ_IOCTL_C1E, COREFREQ_TOGGLE_ON);
}
break;
case BOXKEY_TURBO:
{
Window *win = SearchWinListById(scan->key, &winList);
if (win == NULL)
{
const unsigned int isTurbo = !BITWISEXOR(LOCKLESS,
Shm->Proc.TurboBoost,
Shm->Proc.TurboBoost_Mask);
const Coordinate origin = {
.col = (drawSize.width - strlen((char *) blankStr)) / 2,
.row = TOP_HEADER_ROW + 4
}, select = {
.col = 0,
.row = isTurbo ? 4 : 3
};
AppendWindow(CreateBox(scan->key, origin, select, " Turbo ",
blankStr, blankAttr, SCANKEY_NULL,
descStr[2], descAttr, SCANKEY_NULL,
blankStr, blankAttr, SCANKEY_NULL,
stateStr[1][isTurbo], stateAttr[isTurbo], BOXKEY_TURBO_ON,
stateStr[0][!isTurbo], stateAttr[!isTurbo], BOXKEY_TURBO_OFF,
blankStr, blankAttr, SCANKEY_NULL),
&winList);
} else
SetHead(&winList, win);
}
break;
case BOXKEY_TURBO_OFF:
{
if (!RING_FULL(Shm->Ring))
RING_WRITE(Shm->Ring, COREFREQ_IOCTL_TURBO,COREFREQ_TOGGLE_OFF);
}
break;
case BOXKEY_TURBO_ON:
{
if (!RING_FULL(Shm->Ring))
RING_WRITE(Shm->Ring, COREFREQ_IOCTL_TURBO, COREFREQ_TOGGLE_ON);
}
break;
case BOXKEY_C1A:
{
Window *win = SearchWinListById(scan->key, &winList);
if (win == NULL)
{
const unsigned int isC1A = !BITWISEXOR(LOCKLESS,
Shm->Proc.C1A,
Shm->Proc.C1A_Mask);
const Coordinate origin = {
.col = (drawSize.width - strlen((char *) blankStr)) / 2,
.row = TOP_HEADER_ROW + 5
}, select = {
.col = 0,
.row = isC1A ? 4 : 3
};
AppendWindow(CreateBox(scan->key, origin, select, " C1A ",
blankStr, blankAttr, SCANKEY_NULL,
descStr[3], descAttr, SCANKEY_NULL,
blankStr, blankAttr, SCANKEY_NULL,
stateStr[1][isC1A], stateAttr[isC1A], BOXKEY_C1A_ON,
stateStr[0][!isC1A], stateAttr[!isC1A], BOXKEY_C1A_OFF,
blankStr, blankAttr, SCANKEY_NULL),
&winList);
} else
SetHead(&winList, win);
}
break;
case BOXKEY_C1A_OFF:
{
if (!RING_FULL(Shm->Ring))
RING_WRITE(Shm->Ring, COREFREQ_IOCTL_C1A, COREFREQ_TOGGLE_OFF);
}
break;
case BOXKEY_C1A_ON:
{
if (!RING_FULL(Shm->Ring))
RING_WRITE(Shm->Ring, COREFREQ_IOCTL_C1A, COREFREQ_TOGGLE_ON);
}
break;
case BOXKEY_C3A:
{
Window *win = SearchWinListById(scan->key, &winList);
if (win == NULL)
{
const unsigned int isC3A = !BITWISEXOR(LOCKLESS,
Shm->Proc.C3A,
Shm->Proc.C3A_Mask);
const Coordinate origin = {
.col = (drawSize.width - strlen((char *) blankStr)) / 2,
.row = TOP_HEADER_ROW + 6
}, select = {
.col = 0,
.row = isC3A ? 4 : 3
};
AppendWindow(CreateBox(scan->key, origin, select, " C3A ",
blankStr, blankAttr, SCANKEY_NULL,
descStr[4], descAttr, SCANKEY_NULL,
blankStr, blankAttr, SCANKEY_NULL,
stateStr[1][isC3A], stateAttr[isC3A], BOXKEY_C3A_ON,
stateStr[0][!isC3A], stateAttr[!isC3A], BOXKEY_C3A_OFF,
blankStr, blankAttr, SCANKEY_NULL),
&winList);
} else
SetHead(&winList, win);
}
break;
case BOXKEY_C3A_OFF:
{
if (!RING_FULL(Shm->Ring))
RING_WRITE(Shm->Ring, COREFREQ_IOCTL_C3A, COREFREQ_TOGGLE_OFF);
}
break;
case BOXKEY_C3A_ON:
{
if (!RING_FULL(Shm->Ring))
RING_WRITE(Shm->Ring, COREFREQ_IOCTL_C3A, COREFREQ_TOGGLE_ON);
}
break;
case BOXKEY_C1U:
{
Window *win = SearchWinListById(scan->key, &winList);
if (win == NULL)
{
const unsigned int isC1U = !BITWISEXOR(LOCKLESS,
Shm->Proc.C1U,
Shm->Proc.C1U_Mask);
const Coordinate origin = {
.col = (drawSize.width - strlen((char *) blankStr)) / 2,
.row = TOP_HEADER_ROW + 7
}, select = {
.col = 0,
.row = isC1U ? 4 : 3
};
AppendWindow(CreateBox(scan->key, origin, select, " C1U ",
blankStr, blankAttr, SCANKEY_NULL,
descStr[5], descAttr, SCANKEY_NULL,
blankStr, blankAttr, SCANKEY_NULL,
stateStr[1][isC1U], stateAttr[isC1U], BOXKEY_C1U_ON,
stateStr[0][!isC1U], stateAttr[!isC1U], BOXKEY_C1U_OFF,
blankStr, blankAttr, SCANKEY_NULL),
&winList);
} else
SetHead(&winList, win);
}
break;
case BOXKEY_C1U_OFF:
{
if (!RING_FULL(Shm->Ring))
RING_WRITE(Shm->Ring, COREFREQ_IOCTL_C1U, COREFREQ_TOGGLE_OFF);
}
break;
case BOXKEY_C1U_ON:
{
if (!RING_FULL(Shm->Ring))
RING_WRITE(Shm->Ring, COREFREQ_IOCTL_C1U, COREFREQ_TOGGLE_ON);
}
break;
case BOXKEY_C3U:
{
Window *win = SearchWinListById(scan->key, &winList);
if (win == NULL)
{
const unsigned int isC3U = !BITWISEXOR(LOCKLESS,
Shm->Proc.C3U,
Shm->Proc.C3U_Mask);
const Coordinate origin = {
.col = (drawSize.width - strlen((char *) blankStr)) / 2,
.row = TOP_HEADER_ROW + 8
}, select = {
.col = 0,
.row = isC3U ? 4 : 3
};
AppendWindow(CreateBox(scan->key, origin, select, " C3U ",
blankStr, blankAttr, SCANKEY_NULL,
descStr[6], descAttr, SCANKEY_NULL,
blankStr, blankAttr, SCANKEY_NULL,
stateStr[1][isC3U], stateAttr[isC3U], BOXKEY_C3U_ON,
stateStr[0][!isC3U], stateAttr[!isC3U], BOXKEY_C3U_OFF,
blankStr, blankAttr, SCANKEY_NULL),
&winList);
} else
SetHead(&winList, win);
}
break;
case BOXKEY_C3U_OFF:
{
if (!RING_FULL(Shm->Ring))
RING_WRITE(Shm->Ring, COREFREQ_IOCTL_C3U, COREFREQ_TOGGLE_OFF);
}
break;
case BOXKEY_C3U_ON:
{
if (!RING_FULL(Shm->Ring))
RING_WRITE(Shm->Ring, COREFREQ_IOCTL_C3U, COREFREQ_TOGGLE_ON);
}
break;
case BOXKEY_PKGCST:
{
Window *win = SearchWinListById(scan->key, &winList);
if (win == NULL)
{
const CSINT thisCST[] = {5, 4, 3, 2, -1, -1, 1, 0}; // Row index
const Coordinate origin = {
.col = (drawSize.width - (44 - 17)) / 2,
.row = TOP_HEADER_ROW + 2
}, select = {
.col = 0,
.row = thisCST[Shm->Cpu[0].Query.CStateLimit] != -1 ?
thisCST[Shm->Cpu[0].Query.CStateLimit] : 0
};
Window *wBox = CreateBox(scan->key, origin, select,
" Package C-State Limit ",
(ASCII*)" C7 ", stateAttr[0], BOXKEY_PKGCST_C7,
(ASCII*)" C6 ", stateAttr[0], BOXKEY_PKGCST_C6,
(ASCII*)" C3 ", stateAttr[0], BOXKEY_PKGCST_C3,
(ASCII*)" C2 ", stateAttr[0], BOXKEY_PKGCST_C2,
(ASCII*)" C1 ", stateAttr[0], BOXKEY_PKGCST_C1,
(ASCII*)" C0 ", stateAttr[0], BOXKEY_PKGCST_C0);
if (wBox != NULL) {
TCellAt(wBox, 0, select.row).attr[11] = \
TCellAt(wBox, 0, select.row).attr[12] = \
TCellAt(wBox, 0, select.row).attr[13] = \
TCellAt(wBox, 0, select.row).attr[14] = \
TCellAt(wBox, 0, select.row).attr[15] = \
TCellAt(wBox, 0, select.row).attr[16] = \
stateAttr[1];
TCellAt(wBox, 0, select.row).item[11] = '<';
TCellAt(wBox, 0, select.row).item[16] = '>';
AppendWindow(wBox, &winList);
} else
SetHead(&winList, win);
} else
SetHead(&winList, win);
}
break;
case BOXKEY_PKGCST_C7:
case BOXKEY_PKGCST_C6:
case BOXKEY_PKGCST_C3:
case BOXKEY_PKGCST_C2:
case BOXKEY_PKGCST_C1:
case BOXKEY_PKGCST_C0:
{
const unsigned long newCST = (scan->key - BOXKEY_PKGCST_C0) >> 4;
if (!RING_FULL(Shm->Ring))
RING_WRITE(Shm->Ring, COREFREQ_IOCTL_PKGCST, newCST);
}
break;
case BOXKEY_IOMWAIT:
{
Window *win = SearchWinListById(scan->key, &winList);
if (win == NULL)
{
const unsigned int isIORedir = (Shm->Cpu[0].Query.IORedir == 1);
const Coordinate origin = {
.col = (drawSize.width - strlen((char *) blankStr)) / 2,
.row = TOP_HEADER_ROW + 9
}, select = {
.col = 0,
.row = isIORedir ? 4 : 3
};
AppendWindow(CreateBox(scan->key, origin, select, " I/O MWAIT ",
blankStr, blankAttr, SCANKEY_NULL,
descStr[7], descAttr, SCANKEY_NULL,
blankStr, blankAttr, SCANKEY_NULL,
stateStr[1][isIORedir], stateAttr[isIORedir], BOXKEY_IOMWAIT_ON,
stateStr[0][!isIORedir], stateAttr[!isIORedir],BOXKEY_IOMWAIT_OFF,
blankStr, blankAttr, SCANKEY_NULL),
&winList);
} else
SetHead(&winList, win);
}
break;
case BOXKEY_IOMWAIT_OFF:
{
if (!RING_FULL(Shm->Ring))
RING_WRITE(Shm->Ring, COREFREQ_IOCTL_IOMWAIT, COREFREQ_TOGGLE_OFF);
}
break;
case BOXKEY_IOMWAIT_ON:
{
if (!RING_FULL(Shm->Ring))
RING_WRITE(Shm->Ring, COREFREQ_IOCTL_IOMWAIT, COREFREQ_TOGGLE_ON);
}
break;
case BOXKEY_IORCST:
{
Window *win = SearchWinListById(scan->key, &winList);
if (win == NULL)
{
const CSINT thisCST[]={-1, -1, -1, 3, 2, -1, 1, 0}; // Row index
const Coordinate origin = {
.col = (drawSize.width - (44 - 17)) / 2,
.row = TOP_HEADER_ROW + 3
}, select = {
.col = 0,
.row = thisCST[Shm->Cpu[0].Query.CStateInclude] != -1 ?
thisCST[Shm->Cpu[0].Query.CStateInclude] : 0
};
Window *wBox = CreateBox(scan->key, origin, select,
" I/O MWAIT Max C-State ",
(ASCII*)" C7 ", stateAttr[0], BOXKEY_IORCST_C7,
(ASCII*)" C6 ", stateAttr[0], BOXKEY_IORCST_C6,
(ASCII*)" C4 ", stateAttr[0], BOXKEY_IORCST_C4,
(ASCII*)" C3 ", stateAttr[0], BOXKEY_IORCST_C3);
if (wBox != NULL) {
TCellAt(wBox, 0, select.row).attr[11] = \
TCellAt(wBox, 0, select.row).attr[12] = \
TCellAt(wBox, 0, select.row).attr[13] = \
TCellAt(wBox, 0, select.row).attr[14] = \
TCellAt(wBox, 0, select.row).attr[15] = \
TCellAt(wBox, 0, select.row).attr[16] = \
stateAttr[1];
TCellAt(wBox, 0, select.row).item[11] = '<';
TCellAt(wBox, 0, select.row).item[16] = '>';
AppendWindow(wBox, &winList);
} else
SetHead(&winList, win);
} else
SetHead(&winList, win);
}
break;
case BOXKEY_IORCST_C3:
case BOXKEY_IORCST_C4:
case BOXKEY_IORCST_C6:
case BOXKEY_IORCST_C7:
{
const unsigned long newCST = (scan->key - BOXKEY_IORCST_C0) >> 4;
if (!RING_FULL(Shm->Ring))
RING_WRITE(Shm->Ring, COREFREQ_IOCTL_IORCST, newCST);
}
break;
case BOXKEY_ODCM:
{
Window *win = SearchWinListById(scan->key, &winList);
if (win == NULL)
{
const unsigned int isODCM = !BITWISEXOR(LOCKLESS,
Shm->Proc.ODCM,
Shm->Proc.ODCM_Mask);
const Coordinate origin = {
.col = (drawSize.width - strlen((char *) blankStr)) / 2,
.row = TOP_HEADER_ROW + 6
}, select = {
.col = 0,
.row = isODCM ? 4 : 3
};
AppendWindow(CreateBox(scan->key, origin, select, " ODCM ",
blankStr, blankAttr, SCANKEY_NULL,
descStr[8], descAttr, SCANKEY_NULL,
blankStr, blankAttr, SCANKEY_NULL,
stateStr[1][isODCM], stateAttr[isODCM], BOXKEY_ODCM_ON,
stateStr[0][!isODCM], stateAttr[!isODCM],BOXKEY_ODCM_OFF,
blankStr, blankAttr, SCANKEY_NULL),
&winList);
} else
SetHead(&winList, win);
}
break;
case BOXKEY_ODCM_OFF:
{
if (!RING_FULL(Shm->Ring))
RING_WRITE(Shm->Ring, COREFREQ_IOCTL_ODCM, COREFREQ_TOGGLE_OFF);
}
break;
case BOXKEY_ODCM_ON:
{
if (!RING_FULL(Shm->Ring))
RING_WRITE(Shm->Ring, COREFREQ_IOCTL_ODCM, COREFREQ_TOGGLE_ON);
}
break;
case BOXKEY_DUTYCYCLE:
{
Window *win = SearchWinListById(scan->key, &winList);
if (win == NULL)
{
const CSINT maxCM = 7 << Shm->Cpu[0].PowerThermal.DutyCycle.Extended;
const Coordinate origin = {
.col = (drawSize.width - (44 - 17)) / 2,
.row = TOP_HEADER_ROW + 3
}, select = {
.col = 0,
.row = (Shm->Cpu[0].PowerThermal.DutyCycle.ClockMod >= 0)
&& (Shm->Cpu[0].PowerThermal.DutyCycle.ClockMod <= maxCM) ?
Shm->Cpu[0].PowerThermal.DutyCycle.ClockMod : 1
};
Window *wBox = NULL;
if (Shm->Cpu[0].PowerThermal.DutyCycle.Extended)
wBox = CreateBox(scan->key, origin, select,
" Extended Duty Cycle ",
(ASCII*)" Reserved ", blankAttr, BOXKEY_ODCM_DC00,
(ASCII*)" 6.25% ", stateAttr[0], BOXKEY_ODCM_DC01,
(ASCII*)" 12.50% ", stateAttr[0], BOXKEY_ODCM_DC02,
(ASCII*)" 18.75% ", stateAttr[0], BOXKEY_ODCM_DC03,
(ASCII*)" 25.00% ", stateAttr[0], BOXKEY_ODCM_DC04,
(ASCII*)" 31.25% ", stateAttr[0], BOXKEY_ODCM_DC05,
(ASCII*)" 37.50% ", stateAttr[0], BOXKEY_ODCM_DC06,
(ASCII*)" 43.75% ", stateAttr[0], BOXKEY_ODCM_DC07,
(ASCII*)" 50.00% ", stateAttr[0], BOXKEY_ODCM_DC08,
(ASCII*)" 56.25% ", stateAttr[0], BOXKEY_ODCM_DC09,
(ASCII*)" 63.50% ", stateAttr[0], BOXKEY_ODCM_DC10,
(ASCII*)" 68.75% ", stateAttr[0], BOXKEY_ODCM_DC11,
(ASCII*)" 75.00% ", stateAttr[0], BOXKEY_ODCM_DC12,
(ASCII*)" 81.25% ", stateAttr[0], BOXKEY_ODCM_DC13,
(ASCII*)" 87.50% ", stateAttr[0], BOXKEY_ODCM_DC14);
else
wBox = CreateBox(scan->key, origin, select,
" Duty Cycle ",
(ASCII*)" Reserved ", blankAttr, BOXKEY_ODCM_DC00,
(ASCII*)" 12.50% ", stateAttr[0], BOXKEY_ODCM_DC01,
(ASCII*)" 25.00% ", stateAttr[0], BOXKEY_ODCM_DC02,
(ASCII*)" 37.50% ", stateAttr[0], BOXKEY_ODCM_DC03,
(ASCII*)" 50.00% ", stateAttr[0], BOXKEY_ODCM_DC04,
(ASCII*)" 62.50% ", stateAttr[0], BOXKEY_ODCM_DC05,
(ASCII*)" 75.00% ", stateAttr[0], BOXKEY_ODCM_DC06,
(ASCII*)" 87.50% ", stateAttr[0], BOXKEY_ODCM_DC07);
if (wBox != NULL) {
TCellAt(wBox, 0, select.row).attr[ 8] = \
TCellAt(wBox, 0, select.row).attr[ 9] = \
TCellAt(wBox, 0, select.row).attr[10] = \
TCellAt(wBox, 0, select.row).attr[11] = \
TCellAt(wBox, 0, select.row).attr[12] = \
TCellAt(wBox, 0, select.row).attr[13] = \
TCellAt(wBox, 0, select.row).attr[14] = \
TCellAt(wBox, 0, select.row).attr[15] = \
TCellAt(wBox, 0, select.row).attr[16] = \
TCellAt(wBox, 0, select.row).attr[17] = \
TCellAt(wBox, 0, select.row).attr[18] = \
TCellAt(wBox, 0, select.row).attr[19] = stateAttr[1];
TCellAt(wBox, 0, select.row).item[ 8] = '<';
TCellAt(wBox, 0, select.row).item[19] = '>';
AppendWindow(wBox, &winList);
} else
SetHead(&winList, win);
} else
SetHead(&winList, win);
}
break;
case BOXKEY_ODCM_DC00:
case BOXKEY_ODCM_DC01:
case BOXKEY_ODCM_DC02:
case BOXKEY_ODCM_DC03:
case BOXKEY_ODCM_DC04:
case BOXKEY_ODCM_DC05:
case BOXKEY_ODCM_DC06:
case BOXKEY_ODCM_DC07:
case BOXKEY_ODCM_DC08:
case BOXKEY_ODCM_DC09:
case BOXKEY_ODCM_DC10:
case BOXKEY_ODCM_DC11:
case BOXKEY_ODCM_DC12:
case BOXKEY_ODCM_DC13:
case BOXKEY_ODCM_DC14:
{
const unsigned long newDC = (scan->key - BOXKEY_ODCM_DC00) >> 4;
if (!RING_FULL(Shm->Ring))
RING_WRITE(Shm->Ring, COREFREQ_IOCTL_ODCM_DC, newDC);
}
break;
case SCANKEY_k:
if (BITWISEAND(LOCKLESS, Shm->SysGate.Operation, 0x1) == 0)
break;
// fallthrough
case SCANKEY_e:
case SCANKEY_o:
case SCANKEY_p:
case SCANKEY_SHIFT_i:
case SCANKEY_t:
case SCANKEY_u:
case SCANKEY_w:
{
Window *win = SearchWinListById(scan->key, &winList);
if (win == NULL)
AppendWindow(CreateSysInfo(scan->key), &winList);
else
SetHead(&winList, win);
}
break;
default:
if (scan->key & TRACK_TASK) {
Shm->SysGate.trackTask = scan->key & TRACK_MASK;
drawFlag.layout = 1;
}
else
return(-1);
}
return(0);
}
void PrintLCD(Layer *layer, CUINT col, CUINT row,
unsigned int relativeFreq, double relativeRatio)
{
unsigned int lcdColor, j = 4;
Dec2Digit(relativeFreq, digit);
if (relativeRatio > medianRatio)
lcdColor = RED;
else if (relativeRatio > minRatio)
lcdColor = YELLOW;
else
lcdColor = GREEN;
do {
int offset = col + (4 - j) * 3;
LayerFillAt(layer, offset, row,
3, lcd[digit[9 - j]][0],
MakeAttr(lcdColor, 0, BLACK, 1));
LayerFillAt(layer, offset, (row + 1),
3, lcd[digit[9 - j]][1],
MakeAttr(lcdColor, 0, BLACK, 1));
LayerFillAt(layer, offset, (row + 2),
3, lcd[digit[9 - j]][2],
MakeAttr(lcdColor, 0, BLACK, 1));
j--;
} while (j > 0) ;
}
void PrintTaskMemory(Layer *layer, CUINT row,
int taskCount,
unsigned long freeRAM,
unsigned long totalRAM)
{
sprintf(buffer, "%6u" "%9lu" "%-9lu", taskCount, freeRAM, totalRAM);
memcpy(&LayerAt(layer, code, (drawSize.width -35), row), &buffer[0], 6);
memcpy(&LayerAt(layer, code, (drawSize.width -22), row), &buffer[6], 9);
memcpy(&LayerAt(layer, code, (drawSize.width -12), row), &buffer[15],9);
}
CUINT Layout_Header(Layer *layer, CUINT row)
{
struct FLIP_FLOP *Flop = NULL;
size_t len;
// Reset the Top Frequency
Flop=&Shm->Cpu[Shm->Proc.Top].FlipFlop[!Shm->Cpu[Shm->Proc.Top].Toggle];
PrintLCD(layer, 0, row,
(unsigned int) Flop->Relative.Freq, Flop->Relative.Ratio);
LayerDeclare(12) hProc0 = {
.origin = {.col = 12, .row = row}, .length = 12,
.attr = {LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,HDK},
.code = {' ','P','r','o','c','e','s','s','o','r',' ','['}
};
LayerDeclare(11) hProc1 = {
.origin = {.col = drawSize.width - 11, .row = row},.length = 11,
.attr = {HDK,HWK,HWK,HWK,HDK,HWK,HWK,HWK,LWK,LWK,LWK},
.code = {']',' ',' ',' ','/',' ',' ',' ','C','P','U'}
};
row++;
LayerDeclare(15) hArch0 = {
.origin = {.col = 12, .row = row}, .length = 15,
.attr={LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,HDK},
.code={' ','A','r','c','h','i','t','e','c','t','u','r','e',' ','['}
};
LayerDeclare(30) hArch1 = {
.origin = {.col = drawSize.width - 30, .row = row},.length = 30,
.attr ={HDK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,HWK,HWK,HWK, \
LWK,LWK,LWK,LWK,LWK,HWK,HWK,HWK,LWK,LWK
},
.code ={']',' ','C','a','c','h','e','s',' ', \
'L','1',' ','I','n','s','t','=',' ',' ',' ', \
'D','a','t','a','=',' ',' ',' ','K','B'
}
};
row++;
LayerDeclare(28) hBClk0 = {
.origin = {.col = 12, .row = row}, .length = 28,
.attr ={LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,\
HYK,HYK,HYK,HYK,HYK,HYK,HYK,HYK,HYK,HYK,HYK,HYK,HYK,\
LWK,LWK,LWK
},
.code ={' ','B','a','s','e',' ','C','l','o','c','k',' ',\
'~',' ','0','0','0',' ','0','0','0',' ','0','0','0',\
' ','H','z'
}
};
LayerDeclare(18) hBClk1 = {
.origin = {.col = drawSize.width - 18, .row = row},.length = 18,
.attr ={LWK,LWK,LWK,HWK,HWK,HWK,HWK,HWK, \
LWK,LWK,LWK,HWK,HWK,HWK,HWK,HWK,LWK,LWK
},
.code ={'L','2','=',' ',' ',' ',' ',' ', \
'L','3','=',' ',' ',' ',' ',' ','K','B'
}
};
row++;
sprintf(buffer, "%2u" "%-2u",
Shm->Proc.CPU.OnLine, Shm->Proc.CPU.Count);
hProc1.code[2] = buffer[0];
hProc1.code[3] = buffer[1];
hProc1.code[5] = buffer[2];
hProc1.code[6] = buffer[3];
unsigned int L1I_Size = 0, L1D_Size = 0, L2U_Size = 0, L3U_Size = 0;
if (Shm->Proc.Features.Info.Vendor.CRC == CRC_INTEL) {
L1I_Size = Shm->Cpu[0].Topology.Cache[0].Size / 1024;
L1D_Size = Shm->Cpu[0].Topology.Cache[1].Size / 1024;
L2U_Size = Shm->Cpu[0].Topology.Cache[2].Size / 1024;
L3U_Size = Shm->Cpu[0].Topology.Cache[3].Size / 1024;
} else {
if (Shm->Proc.Features.Info.Vendor.CRC == CRC_AMD) {
L1I_Size = Shm->Cpu[0].Topology.Cache[0].Size;
L1D_Size = Shm->Cpu[0].Topology.Cache[1].Size;
L2U_Size = Shm->Cpu[0].Topology.Cache[2].Size;
L3U_Size = Shm->Cpu[0].Topology.Cache[3].Size;
}
}
sprintf(buffer, "%-3u" "%-3u", L1I_Size, L1D_Size);
hArch1.code[17] = buffer[0];
hArch1.code[18] = buffer[1];
hArch1.code[19] = buffer[2];
hArch1.code[25] = buffer[3];
hArch1.code[26] = buffer[4];
hArch1.code[27] = buffer[5];
sprintf(buffer, "%-4u" "%-5u", L2U_Size, L3U_Size);
hBClk1.code[ 3] = buffer[0];
hBClk1.code[ 4] = buffer[1];
hBClk1.code[ 5] = buffer[2];
hBClk1.code[ 6] = buffer[3];
hBClk1.code[11] = buffer[4];
hBClk1.code[12] = buffer[5];
hBClk1.code[13] = buffer[6];
hBClk1.code[14] = buffer[7];
hBClk1.code[15] = buffer[8];
len = strlen(Shm->Proc.Brand);
LayerCopyAt(layer, hProc0.origin.col, hProc0.origin.row,
hProc0.length, hProc0.attr, hProc0.code);
LayerFillAt(layer, hProc0.origin.col + hProc0.length, hProc0.origin.row,
len, Shm->Proc.Brand,
MakeAttr(CYAN, 0, BLACK, 1));
if ((hProc1.origin.col - len) > 0)
LayerFillAt(layer, hProc0.origin.col + hProc0.length + len,
hProc0.origin.row,
hProc1.origin.col - len, hSpace,
MakeAttr(BLACK, 0, BLACK, 1));
LayerCopyAt(layer, hProc1.origin.col, hProc1.origin.row,
hProc1.length, hProc1.attr, hProc1.code);
len = strlen(Shm->Proc.Architecture);
LayerCopyAt(layer, hArch0.origin.col, hArch0.origin.row,
hArch0.length, hArch0.attr, hArch0.code);
LayerFillAt(layer, hArch0.origin.col + hArch0.length, hArch0.origin.row,
len, Shm->Proc.Architecture,
MakeAttr(CYAN, 0, BLACK, 1));
if ((hArch1.origin.col - len) > 0)
LayerFillAt(layer, hArch0.origin.col + hArch0.length + len,
hArch0.origin.row,
hArch1.origin.col - len, hSpace,
MakeAttr(BLACK, 0, BLACK, 1));
LayerCopyAt(layer, hArch1.origin.col, hArch1.origin.row,
hArch1.length, hArch1.attr, hArch1.code);
LayerCopyAt(layer, hBClk0.origin.col, hBClk0.origin.row,
hBClk0.length, hBClk0.attr, hBClk0.code);
LayerFillAt(layer, hBClk0.origin.col + hBClk0.length, hBClk0.origin.row,
hBClk1.origin.col - hBClk0.origin.col + hBClk0.length,
hSpace,
MakeAttr(BLACK, 0, BLACK, 1));
LayerCopyAt(layer, hBClk1.origin.col, hBClk1.origin.row,
hBClk1.length, hBClk1.attr, hBClk1.code);
return(row);
}
CUINT Layout_Ruller_Load(Layer *layer, CUINT row)
{
LayerDeclare(MAX_WIDTH) hLoad0 = {
.origin = {.col = 0, .row = row}, .length = drawSize.width,
.attr ={LWK,LWK,LWK,LWK,LCK,LCK,LCK,LCK, \
LCK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK
},
.code ={'-','-','-',' ','R','a','t','i', \
'o',' ','-','-','-','-','-','-', \
'-','-','-','-','-','-','-','-', \
'-','-','-','-','-','-','-','-', \
'-','-','-','-','-','-','-','-', \
'-','-','-','-','-','-','-','-', \
'-','-','-','-','-','-','-','-', \
'-','-','-','-','-','-','-','-', \
'-','-','-','-','-','-','-','-', \
'-','-','-','-','-','-','-','-', \
'-','-','-','-','-','-','-','-', \
'-','-','-','-','-','-','-','-', \
'-','-','-','-','-','-','-','-', \
'-','-','-','-','-','-','-','-', \
'-','-','-','-','-','-','-','-', \
'-','-','-','-','-','-','-','-', \
'-','-','-','-'
}
};
// Alternate the color of the frequency ratios
unsigned int idx;
int bright = 0;
for (idx = 0; idx < ratioCount; idx++) {
char tabStop[] = "00";
int hPos = availRatio[idx] * loadWidth / maxRatio;
sprintf(tabStop, "%2.0f", availRatio[idx]);
if (tabStop[0] != 0x20) {
hLoad0.code[hPos + 2] =tabStop[0];
hLoad0.attr[hPos + 2] =MakeAttr(CYAN, 0, BLACK, bright);
}
hLoad0.code[hPos + 3] = tabStop[1];
hLoad0.attr[hPos + 3] = MakeAttr(CYAN, 0, BLACK, bright);
bright = !bright;
}
LayerCopyAt(layer, hLoad0.origin.col, hLoad0.origin.row,
hLoad0.length, hLoad0.attr, hLoad0.code);
return(row);
}
CUINT Layout_Monitor_Frequency(Layer *layer, CUINT row)
{
LayerDeclare(77) hMon0 = {
.origin = { .col = LOAD_LEAD - 1,
.row = (row + Shm->Proc.CPU.Count + 1)
},
.length = 77,
.attr ={HWK, \
HWK,HWK,HWK,HWK,LWK,HWK,HWK,LWK, \
HDK,HWK,HWK,LWK,HWK,HWK,HDK,LWK, \
HWK,HWK,HWK,LWK,HWK,HWK,LWK,LWK, \
HWK,HWK,HWK,LWK,HWK,HWK,LWK,LWK, \
HWK,HWK,HWK,LWK,HWK,HWK,LWK,LWK, \
HWK,HWK,HWK,LWK,HWK,HWK,LWK,LWK, \
HWK,HWK,HWK,LWK,HWK,HWK,LWK,LWK, \
HWK,HWK,HWK,LWK,HWK,HWK,LWK,LWK,LWK, \
HBK,HBK,HBK,HDK, \
LWK,LWK,LWK,HDK, \
LYK,LYK,LYK \
},
.code ={' ', \
' ',' ',' ',' ',0x0,' ',' ',' ', \
0x0,' ',' ',0x0,' ',' ',0x0,' ', \
' ',' ',' ',0x0,' ',' ',0x0,' ', \
' ',' ',' ',0x0,' ',' ',0x0,' ', \
' ',' ',' ',0x0,' ',' ',0x0,' ', \
' ',' ',' ',0x0,' ',' ',0x0,' ', \
' ',' ',' ',0x0,' ',' ',0x0,' ', \
' ',' ',' ',0x0,' ',' ',0x0,' ',' ', \
' ',' ',' ',0x0, \
' ',' ',' ',0x0, \
' ',' ',' ' \
}
};
LayerCopyAt(layer, hMon0.origin.col, hMon0.origin.row,
hMon0.length, hMon0.attr, hMon0.code);
LayerFillAt(layer, (hMon0.origin.col + hMon0.length),
hMon0.origin.row,
(drawSize.width - hMon0.length),
hSpace,
MakeAttr(BLACK, 0, BLACK, 1));
return(row);
}
CUINT Layout_Monitor_Instructions(Layer *layer, CUINT row)
{
LayerDeclare(76) hMon0 = {
.origin = { .col = LOAD_LEAD - 1,
.row = (row + Shm->Proc.CPU.Count + 1)
},
.length = 76,
.attr ={HWK, \
HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK, \
HWK,HWK,HWK,HWK,HWK,HWK,HDK,LWK, \
HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK, \
HWK,HWK,HWK,HWK,HWK,HWK,HDK,LWK, \
HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK, \
HWK,HWK,HWK,HWK,HWK,HWK,HDK,LWK, \
HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK, \
HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK
},
.code ={' ', \
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',0x0, \
' ',' ',' ',' ',' ',' ',0x0,0x0, \
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',0x0, \
' ',' ',' ',' ',' ',' ',0x0,0x0, \
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',0x0, \
' ',' ',' ',' ',' ',' ',0x0,0x0, \
' ',' ',' ',' ',' ',' ',' ',' ',' ', \
' ',' ',' ',' ',' ',' ',' ',' ',' '
}
};
LayerCopyAt(layer, hMon0.origin.col, hMon0.origin.row,
hMon0.length, hMon0.attr, hMon0.code);
LayerFillAt(layer, (hMon0.origin.col + hMon0.length),
hMon0.origin.row,
(drawSize.width - hMon0.length),
hSpace,
MakeAttr(BLACK, 0, BLACK, 1));
return(row);
}
CUINT Layout_Monitor_Common(Layer *layer, CUINT row)
{
LayerDeclare(73) hMon0 = {
.origin = { .col = LOAD_LEAD - 1,
.row = (row + Shm->Proc.CPU.Count + 1)
},
.length = 73,
.attr ={HWK, \
HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK, \
HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK, \
HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK, \
HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK, \
HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK, \
HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK, \
HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK, \
HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK
},
.code ={' ', \
' ',' ',' ',' ',' ',' ',' ',' ',' ', \
' ',' ',' ',' ',' ',' ',' ',' ',' ', \
' ',' ',' ',' ',' ',' ',' ',' ',' ', \
' ',' ',' ',' ',' ',' ',' ',' ',' ', \
' ',' ',' ',' ',' ',' ',' ',' ',' ', \
' ',' ',' ',' ',' ',' ',' ',' ',' ', \
' ',' ',' ',' ',' ',' ',' ',' ',' ', \
' ',' ',' ',' ',' ',' ',' ',' ',' '
}
};
LayerCopyAt(layer, hMon0.origin.col, hMon0.origin.row,
hMon0.length, hMon0.attr, hMon0.code);
LayerFillAt(layer, (hMon0.origin.col + hMon0.length),
hMon0.origin.row,
(drawSize.width - hMon0.length),
hSpace,
MakeAttr(BLACK, 0, BLACK, 1));
return(row);
}
CUINT Layout_Monitor_Tasks(Layer *layer, CUINT row)
{
LayerDeclare(MAX_WIDTH - LOAD_LEAD + 1) hMon0 = {
.origin = { .col = LOAD_LEAD - 1,
.row = (row + Shm->Proc.CPU.Count + 1)
},
.length = MAX_WIDTH - LOAD_LEAD + 1,
.attr ={HWK, \
HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK \
},
.code ={' ', \
' ',' ',' ',' ',0x0,' ',' ',' ', \
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', \
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', \
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', \
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', \
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', \
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', \
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', \
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', \
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', \
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', \
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', \
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ' \
}
};
LayerCopyAt(layer, hMon0.origin.col, hMon0.origin.row,
hMon0.length, hMon0.attr, hMon0.code);
cTask[cpu].col = LOAD_LEAD + 8;
cTask[cpu].row = 2 + TOP_HEADER_ROW + cpu + Shm->Proc.CPU.Count;
return(row);
}
CUINT Layout_Ruller_Frequency(Layer *layer, CUINT row)
{
LayerDeclare(MAX_WIDTH) hFreq0 = {
.origin = {
.col = 0,
.row = row
},
.length = drawSize.width,
.attr = {
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,HDK,LWK,LWK,LWK, \
HDK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK
},
.code = "--- Freq(MHz) Ratio - Turbo --- " \
"C0 ---- C1 ---- C3 ---- C6 ---- C7 --" \
"Min TMP Max " \
"---------------------------------------------------",
};
LayerCopyAt(layer, hFreq0.origin.col, hFreq0.origin.row,
hFreq0.length, hFreq0.attr, hFreq0.code);
if (!drawFlag.avgOrPC) {
LayerDeclare(MAX_WIDTH) hAvg0 = {
.origin = {
.col = 0,
.row = (row + Shm->Proc.CPU.Count + 1)
},
.length = drawSize.width,
.attr ={LWK,LWK,LWK,LWK,LWK,LWK,LWK,_HCK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,HDK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,HDK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK
},
.code ={'-','-','-','-','-','-',' ','%', \
' ','A','v','e','r','a','g','e','s',' ','[', \
' ',' ',' ',' ',0x0,' ',' ',0x0, \
' ',' ',' ',' ',0x0,' ',' ',0x0, \
' ',' ',' ',' ',0x0,' ',' ',0x0, \
' ',' ',' ',' ',0x0,' ',' ',0x0, \
' ',' ',' ',' ',0x0,' ',' ',0x0, \
' ',' ',' ',' ',0x0,' ',' ',0x0,' ',']',' ', \
'-','-','-','-','-','-','-','-','-','-','-', \
'-','-','-','-','-','-','-','-','-','-','-', \
'-','-','-','-','-','-','-','-','-','-','-', \
'-','-','-','-','-','-','-','-','-','-','-', \
'-','-','-','-','-','-','-','-','-','-','-', \
'-','-','-','-','-','-','-'
}
};
LayerCopyAt(layer, hAvg0.origin.col, hAvg0.origin.row,
hAvg0.length, hAvg0.attr, hAvg0.code);
} else {
LayerDeclare(MAX_WIDTH) hPkg0 = {
.origin = {
.col = 0,
.row = (row + Shm->Proc.CPU.Count + 1)
},
.length = drawSize.width,
.attr ={LWK,LWK,LWK,LWK,LWK,LWK,_HCK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,HDK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,HDK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,HDK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,HDK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,HDK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,HDK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,HDK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK
},
.code ={'-','-','-','-','-',' ','%',' ','P','k','g', \
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', \
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', \
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', \
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', \
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', \
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', \
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', \
'-','-','-','-','-','-','-','-','-','-','-', \
'-','-','-','-','-','-','-','-','-','-','-', \
'-','-','-','-','-','-','-','-','-','-','-', \
'-','-','-','-','-','-','-','-','-','-','-', \
'-','-','-','-','-','-','-'
}
};
LayerCopyAt(layer, hPkg0.origin.col, hPkg0.origin.row,
hPkg0.length, hPkg0.attr, hPkg0.code);
}
return(row);
}
CUINT Layout_Ruller_Instructions(Layer *layer, CUINT row)
{
LayerFillAt(layer, 0, row, drawSize.width,
"------------ IPS -------------- IPC ----" \
"---------- CPI ------------------ INST -" \
"----------------------------------------" \
"------------",
MakeAttr(WHITE, 0, BLACK, 0));
LayerFillAt(layer, 0, (row + Shm->Proc.CPU.Count + 1),
drawSize.width, hLine,
MakeAttr(WHITE, 0, BLACK, 0));
return(row);
}
CUINT Layout_Ruller_Cycles(Layer *layer, CUINT row)
{
LayerFillAt(layer, 0, row, drawSize.width,
"-------------- C0:UCC ---------- C0:URC " \
"------------ C1 ------------- TSC ------" \
"----------------------------------------" \
"------------",
MakeAttr(WHITE, 0, BLACK, 0));
LayerFillAt(layer, 0, (row + Shm->Proc.CPU.Count + 1),
drawSize.width, hLine, MakeAttr(WHITE, 0, BLACK, 0));
return(row);
}
CUINT Layout_Ruller_CStates(Layer *layer, CUINT row)
{
LayerFillAt(layer, 0, row, drawSize.width,
"---------------- C1 -------------- C3 --" \
"------------ C6 -------------- C7 ------" \
"----------------------------------------" \
"------------",
MakeAttr(WHITE, 0, BLACK, 0));
LayerFillAt(layer, 0, (row + Shm->Proc.CPU.Count + 1),
drawSize.width, hLine, MakeAttr(WHITE, 0, BLACK, 0));
return(row);
}
CUINT Layout_Ruller_Interrupts(Layer *layer, CUINT row)
{
LayerDeclare(MAX_WIDTH) hIntr0 = {
.origin = {
.col = 0,
.row = row
},
.length = drawSize.width,
.attr = {
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,HDK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,HDK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK
},
.code = "---------- SMI ------------ NMI[ LOCAL UNKNOWN"\
" PCI_SERR# IO_CHECK] -------------------------"\
"------------------------------------",
};
LayerCopyAt(layer, hIntr0.origin.col, hIntr0.origin.row,
hIntr0.length, hIntr0.attr, hIntr0.code);
LayerFillAt(layer, 0, (row + Shm->Proc.CPU.Count + 1),
drawSize.width, hLine, MakeAttr(WHITE, 0, BLACK, 0));
return(row);
}
CUINT Layout_Ruller_Package(Layer *layer, CUINT row)
{
LayerFillAt(layer, 0, row, drawSize.width,
"------------ Cycles ---- State ---------" \
"----------- TSC Ratio ------------------" \
"----------------------------------------" \
"------------",
MakeAttr(WHITE, 0, BLACK, 0));
row++;
Attribute hPCnnAttr[MAX_WIDTH] = {
LWK,LWK,LWK,LWK,HDK, \
HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK, \
HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK, \
HWK,HWK,HWK,HWK,HWK,HWK,HWK,HDK,HDK, \
HBK,HBK,HBK,HBK,HBK,HBK,HBK,HBK,HBK,HBK,HBK,HBK, \
HBK,HBK,HBK,HBK,HBK,HBK,HBK,HBK,HBK,HBK,HBK,HBK, \
HBK,HBK,HBK,HBK,HBK,HBK,HBK,HBK,HBK,HBK,HBK,HBK, \
HBK,HBK,HBK,HBK,HBK,HBK,HBK,HBK,HBK,HBK,HBK,HBK, \
HBK,HBK,HBK,HBK,HBK,HBK,HBK,HBK,HBK,HBK,HBK,HBK, \
HBK,HBK,HBK,HBK,HBK,HBK,HBK,HBK,HBK,HBK,HBK,HBK, \
HBK,HBK,HBK,HBK,HBK,HBK,HBK,HBK,HBK,HBK,HBK,HBK, \
HBK,HBK,HBK,HBK,HBK,HBK,HBK,HBK,HBK,HBK,HBK,HBK, \
HBK,HBK,HBK,HBK
};
ASCII hPCnnCode[MAX_WIDTH] = {
'P','C','0','0',':', \
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, \
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, \
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, \
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', \
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', \
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', \
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', \
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', \
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', \
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', \
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', \
' ',' ',' ',' '
};
ASCII hCState[8][2] = {
{'0', '2'},
{'0', '3'},
{'0', '6'},
{'0', '7'},
{'0', '8'},
{'0', '9'},
{'1', '0'}
};
unsigned int idx;
for (idx = 0; idx < 7; idx++, row++)
{
hPCnnCode[2] = hCState[idx][0];
hPCnnCode[3] = hCState[idx][1];
LayerCopyAt(layer,0, row, drawSize.width, hPCnnAttr, hPCnnCode);
}
LayerDeclare(MAX_WIDTH) hUncore = {
.origin = {
.col = 0,
.row = row
},
.length = drawSize.width,
.attr = {
LWK,LWK,LWK,LWK,HDK, \
HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK, \
HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,\
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,\
LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,HDK, \
HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK, \
HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,\
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,\
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,\
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,\
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK
},
.code = {
' ','T','S','C',':', \
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, \
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, \
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',\
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',\
' ',' ',' ', \
'U','N','C','O','R','E',':', \
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, \
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, \
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',\
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',\
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',\
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',\
' ',' ',' ',' ',' ',' ',' ',' ',' '
}
};
LayerCopyAt(layer, hUncore.origin.col, hUncore.origin.row,
hUncore.length, hUncore.attr, hUncore.code);
row++;
LayerFillAt(layer, 0, row,
drawSize.width, hLine, MakeAttr(WHITE, 0, BLACK, 0));
return(row);
}
CUINT Layout_Ruller_Tasks(Layer *layer, CUINT row)
{
LayerDeclare(MAX_WIDTH) hTask0 = {
.origin = {
.col = 0,
.row = row
},
.length = drawSize.width,
.attr = {
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,HDK,LWK,LWK,LWK, \
HDK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LDK, \
LDK,LDK,LDK,LDK,LDK,LDK,LDK,LDK,LDK,LDK,LDK,LDK, \
LDK,LDK,LDK,LDK,LDK,LDK,LDK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK
},
.code =
"--- Freq(MHz) --- Tasks " \
" -------------------------------------" \
"----------------------------------------" \
"------------"
};
LayerDeclare(21) hTask1 = {
.origin = {.col = 23, .row = row},
.length = 21,
};
struct {
Attribute attr[21];
ASCII code[21];
} hSort[SORTBYCOUNT] = {
{
.attr = {
HDK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,_HCK,LWK, \
LWK,LCK,LCK,LCK,LCK,LCK,HDK,LWK, LWK,LWK,LWK
},
.code = {
'(','s','o','r','t','e','d',' ', 'b','y', \
' ','S','t','a','t','e',')',' ', '-','-','-'
}
},
{
.attr = {
HDK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,_HCK,LWK, \
LWK,LCK,LCK,LCK,LCK,LCK,LCK,LCK, HDK,LWK,LWK
},
.code = {
'(','s','o','r','t','e','d',' ', 'b','y', \
' ','R','u','n','T','i','m','e', ')',' ','-'
}
},
{
.attr = {
HDK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,_HCK,LWK, \
LWK,LCK,LCK,LCK,LCK,LCK,LCK,LCK, LCK,HDK,LWK
},
.code = {
'(','s','o','r','t','e','d',' ', 'b','y', \
' ','U','s','e','r','T','i','m', 'e',')',' '
}
},
{
.attr = {
HDK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,_HCK,LWK, \
LWK,LCK,LCK,LCK,LCK,LCK,LCK,LCK, HDK,LWK,LWK
},
.code = {
'(','s','o','r','t','e','d',' ', 'b','y', \
' ','S','y','s','T','i','m','e', ')',' ','-'
}
},
{
.attr = {
HDK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,_HCK,LWK, \
LWK,LCK,LCK,LCK,HDK,LWK,LWK,LWK, LWK,LWK,LWK
},
.code = {
'(','s','o','r','t','e','d',' ', 'b','y', \
' ','P','I','D',')',' ','-','-', '-','-','-'
}
},
{
.attr = {
HDK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,_HCK,LWK, \
LWK,LCK,LCK,LCK,LCK,LCK,LCK,LCK, HDK,LWK,LWK
},
.code = {
'(','s','o','r','t','e','d',' ', 'b','y', \
' ','C','o','m','m','a','n','d', ')',' ','-'
}
}
};
memcpy(hTask1.attr, hSort[Shm->SysGate.sortByField].attr,hTask1.length);
memcpy(hTask1.code, hSort[Shm->SysGate.sortByField].code,hTask1.length);
LayerDeclare(15) hTask2 = {
.origin = {
.col = drawSize.width - 18,
.row = (row + Shm->Proc.CPU.Count + 1)
},
.length = 15,
};
struct {
Attribute attr[15];
ASCII code[15];
} hReverse[2] = {
{
.attr = {
LWK,_HCK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,HDK,LWK,LWK,LWK,HDK,LWK
},
.code = {
' ', 'R','e','v','e','r','s','e',' ','[','O','F','F',']',' '
}
},
{
.attr = {
LWK,_HCK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,HDK,LCK,LCK,LCK,HDK,LWK
},
.code = {
' ', 'R','e','v','e','r','s','e',' ','[',' ','O','N',']',' '
}
}
};
memcpy(hTask2.attr, hReverse[Shm->SysGate.reverseOrder].attr,
hTask2.length);
memcpy(hTask2.code, hReverse[Shm->SysGate.reverseOrder].code,
hTask2.length);
LayerDeclare(13) hTask3 = {
.origin = {
.col = drawSize.width - 34,
.row = (row + Shm->Proc.CPU.Count + 1)
},
.length = 13,
.attr = {
LWK,_HCK,LWK,LWK,LWK,LWK,LWK,HDK,LWK,LWK,LWK,HDK,LWK
},
.code = {
' ', 'V','a','l','u','e',' ','[',' ',' ',' ',']',' '
}
};
struct {
Attribute attr[3];
ASCII code[3];
} hTaskVal[2] = {
{
.attr = {
LWK,LWK,LWK
},
.code = {
'O','F','F'
}
},
{
.attr = {
LCK,LCK,LCK
},
.code = {
' ','O','N'
}
}
};
memcpy(&hTask3.attr[8], hTaskVal[drawFlag.taskVal].attr, 3);
memcpy(&hTask3.code[8], hTaskVal[drawFlag.taskVal].code, 3);
LayerDeclare(22) hTrack0 = {
.origin = {
.col = 55,
.row = row
},
.length = 22,
.attr = {
LWK,LWK,LWK,LWK,LWK,LWK,LWK,_HCK,LWK, \
LWK,LWK,LWK,LWK,LWK,HDK,LWK, LWK,LWK, \
LWK,LWK,HDK,LWK
},
.code = {
' ','T','r','a','c','k','i', 'n','g', \
' ','P','I','D',' ','[',' ', 'O','F', \
'F',' ',']',' '
}
};
if (Shm->SysGate.trackTask) {
memset(&hTrack0.attr[15], MakeAttr(CYAN, 0, BLACK, 0).value, 5);
sprintf(buffer, "%5d", Shm->SysGate.trackTask);
memcpy(&hTrack0.code[15], buffer, 5);
}
LayerCopyAt(layer, hTask0.origin.col, hTask0.origin.row,
hTask0.length, hTask0.attr, hTask0.code);
LayerCopyAt(layer, hTask1.origin.col, hTask1.origin.row,
hTask1.length, hTask1.attr, hTask1.code);
LayerFillAt(layer, 0, (row + Shm->Proc.CPU.Count + 1),
drawSize.width, hLine, MakeAttr(WHITE, 0, BLACK, 0));
LayerCopyAt(layer, hTask2.origin.col, hTask2.origin.row,
hTask2.length, hTask2.attr, hTask2.code);
LayerCopyAt(layer, hTask3.origin.col, hTask3.origin.row,
hTask3.length, hTask3.attr, hTask3.code);
LayerCopyAt(layer, hTrack0.origin.col, hTrack0.origin.row,
hTrack0.length, hTrack0.attr, hTrack0.code);
return(row);
}
CUINT Layout_Ruller_Voltage(Layer *layer, CUINT row)
{
LayerDeclare(MAX_WIDTH) hVolt0 = {
.origin = {
.col = 0,
.row = row
},
.length = drawSize.width,
.attr = {
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,HDK,LWK,LWK,LWK, \
HDK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK, \
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK
},
.code = "--- Freq(MHz) - VID - Vcore ------------" \
"----------------------------------------" \
"----------------------------------------" \
"------------"
};
LayerCopyAt(layer, hVolt0.origin.col, hVolt0.origin.row,
hVolt0.length, hVolt0.attr, hVolt0.code);
LayerFillAt(layer, 0, (row + Shm->Proc.CPU.Count + 1),
drawSize.width, hLine,
MakeAttr(WHITE, 0, BLACK, 0));
return(row);
}
CUINT Layout_Footer(Layer *layer, CUINT row, unsigned int *processorHot)
{
const unsigned int
isTurbo = !BITWISEXOR(LOCKLESS, Shm->Proc.TurboBoost,
Shm->Proc.TurboBoost_Mask),
isEIST = !BITWISEXOR(LOCKLESS, Shm->Proc.SpeedStep,
Shm->Proc.SpeedStep_Mask),
isC1E = !BITWISEXOR(LOCKLESS,Shm->Proc.C1E, Shm->Proc.C1E_Mask),
isC3A = !BITWISEXOR(LOCKLESS,Shm->Proc.C3A, Shm->Proc.C3A_Mask),
isC1A = !BITWISEXOR(LOCKLESS,Shm->Proc.C1A, Shm->Proc.C1A_Mask),
isC3U = !BITWISEXOR(LOCKLESS,Shm->Proc.C3U, Shm->Proc.C3U_Mask),
isC1U = !BITWISEXOR(LOCKLESS,Shm->Proc.C1U, Shm->Proc.C1U_Mask);
CUINT col = 0;
size_t len;
LayerDeclare(61) hTech0 = {
.origin = {.col = 0, .row = row}, .length = 14,
.attr={LWK,LWK,LWK,LWK,LWK,HDK,HDK,HDK,HDK,HDK,HDK,HDK,HDK,LWK},
.code={'T','e','c','h',' ','[',' ',' ','T','S','C',' ',' ',','},
};
const Attribute Pwr[] = {
MakeAttr(BLACK, 0, BLACK, 1),
MakeAttr(GREEN, 0, BLACK, 1),
MakeAttr(BLUE, 0, BLACK, 1)
};
const struct { ASCII *code; Attribute attr; } TSC[] = {
{(ASCII *) " TSC ", MakeAttr(BLACK, 0, BLACK, 1)},
{(ASCII *) "TSC-VAR" , MakeAttr(BLUE, 0, BLACK, 1)},
{(ASCII *) "TSC-INV" , MakeAttr(GREEN, 0, BLACK, 1)}
};
hTech0.code[ 6] = TSC[Shm->Proc.Features.InvariantTSC].code[0];
hTech0.code[ 7] = TSC[Shm->Proc.Features.InvariantTSC].code[1];
hTech0.code[ 8] = TSC[Shm->Proc.Features.InvariantTSC].code[2];
hTech0.code[ 9] = TSC[Shm->Proc.Features.InvariantTSC].code[3];
hTech0.code[10] = TSC[Shm->Proc.Features.InvariantTSC].code[4];
hTech0.code[11] = TSC[Shm->Proc.Features.InvariantTSC].code[5];
hTech0.code[12] = TSC[Shm->Proc.Features.InvariantTSC].code[6];
hTech0.attr[ 6] = hTech0.attr[ 7]=hTech0.attr[ 8] =
hTech0.attr[ 9] = hTech0.attr[10]=hTech0.attr[11] =
hTech0.attr[12] = TSC[Shm->Proc.Features.InvariantTSC].attr;
LayerCopyAt(layer, hTech0.origin.col, hTech0.origin.row,
hTech0.length, hTech0.attr, hTech0.code);
if (Shm->Proc.Features.Info.Vendor.CRC == CRC_INTEL)
{
LayerDeclare(69) hTech1 = {
.origin={.col=hTech0.length, .row=hTech0.origin.row},.length=55,
.attr ={HDK,HDK,HDK,LWK,HDK,HDK,HDK,HDK,LWK,HDK,HDK,HDK,LWK, \
HDK,HDK,HDK,HDK,HDK,LWK,HDK,HDK,HDK,LWK, \
HDK,HDK,HDK,LWK,HDK,HDK,HDK,LWK,HDK,HDK,HDK,LWK,\
HDK,HDK,HDK,LWK,HDK,HDK,HDK,LWK, \
HDK,HDK,HDK,LWK,HDK,HDK,HDK,LWK,HDK,HDK,HDK,HDK
},
.code ={'H','T','T',',','E','I','S','T',',','I','D','A',',', \
'T','U','R','B','O',',','C','1','E',',', \
' ','P','M',',','C','3','A',',','C','1','A',',',\
'C','3','U',',','C','1','U',',', \
'T','M','1',',','T','M','2',',','H','O','T',']'
},
};
hTech1.attr[0] = hTech1.attr[1] = hTech1.attr[2] =
Pwr[Shm->Proc.Features.HyperThreading];
const Attribute TM1[] = {
MakeAttr(BLACK, 0, BLACK, 1),
MakeAttr(BLUE, 0, BLACK, 1),
MakeAttr(WHITE, 0, BLACK, 1),
MakeAttr(GREEN, 0, BLACK, 1)
};
const Attribute TM2[] = {
MakeAttr(BLACK, 0, BLACK, 1),
MakeAttr(BLUE, 0, BLACK, 1),
MakeAttr(WHITE, 0, BLACK, 1),
MakeAttr(GREEN, 0, BLACK, 1)
};
hTech1.attr[4] = hTech1.attr[5] = hTech1.attr[6] = hTech1.attr[7] =
Pwr[isEIST];
hTech1.attr[9] = hTech1.attr[10] = hTech1.attr[11] =
Pwr[Shm->Proc.Features.Power.EAX.TurboIDA];
hTech1.attr[13] = hTech1.attr[14] = hTech1.attr[15] =
hTech1.attr[16] = hTech1.attr[17] = Pwr[isTurbo];
hTech1.attr[19] = hTech1.attr[20] = hTech1.attr[21] = Pwr[isC1E];
sprintf(buffer, "PM%1d", Shm->Proc.PM_version);
hTech1.code[23] = buffer[0];
hTech1.code[24] = buffer[1];
hTech1.code[25] = buffer[2];
hTech1.attr[23] = hTech1.attr[24] = hTech1.attr[25] =
Pwr[(Shm->Proc.PM_version > 0)];
hTech1.attr[27] = hTech1.attr[28] = hTech1.attr[29] = Pwr[isC3A];
hTech1.attr[31] = hTech1.attr[32] = hTech1.attr[33] = Pwr[isC1A];
hTech1.attr[35] = hTech1.attr[36] = hTech1.attr[37] = Pwr[isC3U];
hTech1.attr[39] = hTech1.attr[40] = hTech1.attr[41] = Pwr[isC1U];
hTech1.attr[43] = hTech1.attr[44] = hTech1.attr[45] =
TM1[Shm->Cpu[0].PowerThermal.TM1];
hTech1.attr[47] = hTech1.attr[48] = hTech1.attr[49] =
TM2[Shm->Cpu[0].PowerThermal.TM2];
if ( (*processorHot) ) {
hTech1.attr[51] = hTech1.attr[52] = hTech1.attr[53] =
MakeAttr(RED, 0, BLACK, 1);
}
LayerCopyAt(layer, hTech1.origin.col, hTech1.origin.row,
hTech1.length, hTech1.attr, hTech1.code);
LayerFillAt(layer, (hTech1.origin.col + hTech1.length),
hTech1.origin.row,
(drawSize.width - hTech0.length-hTech1.length),
hSpace,
MakeAttr(BLACK, 0, BLACK, 1));
} else {
if (Shm->Proc.Features.Info.Vendor.CRC == CRC_AMD) {
LayerDeclare(65) hTech1 = {
.origin={.col=hTech0.length, .row=hTech0.origin.row},.length=39,
.attr={HDK,HDK,HDK,LWK,HDK,HDK,HDK,HDK,HDK,HDK,HDK,HDK,LWK,\
HDK,HDK,HDK,HDK,HDK,LWK,HDK,HDK,HDK,LWK,HDK,HDK,HDK,LWK,\
HDK,HDK,HDK,LWK,HDK,HDK,HDK,LWK,HDK,HDK,HDK,HDK
},
.code={'H','T','T',',','P','o','w','e','r','N','o','w',',',\
'T','U','R','B','O',',','C','1','E',',',' ','P','M',',',\
'D','T','S',',','T','T','P',',','H','O','T',']'
},
};
hTech1.attr[0] = hTech1.attr[1] = hTech1.attr[2] =
Pwr[Shm->Proc.Features.HyperThreading];
hTech1.attr[4] = hTech1.attr[5] = hTech1.attr[ 6] = hTech1.attr[ 7]=
hTech1.attr[8] = hTech1.attr[9] = hTech1.attr[10] = hTech1.attr[11]=
Pwr[(Shm->Proc.PowerNow == 0b11)];
hTech1.attr[13] = hTech1.attr[14] = hTech1.attr[15] =
hTech1.attr[16] = hTech1.attr[17] = Pwr[isTurbo];
hTech1.attr[19] = hTech1.attr[20] = hTech1.attr[21] = Pwr[isC1E];
sprintf(buffer, "PM%1d", Shm->Proc.PM_version);
hTech1.code[23] = buffer[0];
hTech1.code[24] = buffer[1];
hTech1.code[25] = buffer[2];
hTech1.attr[23] = hTech1.attr[24] = hTech1.attr[25] =
Pwr[(Shm->Proc.PM_version > 0)];
hTech1.attr[27] = hTech1.attr[28] = hTech1.attr[29] =
Pwr[(Shm->Proc.Features.AdvPower.EDX.TS != 0)];
hTech1.attr[31] = hTech1.attr[32] = hTech1.attr[33] =
Pwr[(Shm->Proc.Features.AdvPower.EDX.TTP != 0)];
if ( (*processorHot) ) {
hTech1.attr[35] = hTech1.attr[36] = hTech1.attr[37] =
MakeAttr(RED, 0, BLACK, 1);
}
LayerCopyAt(layer, hTech1.origin.col, hTech1.origin.row,
hTech1.length, hTech1.attr, hTech1.code);
LayerFillAt(layer, (hTech1.origin.col + hTech1.length),
hTech1.origin.row,
(drawSize.width - hTech0.length-hTech1.length),
hSpace,
MakeAttr(BLACK, 0, BLACK, 1));
}
}
row++;
len = sprintf( buffer, "%s",
BITWISEAND(LOCKLESS, Shm->SysGate.Operation, 0x1) ?
Shm->SysGate.sysname : "SysGate");
LayerFillAt( layer, col, row,
len, buffer,
MakeAttr(CYAN, 0, BLACK, 0));
col += len;
LayerAt(layer, attr, col, row) = MakeAttr(WHITE, 0, BLACK, 0);
LayerAt(layer, code, col, row) = 0x20;
col++;
LayerAt(layer, attr, col, row) = MakeAttr(BLACK, 0, BLACK, 1);
LayerAt(layer, code, col, row) = '[';
col++;
if (BITWISEAND(LOCKLESS, Shm->SysGate.Operation, 0x1)) {
len = sprintf(buffer, "%hu.%hu.%hu",
Shm->SysGate.kernel.version,
Shm->SysGate.kernel.major,
Shm->SysGate.kernel.minor);
LayerFillAt( layer, col, row,
len, buffer,
MakeAttr(WHITE, 0, BLACK, 1));
col += len;
if ((len = strlen(Shm->SysGate.IdleDriver.Name)) > 0) {
LayerAt(layer, attr, col, row) = MakeAttr(BLACK, 0, BLACK, 1);
LayerAt(layer, code, col, row) = '/';
col++;
LayerFillAt( layer, col, row,
len, Shm->SysGate.IdleDriver.Name,
MakeAttr(WHITE, 0, BLACK, 1));
col += len;
}
} else {
LayerFillAt( layer, col, row,
3, "OFF",
MakeAttr(RED, 0, BLACK, 0));
col += 3;
}
LayerAt(layer, attr, col, row) = MakeAttr(BLACK, 0, BLACK, 1);
LayerAt(layer, code, col, row) = ']';
col++;
LayerDeclare(42) hSys1 = {
.origin = {.col = (drawSize.width - 42), .row = row}, .length = 42,
.attr = {
LWK,LWK,LWK,LWK,LWK,LWK,HDK,HWK,HWK,HWK,HWK,HWK,HWK,HDK, \
LWK,LWK,LWK,LWK,LWK,HDK,HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK, \
HWK,HDK,HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK,HWK,LWK,LWK,HDK
},
.code = {
'T','a','s','k','s',' ','[',' ',' ',' ',' ',' ',' ',']', \
' ','M','e','m',' ','[',' ',' ',' ',' ',' ',' ',' ',' ', \
' ','/',' ',' ',' ',' ',' ',' ',' ',' ',' ','K','B',']'
},
};
len = hSys1.origin.col - col;
if ((signed int)len > 0)
LayerFillAt(layer, col, hSys1.origin.row,
len, hSpace,
MakeAttr(BLACK, 0, BLACK, 1));
LayerCopyAt(layer, hSys1.origin.col, hSys1.origin.row,
hSys1.length, hSys1.attr, hSys1.code);
// Reset Tasks count & Memory usage
if (BITWISEAND(LOCKLESS, Shm->SysGate.Operation, 0x1))
PrintTaskMemory(layer, row,
Shm->SysGate.taskCount,
Shm->SysGate.memInfo.freeram,
Shm->SysGate.memInfo.totalram);
return(row);
}
CUINT Layout_Load(Layer *layer, CUINT row)
{
sprintf(buffer, "%-2u", cpu);
LayerAt(layer, attr, 0, row) = \
LayerAt(layer, attr, 0, (1 + row + Shm->Proc.CPU.Count)) = \
MakeAttr(WHITE, 0, BLACK, 0);
LayerAt(layer, code, 0, row) = \
LayerAt(layer, code, 0, (1 + row + Shm->Proc.CPU.Count)) = '#';
LayerAt(layer, code, 1, row) = \
LayerAt(layer, code, 1, (1 + row + Shm->Proc.CPU.Count)) = \
buffer[0];
LayerAt(layer, code, 2, row) = \
LayerAt(layer, code, 2, (1 + row + Shm->Proc.CPU.Count)) = \
buffer[1];
LayerAt(layer, attr, 3, row) = MakeAttr(YELLOW, 0, BLACK, 1);
LayerAt(layer, code, 3, row) = 0x20;
return(row);
}
CUINT Draw_Load(Layer *layer, CUINT row)
{
if (!BITVAL(Shm->Cpu[cpu].OffLine, HW))
{
struct FLIP_FLOP *Flop = &Shm->Cpu[cpu].FlipFlop[!Shm->Cpu[cpu].Toggle];
if (!BITVAL(Shm->Cpu[cpu].OffLine, OS))
{ // Upper view area
CUINT bar0=(Flop->Relative.Ratio *loadWidth)/maxRatio,
bar1 = loadWidth - bar0;
// Print the Per Core BCLK indicator (yellow)
LayerAt(layer, code, LOAD_LEAD - 1, row) = (cpu == iClock)?
'~' : 0x20;
// Draw the relative Core frequency ratio
LayerFillAt(layer, LOAD_LEAD, row,
bar0, hBar,
MakeAttr((Flop->Relative.Ratio > medianRatio ?
RED : Flop->Relative.Ratio > minRatio ?
YELLOW : GREEN),
0, BLACK, 1));
// Pad with blank characters
LayerFillAt(layer, (bar0 + LOAD_LEAD), row,
bar1, hSpace,
MakeAttr(BLACK, 0, BLACK, 1));
}
}
return(row);
}
CUINT Draw_Monitor_Frequency(Layer *layer, CUINT row)
{
struct FLIP_FLOP *Flop = &Shm->Cpu[cpu].FlipFlop[!Shm->Cpu[cpu].Toggle];
sprintf((char *) &LayerAt(layer, code, LOAD_LEAD, row),
"%7.2f" " (" "%5.2f" ") " \
"%6.2f" "%% " "%6.2f" "%% " "%6.2f" "%% " \
"%6.2f" "%% " "%6.2f" "%% " "%6.2f" "%% " \
"%-3u" "/" "%3u" "/" "%3u",
Flop->Relative.Freq,
Flop->Relative.Ratio,
100.f * Flop->State.Turbo,
100.f * Flop->State.C0,
100.f * Flop->State.C1,
100.f * Flop->State.C3,
100.f * Flop->State.C6,
100.f * Flop->State.C7,
Shm->Cpu[cpu].PowerThermal.Limit[0],
Flop->Thermal.Temp,
Shm->Cpu[cpu].PowerThermal.Limit[1]);
Attribute warning ={.fg=WHITE, .un=0, .bg=BLACK, .bf=1};
if (Flop->Thermal.Temp <=
Shm->Cpu[cpu].PowerThermal.Limit[0])
warning = MakeAttr(BLUE, 0, BLACK, 1);
else {
if (Flop->Thermal.Temp >=
Shm->Cpu[cpu].PowerThermal.Limit[1])
warning = MakeAttr(YELLOW, 0, BLACK, 0);
}
if (Flop->Thermal.Trip) {
warning = MakeAttr(RED, 0, BLACK, 1);
}
LayerAt(layer, attr, LOAD_LEAD + 69, row) =
LayerAt(layer, attr, LOAD_LEAD + 70, row) =
LayerAt(layer, attr, LOAD_LEAD + 71, row) = warning;
return(row);
}
#define Draw_Monitor_Instructions(layer, row) \
({ \
struct FLIP_FLOP *Flop=&Shm->Cpu[cpu].FlipFlop[!Shm->Cpu[cpu].Toggle];\
\
sprintf((char *) &LayerAt(layer, code, LOAD_LEAD, row), \
"%17.6f" "/s" \
"%17.6f" "/c" \
"%17.6f" "/i" \
"%18llu", \
Flop->State.IPS, \
Flop->State.IPC, \
Flop->State.CPI, \
Flop->Delta.INST); \
row; \
})
#define Draw_Monitor_Cycles(layer, row) \
({ \
struct FLIP_FLOP *Flop=&Shm->Cpu[cpu].FlipFlop[!Shm->Cpu[cpu].Toggle];\
\
sprintf((char *) &LayerAt(layer, code, LOAD_LEAD, row), \
"%18llu%18llu%18llu%18llu", \
Flop->Delta.C0.UCC, \
Flop->Delta.C0.URC, \
Flop->Delta.C1, \
Flop->Delta.TSC); \
row; \
})
#define Draw_Monitor_CStates(layer, row) \
({ \
struct FLIP_FLOP *Flop=&Shm->Cpu[cpu].FlipFlop[!Shm->Cpu[cpu].Toggle];\
\
sprintf((char *) &LayerAt(layer, code, LOAD_LEAD, row), \
"%18llu%18llu%18llu%18llu", \
Flop->Delta.C1, \
Flop->Delta.C3, \
Flop->Delta.C6, \
Flop->Delta.C7); \
row; \
})
CUINT Draw_Monitor_Tasks(Layer *layer, CUINT row)
{
struct FLIP_FLOP *Flop = &Shm->Cpu[cpu].FlipFlop[!Shm->Cpu[cpu].Toggle];
size_t len;
sprintf((char *) &LayerAt(layer, code, LOAD_LEAD, row),
"%7.2f", Flop->Relative.Freq);
if (Shm->SysGate.tickStep == Shm->SysGate.tickReset) {
CSINT pos;
char symbol;
Attribute runColor[] = {
HRK,HRK,HRK,HRK,HRK,HRK,HRK,HRK,\
HRK,HRK,HRK,HRK,HRK,HRK,HRK,HRK,\
HRK,HRK,HRK,HRK,HRK,HRK,HRK,HRK,\
HRK,HRK,HRK,HRK,HRK,HRK,HRK,HRK,\
HRK,HRK,HRK,HRK,HRK,HRK,HRK,HRK
}, unintColor[] = {
LYK,LYK,LYK,LYK,LYK,LYK,LYK,LYK,\
LYK,LYK,LYK,LYK,LYK,LYK,LYK,LYK,\
LYK,LYK,LYK,LYK,LYK,LYK,LYK,LYK,\
LYK,LYK,LYK,LYK,LYK,LYK,LYK,LYK,\
LYK,LYK,LYK,LYK,LYK,LYK,LYK,LYK
}, zombieColor[] = {
LKW,LKW,LKW,LKW,LKW,LKW,LKW,LKW,\
LKW,LKW,LKW,LKW,LKW,LKW,LKW,LKW,\
LKW,LKW,LKW,LKW,LKW,LKW,LKW,LKW,\
LKW,LKW,LKW,LKW,LKW,LKW,LKW,LKW,\
LKW,LKW,LKW,LKW,LKW,LKW,LKW,LKW
}, sleepColor[] = {
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,\
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,\
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,\
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK,\
LWK,LWK,LWK,LWK,LWK,LWK,LWK,LWK
}, otherColor[] = {
HBK,HBK,HBK,HBK,HBK,HBK,HBK,HBK,\
HBK,HBK,HBK,HBK,HBK,HBK,HBK,HBK,\
HBK,HBK,HBK,HBK,HBK,HBK,HBK,HBK,\
HBK,HBK,HBK,HBK,HBK,HBK,HBK,HBK,\
HBK,HBK,HBK,HBK,HBK,HBK,HBK,HBK
}, trackerColor[] = {
LKC,LKC,LKC,LKC,LKC,LKC,LKC,LKC,\
LKC,LKC,LKC,LKC,LKC,LKC,LKC,LKC,\
LKC,LKC,LKC,LKC,LKC,LKC,LKC,LKC,\
LKC,LKC,LKC,LKC,LKC,LKC,LKC,LKC,\
LKC,LKC,LKC,LKC,LKC,LKC,LKC,LKC
}, *attr;
cTask[cpu].col = LOAD_LEAD + 8;
LayerFillAt(layer,
cTask[cpu].col,
cTask[cpu].row,
(drawSize.width - LOAD_LEAD - 8),
hSpace,
MakeAttr(WHITE, 0, BLACK, 0));
unsigned int idx;
for (idx = 0; idx < Shm->SysGate.taskCount; idx++)
{
switch (Shm->SysGate.taskList[idx].state) {
case 0: { // TASK_RUNNING
attr = runColor;
symbol = 'R';
}
break;
case 1: { // TASK_INTERRUPTIBLE
attr = sleepColor;
symbol = 'S';
}
break;
case 2: { // TASK_UNINTERRUPTIBLE
attr = unintColor;
symbol = 'U';
}
break;
case 4: { // TASK_ZOMBIE
attr = zombieColor;
symbol = 'Z';
}
break;
case 8: { // TASK_STOPPED
attr = sleepColor;
symbol = 'H';
}
break;
default: {
attr = otherColor;
symbol = 'O';
}
break;
}
if (Shm->SysGate.taskList[idx].pid ==
Shm->SysGate.trackTask)
{
attr = trackerColor;
}
if (!drawFlag.taskVal) {
len = sprintf(buffer, "%s",
Shm->SysGate.taskList[idx].comm);
} else {
switch (Shm->SysGate.sortByField) {
case F_STATE:
len = sprintf(buffer, "%s(%c)",
Shm->SysGate.taskList[idx].comm,
symbol);
break;
case F_RTIME:
len = sprintf(buffer, "%s(%llu)",
Shm->SysGate.taskList[idx].comm,
Shm->SysGate.taskList[idx].runtime);
break;
case F_UTIME:
len = sprintf(buffer, "%s(%llu)",
Shm->SysGate.taskList[idx].comm,
Shm->SysGate.taskList[idx].usertime);
break;
case F_STIME:
len = sprintf(buffer, "%s(%llu)",
Shm->SysGate.taskList[idx].comm,
Shm->SysGate.taskList[idx].systime);
break;
case F_PID:
// fallthrough
case F_COMM:
// fallthrough
default:
len = sprintf(buffer, "%s(%d)",
Shm->SysGate.taskList[idx].comm,
Shm->SysGate.taskList[idx].pid);
break;
}
}
pos = drawSize.width
- cTask[Shm->SysGate.taskList[idx].wake_cpu].col;
if (pos >= 0) {
LayerCopyAt(layer,
cTask[Shm->SysGate.taskList[idx].wake_cpu].col,
cTask[Shm->SysGate.taskList[idx].wake_cpu].row,
(pos > len ? len : pos),
attr,
buffer);
cTask[Shm->SysGate.taskList[idx].wake_cpu].col += len+2;
}
}
}
return(row);
}
#define Draw_Monitor_Interrupts(layer, row) \
({ \
struct FLIP_FLOP *Flop=&Shm->Cpu[cpu].FlipFlop[!Shm->Cpu[cpu].Toggle];\
\
sprintf((char *) &LayerAt(layer, code, LOAD_LEAD, row), \
"%10u", Flop->Counter.SMI); \
\
if (Shm->Registration.nmi) \
sprintf((char *) &LayerAt(layer,code,LOAD_LEAD+24,row), \
"%10u%10u%10u%10u", \
Flop->Counter.NMI.LOCAL, \
Flop->Counter.NMI.UNKNOWN, \
Flop->Counter.NMI.PCISERR, \
Flop->Counter.NMI.IOCHECK); \
row; \
})
#define Draw_Monitor_Voltage(layer, row) \
({ \
struct FLIP_FLOP *Flop=&Shm->Cpu[cpu].FlipFlop[!Shm->Cpu[cpu].Toggle];\
\
sprintf((char *) &LayerAt(layer, code, LOAD_LEAD, row), \
"%7.2f " \
"%7d %5.4f", \
Flop->Relative.Freq, \
Flop->Voltage.VID, \
Flop->Voltage.Vcore); \
row; \
})
#define Draw_AltMonitor_Frequency(layer, row) \
({ \
if (!drawFlag.avgOrPC) \
sprintf((char *) &LayerAt(layer, code, 20, row), \
"%6.2f" "%% " "%6.2f" "%% " "%6.2f" "%% " \
"%6.2f" "%% " "%6.2f" "%% " "%6.2f" "%%", \
100.f * Shm->Proc.Avg.Turbo, \
100.f * Shm->Proc.Avg.C0, \
100.f * Shm->Proc.Avg.C1, \
100.f * Shm->Proc.Avg.C3, \
100.f * Shm->Proc.Avg.C6, \
100.f * Shm->Proc.Avg.C7); \
else \
sprintf((char *) &LayerAt(layer, code, 11, row), \
" c2:%-5.1f" " c3:%-5.1f" " c6:%-5.1f" \
" c7:%-5.1f" " c8:%-5.1f" " c9:%-5.1f" \
" c10:%-5.1f", \
100.f * Shm->Proc.State.PC02, \
100.f * Shm->Proc.State.PC03, \
100.f * Shm->Proc.State.PC06, \
100.f * Shm->Proc.State.PC07, \
100.f * Shm->Proc.State.PC08, \
100.f * Shm->Proc.State.PC09, \
100.f * Shm->Proc.State.PC10); \
row; \
})
CUINT Draw_AltMonitor_Package(Layer *layer, CUINT row)
{
struct PKG_FLIP_FLOP *Pkg = &Shm->Proc.FlipFlop[!Shm->Proc.Toggle];
CUINT bar0, bar1, margin = loadWidth - 18 - 7 - 2;
/* PC02 */
bar0 = (Shm->Proc.State.PC02 * margin) / 100;
bar1 = margin - bar0;
sprintf((char *) &LayerAt(layer, code, 5, row++),
"%18llu" "%7.2f" "%% " "%.*s" "%.*s",
Pkg->Delta.PC02, 100.f * Shm->Proc.State.PC02,
bar0, hBar, bar1, hSpace);
/* PC03 */
bar0 = (Shm->Proc.State.PC03 * margin) / 100;
bar1 = margin - bar0;
sprintf((char *) &LayerAt(layer, code, 5, row++),
"%18llu" "%7.2f" "%% " "%.*s" "%.*s",
Pkg->Delta.PC03, 100.f * Shm->Proc.State.PC03,
bar0, hBar, bar1, hSpace);
/* PC06 */
bar0 = (Shm->Proc.State.PC06 * margin) / 100;
bar1 = margin - bar0;
sprintf((char *) &LayerAt(layer, code, 5, row++),
"%18llu" "%7.2f" "%% " "%.*s" "%.*s",
Pkg->Delta.PC06, 100.f * Shm->Proc.State.PC06,
bar0, hBar, bar1, hSpace);
/* PC07 */
bar0 = (Shm->Proc.State.PC07 * margin) / 100;
bar1 = margin - bar0;
sprintf((char *) &LayerAt(layer, code, 5, row++),
"%18llu" "%7.2f" "%% " "%.*s" "%.*s",
Pkg->Delta.PC07, 100.f * Shm->Proc.State.PC07,
bar0, hBar, bar1, hSpace);
/* PC08 */
bar0 = (Shm->Proc.State.PC08 * margin) / 100;
bar1 = margin - bar0;
sprintf((char *) &LayerAt(layer, code, 5, row++),
"%18llu" "%7.2f" "%% " "%.*s" "%.*s",
Pkg->Delta.PC08, 100.f * Shm->Proc.State.PC08,
bar0, hBar, bar1, hSpace);
/* PC09 */
bar0 = (Shm->Proc.State.PC09 * margin) / 100;
bar1 = margin - bar0;
sprintf((char *) &LayerAt(layer, code, 5, row++),
"%18llu" "%7.2f" "%% " "%.*s" "%.*s",
Pkg->Delta.PC09, 100.f * Shm->Proc.State.PC09,
bar0, hBar, bar1, hSpace);
/* PC10 */
bar0 = (Shm->Proc.State.PC10 * margin) / 100;
bar1 = margin - bar0;
sprintf((char *) &LayerAt(layer, code, 5, row++),
"%18llu" "%7.2f" "%% " "%.*s" "%.*s",
Pkg->Delta.PC10, 100.f * Shm->Proc.State.PC10,
bar0, hBar, bar1, hSpace);
/* TSC & UNCORE */
sprintf((char *) &LayerAt(layer, code, 5, row),
"%18llu", Pkg->Delta.PTSC);
sprintf((char *) &LayerAt(layer, code, 50, row++),
"UNCORE:%18llu", Pkg->Uncore.FC0);
return(row);
}
CUINT Draw_Footer(Layer *layer, CUINT row)
{ // Update Footer view area
if (BITWISEAND(LOCKLESS, Shm->SysGate.Operation, 0x1)
&& (Shm->SysGate.tickStep == Shm->SysGate.tickReset)) {
if ((prevTaskCount != Shm->SysGate.taskCount)
|| (prevFreeRAM != Shm->SysGate.memInfo.freeram)) {
prevTaskCount = Shm->SysGate.taskCount;
prevFreeRAM = Shm->SysGate.memInfo.freeram;
PrintTaskMemory(layer, row,
Shm->SysGate.taskCount,
Shm->SysGate.memInfo.freeram,
Shm->SysGate.memInfo.totalram);
}
}
return(row);
}
CUINT Draw_Header(Layer *layer, CUINT row)
{ // Update Header view area
struct FLIP_FLOP *Flop = \
&Shm->Cpu[Shm->Proc.Top].FlipFlop[!Shm->Cpu[Shm->Proc.Top].Toggle];
// Print the Top Frequency
unsigned int relativeTopFreq = (unsigned int) Flop->Relative.Freq;
if (prevTopFreq != relativeTopFreq) {
prevTopFreq = relativeTopFreq;
PrintLCD(layer, 0, row, relativeTopFreq, Flop->Relative.Ratio);
}
// Print the focus BCLK
row += 2;
memcpy(&LayerAt(layer, code, 26, row), hBClk[iClock], 11);
return(row);
}
void Layout_Header_DualView_Footer(Layer *layer)
{
unsigned int processorHot = 0;
CUINT row = 0;
loadWidth = drawSize.width - LOAD_LEAD;
row = Layout_Header(layer, row);
row = Layout_Ruller_Load(layer, row);
for (cpu = 0; cpu < Shm->Proc.CPU.Count; cpu++)
{
row++;
row = Layout_Load(layer, row);
if (!BITVAL(Shm->Cpu[cpu].OffLine, OS)) {
struct FLIP_FLOP *Flop =
&Shm->Cpu[cpu].FlipFlop[!Shm->Cpu[cpu].Toggle];
LayerAt(layer, attr, 1, row) = \
LayerAt(layer, attr, 1, (1 + row + Shm->Proc.CPU.Count)) = \
MakeAttr(CYAN, 0, BLACK, 0);
LayerAt(layer, attr, 2, row) = \
LayerAt(layer, attr, 2, (1 + row + Shm->Proc.CPU.Count)) = \
MakeAttr(CYAN, 0, BLACK, 0);
switch (drawFlag.view) {
default:
case V_FREQ:
row = Layout_Monitor_Frequency(layer, row);
break;
case V_INST:
row = Layout_Monitor_Instructions(layer, row);
break;
case V_INTR:
case V_CYCLES:
case V_CSTATES:
case V_VOLTAGE:
row = Layout_Monitor_Common(layer, row);
break;
case V_PACKAGE:
break;
case V_TASKS:
row = Layout_Monitor_Tasks(layer, row);
break;
}
if (Flop->Thermal.Trip && !processorHot) {
processorHot = cpu;
}
} else {
LayerAt(layer, attr, 1, row) = \
LayerAt(layer, attr, 1, (1 + row + Shm->Proc.CPU.Count)) = \
MakeAttr(BLUE, 0, BLACK, 0);
LayerAt(layer, attr, 2, row) = \
LayerAt(layer, attr, 2, (1 + row + Shm->Proc.CPU.Count)) = \
MakeAttr(BLUE, 0, BLACK, 0);
LayerFillAt(layer, LOAD_LEAD, row,
(drawSize.width - LOAD_LEAD), hSpace,
MakeAttr(WHITE, 0, BLACK, 0));
LayerFillAt(layer,(LOAD_LEAD - 1),(row + Shm->Proc.CPU.Count+1),
(drawSize.width - LOAD_LEAD + 1), hSpace,
MakeAttr(WHITE, 0, BLACK, 0));
}
Dec2Digit(Shm->Cpu[cpu].Clock.Hz, digit);
hBClk[cpu][ 0] = digit[0] + '0';
hBClk[cpu][ 1] = digit[1] + '0';
hBClk[cpu][ 2] = digit[2] + '0';
hBClk[cpu][ 4] = digit[3] + '0';
hBClk[cpu][ 5] = digit[4] + '0';
hBClk[cpu][ 6] = digit[5] + '0';
hBClk[cpu][ 8] = digit[6] + '0';
hBClk[cpu][ 9] = digit[7] + '0';
hBClk[cpu][10] = digit[8] + '0';
}
row++;
switch (drawFlag.view) {
default:
case V_FREQ:
row = Layout_Ruller_Frequency(layer, row);
row += Shm->Proc.CPU.Count + 2;
break;
case V_INST:
row = Layout_Ruller_Instructions(layer, row);
row += Shm->Proc.CPU.Count + 2;
break;
case V_CYCLES:
row = Layout_Ruller_Cycles(layer, row);
row += Shm->Proc.CPU.Count + 2;
break;
case V_CSTATES:
row = Layout_Ruller_CStates(layer, row);
row += Shm->Proc.CPU.Count + 2;
break;
case V_INTR:
row = Layout_Ruller_Interrupts(layer, row);
row += Shm->Proc.CPU.Count + 2;
break;
case V_PACKAGE:
row = Layout_Ruller_Package(layer, row);
row++;
break;
case V_TASKS:
row = Layout_Ruller_Tasks(layer, row);
row += Shm->Proc.CPU.Count + 2;
break;
case V_VOLTAGE:
row = Layout_Ruller_Voltage(layer, row);
row += Shm->Proc.CPU.Count + 2;
break;
}
row = Layout_Footer(layer, row, &processorHot);
// Clear garbage in bottom screen
while (++row < drawSize.height)
LayerFillAt( layer, 0, row,
drawSize.width, hSpace,
MakeAttr(BLACK, 0, BLACK, 1));
}
void Dynamic_Header_DualView_Footer(Layer *layer)
{
CUINT row = 0;
row = Draw_Header(layer, row);
for (cpu = 0;
(cpu < Shm->Proc.CPU.Count) && !BITVAL(Shutdown, 0);
cpu++, row++)
{
row = Draw_Load(layer, TOP_UPPER_FIRST + cpu);
if (!BITVAL(Shm->Cpu[cpu].OffLine, HW)) {
row = TOP_LOWER_FIRST + cpu;
switch (drawFlag.view) {
case V_FREQ:
row = Draw_Monitor_Frequency(layer, row);
break;
case V_INST:
row = Draw_Monitor_Instructions(layer, row);
break;
case V_CYCLES:
row = Draw_Monitor_Cycles(layer, row);
break;
case V_CSTATES:
row = Draw_Monitor_CStates(layer, row);
break;
case V_PACKAGE:
break;
case V_TASKS:
row = Draw_Monitor_Tasks(layer, row);
break;
case V_INTR:
row = Draw_Monitor_Interrupts(layer, row);
break;
case V_VOLTAGE:
row = Draw_Monitor_Voltage(layer, row);
break;
}
}
}
switch (drawFlag.view) {
case V_FREQ:
row = TOP_LOWER_LAST;
row = Draw_AltMonitor_Frequency(layer, row);
row += 2;
break;
case V_PACKAGE:
row = TOP_LOWER_FIRST;
row = Draw_AltMonitor_Package(layer, row);
row += 2;
break;
default: // V_INST, V_CYCLES, V_CSTATES, V_TASKS, V_TASKS, V_VOLTAGE
row = TOP_FOOTER_LAST;
break;
}
row = Draw_Footer(layer, row);
}
void Layout_NoHeader_SingleView_NoFooter(Layer *layer)
{
CUINT row;
for (row = 0; row < drawSize.height; row++)
LayerFillAt( layer, 0, row,
drawSize.width, hSpace,
MakeAttr(BLACK, 0, BLACK, 1));
}
void Dynamic_NoHeader_SingleView_NoFooter(Layer *layer)
{
CUINT leadingLeft = LEADING_LEFT;
CUINT leadingTop = LEADING_TOP;
CUINT marginWidth = MARGIN_WIDTH + (4 * INTER_WIDTH);
CUINT marginHeight = MARGIN_HEIGHT + INTER_HEIGHT;
CUINT X = leadingLeft, Y = leadingTop;
const CUINT rightEdge = drawSize.width - marginWidth + INTER_WIDTH,
bottomEdge = drawSize.height - marginHeight;
int MoveCursorXY(int endline)
{
if (endline == 0) {
X += marginWidth;
} else {
X = rightEdge;
}
if (X >= rightEdge) {
X = leadingLeft;
Y += marginHeight;
}
if (Y > bottomEdge) {
return(-1);
}
return(0);
}
for (cpu = 0;
(cpu < Shm->Proc.CPU.Count) && !BITVAL(Shutdown, 0);
cpu++)
if (!BITVAL(Shm->Cpu[cpu].OffLine, HW)) {
struct FLIP_FLOP *Flop=&Shm->Cpu[cpu].FlipFlop[!Shm->Cpu[cpu].Toggle];
if (!BITVAL(Shm->Cpu[cpu].OffLine, OS)) {
Attribute warning ={.fg=WHITE, .un=0, .bg=BLACK, .bf=1};
if (Flop->Thermal.Temp <=
Shm->Cpu[cpu].PowerThermal.Limit[0])
warning = MakeAttr(BLUE, 0, BLACK, 1);
else {
if (Flop->Thermal.Temp >=
Shm->Cpu[cpu].PowerThermal.Limit[1])
warning = MakeAttr(YELLOW, 0, BLACK, 0);
}
if (Flop->Thermal.Trip) {
warning = MakeAttr(RED, 0, BLACK, 1);
}
PrintLCD(layer, X, Y,
(unsigned int) Flop->Relative.Freq, Flop->Relative.Ratio);
LayerAt(layer, attr, (X + 5), (Y + 3)) = \
LayerAt(layer, attr, (X + 6), (Y + 3)) = \
LayerAt(layer, attr, (X + 7), (Y + 3)) = \
LayerAt(layer, attr, (X + 8), (Y + 3)) = warning;
sprintf((char *) &LayerAt(layer, code, X, (Y + 3)),
"[ #%-2u%4uC ]", cpu, Flop->Thermal.Temp);
} else {
sprintf((char *) &LayerAt(layer, code, X, (Y + 1)),
"%s", "_ _ _ _");
sprintf((char *) &LayerAt(layer, code, X, (Y + 3)),
"[ #%-2u OFF ]", cpu);
}
if (MoveCursorXY(0) == -1)
break;
}
struct PKG_FLIP_FLOP *Pkg = &Shm->Proc.FlipFlop[!Shm->Proc.Toggle];
if (MoveCursorXY(1) == 0) {
PrintLCD(layer, X, Y,
(unsigned int) Pkg->Delta.PTSC / 1000000, 0);
sprintf((char *) &LayerAt(layer, code, X, (Y + 3)),
"%s", "[ BSP TSC ]");
}
if (MoveCursorXY(0) == 0) {
PrintLCD(layer, X, Y,
(unsigned int) Pkg->Uncore.FC0 / 1000000, 0);
sprintf((char *) &LayerAt(layer, code, X, (Y + 3)),
"%s", "[ UNCORE ]");
}
}
size_t FuseAll(char stream[])
{
unsigned int sdx = 0;
Attribute attr = {.value = 0};
CUINT _col, _row;
for (_row = 0; _row < drawSize.height; _row++)
{
struct {
int cursor;
} flag = {0};
int _bix = 0, _bdx;
CUINT _wth = _row * fuze->size.wth;
for (_col = 0; _col < drawSize.width; _col++)
{
int _idx = _col + _wth;
Attribute *fa = &fuze->attr[_idx],
*sa = &sLayer->attr[_idx],
*da = &dLayer->attr[_idx],
*wa = &wLayer->attr[_idx];
ASCII *fc = &fuze->code[_idx],
*sc = &sLayer->code[_idx],
*dc = &dLayer->code[_idx],
*wc = &wLayer->code[_idx];
/* STATIC LAYER */
if (sa->value != 0)
fa->value = sa->value;
if (*sc != 0)
*fc = *sc;
/* DYNAMIC LAYER */
if (da->value != 0)
fa->value = da->value;
if (*dc != 0)
*fc = *dc;
/* WINDOWS LAYER */
if (wa->value != 0)
fa->value = wa->value;
if (*wc != 0)
*fc = *wc;
/* FUZED LAYER */
if((fa->fg ^ attr.fg) || (fa->bg ^ attr.bg) || (fa->bf ^ attr.bf)) {
buffer[_bix++] = 0x1b;
buffer[_bix++] = '[';
buffer[_bix++] = '0' + fa->bf;
buffer[_bix++] = ';';
buffer[_bix++] = '3';
buffer[_bix++] = '0' + fa->fg;
buffer[_bix++] = ';';
buffer[_bix++] = '4';
buffer[_bix++] = '0' + fa->bg;
buffer[_bix++] = 'm';
}
if (fa->un ^ attr.un) {
buffer[_bix++] = 0x1b;
buffer[_bix++] = '[';
if (fa->un) {
buffer[_bix++] = '4';
buffer[_bix++] = 'm';
} else {
buffer[_bix++] = '2';
buffer[_bix++] = '4';
buffer[_bix++] = 'm';
}
}
attr.value = fa->value;
if (*fc != 0) {
if (flag.cursor == 0) {
flag.cursor = 1;
struct {
CUINT col, row;
} scr = {.col = _col + 1, .row = _row + 1};
buffer[_bix++] = 0x1b;
buffer[_bix++] = '[';
_bix = log10(scr.row) + _bix + 1;
for(_bdx = _bix; scr.row > 0; scr.row /= 10)
buffer[--_bdx] = '0' + (scr.row % 10);
buffer[_bix++] = ';';
_bix = log10(scr.col) + _bix + 1;
for(_bdx = _bix; scr.col > 0; scr.col /= 10)
buffer[--_bdx] = '0' + (scr.col % 10);
buffer[_bix++] = 'H';
}
buffer[_bix++] = *fc;
}
else
flag.cursor = 0;
}
memcpy(&stream[sdx], buffer, _bix);
sdx += _bix;
}
return((size_t) sdx);
}
TrapScreenSize(SIGWINCH);
signal(SIGWINCH, TrapScreenSize);
AllocAll();
typedef void (*LAYOUT_VIEW_FUNC)(Layer*);
LAYOUT_VIEW_FUNC LayoutView[2] = {
Layout_Header_DualView_Footer,
Layout_NoHeader_SingleView_NoFooter
};
LAYOUT_VIEW_FUNC DynamicView[2] = {
Dynamic_Header_DualView_Footer,
Dynamic_NoHeader_SingleView_NoFooter
};
while (!BITVAL(Shutdown, 0))
{
size_t writeSize = 0;
do
{
SCANKEY scan = {.key = 0};
if ((drawFlag.daemon = BITVAL(Shm->Proc.Sync, 0)) == 0) {
if (GetKey(&scan, &Shm->Proc.BaseSleep) > 0) {
if (Shortcut(&scan) == -1) {
if (IsDead(&winList))
AppendWindow(CreateMenu(SCANKEY_F2), &winList);
else
if (Motion_Trigger(&scan,GetFocus(&winList),&winList) > 0)
Shortcut(&scan);
}
PrintWindowStack();
break;
}
} else {
BITCLR(LOCKLESS, Shm->Proc.Sync, 0);
}
if (BITVAL(Shm->Proc.Sync, 63)) {
// Platform changed, redraw the layout.
drawFlag.layout = 1;
BITCLR(LOCKLESS, Shm->Proc.Sync, 63);
}
} while (!BITVAL(Shutdown, 0) && !drawFlag.daemon && !drawFlag.layout) ;
if (drawFlag.height & drawFlag.width)
{
if (drawFlag.clear) {
drawFlag.clear = 0;
drawFlag.layout = 1;
ResetLayer(dLayer);
}
if (drawFlag.layout) {
drawFlag.layout = 0;
ResetLayer(sLayer);
LayoutView[drawFlag.disposal](sLayer);
}
if (drawFlag.daemon) {
DynamicView[drawFlag.disposal](dLayer);
// Increment the BCLK indicator (skip offline CPU)
do {
iClock++;
if (iClock == Shm->Proc.CPU.Count)
iClock = 0;
} while (BITVAL(Shm->Cpu[iClock].OffLine, OS) && iClock) ;
}
// Write buffer to the standard output
if ((writeSize = FuseAll(console)) > 0) {
fwrite(console, writeSize, 1, stdout);
fflush(stdout);
}
} else
printf( CUH RoK "Term(%u x %u) < View(%u x %u)\n",
drawSize.width, drawSize.height, MIN_WIDTH, MIN_HEIGHT);
}
FreeAll();
}
int Help(char *appName)
{
printf( "CoreFreq." \
" Copyright (C) 2015-2017 CYRIL INGENIERIE\n\n");
printf( "usage:\t%s [-option <arguments>]\n" \
"\t-t\tShow Top (default)\n" \
"\t-d\tShow Dashboard\n" \
"\t-V\tMonitor Voltage\n" \
"\t-c\tMonitor Counters\n" \
"\t-i\tMonitor Instructions\n" \
"\t-s\tPrint System Information\n" \
"\t-M\tPrint Memory Controller\n" \
"\t-m\tPrint Topology\n" \
"\t-u\tPrint CPUID\n" \
"\t-k\tPrint Kernel\n" \
"\t-h\tPrint out this message\n" \
"\nExit status:\n" \
"0\tif OK,\n" \
"1\tif problems,\n" \
">1\tif serious trouble.\n" \
"\nReport bugs to labs[at]cyring.fr\n", appName);
return(1);
}
int main(int argc, char *argv[])
{
struct termios oldt, newt;
struct stat shmStat = {0};
SHM_STRUCT *Shm;
int fd = -1, rc = EXIT_SUCCESS;
char *program = strdup(argv[0]), *appName=basename(program);
char option = 't';
if ((argc >= 2) && (argv[1][0] == '-'))
option = argv[1][1];
if (option == 'h')
Help(appName);
else if (((fd = shm_open(SHM_FILENAME, O_RDWR,
S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) !=-1)
&& ((fstat(fd, &shmStat) != -1)
&& ((Shm = mmap(0, shmStat.st_size,
PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0))!=MAP_FAILED)))
{
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
CPU_SET(0, &cpuset);
sched_setaffinity(0, sizeof(cpu_set_t), &cpuset);
switch (option) {
case 'k':
if (BITWISEAND(LOCKLESS, Shm->SysGate.Operation, 0x1)) {
SysInfoKernel(Shm, 80, NULL);
}
break;
case 'u':
SysInfoCPUID(Shm, 80, NULL);
break;
case 's':
{
SysInfoProc(Shm, 80, NULL);
printv(NULL, SCANKEY_VOID, 80, 0,"");
printv(NULL, SCANKEY_VOID, 80, 0,"ISA Extensions:");
SysInfoISA(Shm, 80, NULL);
printv(NULL, SCANKEY_VOID, 80, 0,"");
printv(NULL, SCANKEY_VOID, 80, 0,"Features:");
SysInfoFeatures(Shm, 80, NULL);
printv(NULL, SCANKEY_VOID, 80, 0,"");
printv(NULL, SCANKEY_VOID, 80, 0,"Technologies:");
SysInfoTech(Shm, 80, NULL);
printv(NULL, SCANKEY_VOID, 80, 0,"");
printv(NULL, SCANKEY_VOID, 80, 0,"Performance Monitoring:");
SysInfoPerfMon(Shm, 80, NULL);
printv(NULL, SCANKEY_VOID, 80, 0,"");
printv(NULL, SCANKEY_VOID, 80, 0,"Power & Thermal Monitoring:");
SysInfoPwrThermal(Shm, 80, NULL);
}
break;
case 'm':
Topology(Shm, NULL);
break;
case 'M':
MemoryController(Shm, NULL);
break;
case 'i':
TrapSignal();
Instructions(Shm);
break;
case 'c':
TrapSignal();
Counters(Shm);
break;
case 'V':
TrapSignal();
Voltage(Shm);
break;
case 'd':
// Fallthrough
case 't':
{
printf(SCP SCR1 HIDE);
tcgetattr(STDIN_FILENO, &oldt);
newt = oldt;
newt.c_lflag &= ~( ICANON | ECHO );
newt.c_cc[VTIME] = 0;
newt.c_cc[VMIN] = 0;
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
TrapSignal();
Top(Shm, option);
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
printf(SHOW SCR0 RCP COLOR(0,9,9));
}
break;
default:
rc = Help(appName);
break;
}
munmap(Shm, shmStat.st_size);
close(fd);
}
else
rc = 2;
free(program);
return(rc);
}