| Benny Baumann | e0229b2 | 2022-05-01 22:43:00 +0200 | [diff] [blame] | 1 | /* |
| 2 | htop - FileDescriptorMeter.c |
| 3 | (C) 2022 htop dev team |
| 4 | Released under the GNU GPLv2+, see the COPYING file |
| 5 | in the source distribution for its full text. |
| 6 | */ |
| 7 | |
| Daniel Lange | 179aeb0 | 2023-11-29 17:44:20 +0100 | [diff] [blame] | 8 | #include "config.h" // IWYU pragma: keep |
| 9 | |
| Benny Baumann | e0229b2 | 2022-05-01 22:43:00 +0200 | [diff] [blame] | 10 | #include "FileDescriptorMeter.h" |
| 11 | |
| 12 | #include <math.h> |
| Benny Baumann | e0229b2 | 2022-05-01 22:43:00 +0200 | [diff] [blame] | 13 | |
| 14 | #include "CRT.h" |
| Explorer09 | b416433 | 2023-07-29 16:24:12 +0800 | [diff] [blame] | 15 | #include "Macros.h" |
| Benny Baumann | e0229b2 | 2022-05-01 22:43:00 +0200 | [diff] [blame] | 16 | #include "Meter.h" |
| 17 | #include "Object.h" |
| 18 | #include "Platform.h" |
| 19 | #include "RichString.h" |
| 20 | #include "XUtils.h" |
| 21 | |
| 22 | |
| Explorer09 | b416433 | 2023-07-29 16:24:12 +0800 | [diff] [blame] | 23 | #define FD_EFFECTIVE_UNLIMITED(x) (!isgreaterequal((double)(1<<30), (x))) |
| Benny Baumann | 89872e3 | 2023-02-14 10:59:04 +0100 | [diff] [blame] | 24 | |
| Benny Baumann | e0229b2 | 2022-05-01 22:43:00 +0200 | [diff] [blame] | 25 | static const int FileDescriptorMeter_attributes[] = { |
| 26 | FILE_DESCRIPTOR_USED, |
| 27 | FILE_DESCRIPTOR_MAX |
| 28 | }; |
| 29 | |
| 30 | static void FileDescriptorMeter_updateValues(Meter* this) { |
| 31 | this->values[0] = 0; |
| 32 | this->values[1] = 1; |
| 33 | |
| 34 | Platform_getFileDescriptors(&this->values[0], &this->values[1]); |
| 35 | |
| 36 | /* only print bar for first value */ |
| 37 | this->curItems = 1; |
| 38 | |
| Benny Baumann | 89872e3 | 2023-02-14 10:59:04 +0100 | [diff] [blame] | 39 | /* Use maximum value for scaling of bar mode |
| 40 | * |
| 41 | * As the plain total value can be very large compared to |
| 42 | * the actually used value, this is capped in the following way: |
| 43 | * |
| 44 | * 1. If the maximum value is below (or equal to) 1<<16, use it directly |
| 45 | * 2. If the maximum value is above, use powers of 2 starting at 1<<16 and |
| 46 | * double it until it's larger than 16 times the used file handles |
| 47 | * (capped at the maximum number of files) |
| 48 | * 3. If the maximum is effectively unlimited (AKA > 1<<30), |
| 49 | * Do the same as for 2, but cap at 1<<30. |
| 50 | */ |
| Benny Baumann | da255cb | 2023-04-11 22:49:39 +0200 | [diff] [blame] | 51 | if (this->values[1] <= 1 << 16) { |
| Benny Baumann | 89872e3 | 2023-02-14 10:59:04 +0100 | [diff] [blame] | 52 | this->total = this->values[1]; |
| 53 | } else { |
| 54 | if (this->total < 16 * this->values[0]) { |
| Benny Baumann | da255cb | 2023-04-11 22:49:39 +0200 | [diff] [blame] | 55 | for (this->total = 1 << 16; this->total < 16 * this->values[0]; this->total *= 2) { |
| 56 | if (this->total >= 1 << 30) { |
| Benny Baumann | 89872e3 | 2023-02-14 10:59:04 +0100 | [diff] [blame] | 57 | break; |
| 58 | } |
| 59 | } |
| 60 | } |
| 61 | |
| 62 | if (this->total > this->values[1]) { |
| 63 | this->total = this->values[1]; |
| 64 | } |
| 65 | |
| Benny Baumann | da255cb | 2023-04-11 22:49:39 +0200 | [diff] [blame] | 66 | if (this->total > 1 << 30) { |
| 67 | this->total = 1 << 30; |
| Benny Baumann | 89872e3 | 2023-02-14 10:59:04 +0100 | [diff] [blame] | 68 | } |
| 69 | } |
| Benny Baumann | e0229b2 | 2022-05-01 22:43:00 +0200 | [diff] [blame] | 70 | |
| Explorer09 | b416433 | 2023-07-29 16:24:12 +0800 | [diff] [blame] | 71 | if (!isNonnegative(this->values[0])) { |
| Benny Baumann | e0229b2 | 2022-05-01 22:43:00 +0200 | [diff] [blame] | 72 | xSnprintf(this->txtBuffer, sizeof(this->txtBuffer), "unknown/unknown"); |
| Explorer09 | b416433 | 2023-07-29 16:24:12 +0800 | [diff] [blame] | 73 | } else if (FD_EFFECTIVE_UNLIMITED(this->values[1])) { |
| Benny Baumann | 89872e3 | 2023-02-14 10:59:04 +0100 | [diff] [blame] | 74 | xSnprintf(this->txtBuffer, sizeof(this->txtBuffer), "%.0lf/unlimited", this->values[0]); |
| Benny Baumann | e0229b2 | 2022-05-01 22:43:00 +0200 | [diff] [blame] | 75 | } else { |
| 76 | xSnprintf(this->txtBuffer, sizeof(this->txtBuffer), "%.0lf/%.0lf", this->values[0], this->values[1]); |
| 77 | } |
| 78 | } |
| 79 | |
| 80 | static void FileDescriptorMeter_display(const Object* cast, RichString* out) { |
| 81 | const Meter* this = (const Meter*)cast; |
| 82 | char buffer[50]; |
| 83 | int len; |
| 84 | |
| Explorer09 | b416433 | 2023-07-29 16:24:12 +0800 | [diff] [blame] | 85 | if (!isNonnegative(this->values[0])) { |
| Benny Baumann | e0229b2 | 2022-05-01 22:43:00 +0200 | [diff] [blame] | 86 | RichString_appendAscii(out, CRT_colors[METER_TEXT], "unknown"); |
| 87 | return; |
| 88 | } |
| 89 | |
| 90 | RichString_appendAscii(out, CRT_colors[METER_TEXT], "used: "); |
| 91 | len = xSnprintf(buffer, sizeof(buffer), "%.0lf", this->values[0]); |
| 92 | RichString_appendnAscii(out, CRT_colors[FILE_DESCRIPTOR_USED], buffer, len); |
| 93 | |
| 94 | RichString_appendAscii(out, CRT_colors[METER_TEXT], " max: "); |
| Explorer09 | b416433 | 2023-07-29 16:24:12 +0800 | [diff] [blame] | 95 | if (FD_EFFECTIVE_UNLIMITED(this->values[1])) { |
| Benny Baumann | 89872e3 | 2023-02-14 10:59:04 +0100 | [diff] [blame] | 96 | RichString_appendAscii(out, CRT_colors[FILE_DESCRIPTOR_MAX], "unlimited"); |
| 97 | } else { |
| 98 | len = xSnprintf(buffer, sizeof(buffer), "%.0lf", this->values[1]); |
| 99 | RichString_appendnAscii(out, CRT_colors[FILE_DESCRIPTOR_MAX], buffer, len); |
| 100 | } |
| Benny Baumann | e0229b2 | 2022-05-01 22:43:00 +0200 | [diff] [blame] | 101 | } |
| 102 | |
| 103 | const MeterClass FileDescriptorMeter_class = { |
| 104 | .super = { |
| 105 | .extends = Class(Meter), |
| 106 | .delete = Meter_delete, |
| 107 | .display = FileDescriptorMeter_display, |
| 108 | }, |
| 109 | .updateValues = FileDescriptorMeter_updateValues, |
| 110 | .defaultMode = TEXT_METERMODE, |
| Explorer09 | 36626ce | 2024-05-03 03:52:57 +0800 | [diff] [blame] | 111 | .supportedModes = METERMODE_DEFAULT_SUPPORTED, |
| Benny Baumann | e0229b2 | 2022-05-01 22:43:00 +0200 | [diff] [blame] | 112 | .maxItems = 2, |
| Benny Baumann | 89872e3 | 2023-02-14 10:59:04 +0100 | [diff] [blame] | 113 | .total = 65536.0, |
| Benny Baumann | e0229b2 | 2022-05-01 22:43:00 +0200 | [diff] [blame] | 114 | .attributes = FileDescriptorMeter_attributes, |
| 115 | .name = "FileDescriptors", |
| 116 | .uiName = "File Descriptors", |
| 117 | .caption = "FDs: ", |
| 118 | .description = "Number of allocated/available file descriptors" |
| 119 | }; |