aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjoern Brandenburg <bbb@mpi-sws.org>2017-07-28 11:02:37 -0400
committerBjoern Brandenburg <bbb@mpi-sws.org>2017-07-28 11:02:37 -0400
commit914897a4bc19ddf24ec85e5f4306431b1f07cbf2 (patch)
treeda185d716e7bf8f84250fd81fd504f3659ec7427
parent77ce0c782ba2c921e00e028760ac5e26cfb3d9da (diff)
rtspin: add -O option to generate output at end of job
The combination of -S and -O can be used to generate simple event chains. For example, under the GSN-EDF plugin, the following command creates a simple two-stage pipeline that is triggered about once a second for seven seconds. (for x in 1 2 3 4 5 6 7; do echo $x; sleep 1; done) | rtspin -v 10 1000 10 -O -S | rtspin -v 10 100 10 -O -S > /tmp/foo.txt The output is logged to /tmp/foo.txt.
-rw-r--r--bin/rtspin.c57
1 files changed, 54 insertions, 3 deletions
diff --git a/bin/rtspin.c b/bin/rtspin.c
index 49542af..d7cb7b0 100644
--- a/bin/rtspin.c
+++ b/bin/rtspin.c
@@ -62,6 +62,10 @@ const char *usage_msg =
62 " -S[FILE] read from FILE to trigger sporadic job releases\n" 62 " -S[FILE] read from FILE to trigger sporadic job releases\n"
63 " default w/o -S: periodic job releases\n" 63 " default w/o -S: periodic job releases\n"
64 " default if FILE is omitted: read from STDIN\n" 64 " default if FILE is omitted: read from STDIN\n"
65 " -O[FILE] write to FILE when job completes (this is useful with -S\n"
66 " to create precedence constraints/event chains)\n"
67 " default w/o -O: no output\n"
68 " default if FILE is omitted: write to STDOUT\n"
65 "\n" 69 "\n"
66 " -T use clock_nanosleep() instead of sleep_next_period()\n" 70 " -T use clock_nanosleep() instead of sleep_next_period()\n"
67 " -D MAX-DELTA set maximum inter-arrival delay to MAX-DELTA [default: period]\n" 71 " -D MAX-DELTA set maximum inter-arrival delay to MAX-DELTA [default: period]\n"
@@ -251,6 +255,8 @@ static void debug_delay_loop(void)
251 } 255 }
252} 256}
253 257
258static char input_buf[4096] = "<no input>";
259
254static int wait_for_input(int event_fd) 260static int wait_for_input(int event_fd)
255{ 261{
256 /* We do a blocking read, accepting up to 4KiB of data. 262 /* We do a blocking read, accepting up to 4KiB of data.
@@ -260,19 +266,42 @@ static int wait_for_input(int event_fd)
260 * be some sort of configurable job boundary marker, but that's 266 * be some sort of configurable job boundary marker, but that's
261 * not supported in this basic version yet. Patches welcome. 267 * not supported in this basic version yet. Patches welcome.
262 */ 268 */
263 char buf[4096];
264 size_t consumed; 269 size_t consumed;
265 270
266 consumed = read(event_fd, buf, sizeof(buf)); 271 consumed = read(event_fd, input_buf, sizeof(input_buf) - 1);
267 272
268 if (consumed == 0) 273 if (consumed == 0)
269 fprintf(stderr, "reached end-of-file on input event stream\n"); 274 fprintf(stderr, "reached end-of-file on input event stream\n");
270 if (consumed < 0) 275 if (consumed < 0)
271 fprintf(stderr, "error reading input event stream (%m)\n"); 276 fprintf(stderr, "error reading input event stream (%m)\n");
272 277
278 if (consumed > 0) {
279 /* zero-terminate string buffer */
280 input_buf[consumed] = '\0';
281 /* check if we can remove a trailing newline */
282 if (consumed > 1 && input_buf[consumed - 1] == '\n') {
283 input_buf[consumed - 1] = '\0';
284 }
285 }
286
273 return consumed > 0; 287 return consumed > 0;
274} 288}
275 289
290static int generate_output(int output_fd)
291{
292 char buf[4096];
293 size_t len, written;
294 unsigned int job_no;
295
296 get_job_no(&job_no);
297 len = snprintf(buf, 4095, "(rtspin/%d:%u completed: %s @ %" PRIu64 "ns)\n",
298 getpid(), job_no, input_buf, (uint64_t) litmus_clock());
299
300 written = write(output_fd, buf, len);
301
302 return written == len;
303}
304
276static void job(double exec_time, double program_end, int lock_od, double cs_length) 305static void job(double exec_time, double program_end, int lock_od, double cs_length)
277{ 306{
278 double chunk1, chunk2; 307 double chunk1, chunk2;
@@ -297,7 +326,7 @@ static void job(double exec_time, double program_end, int lock_od, double cs_len
297 } 326 }
298} 327}
299 328
300#define OPTSTR "p:c:wlveo:F:s:m:q:r:X:L:Q:iRu:U:Bhd:C:S::TD:E:" 329#define OPTSTR "p:c:wlveo:F:s:m:q:r:X:L:Q:iRu:U:Bhd:C:S::O::TD:E:"
301 330
302int main(int argc, char** argv) 331int main(int argc, char** argv)
303{ 332{
@@ -334,6 +363,8 @@ int main(int argc, char** argv)
334 363
335 int sporadic = 0; /* trigger jobs sporadically? */ 364 int sporadic = 0; /* trigger jobs sporadically? */
336 int event_fd = -1; /* file descriptor for sporadic events */ 365 int event_fd = -1; /* file descriptor for sporadic events */
366 int want_output = 0; /* create output at end of job? */
367 int output_fd = -1; /* file descriptor for output */
337 368
338 int linux_sleep = 0; /* use Linux API for periodic activations? */ 369 int linux_sleep = 0; /* use Linux API for periodic activations? */
339 lt_t next_release; 370 lt_t next_release;
@@ -407,6 +438,21 @@ int main(int argc, char** argv)
407 "for STDIN."); 438 "for STDIN.");
408 } 439 }
409 break; 440 break;
441
442 case 'O':
443 want_output = 1;
444 if (!optarg || strcmp(optarg, "-") == 0)
445 output_fd = STDOUT_FILENO;
446 else
447 output_fd = open(optarg, O_WRONLY | O_APPEND);
448 if (output_fd == -1) {
449 fprintf(stderr, "Could not open file '%s' "
450 "(%m)\n", optarg);
451 usage("-O requires a valid file path or '-' "
452 "for STDOUT.");
453 }
454 break;
455
410 case 'T': 456 case 'T':
411 linux_sleep = 1; 457 linux_sleep = 1;
412 break; 458 break;
@@ -708,6 +754,11 @@ int main(int argc, char** argv)
708 /* burn cycles */ 754 /* burn cycles */
709 job(acet, start + duration, lock_od, cs_length * 0.001); 755 job(acet, start + duration, lock_od, cs_length * 0.001);
710 756
757 if (want_output) {
758 /* generate some output at end of job */
759 generate_output(output_fd);
760 }
761
711 /* wait for periodic job activation (unless sporadic) */ 762 /* wait for periodic job activation (unless sporadic) */
712 if (!sporadic) { 763 if (!sporadic) {
713 /* periodic job activations */ 764 /* periodic job activations */