in coinrun/coinrun.cpp [1929:1967]
void vec_wait(
int handle,
uint8_t* obs_rgb,
uint8_t* obs_hires_rgb,
float* rew,
bool* done)
{
std::shared_ptr<VectorOfStates> vstate = vstate_find(handle);
while (1) {
QMutexLocker sleeplock(&h2s_mutex);
bool all_steps_completed = true;
{
QMutexLocker lock2(&vstate->states_mutex);
for (int e = 0; e < vstate->nenvs; e++) {
std::shared_ptr<State> state = vstate->states[e];
QMutexLocker lock3(&state->step_mutex);
all_steps_completed &= !state->agent_ready;
}
}
if (all_steps_completed)
break;
wait_for_step_completed.wait(&h2s_mutex, 1000); // milliseconds
}
QMutexLocker lock1(&vstate->states_mutex);
for (int e = 0; e < vstate->nenvs; e++) {
std::shared_ptr<State> state_e = vstate->states[e];
QMutexLocker lock2(&state_e->state_mutex);
// don't really need a mutex, because step is completed, but it's cheap to lock anyway
Agent& a = state_e->agent;
if (a.render_hires_buf)
copy_render_buf(e, obs_hires_rgb, a.render_hires_buf, VIDEORES, VIDEORES);
copy_render_buf(e, obs_rgb, a.render_buf, RES_W, RES_H);
rew[e] = a.reward;
done[e] = a.game_over;
a.reward = 0;
a.game_over = false;
}
}