diff options
author | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2010-11-11 15:01:12 -0500 |
---|---|---|
committer | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2010-11-11 15:01:12 -0500 |
commit | 18765909b0fd8f5a0b0780d2a70e999791781107 (patch) | |
tree | 8695a8047c89054f5dcadac05f1e13ad9df67145 |
cpu hog
-rwxr-xr-x | launch.sh | 12 | ||||
-rw-r--r-- | loop.c | 97 |
2 files changed, 109 insertions, 0 deletions
diff --git a/launch.sh b/launch.sh new file mode 100755 index 0000000..bb68274 --- /dev/null +++ b/launch.sh | |||
@@ -0,0 +1,12 @@ | |||
1 | #!/bin/bash | ||
2 | |||
3 | ./loop 0 0.33 & | ||
4 | ./loop 1 0.5 & | ||
5 | ./loop 2 0.1 & | ||
6 | ./loop 3 0.2 & | ||
7 | |||
8 | read | ||
9 | |||
10 | kill `pidof loop` | ||
11 | |||
12 | wait | ||
@@ -0,0 +1,97 @@ | |||
1 | #define _GNU_SOURCE /* for cpu sets */ | ||
2 | |||
3 | #include <sys/time.h> | ||
4 | #include <stdio.h> | ||
5 | #include <stdlib.h> | ||
6 | #include <unistd.h> | ||
7 | #include <time.h> | ||
8 | |||
9 | #include <sched.h> | ||
10 | |||
11 | static int migrate_to(int target_cpu) | ||
12 | { | ||
13 | cpu_set_t cpu_set; | ||
14 | |||
15 | CPU_ZERO(&cpu_set); | ||
16 | CPU_SET(target_cpu, &cpu_set); | ||
17 | return sched_setaffinity(0, sizeof(cpu_set_t), &cpu_set); | ||
18 | } | ||
19 | |||
20 | static int become_fifo_task(void) | ||
21 | { | ||
22 | struct sched_param sp; | ||
23 | sp.sched_priority = sched_get_priority_max(SCHED_FIFO); | ||
24 | return sched_setscheduler(0, SCHED_FIFO, &sp); | ||
25 | } | ||
26 | |||
27 | static int suspend(double seconds) | ||
28 | { | ||
29 | struct timespec delay; | ||
30 | delay.tv_sec = (time_t) seconds; | ||
31 | delay.tv_nsec = (long) ((seconds - delay.tv_sec) * 1E9); | ||
32 | return nanosleep(&delay, NULL); | ||
33 | } | ||
34 | |||
35 | static double cputime(void) | ||
36 | { | ||
37 | struct timespec ts; | ||
38 | int err; | ||
39 | err = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts); | ||
40 | if (err != 0) | ||
41 | perror("clock_gettime"); | ||
42 | return (ts.tv_sec + 1E-9 * ts.tv_nsec); | ||
43 | } | ||
44 | |||
45 | static double wctime(void) | ||
46 | { | ||
47 | struct timeval tv; | ||
48 | gettimeofday(&tv, NULL); | ||
49 | return (tv.tv_sec + 1E-6 * tv.tv_usec); | ||
50 | } | ||
51 | |||
52 | static void waste_time(double seconds) | ||
53 | { | ||
54 | double start = cputime(); | ||
55 | |||
56 | while (start + seconds > cputime()) | ||
57 | ; | ||
58 | } | ||
59 | |||
60 | |||
61 | int main(int argc, char** argv) | ||
62 | { | ||
63 | int i = 1, cpu; | ||
64 | double start, end; | ||
65 | double delay; | ||
66 | |||
67 | if (argc != 3) { | ||
68 | fprintf(stderr, "usage: loop <cpu> <loop length (seconds)>\n"); | ||
69 | return 1; | ||
70 | } else { | ||
71 | cpu = atoi(argv[1]); | ||
72 | delay = atof(argv[2]); | ||
73 | } | ||
74 | |||
75 | if (migrate_to(cpu) != 0) { | ||
76 | perror("migrate_to"); | ||
77 | return 1; | ||
78 | } | ||
79 | |||
80 | if (delay <= 0) { | ||
81 | fprintf(stderr, "bad delay: must exceed 0 seconds\n"); | ||
82 | return 1; | ||
83 | } | ||
84 | |||
85 | if (become_fifo_task() != 0) | ||
86 | fprintf(stderr, "cold not become SCHED_FIFO task (%m)\n"); | ||
87 | |||
88 | while (1) { | ||
89 | start = wctime(); | ||
90 | waste_time(delay); | ||
91 | end = wctime(); | ||
92 | printf("%d: loop %d took %.2f seconds \n", | ||
93 | getpid(), i++, end - start); | ||
94 | suspend(delay * 4); /* about 20% utilization */ | ||
95 | } | ||
96 | return 0; | ||
97 | } | ||