Loop Timing Witness
Native controller and runtime interfaces; hardware qualification pending
Loading...
Searching...
No Matches
run_options.h
Go to the documentation of this file.
1// SPDX-License-Identifier: AGPL-3.0-or-later
2// Commercial license available
3// © Concepts 1996–2026 Miroslav Šotek. All rights reserved.
4// © Code 2020–2026 Miroslav Šotek. All rights reserved.
5// ORCID: 0009-0009-3560-0851
6// Contact: www.anulum.li | protoscience@anulum.li
7// Loop Timing Witness — native run command options
8
12
13#ifndef WITNESS_RUN_OPTIONS_H
14#define WITNESS_RUN_OPTIONS_H
15#include <charconv>
16#include "refusal.h"
17#include <cstring>
18#include <stdexcept>
19
20namespace witness {
22struct RunOptions {
23 const char *metadata = nullptr;
24 const char *power_configuration = nullptr;
25 const char *power_journal = nullptr;
26 int cpu = -1;
27 int scheduler = -1;
28 int priority = -1;
29};
30
32inline void validate_run_options(const RunOptions &options) {
33 if (options.cpu < -1 || options.scheduler < -1 || options.scheduler > 1 ||
34 options.priority < -1)
35 throw witness::RuntimeRefused("invalid CPU, scheduler or priority request");
36 if (options.scheduler == 1 && (options.cpu < 0 || options.priority <= 0))
37 throw witness::RuntimeRefused("FIFO requires explicit CPU and positive priority");
38 if (options.scheduler != 1 && options.priority != -1 &&
39 !(options.scheduler == 0 && options.priority == 0))
40 throw witness::RuntimeRefused("priority requires an explicit scheduler");
41 if ((options.power_configuration == nullptr) != (options.power_journal == nullptr))
42 throw witness::RuntimeRefused("power configuration and journal must be supplied together");
43 if (options.power_configuration && !options.metadata)
44 throw witness::RuntimeRefused("power acquisition requires native metadata");
45}
46
48inline int option_number(const char *text) {
49 int result = 0;
50 const auto parsed = std::from_chars(text, text + std::strlen(text), result);
51 if (parsed.ec != std::errc{} || parsed.ptr != text + std::strlen(text) || result < 0)
52 throw witness::RuntimeRefused("run option requires a nonnegative decimal integer");
53 return result;
54}
55
57inline RunOptions read_run_options(int argc, char **argv, int first) {
58 RunOptions result;
59 for (int index = first; index < argc; index += 2) {
60 if (index + 1 >= argc)
61 throw witness::RuntimeRefused("run option requires a value");
62 if (std::strcmp(argv[index], "--metadata") == 0 && !result.metadata) {
63 result.metadata = argv[index + 1];
64 } else if (std::strcmp(argv[index], "--power-config") == 0 && !result.power_configuration) {
65 result.power_configuration = argv[index + 1];
66 } else if (std::strcmp(argv[index], "--power-journal") == 0 && !result.power_journal) {
67 result.power_journal = argv[index + 1];
68 } else if (std::strcmp(argv[index], "--cpu") == 0 && result.cpu == -1) {
69 result.cpu = option_number(argv[index + 1]);
70 } else if (std::strcmp(argv[index], "--scheduler") == 0 && result.scheduler == -1) {
71 if (std::strcmp(argv[index + 1], "normal") == 0)
72 result.scheduler = 0;
73 else if (std::strcmp(argv[index + 1], "fifo") == 0)
74 result.scheduler = 1;
75 else
76 throw witness::RuntimeRefused("scheduler must be normal or fifo");
77 } else if (std::strcmp(argv[index], "--priority") == 0 && result.priority == -1) {
78 result.priority = option_number(argv[index + 1]);
79 } else
80 throw witness::RuntimeRefused("unknown or duplicate run option");
81 }
83 return result;
84}
85} // namespace witness
104
105#endif
void validate_run_options(const RunOptions &options)
Definition run_options.h:32
RunOptions read_run_options(int argc, char **argv, int first)
Definition run_options.h:57
int option_number(const char *text)
Definition run_options.h:48
const char * power_configuration
Definition run_options.h:24
const char * power_journal
Definition run_options.h:25
const char * metadata
Definition run_options.h:23