aboutsummaryrefslogtreecommitdiffstats
path: root/src/process_group.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/process_group.c')
-rw-r--r--src/process_group.c110
1 files changed, 101 insertions, 9 deletions
diff --git a/src/process_group.c b/src/process_group.c
index 2afef71..043ee69 100644
--- a/src/process_group.c
+++ b/src/process_group.c
@@ -2,6 +2,9 @@
#include <string.h>
#include <stdlib.h>
#include <limits.h>
+#include <sys/time.h>
+
+#include <assert.h>
#include "process_iterator.h"
#include "process_group.h"
@@ -14,6 +17,8 @@ int init_process_group(struct process_group *pgroup, int target_pid, int include
pgroup->target_pid = target_pid;
pgroup->include_children = include_children;
pgroup->proclist = (struct list*)malloc(sizeof(struct list));
+ init_list(pgroup->proclist, 4);
+ memset(&pgroup->last_update, 0, sizeof(pgroup->last_update));
return 0;
}
@@ -29,40 +34,127 @@ int close_process_group(struct process_group *pgroup)
pgroup->proctable[i] = NULL;
}
}
+ clear_list(pgroup->proclist);
free(pgroup->proclist);
pgroup->proclist = NULL;
return 0;
}
+void remove_terminated_processes(struct process_group *pgroup)
+{
+ //TODO
+}
+
+//return t1-t2 in microseconds (no overflow checks, so better watch out!)
+static inline unsigned long timediff(const struct timeval *t1,const struct timeval *t2)
+{
+ return (t1->tv_sec - t2->tv_sec) * 1000000 + (t1->tv_usec - t2->tv_usec);
+}
+
+//parameter in range 0-1
+#define ALFA 0.08
+
+int process_monitor(struct process *proc)
+{
+ // int j = get_jiffies(proc);
+ // if (j<0) return -1; //error retrieving jiffies count (maybe the process is dead)
+ // struct timeval now;
+ // gettimeofday(&now, NULL);
+ // if (proc->last_jiffies==-1) {
+ // //store current time
+ // proc->last_sample = now;
+ // //store current jiffies
+ // proc->last_jiffies = j;
+ // //it's the first sample, cannot figure out the cpu usage
+ // proc->cpu_usage = -1;
+ // return 0;
+ // }
+ // //time from previous sample (in ns)
+ // long dt = timediff(&now, &(proc->last_sample));
+ // //how many jiffies in dt?
+ // double max_jiffies = dt * HZ / 1000000.0;
+ // double sample = (j - proc->last_jiffies) / max_jiffies;
+ // if (proc->cpu_usage == -1) {
+ // //initialization
+ // proc->cpu_usage = sample;
+ // }
+ // else {
+ // //usage adjustment
+ // proc->cpu_usage = (1-ALFA) * proc->cpu_usage + ALFA * sample;
+ // }
+ // //store current time
+ // proc->last_sample = now;
+ // //store current jiffies
+ // proc->last_jiffies = j;
+ return 0;
+}
+
void update_process_group(struct process_group *pgroup)
{
struct process_iterator it;
- struct process process;
+ struct process tmp_process;
struct process_filter filter;
filter.pid = pgroup->target_pid;
filter.include_children = pgroup->include_children;
init_process_iterator(&it, &filter);
- while (get_next_process(&it, &process) != -1)
+ clear_list(pgroup->proclist);
+ init_list(pgroup->proclist, 4);
+ struct timeval now;
+ gettimeofday(&now, NULL);
+ //time elapsed from previous sample (in ms)
+ long dt = timediff(&now, &pgroup->last_update) / 1000;
+ while (get_next_process(&it, &tmp_process) != -1)
{
- printf("Read process %d\n", process.pid);
- printf("Parent %d\n", process.ppid);
- printf("Starttime %d\n", process.starttime);
- printf("CPU time %d\n", process.cputime);
- int hashkey = pid_hashfn(process.pid + process.starttime);
+ // printf("Read process %d\n", tmp_process.pid);
+ // printf("Parent %d\n", tmp_process.ppid);
+ // printf("Starttime %d\n", tmp_process.starttime);
+ // printf("CPU time %d\n", tmp_process.cputime);
+ int hashkey = pid_hashfn(tmp_process.pid + tmp_process.starttime);
if (pgroup->proctable[hashkey] == NULL)
{
//empty bucket
pgroup->proctable[hashkey] = malloc(sizeof(struct list));
struct process *new_process = malloc(sizeof(struct process));
- memcpy(new_process, &process, sizeof(struct process));
+ tmp_process.cpu_usage = -1;
+ memcpy(new_process, &tmp_process, sizeof(struct process));
init_list(pgroup->proctable[hashkey], 4);
add_elem(pgroup->proctable[hashkey], new_process);
+ add_elem(pgroup->proclist, new_process);
}
else
{
//existing bucket
-
+ struct process *p = (struct process*)locate_elem(pgroup->proctable[hashkey], &tmp_process);
+ if (p == NULL)
+ {
+ //process is new. add it
+ struct process *new_process = malloc(sizeof(struct process));
+ tmp_process.cpu_usage = -1;
+ memcpy(new_process, &tmp_process, sizeof(struct process));
+ add_elem(pgroup->proctable[hashkey], new_process);
+ add_elem(pgroup->proclist, new_process);
+ }
+ else
+ {
+ assert(tmp_process.pid == p->pid);
+ assert(tmp_process.ppid == p->ppid);
+ assert(tmp_process.starttime == p->starttime);
+ //process exists. update CPU usage
+ double sample = (tmp_process.cputime - p->cputime) / dt;
+ if (p->cpu_usage == -1) {
+ //initialization
+ p->cpu_usage = sample;
+ }
+ else {
+ //usage adjustment
+ p->cpu_usage = (1-ALFA) * p->cpu_usage + ALFA * sample;
+ }
+ p->cpu_usage = (1-ALFA) * p->cpu_usage + ALFA * sample;
+ p->cputime = tmp_process.cputime;
+ add_elem(pgroup->proclist, p);
+ }
}
}
close_process_iterator(&it);
+ pgroup->last_update = now;
}
Un proyecto texto-plano.xyz