-
Notifications
You must be signed in to change notification settings - Fork 0
/
burn.c
121 lines (104 loc) · 2.75 KB
/
burn.c
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <err.h>
#include <malloc.h>
#include <signal.h>
#include <pthread.h>
#include <libgen.h>
#include <sys/time.h>
#include <sys/resource.h>
// burn t cpu seconds in t threads while holding m GB virtual memory
// of which r% is resident
void
usage(char *name)
{
fprintf(stderr,\
"Usage: %s [-m memory] [-r percent] [-s secs] [-t threads]\
\n\t-m m\tconsume m GB, default 1\
\n\t-r r\tforce r%% resident memory, default 0%%\
\n\t-s s\tconsume s seconds, default 60\
\n\t-t t\tconsume t threads, default 1\n",\
name);
}
void *
loop(void *arg)
{
for (;;)
;
}
void
handler(int sig)
{
exit(0);
}
int
main(int argc, char **argv)
{
struct rlimit rl = {0, 0};
size_t memtot = 0, memsiz;
char *p, *myname = basename(argv[0]);
unsigned int secs = 60;
int i, opt, threads = 1, mem = 1, touch = 0;
pthread_t t;
// parse arguments
while ((opt = getopt(argc, argv, "hm:r:s:t:?")) != -1) {
switch (opt) {
case 'm':
if ((i = atoi(optarg)) > 0)
mem = i;
break;
case 'r':
if ((i = atoi(optarg)) < 0)
touch = 0;
else if (i > 100)
touch = 100;
else
touch = i;
break;
case 's':
if ((i = atoi(optarg)) >= 0)
secs = i;
break;
case 't':
if ((i = atoi(optarg)) > 0)
threads = i;
break;
default:
usage(myname);
exit(EXIT_FAILURE);
}
}
printf("%s: burning for %d sec on %d threads with %d GB %d%% resident memory\n", myname, secs, threads, mem, touch);
// suppress any attempted core dumps
if (setrlimit(RLIMIT_CORE, &rl) < 0)
warn("setrlimit");
// allocate requested virtual memory
memsiz = mem * (size_t)1024*1024*1024;
if (!(p = malloc(memsiz)))
errx(1, "malloc(%lld) failed", memsiz);
// bring requested percentage of virtual memory into physical memory
// by writing one byte into that percentage of the allocated pages of
// virtual memory, which page faults those pages into physical memory.
// in the absence of swapping, those pages should remain in physical
// memory, but no attempt is made to enforce this.
if (touch)
for (i = 0; i<(memsiz/getpagesize())*touch/100; i++, p += getpagesize())
*p = i & 0xff;
// start the requested number of threads, less one, and
// execute an endless loop in each.
for (i = 1; i < threads; i++)
if (pthread_create(&t, NULL, &loop, NULL))
err(1, "pthread_create");
// set an alarm signal handler, then set an alarm to go off the
// requested number of seconds from now. the alarm signal invokes
// the handler, which simply exits.
if (signal(SIGALRM, handler))
err(1, "signal");
if (alarm(secs) < 0)
err(1, "alarm");
// until the alarm goes off, the main thread executes the same
// endless loop, consuming the remaining core.
loop(NULL);
}