I did not know about C_SafeCond, nice :-) I took a look at how ObjectCacher::flush_set(ObjectSet *oset, Context *onfinish) uses it when called from Client::_flush_range(Inode *in, int64_t offset, uint64_t size). A similar approach would be to Signal a C_SafeCond when the Throttle list<Cond*> cond is not empty ( meaning all calls to Throttle::get_or_fail would return false ), just after cond.push_back(cv); in Throttle::_wait. To achieve that the C_SafeCond object would have to be given in argument to Throttle::_wait and Throttle::get(int64_t c, int64_t m). I don't see a use for such an API change, except for testing purposes but if you think it's worth it, I'd be happy to amend the patch accordingly.
When trying to figure a way to wait for the required condition to happen in a given thread, I was most concerned about the delay it introduces. It is annoying when unit tests are slow. By starting with a delay of one microsecond and doubling it when it's not enough, I've experienced that even on a laptop it rarely needs to pause more than two microseconds.