Last active
July 24, 2018 02:46
-
-
Save croepha/a12080ff844388431d995c961a1ebd0a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <unistd.h> | |
#include <sys/types.h> | |
#include <sys/stat.h> | |
#include <fcntl.h> | |
#include <stdlib.h> | |
#include <assert.h> | |
#define acount(m_a) (sizeof m_a/sizeof m_a[0]) | |
typedef unsigned long long u64; | |
typedef int s32; | |
static_assert(sizeof(s32) == 4); | |
const s32 READ_BUFFER_SIZE = 4096; | |
const s32 BUCKET_COUNT = 2; | |
const s32 CPU_COUNT = 8; | |
// Assign specific cores to buckets | |
const s32 logical_core_bucket_assignments[] = { | |
0, 1, 0, 1, 0, 1, 0, 1, | |
//0 1 2 3 4 5 6 7 | |
}; | |
namespace TIME_TYPES { enum { | |
user, nice, system, idle, | |
_COUNT | |
};} | |
u64 cpu_times[CPU_COUNT][TIME_TYPES::_COUNT]; | |
char read_buffer[READ_BUFFER_SIZE]; | |
char* read_buffer_end = read_buffer + READ_BUFFER_SIZE; | |
inline static int scan_cmp(char*&c, char*to) { | |
while (*to && *c == *to) { c++; to++; } | |
return !*to; | |
} | |
inline static bool scan_decimal(char*&c, u64&v) { | |
v = 0; | |
bool is_valid = false; | |
for(;;) { | |
if (*c < '0' || *c > '9') break; | |
v *= 10; | |
v += *c - '0'; | |
is_valid = true; | |
c++; | |
} | |
return is_valid; | |
} | |
inline static void scan_until(char*&c, char to) { | |
while (*c && *c != to) { c++; } | |
} | |
const int sleep_ms = 500; | |
int main() { | |
s32 total_time = (sleep_ms * sysconf(_SC_CLK_TCK)) / 1000; | |
s32 total[BUCKET_COUNT] = {}; | |
for (int i = 0; i<CPU_COUNT; i++) { | |
total[logical_core_bucket_assignments[i]] += total_time; | |
} | |
auto fd = open("/proc/stat", O_RDONLY); | |
for (;;) { | |
auto byte_count = read(fd, read_buffer, READ_BUFFER_SIZE - 1); | |
assert(byte_count>=0); | |
char*c = read_buffer; | |
printf("\033[1;1H\033[2J"); //clear screen | |
u64 delta[BUCKET_COUNT][TIME_TYPES::_COUNT] = {}; | |
for (;;) { | |
u64 cpu_logical_id; | |
if (!scan_cmp(c, "cpu")) break; | |
if (!scan_decimal(c, cpu_logical_id)) goto read_rest_of_line; // the "all cpus" entry... | |
if (cpu_logical_id < 0 || cpu_logical_id >= acount(logical_core_bucket_assignments)) | |
exit(-__LINE__); | |
{ | |
u64 times[TIME_TYPES::_COUNT]; | |
if (!scan_cmp(c, " ") ) abort(); | |
if (!scan_decimal(c, times[TIME_TYPES::user]) ) abort(); | |
if (!scan_cmp(c, " ") ) abort(); | |
if (!scan_decimal(c, times[TIME_TYPES::nice]) ) abort(); | |
if (!scan_cmp(c, " ") ) abort(); | |
if (!scan_decimal(c, times[TIME_TYPES::system])) abort(); | |
if (!scan_cmp(c, " ") ) abort(); | |
if (!scan_decimal(c, times[TIME_TYPES::idle]) ) abort(); | |
for (int i=0;i<TIME_TYPES::_COUNT;i++) { | |
int bucket_id = logical_core_bucket_assignments[cpu_logical_id]; | |
if (cpu_times[cpu_logical_id][i]) { | |
delta[bucket_id][i] += times[i] - cpu_times[cpu_logical_id][i]; | |
} | |
cpu_times[cpu_logical_id][i] = times[i]; | |
} | |
} | |
read_rest_of_line: | |
scan_until(c, '\n'); | |
c++; | |
} | |
for (int bi=0; bi<BUCKET_COUNT; bi++) { | |
int total_width = 50; | |
int widths[TIME_TYPES::_COUNT]; | |
float total_so_far = 0; | |
for (int i=0;i<TIME_TYPES::_COUNT;i++) { | |
total_so_far = total_so_far + ((float)delta[bi][i] *(float)total_width) / (float)total[bi]; | |
widths[i] = total_so_far; | |
} | |
printf("bucket:%d user:%llu nice:%llu system:%llu idle:%lld total:%d\n", | |
bi, | |
delta[bi][TIME_TYPES::user ], | |
delta[bi][TIME_TYPES::nice ], | |
delta[bi][TIME_TYPES::system], | |
delta[bi][TIME_TYPES::idle ], | |
total[bi]); | |
char line_buf[1024]; | |
for (int i=0;i<total_width;i++) { | |
// user, nice, system, idle, | |
line_buf[i] = '?'; | |
if (i<widths[TIME_TYPES::idle ]) line_buf[i] = ' '; | |
if (i<widths[TIME_TYPES::system]) line_buf[i] = 'S'; | |
if (i<widths[TIME_TYPES::nice ]) line_buf[i] = 'N'; | |
if (i<widths[TIME_TYPES::user ]) line_buf[i] = 'U'; | |
} | |
line_buf[total_width] = 0; | |
printf("%s\n", line_buf); | |
} | |
lseek(fd, 0, SEEK_SET); | |
usleep(sleep_ms * 1000); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment