src/cfrp.cpp
// This breaks if we get Post() before call to WaitForFinalSubgames(), but
// not corresponding join.  Saw num_remaining two but num active three.
This breaks if we get Post() before call to WaitForFinalSubgames(), but
not corresponding join.  Saw num_remaining two but num active three.
This breaks if we get Post () before call to WaitForFinalSubgames () but not corresponding join . Saw num_remaining two but num active three .
void CFRP::WaitForFinalSubgames(void) {
  int num_remaining = 0;
  for (int t = 0; t < num_threads_; ++t) {
    if (active_subgames_[t]) ++num_remaining;
  }
  if (num_remaining != g_num_active) {
    fprintf(stderr, "Expect num_remaining %u to match num_active %u\n",
	    num_remaining, g_num_active);
    exit(-1);
  }
  while (num_remaining > 0) {
    while (sem_wait(&available_) == EINTR) ;
    int t;
    for (t = 0; t < num_threads_; ++t) {
      if (! subgame_running_[t] && active_subgames_[t]) {
	CFRPSubgame *subgame = active_subgames_[t];
	if (subgame == nullptr) {
	  fprintf(stderr, "Subgame finished, but no subgame object?!?\n");
	  exit(-1);
	}
	pthread_join(pthread_ids_[t], NULL);
	Node *root = subgame->Root();
	int p = root->PlayerActing();
	int nt = root->NonterminalID();
	int root_bd = subgame->RootBd();
	final_vals_[p][nt][root_bd] = subgame->FinalVals();
	delete subgame;
	active_subgames_[t] = nullptr;
	--num_remaining;
	--g_num_active;
	break;
      }
    }
  }
  if (g_num_active > 0) {
    fprintf(stderr, "Num active %u at end of WaitForFinalSubgames()\n",
	    g_num_active);
    exit(-1);
  }
}
void CFRP :: WaitForFinalSubgames ( void ) { int num_remaining = 0 ; for ( int t = 0 ; t < num_threads_ ; ++ t ) { if ( active_subgames_ [ t ] ) ++ num_remaining ; } if ( num_remaining != g_num_active ) { fprintf ( stderr , " \n " , num_remaining , g_num_active ) ; exit ( -1 ) ; } while ( num_remaining > 0 ) { while ( sem_wait ( & available_ ) == EINTR ) ; int t ; for ( t = 0 ; t < num_threads_ ; ++ t ) { if ( ! subgame_running_ [ t ] && active_subgames_ [ t ] ) { CFRPSubgame * subgame = active_subgames_ [ t ] ; if ( subgame == nullptr ) { fprintf ( stderr , " \n " ) ; exit ( -1 ) ; } pthread_join ( pthread_ids_ [ t ] , NULL ) ; Node * root = subgame -> Root ( ) ; int p = root -> PlayerActing ( ) ; int nt = root -> NonterminalID ( ) ; int root_bd = subgame -> RootBd ( ) ; final_vals_ [ p ] [ nt ] [ root_bd ] = subgame -> FinalVals ( ) ; delete subgame ; active_subgames_ [ t ] = nullptr ; -- num_remaining ; -- g_num_active ; break ; } } } if ( g_num_active > 0 ) { fprintf ( stderr , " \n " , g_num_active ) ; exit ( -1 ) ; } }
This breaks if we get Post() before call to WaitForFinalSubgames(), but
not corresponding join.
This breaks if we get Post () before call to WaitForFinalSubgames () but not corresponding join .
// This was buggy // if (subgame_running_[t]) ++num_remaining; // It's possible for sem_wait() to return even though there is no thread // ready to be joined.