123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- /*
- htop - FileDescriptorMeter.c
- (C) 2022 htop dev team
- Released under the GNU GPLv2+, see the COPYING file
- in the source distribution for its full text.
- */
- #include "config.h" // IWYU pragma: keep
- #include "FileDescriptorMeter.h"
- #include <math.h>
- #include "CRT.h"
- #include "Macros.h"
- #include "Meter.h"
- #include "Object.h"
- #include "Platform.h"
- #include "RichString.h"
- #include "XUtils.h"
- #define FD_EFFECTIVE_UNLIMITED(x) (!isgreaterequal((double)(1<<30), (x)))
- static const int FileDescriptorMeter_attributes[] = {
- FILE_DESCRIPTOR_USED,
- FILE_DESCRIPTOR_MAX
- };
- static void FileDescriptorMeter_updateValues(Meter* this) {
- this->values[0] = 0;
- this->values[1] = 1;
- Platform_getFileDescriptors(&this->values[0], &this->values[1]);
- /* only print bar for first value */
- this->curItems = 1;
- /* Use maximum value for scaling of bar mode
- *
- * As the plain total value can be very large compared to
- * the actually used value, this is capped in the following way:
- *
- * 1. If the maximum value is below (or equal to) 1<<16, use it directly
- * 2. If the maximum value is above, use powers of 2 starting at 1<<16 and
- * double it until it's larger than 16 times the used file handles
- * (capped at the maximum number of files)
- * 3. If the maximum is effectively unlimited (AKA > 1<<30),
- * Do the same as for 2, but cap at 1<<30.
- */
- if (this->values[1] <= 1 << 16) {
- this->total = this->values[1];
- } else {
- if (this->total < 16 * this->values[0]) {
- for (this->total = 1 << 16; this->total < 16 * this->values[0]; this->total *= 2) {
- if (this->total >= 1 << 30) {
- break;
- }
- }
- }
- if (this->total > this->values[1]) {
- this->total = this->values[1];
- }
- if (this->total > 1 << 30) {
- this->total = 1 << 30;
- }
- }
- if (!isNonnegative(this->values[0])) {
- xSnprintf(this->txtBuffer, sizeof(this->txtBuffer), "unknown/unknown");
- } else if (FD_EFFECTIVE_UNLIMITED(this->values[1])) {
- xSnprintf(this->txtBuffer, sizeof(this->txtBuffer), "%.0lf/unlimited", this->values[0]);
- } else {
- xSnprintf(this->txtBuffer, sizeof(this->txtBuffer), "%.0lf/%.0lf", this->values[0], this->values[1]);
- }
- }
- static void FileDescriptorMeter_display(const Object* cast, RichString* out) {
- const Meter* this = (const Meter*)cast;
- char buffer[50];
- int len;
- if (!isNonnegative(this->values[0])) {
- RichString_appendAscii(out, CRT_colors[METER_TEXT], "unknown");
- return;
- }
- RichString_appendAscii(out, CRT_colors[METER_TEXT], "used: ");
- len = xSnprintf(buffer, sizeof(buffer), "%.0lf", this->values[0]);
- RichString_appendnAscii(out, CRT_colors[FILE_DESCRIPTOR_USED], buffer, len);
- RichString_appendAscii(out, CRT_colors[METER_TEXT], " max: ");
- if (FD_EFFECTIVE_UNLIMITED(this->values[1])) {
- RichString_appendAscii(out, CRT_colors[FILE_DESCRIPTOR_MAX], "unlimited");
- } else {
- len = xSnprintf(buffer, sizeof(buffer), "%.0lf", this->values[1]);
- RichString_appendnAscii(out, CRT_colors[FILE_DESCRIPTOR_MAX], buffer, len);
- }
- }
- const MeterClass FileDescriptorMeter_class = {
- .super = {
- .extends = Class(Meter),
- .delete = Meter_delete,
- .display = FileDescriptorMeter_display,
- },
- .updateValues = FileDescriptorMeter_updateValues,
- .defaultMode = TEXT_METERMODE,
- .supportedModes = METERMODE_DEFAULT_SUPPORTED,
- .maxItems = 2,
- .total = 65536.0,
- .attributes = FileDescriptorMeter_attributes,
- .name = "FileDescriptors",
- .uiName = "File Descriptors",
- .caption = "FDs: ",
- .description = "Number of allocated/available file descriptors"
- };
|