diff options
author | Christopher Kenna <cjk@cs.unc.edu> | 2012-04-09 23:20:14 -0400 |
---|---|---|
committer | Christopher Kenna <cjk@cs.unc.edu> | 2012-04-09 23:20:14 -0400 |
commit | 041df061efacf3a8e83edb47ac4db37e67e1a258 (patch) | |
tree | b20490f5da2deff790d1b344bb74308ae147712c | |
parent | b52581ce89bc80938f497bfb61969466e0f2610e (diff) |
partial benchmark program (squash this)
-rw-r--r-- | Makefile | 5 | ||||
-rw-r--r-- | bin/colorbench.c | 169 | ||||
-rw-r--r-- | include/color.h | 2 |
3 files changed, 175 insertions, 1 deletions
@@ -71,7 +71,7 @@ AR := ${CROSS_COMPILE}${AR} | |||
71 | 71 | ||
72 | all = lib ${rt-apps} | 72 | all = lib ${rt-apps} |
73 | rt-apps = cycles base_task rt_launch rtspin release_ts measure_syscall \ | 73 | rt-apps = cycles base_task rt_launch rtspin release_ts measure_syscall \ |
74 | base_mt_task runtests colortest | 74 | base_mt_task runtests colortest colorbench |
75 | 75 | ||
76 | .PHONY: all lib clean dump-config TAGS tags cscope help | 76 | .PHONY: all lib clean dump-config TAGS tags cscope help |
77 | 77 | ||
@@ -219,6 +219,9 @@ lib-measure_syscall = -lm | |||
219 | obj-colortest = colortest.o color.o | 219 | obj-colortest = colortest.o color.o |
220 | lib-colortest = -static | 220 | lib-colortest = -static |
221 | 221 | ||
222 | obj-colorbench = colorbench.o color.o | ||
223 | lib-colorbench = -lpthread -static | ||
224 | |||
222 | # ############################################################################## | 225 | # ############################################################################## |
223 | # Build everything that depends on liblitmus. | 226 | # Build everything that depends on liblitmus. |
224 | 227 | ||
diff --git a/bin/colorbench.c b/bin/colorbench.c new file mode 100644 index 0000000..186bf92 --- /dev/null +++ b/bin/colorbench.c | |||
@@ -0,0 +1,169 @@ | |||
1 | #include <stdint.h> /* for uint32_t */ | ||
2 | #include <stdlib.h> | ||
3 | #include <pthread.h> | ||
4 | #include <sched.h> | ||
5 | #include <sys/mman.h> | ||
6 | |||
7 | #define DEBUG 1 | ||
8 | #ifdef DEBUG | ||
9 | #include <stdio.h> | ||
10 | #endif | ||
11 | |||
12 | #include <litmus/rt_param.h> | ||
13 | |||
14 | #include "color.h" | ||
15 | |||
16 | #define NR_CPUS 4 | ||
17 | |||
18 | struct pthread_state { | ||
19 | int thread; | ||
20 | int retval; | ||
21 | struct color_ctrl_page *color_ctrl; | ||
22 | int *arena; | ||
23 | }; | ||
24 | |||
25 | static pthread_mutex_t ready_mutex; | ||
26 | static pthread_cond_t ready_cond; | ||
27 | static int nr_ready; | ||
28 | static int arena_size = 5 * PAGE_SIZE; | ||
29 | |||
30 | #define ARENA_INTS (arena_size / sizeof(int)) | ||
31 | |||
32 | static int loop_once(struct pthread_state *state) | ||
33 | { | ||
34 | int i, j = 0; | ||
35 | for (i = 0; i < ARENA_INTS; i++) | ||
36 | j += state->arena[i]++; | ||
37 | return j; | ||
38 | } | ||
39 | |||
40 | int thread_init(struct pthread_state *state) | ||
41 | { | ||
42 | cpu_set_t cpu_set; | ||
43 | int err = 0; | ||
44 | |||
45 | CPU_ZERO(&cpu_set); | ||
46 | CPU_SET(state->thread, &cpu_set); | ||
47 | err = sched_setaffinity(0, sizeof(cpu_set_t), &cpu_set); | ||
48 | if (err) { | ||
49 | #ifdef DEBUG | ||
50 | fprintf(stderr, "T%d: set affinity failed\n", state->thread); | ||
51 | #endif | ||
52 | goto out; | ||
53 | } | ||
54 | |||
55 | err = map_color_ctrl((void**)&state->color_ctrl); | ||
56 | if (err) { | ||
57 | #ifdef DEBUG | ||
58 | fprintf(stderr, "couldn't map control device\n"); | ||
59 | #endif | ||
60 | goto out; | ||
61 | } | ||
62 | |||
63 | state->color_ctrl->colors[0] = state->thread; | ||
64 | state->arena = color_malloc(arena_size); | ||
65 | if (!state->arena) { | ||
66 | #ifdef DEBUG | ||
67 | fprintf(stderr, "T%d: alloc arena failed\n", state->thread); | ||
68 | #endif | ||
69 | err = 1; | ||
70 | goto out; | ||
71 | } | ||
72 | |||
73 | err = mlockall(MCL_CURRENT|MCL_FUTURE); | ||
74 | if (err) | ||
75 | { | ||
76 | #ifdef DEBUG | ||
77 | fprintf(stderr, "T%d: mlockall failed\n", state->thread); | ||
78 | #endif | ||
79 | goto out; | ||
80 | } | ||
81 | out: | ||
82 | return err; | ||
83 | } | ||
84 | |||
85 | #define CHECKPRINT(func, ...) do { \ | ||
86 | int err = func(__VA_ARGS__); \ | ||
87 | if (err) \ | ||
88 | fprintf(stderr, "T%d: func failed\n", state->thread); \ | ||
89 | } while (0) | ||
90 | |||
91 | void * thread_start(void *data) | ||
92 | { | ||
93 | struct pthread_state *state = (struct pthread_state*) data; | ||
94 | int i; | ||
95 | |||
96 | state->retval = thread_init(state); | ||
97 | if (state->retval) | ||
98 | goto out; | ||
99 | |||
100 | CHECKPRINT(pthread_mutex_lock, &ready_mutex); | ||
101 | nr_ready++; | ||
102 | if (NR_CPUS == nr_ready) { | ||
103 | CHECKPRINT(pthread_cond_broadcast, &ready_cond); | ||
104 | } else { | ||
105 | while (NR_CPUS > nr_ready) | ||
106 | CHECKPRINT(pthread_cond_wait, &ready_cond, &ready_mutex); | ||
107 | } | ||
108 | CHECKPRINT(pthread_mutex_unlock, &ready_mutex); | ||
109 | |||
110 | loop_once(state); | ||
111 | |||
112 | for (i = 0; i < 1e5; ++i) | ||
113 | loop_once(state); | ||
114 | out: | ||
115 | pthread_exit(&state->retval); | ||
116 | } | ||
117 | |||
118 | static struct pthread_state pthread_state[NR_CPUS]; | ||
119 | |||
120 | #define CHECK(fun, ...) { \ | ||
121 | int err = fun(__VA_ARGS__); \ | ||
122 | if (err) \ | ||
123 | return err; \ | ||
124 | } | ||
125 | |||
126 | int main(int argc, char **argv) | ||
127 | { | ||
128 | int ret = 0, err, i; | ||
129 | |||
130 | pthread_t threads[NR_CPUS]; | ||
131 | pthread_attr_t attr; | ||
132 | |||
133 | CHECK(pthread_attr_init, &attr); | ||
134 | CHECK(pthread_attr_setdetachstate, &attr, PTHREAD_CREATE_JOINABLE); | ||
135 | CHECK(pthread_mutex_init, &ready_mutex, NULL); | ||
136 | CHECK(pthread_cond_init, &ready_cond, NULL); | ||
137 | |||
138 | for (i = 0; i < NR_CPUS; i++) { | ||
139 | pthread_state[i].thread = i; | ||
140 | CHECK(pthread_create, &threads[i], &attr, thread_start, | ||
141 | (void*)&pthread_state[i]); | ||
142 | } | ||
143 | |||
144 | for (i = 0; i < NR_CPUS; i++) { | ||
145 | int *retval; | ||
146 | printf("join %d\n", i); | ||
147 | err = pthread_join(threads[i], (void**)&retval); | ||
148 | if (err) { | ||
149 | #ifdef DEBUG | ||
150 | fprintf(stderr, "pthread_join failed\n"); | ||
151 | #endif | ||
152 | ret = err; | ||
153 | goto out; | ||
154 | } | ||
155 | if (PTHREAD_CANCELED == retval || *retval) { | ||
156 | #ifdef DEBUG | ||
157 | fprintf(stderr, "T%d bad retval.\n", i); | ||
158 | #endif | ||
159 | ret = 1; | ||
160 | } | ||
161 | } | ||
162 | |||
163 | CHECK(pthread_cond_destroy, &ready_cond); | ||
164 | CHECK(pthread_attr_destroy, &attr); | ||
165 | CHECK(pthread_mutex_destroy, &ready_mutex); | ||
166 | |||
167 | out: | ||
168 | return ret; | ||
169 | } | ||
diff --git a/include/color.h b/include/color.h index 50707fd..dc1b1cc 100644 --- a/include/color.h +++ b/include/color.h | |||
@@ -1,6 +1,8 @@ | |||
1 | #ifndef COLOR_H | 1 | #ifndef COLOR_H |
2 | #define COLOR_H | 2 | #define COLOR_H |
3 | 3 | ||
4 | #include <stddef.h> /* for size_t */ | ||
5 | |||
4 | int map_color_ctrl(void **); | 6 | int map_color_ctrl(void **); |
5 | void* color_malloc(size_t); | 7 | void* color_malloc(size_t); |
6 | 8 | ||