-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrusage.c
More file actions
91 lines (79 loc) · 2.21 KB
/
rusage.c
File metadata and controls
91 lines (79 loc) · 2.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/*
* A command line util to measure the resource usage of the specified program
* ./rusage command arg...
*
* Note the use of sigprocmask so only the child receives terminal generated signals.
* Tested on openbsd
*/
#include <sys/resource.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
static void exit_error() {
printf("error: %s\n", strerror(errno));
exit(errno);
}
static void exit_usage() {
puts("./rusage command arg...");
exit(EXIT_FAILURE);
}
static void ptval(struct timeval *tval) {
printf("%.2f", (double)tval->tv_sec + (double)tval->tv_usec / 1000000);
}
static void plong(char *msg, long *val) {
printf("%s: %ld\n", msg, *val);
}
static void pinfo() {
struct rusage rusage;
struct timeval *time;
if (getrusage(RUSAGE_CHILDREN, &rusage) == -1)
exit_error();
printf("user time used: ");
ptval(&rusage.ru_utime);
puts("");
printf("system time used: ");
ptval(&rusage.ru_stime);
puts("");
plong("max resident set size", &rusage.ru_maxrss);
plong("integral shared text memory size", &rusage.ru_ixrss);
plong("integral unshared data size", &rusage.ru_idrss);
plong("integral unshared stack size", &rusage.ru_isrss);
plong("page reclaims", &rusage.ru_minflt);
plong("page faults", &rusage.ru_majflt);
plong("swaps", &rusage.ru_nswap);
plong("block input operations", &rusage.ru_inblock);
plong("block output operations", &rusage.ru_oublock);
plong("messages sent", &rusage.ru_msgsnd);
plong("messages received", &rusage.ru_msgrcv);
plong("signals received", &rusage.ru_nsignals);
plong("voluntary context switches", &rusage.ru_nvcsw);
plong("involuntary context switches", &rusage.ru_nivcsw);
}
int main(int argc, char **argv) {
pid_t child;
int i, waitr, fd;
sigset_t block, prev;
if (argc < 2)
exit_usage();
if (sigfillset(&block) == -1)
exit_error();
if (sigprocmask(SIG_BLOCK, &block, &prev) == -1)
exit_error();
if ((child = fork()) == 0) {
if (sigprocmask(SIG_SETMASK, &prev, NULL) == -1)
exit_error();
execvp(argv[1], argv + 1);
exit_error();
} else if (child == -1) {
exit_error();
}
if (wait(&waitr) == -1)
exit_error();
pinfo();
exit(EXIT_SUCCESS);
}