LinuxProcess.c 3.34 KB
Newer Older
1
2
3
4
5
6
7
8
/*
htop - LinuxProcess.c
(C) 2014 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/

#include "Process.h"
Hisham Muhammad's avatar
Hisham Muhammad committed
9
10
11
12
#include "ProcessList.h"
#include "LinuxProcess.h"
#include "CRT.h"

13
#include <stdlib.h>
Hisham Muhammad's avatar
Hisham Muhammad committed
14
15
#include <unistd.h>
#include <sys/syscall.h>
16
17
18

/*{

Hisham Muhammad's avatar
Hisham Muhammad committed
19
20
#include "IOPriority.h"

21
22
23
24
25
typedef struct LinuxProcess_ {
   Process super;
   IOPriority ioPriority;
} LinuxProcess;

26
27
#define Process_delete LinuxProcess_delete

28
29
}*/

30
31
LinuxProcess* LinuxProcess_new(Settings* settings) {
   LinuxProcess* this = calloc(sizeof(LinuxProcess), 1);
32
   Object_setClass(this, Class(Process));
33
34
35
36
37
   Process_init(&this->super, settings);
   return this;
}

void LinuxProcess_delete(Object* cast) {
38
   LinuxProcess* this = (LinuxProcess*) cast;
39
40
41
42
   Process_done((Process*)cast);
   free(this);
}

43
44
45
46
47
48
49
50
/*
[1] Note that before kernel 2.6.26 a process that has not asked for
an io priority formally uses "none" as scheduling class, but the
io scheduler will treat such processes as if it were in the best
effort class. The priority within the best effort class will  be
dynamically  derived  from  the  cpu  nice level of the process:
io_priority = (cpu_nice + 20) / 5. -- From ionice(1) man page
*/
Hisham Muhammad's avatar
Hisham Muhammad committed
51
#define LinuxProcess_effectiveIOPriority(p_) (IOPriority_class(p_->ioPriority) == IOPRIO_CLASS_NONE ? IOPriority_tuple(IOPRIO_CLASS_BE, (p_->super.nice + 20) / 5) : p_->ioPriority)
52

Hisham Muhammad's avatar
Hisham Muhammad committed
53
54
IOPriority LinuxProcess_updateIOPriority(LinuxProcess* this) {
   IOPriority ioprio = syscall(SYS_ioprio_get, IOPRIO_WHO_PROCESS, this->super.pid);
55
56
57
58
   this->ioPriority = ioprio;
   return ioprio;
}

Hisham Muhammad's avatar
Hisham Muhammad committed
59
60
61
bool LinuxProcess_setIOPriority(LinuxProcess* this, IOPriority ioprio) {
   syscall(SYS_ioprio_set, IOPRIO_WHO_PROCESS, this->super.pid, ioprio);
   return (LinuxProcess_updateIOPriority(this) == ioprio);
62
63
}

Hisham Muhammad's avatar
Hisham Muhammad committed
64
65
void Process_writeField(Process* this, RichString* str, ProcessField field) {
   LinuxProcess* lp = (LinuxProcess*) this;
Hisham Muhammad's avatar
Hisham Muhammad committed
66
67
68
   char buffer[256]; buffer[255] = '\0';
   int attr = CRT_colors[DEFAULT_COLOR];
   int n = sizeof(buffer) - 1;
69
70
   switch (field) {
   case IO_PRIORITY: {
Hisham Muhammad's avatar
Hisham Muhammad committed
71
      int klass = IOPriority_class(lp->ioPriority);
72
73
      if (klass == IOPRIO_CLASS_NONE) {
         // see note [1] above
Hisham Muhammad's avatar
Hisham Muhammad committed
74
         snprintf(buffer, n, "B%1d ", (int) (this->nice + 20) / 5);
75
      } else if (klass == IOPRIO_CLASS_BE) {
Hisham Muhammad's avatar
Hisham Muhammad committed
76
         snprintf(buffer, n, "B%1d ", IOPriority_data(lp->ioPriority));
77
78
      } else if (klass == IOPRIO_CLASS_RT) {
         attr = CRT_colors[PROCESS_HIGH_PRIORITY];
Hisham Muhammad's avatar
Hisham Muhammad committed
79
80
         snprintf(buffer, n, "R%1d ", IOPriority_data(lp->ioPriority));
      } else if (lp->ioPriority == IOPriority_Idle) {
81
82
83
84
85
86
87
88
         attr = CRT_colors[PROCESS_LOW_PRIORITY]; 
         snprintf(buffer, n, "id ");
      } else {
         snprintf(buffer, n, "?? ");
      }
      break;
   }
   default:
Hisham Muhammad's avatar
Hisham Muhammad committed
89
90
      Process_writeDefaultField(this, str, field);
      return;
91
92
93
94
   }
   RichString_append(str, attr, buffer);
}

Hisham Muhammad's avatar
Hisham Muhammad committed
95
long Process_compare(const void* v1, const void* v2) {
96
   LinuxProcess *p1, *p2;
Hisham Muhammad's avatar
Hisham Muhammad committed
97
98
   Settings *settings = ((Process*)v1)->settings;
   if (settings->direction == 1) {
99
100
101
102
103
104
      p1 = (LinuxProcess*)v1;
      p2 = (LinuxProcess*)v2;
   } else {
      p2 = (LinuxProcess*)v1;
      p1 = (LinuxProcess*)v2;
   }
Hisham Muhammad's avatar
Hisham Muhammad committed
105
   switch (settings->sortKey) {
106
   case IO_PRIORITY:
Hisham Muhammad's avatar
Hisham Muhammad committed
107
      return LinuxProcess_effectiveIOPriority(p1) - LinuxProcess_effectiveIOPriority(p2);
108
   default:
Hisham Muhammad's avatar
Hisham Muhammad committed
109
      return Process_defaultCompare(v1, v2);
110
111
   }
}