Measure time until an std::future object becomes available

168 Views Asked by At

I am trying to measure the duration of an API call which returns an std::future object.

My current approach looks like this:

std::chrono::high_resolution_clock::time_point endTime, startTime = std::chrono::high_resolution_clock::now();

std::shared_future<API::response> responseFuture = API::request();

std::future_status status = responseFuture.wait_for(3s); // Some Timeout

if (status == std::future_status::ready)
  endTime = std::chrono::high_resolution_clock::now();
else
  // error handling

However, I'm unsure about the use of std::future::wait_for. cppreference.com states:

This function may block for longer than timeout_duration due to scheduling or resource contention delays.

I am not worried about blocking longer than timeout_duration, but I do require wait_for to immediately return once the std::future object is available, i.e. not having an implementation along the lines of

while(!ready){
  std::this_thread::sleep_for(10ms);
}

Is this guaranteed?

2

There are 2 best solutions below

0
On

You are working in a preemptive multithreading environment; nothing happens "immediately". Once you give your timeslice over to the OS by blocking (or it steals your timeslice), you've given up control. The OS will unblock your thread at some point after the mutex is unlocked. OS's try to be prompt about these things, but there are no guarantees.

The best you can hope for is "soon after". wait_for will get you that.

0
On

The function will return once the shared state is ready, or the timeout (plus a bit) elapses. Per [futures.unique.future]/21 the effect of the function is

None if the shared state contains a deferred function ([futures.async]), otherwise blocks until the shared state is ready or until the relative timeout ([thread.req.timing]) specified by rel_­time has expired.

emphasis mine

And [thread.req.timing] has

  1. Implementations necessarily have some delay in returning from a timeout. Any overhead in interrupt response, function return, and scheduling induces a “quality of implementation” delay, expressed as duration Di. Ideally, this delay would be zero. Further, any contention for processor and memory resources induces a “quality of management” delay, expressed as duration Dm. The delay durations may vary from timeout to timeout, but in all cases shorter is better.

  2. The functions whose names end in _­for take an argument that specifies a duration. These functions produce relative timeouts. Implementations should use a steady clock to measure time for these functions.326 Given a duration argument Dt, the real-time duration of the timeout is Dt+Di+Dm.

Which talks about the extra added time there may be added to the timeout before the function actually returns.