|
8 | 8 | #include <chrono> |
9 | 9 | #include <cuda_runtime.h> |
10 | 10 | #include <optional> |
| 11 | +#include <system_error> |
| 12 | +#include <cstdlib> |
| 13 | +#include <cerrno> |
| 14 | +#include <limits> |
11 | 15 | #include <random> |
12 | 16 | #include <nvtx3/nvToolsExt.h> |
13 | 17 | #include <nanobind/stl/string.h> |
@@ -60,32 +64,49 @@ static void trigger_gc() { |
60 | 64 |
|
61 | 65 | BenchmarkParameters read_benchmark_parameters(int input_fd) { |
62 | 66 | char buf[256]; |
63 | | - FILE* sig_file = fdopen(input_fd, "r"); |
64 | | - if (!sig_file) { |
65 | | - throw std::runtime_error("Could not open signature pipe"); |
| 67 | + FILE* inp_file = fdopen(input_fd, "r"); |
| 68 | + if (!inp_file) { |
| 69 | + throw std::system_error(errno, std::generic_category(), "Could not open input pipe"); |
66 | 70 | } |
67 | | - if (!fgets(buf, sizeof(buf), sig_file)) { |
68 | | - fclose(sig_file); |
69 | | - throw std::runtime_error("Could not read signature"); |
70 | | - } |
71 | | - std::string signature = std::string(buf); |
72 | | - |
73 | | - if (!fgets(buf, sizeof(buf), sig_file)) { |
74 | | - fclose(sig_file); |
75 | | - throw std::runtime_error("Could not read seed"); |
76 | | - } |
77 | | - std::uint64_t seed = std::strtoull(buf, nullptr, 10); |
78 | 71 |
|
| 72 | + auto read_line = [&](const char* field_name) { |
| 73 | + if (!fgets(buf, sizeof(buf), inp_file)) { |
| 74 | + int err = errno; |
| 75 | + if (feof(inp_file)) { |
| 76 | + fclose(inp_file); |
| 77 | + throw std::runtime_error(std::string("Unexpected EOF reading ") + field_name); |
| 78 | + } |
| 79 | + fclose(inp_file); |
| 80 | + throw std::system_error(err, std::generic_category(), |
| 81 | + std::string("Could not read ") + field_name); |
| 82 | + } |
| 83 | + }; |
79 | 84 |
|
80 | | - if (!fgets(buf, sizeof(buf), sig_file)) { |
81 | | - fclose(sig_file); |
82 | | - throw std::runtime_error("Could not read repeats"); |
| 85 | + read_line("signature"); |
| 86 | + std::string signature(buf); |
| 87 | + if (signature.empty() || signature.back() != '\n') { |
| 88 | + fclose(inp_file); |
| 89 | + throw std::invalid_argument("Malformed or empty signature"); |
| 90 | + } |
| 91 | + signature.pop_back(); |
| 92 | + |
| 93 | + read_line("seed"); |
| 94 | + char* end; |
| 95 | + std::uint64_t seed = std::strtoull(buf, &end, 10); |
| 96 | + if (end == buf || (*end != '\n' && *end != '\0')) { |
| 97 | + fclose(inp_file); |
| 98 | + throw std::invalid_argument("Invalid seed: " + std::string(buf)); |
83 | 99 | } |
| 100 | + |
| 101 | + read_line("repeats"); |
84 | 102 | long repeats = std::strtol(buf, nullptr, 10); |
85 | | - if (repeats >= std::numeric_limits<int>::max()) { |
86 | | - throw std::runtime_error("Repeats exceeds 2^32"); |
| 103 | + if (repeats >= std::numeric_limits<int>::max() || repeats < 2) { |
| 104 | + fclose(inp_file); |
| 105 | + throw std::invalid_argument( |
| 106 | + "Invalid number of repeats: " + std::to_string(repeats)); |
87 | 107 | } |
88 | 108 |
|
| 109 | + fclose(inp_file); |
89 | 110 | return {signature, seed, static_cast<int>(repeats)}; |
90 | 111 | } |
91 | 112 |
|
|
0 commit comments