+
+static void
+parse_args(int argc, char *argv[])
+{
+ int ch, option_index = 0;
+ char *cp;
+
+ static struct option longopts[] = {
+ { "spin-time", required_argument, NULL, 2 },
+ { "trace", required_argument, NULL, 3 },
+ { "switched_apptype", no_argument, (int*)&g_seen_apptype, TRUE },
+ { "spin-one", no_argument, (int*)&g_do_one_long_spin, TRUE },
+ { "spin-all", no_argument, (int*)&g_do_all_spin, TRUE },
+ { "affinity", no_argument, (int*)&g_do_affinity, TRUE },
+ { "no-sleep", no_argument, (int*)&g_do_sleep, FALSE },
+ { "verbose", no_argument, (int*)&g_verbose, TRUE },
+ { "help", no_argument, NULL, 'h' },
+ { NULL, 0, NULL, 0 }
+ };
+
+ while ((ch = getopt_long(argc, argv, "h", longopts, &option_index)) != -1) {
+ switch (ch) {
+ case 0:
+ /* getopt_long set a variable */
+ break;
+ case 2:
+ /* spin-time */
+ g_do_each_spin = TRUE;
+ g_each_spin_duration_ns = strtoull(optarg, &cp, 10);
+
+ if (cp == optarg || *cp)
+ errx(EX_USAGE, "arg --%s requires a decimal number, found \"%s\"",
+ longopts[option_index].name, optarg);
+ break;
+ case 3:
+ /* trace */
+ g_traceworthy_latency_ns = strtoull(optarg, &cp, 10);
+
+ if (cp == optarg || *cp)
+ errx(EX_USAGE, "arg --%s requires a decimal number, found \"%s\"",
+ longopts[option_index].name, optarg);
+ break;
+ case '?':
+ case 'h':
+ default:
+ usage();
+ /* NORETURN */
+ }
+ }
+
+ /*
+ * getopt_long reorders all the options to the beginning of the argv array.
+ * Jump past them to the non-option arguments.
+ */
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc > 4) {
+ warnx("Too many non-option arguments passed");
+ usage();
+ }
+
+ if (argc != 4) {
+ warnx("Missing required <threads> <waketype> <policy> <iterations> arguments");
+ usage();
+ }
+
+ /* How many threads? */
+ g_numthreads = (uint32_t)strtoull(argv[0], &cp, 10);
+
+ if (cp == argv[0] || *cp)
+ errx(EX_USAGE, "numthreads requires a decimal number, found \"%s\"", argv[0]);
+
+ if (g_numthreads < 1)
+ errx(EX_USAGE, "Must use at least one thread");
+
+ /* What wakeup pattern? */
+ g_waketype = parse_wakeup_pattern(argv[1]);
+
+ /* Policy */
+ g_policy = parse_thread_policy(argv[2]);
+
+ /* Iterations */
+ g_iterations = (uint32_t)strtoull(argv[3], &cp, 10);
+
+ if (cp == argv[3] || *cp)
+ errx(EX_USAGE, "numthreads requires a decimal number, found \"%s\"", argv[3]);
+
+ if (g_iterations < 1)
+ errx(EX_USAGE, "Must have at least one iteration");
+
+ if (g_numthreads == 1 && g_waketype == WAKE_CHAIN)
+ errx(EX_USAGE, "chain mode requires more than one thread");
+
+ if (g_numthreads == 1 && g_waketype == WAKE_HOP)
+ errx(EX_USAGE, "hop mode requires more than one thread");
+}
+
+