aboutsummaryrefslogtreecommitdiffstats
path: root/gpu/locktest.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2013-01-10 17:48:39 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2013-01-10 17:48:39 -0500
commit629486d62ae22c33251d3c367af3febff5fe1e28 (patch)
treeef78fc8235c61f8ba37d109ea04266b6ce49b804 /gpu/locktest.c
parent1bf0f0094cd9671adfc07cf840bde67cd4cc0c38 (diff)
Clean up GPU test code placement.
Diffstat (limited to 'gpu/locktest.c')
-rw-r--r--gpu/locktest.c206
1 files changed, 206 insertions, 0 deletions
diff --git a/gpu/locktest.c b/gpu/locktest.c
new file mode 100644
index 0000000..bc4fc54
--- /dev/null
+++ b/gpu/locktest.c
@@ -0,0 +1,206 @@
1#include <stdio.h>
2#include <stdlib.h>
3#include <stdint.h>
4#include <unistd.h>
5#include <assert.h>
6#include <errno.h>
7#include <sys/types.h>
8#include <sys/stat.h>
9#include <fcntl.h>
10
11/* Include gettid() */
12#include <sys/types.h>
13
14/* Include threading support. */
15#include <pthread.h>
16
17/* Include the LITMUS^RT API.*/
18#include "litmus.h"
19
20/* Catch errors.
21 */
22#define CALL( exp ) do { \
23 int ret; \
24 ret = exp; \
25 if (ret != 0) \
26 fprintf(stderr, "%s failed: %m\n", #exp);\
27 else \
28 fprintf(stderr, "%s ok.\n", #exp); \
29 } while (0)
30
31#define TH_CALL( exp ) do { \
32 int ret; \
33 ret = exp; \
34 if (ret != 0) \
35 fprintf(stderr, "[%d] %s failed: %m\n", ctx->id, #exp); \
36 else \
37 fprintf(stderr, "[%d] %s ok.\n", ctx->id, #exp); \
38 } while (0)
39
40#define TH_SAFE_CALL( exp ) do { \
41 int ret; \
42 fprintf(stderr, "[%d] calling %s...\n", ctx->id, #exp); \
43 ret = exp; \
44 if (ret != 0) \
45 fprintf(stderr, "\t...[%d] %s failed: %m\n", ctx->id, #exp); \
46 else \
47 fprintf(stderr, "\t...[%d] %s ok.\n", ctx->id, #exp); \
48 } while (0)
49
50
51/* these are only default values */
52int NUM_THREADS=3;
53int NUM_SEMS=10;
54
55#define MAX_SEMS 1000
56
57#define EXEC_COST 10
58#define PERIOD 100
59
60/* The information passed to each thread. Could be anything. */
61struct thread_context {
62 int id;
63 int fd;
64 int od[MAX_SEMS];
65 int count;
66 unsigned int rand;
67};
68
69void* rt_thread(void* _ctx);
70int nested_job(struct thread_context* ctx, int *count, int *next);
71int job(struct thread_context*);
72
73#define OPTSTR "t:s:"
74
75int main(int argc, char** argv)
76{
77 int i;
78 struct thread_context* ctx;
79 pthread_t* task;
80 int fd;
81
82 int opt;
83 while((opt = getopt(argc, argv, OPTSTR)) != -1) {
84 switch(opt) {
85 case 't':
86 NUM_THREADS = atoi(optarg);
87 break;
88 case 's':
89 NUM_SEMS = atoi(optarg);
90 assert(NUM_SEMS <= MAX_SEMS);
91 break;
92 default:
93 fprintf(stderr, "Unknown option: %c\n", opt);
94 exit(-1);
95 break;
96 }
97 }
98
99 ctx = (struct thread_context*) calloc(NUM_THREADS, sizeof(struct thread_context));
100 task = (pthread_t*) calloc(NUM_THREADS, sizeof(pthread_t));
101
102 srand(0); /* something repeatable for now */
103
104 fd = open("semaphores", O_RDONLY | O_CREAT, S_IRUSR | S_IWUSR);
105
106 CALL( init_litmus() );
107
108 for (i = 0; i < NUM_THREADS; i++) {
109 ctx[i].id = i;
110 ctx[i].fd = fd;
111 ctx[i].rand = rand();
112 CALL( pthread_create(task + i, NULL, rt_thread, ctx + i) );
113 }
114
115
116 for (i = 0; i < NUM_THREADS; i++)
117 pthread_join(task[i], NULL);
118
119
120 return 0;
121}
122
123void* rt_thread(void* _ctx)
124{
125 int i;
126 int do_exit = 0;
127
128 struct thread_context *ctx = (struct thread_context*)_ctx;
129
130 TH_CALL( init_rt_thread() );
131
132 /* Vary period a little bit. */
133 TH_CALL( sporadic_global(EXEC_COST, PERIOD + 10*ctx->id) );
134
135 for (i = 0; i < NUM_SEMS; i++) {
136 ctx->od[i] = open_fmlp_sem(ctx->fd, i);
137 if(ctx->od[i] < 0)
138 perror("open_fmlp_sem");
139 }
140
141 TH_CALL( task_mode(LITMUS_RT_TASK) );
142
143
144 printf("[%d] Waiting for TS release.\n ", ctx->id);
145 wait_for_ts_release();
146 ctx->count = 0;
147
148 do {
149 int which_sem = (int)(NUM_SEMS * (rand_r(&(ctx->rand)) / (RAND_MAX + 1.0)));
150
151 printf("[%d]: trying to get semaphore %d.\n", ctx->id, which_sem);
152 fflush(stdout);
153
154 TH_SAFE_CALL ( litmus_lock(which_sem) );
155
156 printf("[%d] got semaphore %d.\n", ctx->id, which_sem);
157 fflush(stdout);
158
159 do_exit = job(ctx);
160
161 printf("[%d]: freeing semaphore %d.\n", ctx->id, which_sem);
162 fflush(stdout);
163
164 TH_SAFE_CALL ( litmus_unlock(which_sem) );
165
166 if(!do_exit) {
167 sleep_next_period();
168 }
169 } while(!do_exit);
170
171 /*****
172 * 4) Transition to background mode.
173 */
174 TH_CALL( task_mode(BACKGROUND_TASK) );
175
176
177 return NULL;
178}
179
180void dirty_kb(int kb)
181{
182 int32_t one_kb[256];
183 int32_t sum = 0;
184 int32_t i;
185
186 for (i = 0; i < 256; i++)
187 sum += one_kb[i];
188 kb--;
189 /* prevent tail recursion */
190 if (kb)
191 dirty_kb(kb);
192 for (i = 0; i < 256; i++)
193 sum += one_kb[i];
194}
195
196int job(struct thread_context* ctx)
197{
198 /* Do real-time calculation. */
199 dirty_kb(8);
200
201 /* Don't exit. */
202 //return ctx->count++ > 100;
203 //return ctx->count++ > 12000;
204 //return ctx->count++ > 120000;
205 return ctx->count++ > 30000; // controls number of jobs per task
206}