diff options
-rw-r--r-- | bin/rtspin.c | 71 | ||||
-rw-r--r-- | include/litmus.h | 7 | ||||
-rw-r--r-- | src/litmus.c | 20 |
3 files changed, 91 insertions, 7 deletions
diff --git a/bin/rtspin.c b/bin/rtspin.c index f0a477d..5054d0b 100644 --- a/bin/rtspin.c +++ b/bin/rtspin.c | |||
@@ -4,6 +4,7 @@ | |||
4 | #include <stdlib.h> | 4 | #include <stdlib.h> |
5 | #include <unistd.h> | 5 | #include <unistd.h> |
6 | #include <time.h> | 6 | #include <time.h> |
7 | #include <string.h> | ||
7 | #include <assert.h> | 8 | #include <assert.h> |
8 | 9 | ||
9 | 10 | ||
@@ -21,8 +22,10 @@ static void usage(char *error) { | |||
21 | " rt_spin -l\n" | 22 | " rt_spin -l\n" |
22 | "\n" | 23 | "\n" |
23 | "COMMON-OPTS = [-w] [-p PARTITION] [-c CLASS] [-s SCALE]\n" | 24 | "COMMON-OPTS = [-w] [-p PARTITION] [-c CLASS] [-s SCALE]\n" |
25 | " [-X LOCKING-PROTOCOL] [-L CRITICAL SECTION LENGTH] [-Q RESOURCE-ID]" | ||
24 | "\n" | 26 | "\n" |
25 | "WCET and PERIOD are milliseconds, DURATION is seconds.\n"); | 27 | "WCET and PERIOD are milliseconds, DURATION is seconds.\n" |
28 | "CRITICAL SECTION LENGTH is in milliseconds.\n"); | ||
26 | exit(EXIT_FAILURE); | 29 | exit(EXIT_FAILURE); |
27 | } | 30 | } |
28 | 31 | ||
@@ -150,18 +153,37 @@ static void debug_delay_loop(void) | |||
150 | } | 153 | } |
151 | } | 154 | } |
152 | 155 | ||
153 | static int job(double exec_time, double program_end) | 156 | static int job(double exec_time, double program_end, int lock_od, double cs_length) |
154 | { | 157 | { |
158 | double chunk1, chunk2; | ||
159 | |||
155 | if (wctime() > program_end) | 160 | if (wctime() > program_end) |
156 | return 0; | 161 | return 0; |
157 | else { | 162 | else { |
158 | loop_for(exec_time, program_end + 1); | 163 | if (lock_od >= 0) { |
164 | /* simulate critical section somewhere in the middle */ | ||
165 | chunk1 = drand48() * (exec_time - cs_length); | ||
166 | chunk2 = exec_time - cs_length - chunk1; | ||
167 | |||
168 | /* non-critical section */ | ||
169 | loop_for(chunk1, program_end + 1); | ||
170 | |||
171 | /* critical section */ | ||
172 | litmus_lock(lock_od); | ||
173 | loop_for(cs_length, program_end + 1); | ||
174 | litmus_unlock(lock_od); | ||
175 | |||
176 | /* non-critical section */ | ||
177 | loop_for(chunk2, program_end + 2); | ||
178 | } else { | ||
179 | loop_for(exec_time, program_end + 1); | ||
180 | } | ||
159 | sleep_next_period(); | 181 | sleep_next_period(); |
160 | return 1; | 182 | return 1; |
161 | } | 183 | } |
162 | } | 184 | } |
163 | 185 | ||
164 | #define OPTSTR "p:c:wlveo:f:s:q:" | 186 | #define OPTSTR "p:c:wlveo:f:s:q:X:L:Q:" |
165 | 187 | ||
166 | int main(int argc, char** argv) | 188 | int main(int argc, char** argv) |
167 | { | 189 | { |
@@ -184,6 +206,13 @@ int main(int argc, char** argv) | |||
184 | task_class_t class = RT_CLASS_HARD; | 206 | task_class_t class = RT_CLASS_HARD; |
185 | int cur_job, num_jobs; | 207 | int cur_job, num_jobs; |
186 | 208 | ||
209 | /* locking */ | ||
210 | int lock_od = -1; | ||
211 | int resource_id = 0; | ||
212 | const char *lock_namespace = "./rtspin-locks"; | ||
213 | int protocol = -1; | ||
214 | double cs_length = 1; /* millisecond */ | ||
215 | |||
187 | progname = argv[0]; | 216 | progname = argv[0]; |
188 | 217 | ||
189 | while ((opt = getopt(argc, argv, OPTSTR)) != -1) { | 218 | while ((opt = getopt(argc, argv, OPTSTR)) != -1) { |
@@ -220,6 +249,21 @@ int main(int argc, char** argv) | |||
220 | case 's': | 249 | case 's': |
221 | scale = atof(optarg); | 250 | scale = atof(optarg); |
222 | break; | 251 | break; |
252 | case 'X': | ||
253 | protocol = lock_protocol_for_name(optarg); | ||
254 | if (protocol < 0) | ||
255 | usage("Unknown locking protocol specified."); | ||
256 | break; | ||
257 | case 'L': | ||
258 | cs_length = atof(optarg); | ||
259 | if (cs_length <= 0) | ||
260 | usage("Invalid critical section length."); | ||
261 | break; | ||
262 | case 'Q': | ||
263 | resource_id = atoi(optarg); | ||
264 | if (resource_id <= 0 && strcmp(optarg, "0")) | ||
265 | usage("Invalid resource ID."); | ||
266 | break; | ||
223 | case ':': | 267 | case ':': |
224 | usage("Argument missing."); | 268 | usage("Argument missing."); |
225 | break; | 269 | break; |
@@ -235,6 +279,8 @@ int main(int argc, char** argv) | |||
235 | return 0; | 279 | return 0; |
236 | } | 280 | } |
237 | 281 | ||
282 | srand(getpid()); | ||
283 | |||
238 | if (file) { | 284 | if (file) { |
239 | get_exec_times(file, column, &num_jobs, &exec_times); | 285 | get_exec_times(file, column, &num_jobs, &exec_times); |
240 | 286 | ||
@@ -293,6 +339,15 @@ int main(int argc, char** argv) | |||
293 | if (ret != 0) | 339 | if (ret != 0) |
294 | bail_out("could not become RT task"); | 340 | bail_out("could not become RT task"); |
295 | 341 | ||
342 | if (protocol >= 0) { | ||
343 | /* open reference to semaphore */ | ||
344 | lock_od = litmus_open_lock(protocol, resource_id, lock_namespace, &cpu); | ||
345 | if (lock_od < 0) { | ||
346 | perror("litmus_open_lock"); | ||
347 | usage("Could not open lock."); | ||
348 | } | ||
349 | } | ||
350 | |||
296 | if (wait) { | 351 | if (wait) { |
297 | ret = wait_for_ts_release(); | 352 | ret = wait_for_ts_release(); |
298 | if (ret != 0) | 353 | if (ret != 0) |
@@ -306,11 +361,13 @@ int main(int argc, char** argv) | |||
306 | for (cur_job = 0; cur_job < num_jobs; ++cur_job) { | 361 | for (cur_job = 0; cur_job < num_jobs; ++cur_job) { |
307 | /* convert job's length to seconds */ | 362 | /* convert job's length to seconds */ |
308 | job(exec_times[cur_job] * 0.001 * scale, | 363 | job(exec_times[cur_job] * 0.001 * scale, |
309 | start + duration); | 364 | start + duration, |
365 | lock_od, cs_length * 0.001); | ||
310 | } | 366 | } |
311 | } else { | 367 | } else { |
312 | /* conver to seconds and scale */ | 368 | /* convert to seconds and scale */ |
313 | while (job(wcet_ms * 0.001 * scale, start + duration)); | 369 | while (job(wcet_ms * 0.001 * scale, start + duration, |
370 | lock_od, cs_length * 0.001)); | ||
314 | } | 371 | } |
315 | 372 | ||
316 | ret = task_mode(BACKGROUND_TASK); | 373 | ret = task_mode(BACKGROUND_TASK); |
diff --git a/include/litmus.h b/include/litmus.h index 2b6a1dd..58af6b7 100644 --- a/include/litmus.h +++ b/include/litmus.h | |||
@@ -80,6 +80,13 @@ static inline int od_open(int fd, obj_type_t type, int obj_id) | |||
80 | return od_openx(fd, type, obj_id, 0); | 80 | return od_openx(fd, type, obj_id, 0); |
81 | } | 81 | } |
82 | 82 | ||
83 | int litmus_open_lock( | ||
84 | obj_type_t protocol, /* which locking protocol to use, e.g., FMLP_SEM */ | ||
85 | int lock_id, /* numerical id of the lock, user-specified */ | ||
86 | const char* namespace, /* path to a shared file */ | ||
87 | void *config_param); /* any extra info needed by the protocol (such | ||
88 | * as CPU under SRP and PCP), may be NULL */ | ||
89 | |||
83 | /* real-time locking protocol support */ | 90 | /* real-time locking protocol support */ |
84 | int litmus_lock(int od); | 91 | int litmus_lock(int od); |
85 | int litmus_unlock(int od); | 92 | int litmus_unlock(int od); |
diff --git a/src/litmus.c b/src/litmus.c index b32254b..e0d9253 100644 --- a/src/litmus.c +++ b/src/litmus.c | |||
@@ -3,7 +3,10 @@ | |||
3 | #include <stdio.h> | 3 | #include <stdio.h> |
4 | #include <string.h> | 4 | #include <string.h> |
5 | #include <signal.h> | 5 | #include <signal.h> |
6 | #include <fcntl.h> | ||
6 | #include <sys/mman.h> | 7 | #include <sys/mman.h> |
8 | #include <sys/types.h> | ||
9 | |||
7 | 10 | ||
8 | #include <sched.h> /* for cpu sets */ | 11 | #include <sched.h> /* for cpu sets */ |
9 | 12 | ||
@@ -49,6 +52,23 @@ const char* name_for_lock_protocol(int id) | |||
49 | return "<UNKNOWN>"; | 52 | return "<UNKNOWN>"; |
50 | } | 53 | } |
51 | 54 | ||
55 | int litmus_open_lock( | ||
56 | obj_type_t protocol, | ||
57 | int lock_id, | ||
58 | const char* namespace, | ||
59 | void *config_param) | ||
60 | { | ||
61 | int fd, od; | ||
62 | |||
63 | fd = open(namespace, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); | ||
64 | if (fd < 0) | ||
65 | return -1; | ||
66 | od = od_openx(fd, protocol, lock_id, config_param); | ||
67 | close(fd); | ||
68 | return od; | ||
69 | } | ||
70 | |||
71 | |||
52 | 72 | ||
53 | void show_rt_param(struct rt_task* tp) | 73 | void show_rt_param(struct rt_task* tp) |
54 | { | 74 | { |