Skip to content

Commit

Permalink
Initial commit of crystal-htop modifications
Browse files Browse the repository at this point in the history
  • Loading branch information
locupleto committed Jan 13, 2024
1 parent b6b9384 commit 80af24c
Show file tree
Hide file tree
Showing 12 changed files with 406 additions and 11 deletions.
58 changes: 49 additions & 9 deletions CPUMeter.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,21 @@ Released under the GNU GPLv2+, see the COPYING file
in the source distribution for its full text.
*/

/*
* crystal_htop - Additions
* 2024-01-13 Urban Ottosson
*
* This file contains minor additions to the original htop codebase.
* These modifications enable htop to log samples of its measurements to a file,
* a functionality not provided in the original htop.
*
* All additions are clearly marked to facilitate easy comparison with
* the original code. Search for 'crystal_htop' in the code.
*
* Repository: https://github.com/locupleto/crystal_htop
*/


#include "config.h" // IWYU pragma: keep

#include "CPUMeter.h"
Expand Down Expand Up @@ -66,6 +81,22 @@ static void CPUMeter_updateValues(Meter* this) {
const Machine* host = this->host;
const Settings* settings = host->settings;

/* --- Start of crystal_htop Additions --- */

const char* defaultTempDir = "/tmp";
const char* tempDir;

// Attempt to retrieve the value of the HTOP_TEMP_DIR environment variable
const char* envTempDir = getenv("HTOP_TEMP_DIR");

// Check if the environment variable is set
if (envTempDir != NULL)
tempDir = envTempDir;
else
tempDir = defaultTempDir;

/* --- End of crystal_htop Additions --- */

unsigned int cpu = this->param;
if (cpu > host->existingCPUs) {
xSnprintf(this->txtBuffer, sizeof(this->txtBuffer), "absent");
Expand All @@ -83,17 +114,26 @@ static void CPUMeter_updateValues(Meter* this) {
char cpuTemperatureBuffer[16] = { 0 };

if (settings->showCPUUsage) {
xSnprintf(cpuUsageBuffer, sizeof(cpuUsageBuffer), "%.1f%%", percent);
/* --- Start of crystal_htop Additions --- */
char cpuUsageFilePath[256];
snprintf(cpuUsageFilePath, sizeof(cpuUsageFilePath), "%s/htop_cpu_%03u.txt", tempDir, cpu);
FILE *file = fopen(cpuUsageFilePath, "w");
xSnprintf(cpuUsageBuffer, sizeof(cpuUsageBuffer), "%.1f", percent);
if (file != NULL) {
fprintf(file, "%s", cpuUsageBuffer);
fclose(file);
}
/* --- End of crystal_htop Additions --- */
}

if (settings->showCPUFrequency) {
double cpuFrequency = this->values[CPU_METER_FREQUENCY];
if (isNonnegative(cpuFrequency)) {
xSnprintf(cpuFrequencyBuffer, sizeof(cpuFrequencyBuffer), "%4uMHz", (unsigned)cpuFrequency);
} else {
xSnprintf(cpuFrequencyBuffer, sizeof(cpuFrequencyBuffer), "N/A");
}
}
if (settings->showCPUFrequency) {
double cpuFrequency = this->values[CPU_METER_FREQUENCY];
if (isNonnegative(cpuFrequency)) {
xSnprintf(cpuFrequencyBuffer, sizeof(cpuFrequencyBuffer), "%4uMHz", (unsigned)cpuFrequency);
} else {
xSnprintf(cpuFrequencyBuffer, sizeof(cpuFrequencyBuffer), "N/A");
}
}

#ifdef BUILD_WITH_CPU_TEMP
if (settings->showCPUTemperature) {
Expand Down
41 changes: 41 additions & 0 deletions LoadAverageMeter.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,20 @@ Released under the GNU GPLv2+, see the COPYING file
in the source distribution for its full text.
*/

/*
* crystal_htop - Additions
* 2024-01-13 Urban Ottosson
*
* This file contains minor additions to the original htop codebase.
* These modifications enable htop to log samples of its measurements to a file,
* a functionality not provided in the original htop.
*
* All additions are clearly marked to facilitate easy comparison with
* the original code. Search for 'crystal_htop' in the code.
*
* Repository: https://github.com/locupleto/crystal_htop
*/

#include "config.h" // IWYU pragma: keep

#include "LoadAverageMeter.h"
Expand Down Expand Up @@ -58,6 +72,33 @@ static void LoadAverageMeter_updateValues(Meter* this) {
}

xSnprintf(this->txtBuffer, sizeof(this->txtBuffer), "%.2f/%.2f/%.2f", this->values[0], this->values[1], this->values[2]);

/* --- Start of crystal_htop Additions --- */
const char* defaultTempDir = "/tmp";
const char* tempDir;

// Attempt to retrieve the value of the HTOP_TEMP_DIR environment variable
const char* envTempDir = getenv("HTOP_TEMP_DIR");

// Check if the environment variable is set
if (envTempDir != NULL)
tempDir = envTempDir;
else
tempDir = defaultTempDir;

for (int i = 1; i <= 3; i++) {
char loadAvgFilePath[256];
snprintf(loadAvgFilePath, sizeof(loadAvgFilePath), "%s/htop_load_avg_%d.txt", tempDir, i);
FILE *file = fopen(loadAvgFilePath, "w");

if (file != NULL) {
char doubleBuffer[16] = { 0 };
xSnprintf(doubleBuffer, sizeof(doubleBuffer), "%.2f", this->values[i-1]);
fprintf(file, "%s", doubleBuffer);
fclose(file);
}
}
/* --- End of crystal_htop Additions --- */
}

static void LoadAverageMeter_display(const Object* cast, RichString* out) {
Expand Down
7 changes: 7 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -510,3 +510,10 @@ lcov:
mkdir -p lcov
lcov --capture --directory . --output-file coverage.info
genhtml coverage.info --output-directory lcov

# Custom target to copy htop to crystal_htop
copy_htop: all
cp $(builddir)/htop $(builddir)/crystal_htop

# Make the 'all' target depend on 'copy_htop' so it executes afterwards
all: copy_htop
51 changes: 51 additions & 0 deletions MemoryMeter.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,20 @@ Released under the GNU GPLv2+, see the COPYING file
in the source distribution for its full text.
*/

/*
* crystal_htop - Additions
* 2024-01-13 Urban Ottosson
*
* This file contains minor additions to the original htop codebase.
* These modifications enable htop to log samples of its measurements to a file,
* a functionality not provided in the original htop.
*
* All additions are clearly marked to facilitate easy comparison with
* the original code. Search for 'crystal_htop' in the code.
*
* Repository: https://github.com/locupleto/crystal_htop
*/

#include "config.h" // IWYU pragma: keep

#include "MemoryMeter.h"
Expand Down Expand Up @@ -39,6 +53,24 @@ static void MemoryMeter_updateValues(Meter* this) {
this->values[MEMORY_METER_AVAILABLE] = NAN;
Platform_setMemoryValues(this);

/* --- Start of crystal_htop Additions --- */
const char* defaultTempDir = "/tmp";
const char* tempDir;

// Attempt to retrieve the value of the htop_TEMP_DIR environment variable
const char* envTempDir = getenv("HTOP_TEMP_DIR");

// Check if the environment variable is set
if (envTempDir != NULL)
tempDir = envTempDir;
else
tempDir = defaultTempDir;
char usedMemFilePath[256];
char availMemFilePath[256];
snprintf(usedMemFilePath, sizeof(usedMemFilePath), "%s/htop_mem_used.txt", tempDir);
snprintf(availMemFilePath, sizeof(availMemFilePath), "%s/htop_mem_avail.txt", tempDir);
/* --- End of crystal_htop Additions --- */

/* Do not print available memory in bar mode */
static_assert(MEMORY_METER_AVAILABLE + 1 == MEMORY_METER_ITEMCOUNT,
"MEMORY_METER_AVAILABLE is not the last item in MemoryMeterValues");
Expand All @@ -52,11 +84,30 @@ static void MemoryMeter_updateValues(Meter* this) {
used += this->values[MEMORY_METER_COMPRESSED];

written = Meter_humanUnit(buffer, used, size);

/* --- Start of crystal_htop Additions --- */
FILE *file = fopen(usedMemFilePath, "w");
if (file != NULL) {
double kibibytes = humanUnitToKibibytes(buffer);
fprintf(file, "%f %s", kibibytes, buffer);
fclose(file);
}
/* --- End of crystal_htop Additions --- */

METER_BUFFER_CHECK(buffer, size, written);

METER_BUFFER_APPEND_CHR(buffer, size, '/');

Meter_humanUnit(buffer, this->total, size);

/* --- Start of crystal_htop Additions --- */
file = fopen(availMemFilePath, "w");
if (file != NULL) {
double kibibytes = humanUnitToKibibytes(buffer);
fprintf(file, "%f %s", kibibytes, buffer);
fclose(file);
}
/* --- End of crystal_htop Additions --- */
}

static void MemoryMeter_display(const Object* cast, RichString* out) {
Expand Down
33 changes: 33 additions & 0 deletions Meter.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,20 @@ Released under the GNU GPLv2+, see the COPYING file
in the source distribution for its full text.
*/

/*
* crystal_htop - Additions
* 2024-01-13 Urban Ottosson
*
* This file contains minor additions to the original htop codebase.
* These modifications enable htop to log samples of its measurements to a file,
* a functionality not provided in the original htop.
*
* All additions are clearly marked to facilitate easy comparison with
* the original code. Search for 'crystal_htop' in the code.
*
* Repository: https://github.com/locupleto/crystal_htop
*/

#include "config.h" // IWYU pragma: keep

#include "Meter.h"
Expand Down Expand Up @@ -502,3 +516,22 @@ const MeterClass BlankMeter_class = {
.uiName = "Blank",
.caption = ""
};

/* --- Start of crystal_htop Additions --- */
double humanUnitToKibibytes(const char* str) {
char *end;
double value = strtod(str, &end); // Convert the initial part of str to double

// Check which unit is used and multiply by the corresponding factor
switch (toupper(*end)) {
case 'G': value *= ONE_K; // Fallthrough for G -> M -> K
case 'M': value *= ONE_K;
case 'K': break; // No multiplier needed for kibibytes
case '\0': break; // No unit means default to kibibytes
default: // Unknown unit
fprintf(stderr, "Error: Unknown unit '%c' in input '%s'\n", *end, str);
return -1;
}
return value;
}
/* --- End of crystal_htop Additions --- */
2 changes: 2 additions & 0 deletions Meter.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,4 +160,6 @@ extern const MeterMode* const Meter_modes[];

extern const MeterClass BlankMeter_class;

double humanUnitToKibibytes(const char* str);

#endif
48 changes: 47 additions & 1 deletion SwapMeter.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,20 @@ Released under the GNU GPLv2+, see the COPYING file
in the source distribution for its full text.
*/

/*
* crystal_htop - Additions
* 2024-01-13 Urban Ottosson
*
* This file contains minor additions to the original htop codebase.
* These modifications enable htop to log samples of its measurements to a file,
* a functionality not provided in the original htop.
*
* All additions are clearly marked to facilitate easy comparison with
* the original code. Search for 'crystal_htop' in the code.
*
* Repository: https://github.com/locupleto/crystal_htop
*/

#include "config.h" // IWYU pragma: keep

#include "SwapMeter.h"
Expand Down Expand Up @@ -34,12 +48,44 @@ static void SwapMeter_updateValues(Meter* this) {
this->values[SWAP_METER_FRONTSWAP] = NAN; /* 'frontswap' not present on all platforms */
Platform_setSwapValues(this);

written = Meter_humanUnit(buffer, this->values[SWAP_METER_USED], size);
written = Meter_humanUnit(buffer, this->values[SWAP_METER_USED], size);
/* --- Start of crystal_htop Additions --- */
char swapUsedHumanBuffer[256] = { 0 };
strncpy(swapUsedHumanBuffer, buffer, sizeof(swapUsedHumanBuffer) - 1);
double swapUsedRaw = this->values[SWAP_METER_USED];
/* --- End of crystal_htop Additions --- */
METER_BUFFER_CHECK(buffer, size, written);

METER_BUFFER_APPEND_CHR(buffer, size, '/');

Meter_humanUnit(buffer, this->total, size);
/* --- Start of crystal_htop Additions --- */
char swapTotalHumanBuffer[256] = { 0 };
strncpy(swapTotalHumanBuffer, buffer, sizeof(swapTotalHumanBuffer) - 1);
double swapTotalRaw = this->total;

// Determine temp directory
const char* defaultTempDir = "/tmp";
const char* tempDir = getenv("HTOP_TEMP_DIR") ? getenv("HTOP_TEMP_DIR") : defaultTempDir;

// Write to swap used file
char swapUsedFilePath[256];
snprintf(swapUsedFilePath, sizeof(swapUsedFilePath), "%s/htop_swap_used.txt", tempDir);
FILE *file = fopen(swapUsedFilePath, "w");
if (file != NULL) {
fprintf(file, "%f %s", swapUsedRaw, swapUsedHumanBuffer);
fclose(file);
}

// Write to total swap file
char swapTotalFilePath[256];
snprintf(swapTotalFilePath, sizeof(swapTotalFilePath), "%s/htop_swap_total.txt", tempDir);
file = fopen(swapTotalFilePath, "w");
if (file != NULL) {
fprintf(file, "%f %s", swapTotalRaw, swapTotalHumanBuffer);
fclose(file);
}
/* --- Start of crystal_htop Additions --- */
}

static void SwapMeter_display(const Object* cast, RichString* out) {
Expand Down
Loading

0 comments on commit 80af24c

Please sign in to comment.