Starts the auto-tuning executable and keeps it running for the process lifetime.
More...
Starts the auto-tuning executable and keeps it running for the process lifetime.
start and stop belong to the composition root and run on one thread. They are the only members that touch the child. Everything else is read-only after a successful start, and safe to read from any thread, which is what the HTTP routes do.
There is deliberately no "is it running" query. Answering it means reaping the child, and a reaped process id can be reissued to something else — so a query that reaped would let a later stop signal an unrelated process. The child's health is discovered by calling it: a request to a dead child fails, and that is the honest answer rather than a flag that was true a moment ago.
| std::expected< void, std::string > mm::auto_tuning::Process::start |
( |
| ) |
|
Spawns the child and waits for it to serve.
Runs the executable as <binary> --http --host 127.0.0.1 --port <port>, then polls GET /api/health until it answers or startTimeout expires. The reply carries the program's version, which version then reports.
Call this before the calling thread becomes real-time. A child inherits the scheduling policy of the thread that spawned it, and this child spreads its work over one numerical worker thread per core, which synchronise by spin-waiting. At real-time priority each of those burns a whole timeslice waiting for the others: measured on the previous integration, a seven-second identification took minutes and starved the 1 ms cycle while it ran.
- Returns
- Nothing on success, or an error naming what failed: a missing executable, a spawn failure, a child that exited during the wait, or a timeout.
Asks the child to exit, then kills it if it does not.
Three steps, politest first: a {"run":"exit"} request, which the auto-tuning program answers by shutting its server down; then a termination signal; then a kill of the whole process group. The request matters most on Windows, which has no signal the program handles, and where its own output is block-buffered — so a hard kill there would lose the tail of its log.
Safe to call when nothing was started, and safe to call twice.
- Returns
- Which step ended it.
Killed is the one worth a warning: a child wedged inside a numerical routine had to be taken down, and that is the case where something could be left holding the port.