/* * We visit terms breadth-first to check for cycles. * The index of all visited terms are stored in subst->cache. * The terms to process are stored in subst->queue. */ static void bfs_visit_index(intern_tbl_t *tbl, int32_t i) { if (kind_for_idx(tbl->terms, i) == UNINTERPRETED_TERM) { // replace i by its root i = index_of(intern_tbl_get_root(tbl, pos_term(i))); } if (int_hset_add(tbl->cache, i)) { // i has not been seen before int_queue_push(tbl->queue, i); } }
/* * Check whether t is in the cache. * If not, add t to the cache and to the end of the queue */ static void flattener_push_term(flattener_t *flat, term_t t) { if (int_hset_add(&flat->cache, t)) { int_queue_push(&flat->queue, t); } }
int main(int argc, char **argv) { // check args if(argc != 3) { fprintf(stderr, "Usage : ./bidding_system [host_num : 1~12] [player_num : 4~20]\n"); exit(-1); } // parse host & player number. int host_num, player_num; parse_args(argv, &host_num, &player_num); // open pipes and fork hosts host_t hosts[host_num]; for(int idx = 0; idx < host_num; ++idx) { hosts[idx].id = idx + 1; pipe(hosts[idx].rpipe); pipe(hosts[idx].wpipe); fork_host(hosts, idx); } // Use I/O multiplex to handle response fd_set mread_set, read_set; FD_ZERO(&mread_set); // Init queue and fd_set for idle host int_queue idle_queue; int_queue_init(&idle_queue, host_num + 1); for(int idx = 0; idx < host_num; ++idx) { int_queue_push(&idle_queue, idx); FD_SET(hosts[idx].rpipe[READ_END], &mread_set); } // init players inf. player_t players[player_num]; for(int i = 0; i < player_num; ++i) { players[i].id = i + 1; players[i].score = 0; } // generate combinations. comb_gen gen; comb_gen_init(&gen, player_num, 4); int *comb = NULL; int done = 0; for(;;) { if(!done && idle_queue.size != 0) { // if all combinations are generated if((done = (comb = comb_gen_next(&gen)) == NULL)) continue; // Extract idle host from queue. int idle_idx; int_queue_extract(&idle_queue, &idle_idx); // Write to host sprintf(buf, "%d %d %d %d\n", comb[0], comb[1], comb[2], comb[3]); write(hosts[idle_idx].wpipe[WRITE_END], buf, strlen(buf)); continue; } // if all combinations are generated and all hosts are done. if(done && idle_queue.size == host_num) break; // Check if any host is done, handle the response and push the host back into the idle queue. memcpy(&read_set, &mread_set, sizeof(fd_set)); int ready = select(3 + host_num * 2, &read_set, NULL, NULL, &(struct timeval) {0, 800}); if(ready <= 0) continue; for(int idx = 0; idx < host_num; ++idx) { if(!FD_ISSET(hosts[idx].rpipe[READ_END], &read_set)) continue; read(hosts[idx].rpipe[READ_END], buf, sizeof(buf)); handle_response(players, buf); int_queue_push(&idle_queue, idx); } }
/* * Add t to queue and cache if it's not already in the cache */ static void push_term(int_queue_t *queue, int_hset_t *cache, term_t t) { if (int_hset_add(cache, t)) { int_queue_push(queue, t); } }