FileDescriptorMeter.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  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. #include "config.h" // IWYU pragma: keep
  8. #include "FileDescriptorMeter.h"
  9. #include <math.h>
  10. #include "CRT.h"
  11. #include "Macros.h"
  12. #include "Meter.h"
  13. #include "Object.h"
  14. #include "Platform.h"
  15. #include "RichString.h"
  16. #include "XUtils.h"
  17. #define FD_EFFECTIVE_UNLIMITED(x) (!isgreaterequal((double)(1<<30), (x)))
  18. static const int FileDescriptorMeter_attributes[] = {
  19. FILE_DESCRIPTOR_USED,
  20. FILE_DESCRIPTOR_MAX
  21. };
  22. static void FileDescriptorMeter_updateValues(Meter* this) {
  23. this->values[0] = 0;
  24. this->values[1] = 1;
  25. Platform_getFileDescriptors(&this->values[0], &this->values[1]);
  26. /* only print bar for first value */
  27. this->curItems = 1;
  28. /* Use maximum value for scaling of bar mode
  29. *
  30. * As the plain total value can be very large compared to
  31. * the actually used value, this is capped in the following way:
  32. *
  33. * 1. If the maximum value is below (or equal to) 1<<16, use it directly
  34. * 2. If the maximum value is above, use powers of 2 starting at 1<<16 and
  35. * double it until it's larger than 16 times the used file handles
  36. * (capped at the maximum number of files)
  37. * 3. If the maximum is effectively unlimited (AKA > 1<<30),
  38. * Do the same as for 2, but cap at 1<<30.
  39. */
  40. if (this->values[1] <= 1 << 16) {
  41. this->total = this->values[1];
  42. } else {
  43. if (this->total < 16 * this->values[0]) {
  44. for (this->total = 1 << 16; this->total < 16 * this->values[0]; this->total *= 2) {
  45. if (this->total >= 1 << 30) {
  46. break;
  47. }
  48. }
  49. }
  50. if (this->total > this->values[1]) {
  51. this->total = this->values[1];
  52. }
  53. if (this->total > 1 << 30) {
  54. this->total = 1 << 30;
  55. }
  56. }
  57. if (!isNonnegative(this->values[0])) {
  58. xSnprintf(this->txtBuffer, sizeof(this->txtBuffer), "unknown/unknown");
  59. } else if (FD_EFFECTIVE_UNLIMITED(this->values[1])) {
  60. xSnprintf(this->txtBuffer, sizeof(this->txtBuffer), "%.0lf/unlimited", this->values[0]);
  61. } else {
  62. xSnprintf(this->txtBuffer, sizeof(this->txtBuffer), "%.0lf/%.0lf", this->values[0], this->values[1]);
  63. }
  64. }
  65. static void FileDescriptorMeter_display(const Object* cast, RichString* out) {
  66. const Meter* this = (const Meter*)cast;
  67. char buffer[50];
  68. int len;
  69. if (!isNonnegative(this->values[0])) {
  70. RichString_appendAscii(out, CRT_colors[METER_TEXT], "unknown");
  71. return;
  72. }
  73. RichString_appendAscii(out, CRT_colors[METER_TEXT], "used: ");
  74. len = xSnprintf(buffer, sizeof(buffer), "%.0lf", this->values[0]);
  75. RichString_appendnAscii(out, CRT_colors[FILE_DESCRIPTOR_USED], buffer, len);
  76. RichString_appendAscii(out, CRT_colors[METER_TEXT], " max: ");
  77. if (FD_EFFECTIVE_UNLIMITED(this->values[1])) {
  78. RichString_appendAscii(out, CRT_colors[FILE_DESCRIPTOR_MAX], "unlimited");
  79. } else {
  80. len = xSnprintf(buffer, sizeof(buffer), "%.0lf", this->values[1]);
  81. RichString_appendnAscii(out, CRT_colors[FILE_DESCRIPTOR_MAX], buffer, len);
  82. }
  83. }
  84. const MeterClass FileDescriptorMeter_class = {
  85. .super = {
  86. .extends = Class(Meter),
  87. .delete = Meter_delete,
  88. .display = FileDescriptorMeter_display,
  89. },
  90. .updateValues = FileDescriptorMeter_updateValues,
  91. .defaultMode = TEXT_METERMODE,
  92. .supportedModes = METERMODE_DEFAULT_SUPPORTED,
  93. .maxItems = 2,
  94. .total = 65536.0,
  95. .attributes = FileDescriptorMeter_attributes,
  96. .name = "FileDescriptors",
  97. .uiName = "File Descriptors",
  98. .caption = "FDs: ",
  99. .description = "Number of allocated/available file descriptors"
  100. };