ProcessTableModel.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. #include "ProcessTableModel.h"
  2. #include <fcntl.h>
  3. #include <stdio.h>
  4. ProcessTableModel::ProcessTableModel()
  5. {
  6. }
  7. ProcessTableModel::~ProcessTableModel()
  8. {
  9. }
  10. int ProcessTableModel::row_count() const
  11. {
  12. return m_processes.size();
  13. }
  14. int ProcessTableModel::column_count() const
  15. {
  16. return 4;
  17. }
  18. String ProcessTableModel::column_name(int column) const
  19. {
  20. switch (column) {
  21. case 0: return "PID";
  22. case 1: return "State";
  23. case 2: return "CPU";
  24. case 3: return "Name";
  25. default: ASSERT_NOT_REACHED();
  26. }
  27. }
  28. int ProcessTableModel::column_width(int column) const
  29. {
  30. switch (column) {
  31. case 0: return 30;
  32. case 1: return 80;
  33. case 2: return 30;
  34. case 3: return 200;
  35. default: ASSERT_NOT_REACHED();
  36. }
  37. }
  38. GModelIndex ProcessTableModel::selected_index() const
  39. {
  40. return { m_selected_row, 0 };
  41. }
  42. void ProcessTableModel::set_selected_index(GModelIndex index)
  43. {
  44. if (index.row() >= 0 && index.row() < m_pids.size())
  45. m_selected_row = index.row();
  46. }
  47. String ProcessTableModel::data(int row, int column) const
  48. {
  49. ASSERT(is_valid({ row, column }));
  50. auto it = m_processes.find(m_pids[row]);
  51. auto& process = *(*it).value;
  52. switch (column) {
  53. case 0: return String::format("%d", process.current_state.pid);
  54. case 1: return process.current_state.state;
  55. case 2: return String::format("%d", (int)process.current_state.cpu_percent);
  56. case 3: return process.current_state.name;
  57. }
  58. ASSERT_NOT_REACHED();
  59. }
  60. void ProcessTableModel::update()
  61. {
  62. FILE* fp = fopen("/proc/all", "r");
  63. if (!fp) {
  64. perror("failed to open /proc/all");
  65. exit(1);
  66. }
  67. unsigned last_sum_nsched = 0;
  68. for (auto& it : m_processes)
  69. last_sum_nsched += it.value->current_state.nsched;
  70. HashTable<pid_t> live_pids;
  71. unsigned sum_nsched = 0;
  72. for (;;) {
  73. char buf[BUFSIZ];
  74. char* ptr = fgets(buf, sizeof(buf), fp);
  75. if (!ptr)
  76. break;
  77. auto parts = String(buf, Chomp).split(',');
  78. if (parts.size() < 17)
  79. break;
  80. bool ok;
  81. pid_t pid = parts[0].to_uint(ok);
  82. ASSERT(ok);
  83. unsigned nsched = parts[1].to_uint(ok);
  84. ASSERT(ok);
  85. ProcessState state;
  86. state.pid = pid;
  87. state.nsched = nsched;
  88. unsigned uid = parts[5].to_uint(ok);
  89. ASSERT(ok);
  90. //state.user = s_usernames->get(uid);
  91. state.user = String::format("%u", uid);
  92. state.priority = parts[16];
  93. state.state = parts[7];
  94. state.name = parts[11];
  95. state.linear = parts[12].to_uint(ok);
  96. ASSERT(ok);
  97. state.committed = parts[13].to_uint(ok);
  98. ASSERT(ok);
  99. {
  100. auto it = m_processes.find(pid);
  101. if (it == m_processes.end())
  102. m_processes.set(pid, make<Process>());
  103. }
  104. auto it = m_processes.find(pid);
  105. ASSERT(it != m_processes.end());
  106. (*it).value->previous_state = (*it).value->current_state;
  107. (*it).value->current_state = state;
  108. live_pids.set(pid);
  109. sum_nsched += nsched;
  110. }
  111. int rc = fclose(fp);
  112. ASSERT(rc == 0);
  113. m_pids.clear();
  114. Vector<pid_t> pids_to_remove;
  115. for (auto& it : m_processes) {
  116. if (!live_pids.contains(it.key)) {
  117. pids_to_remove.append(it.key);
  118. continue;
  119. }
  120. auto& process = *it.value;
  121. dword nsched_diff = process.current_state.nsched - process.previous_state.nsched;
  122. process.current_state.cpu_percent = ((float)nsched_diff * 100) / (float)(sum_nsched - last_sum_nsched);
  123. m_pids.append(it.key);
  124. }
  125. for (auto pid : pids_to_remove)
  126. m_processes.remove(pid);
  127. }
  128. pid_t ProcessTableModel::selected_pid() const
  129. {
  130. if (m_selected_row == -1)
  131. return -1;
  132. return m_pids[m_selected_row];
  133. }