static int fetch_hash_value(struct node *node) { ht_entry entry = ht_lookup_deep(node->tt, node->pos, node->depth, node->beta); if (ht_is_set(entry)) { if (move_order_add_hint(node->mo, ht_move(entry), 1) == 0) { node->deep_entry = entry; if (check_hash_value(node, entry) == hash_cutoff) return hash_cutoff; } } entry = ht_lookup_fresh(node->tt, node->pos); if (!ht_is_set(entry)) return 0; if (ht_has_move(node->deep_entry)) { if (move_order_add_weak_hint(node->mo, ht_move(entry)) != 0) return 0; } else { if (move_order_add_hint(node->mo, ht_move(entry), 1) != 0) return 0; } node->fresh_entry = entry; if (check_hash_value(node, entry) == hash_cutoff) { ht_pos_insert(node->tt, node->pos, entry); return hash_cutoff; } return 0; }
static void setup_best_move(struct node *node) { if (node->best_move == 0) { if (ht_has_move(node->deep_entry)) node->best_move = ht_move(node->deep_entry); else if (ht_has_move(node->fresh_entry)) node->best_move = ht_move(node->fresh_entry); } }
static int check_hash_value_lower_bound(struct node *node, ht_entry entry) { int hash_bound = ht_value(entry); if (hash_bound > 0 && node->has_repetition_in_history) hash_bound = 0; if (node->lower_bound < hash_bound) { node->lower_bound = hash_bound; if (node->lower_bound >= node->beta) { node->best_move = ht_move(entry); node->value = node->lower_bound; return hash_cutoff; } } return 0; }
void *test(void *data) { int val2, numtx, r, last = -1; val_t val = 0; int unext, mnext, cnext; thread_data_t *d = (thread_data_t *)data; /* Create transaction */ TM_THREAD_ENTER(); /* Wait on barrier */ barrier_cross(d->barrier); /* Is the first op an update, a move? */ r = rand_range_re(&d->seed, 100) - 1; unext = (r < d->update); mnext = (r < d->move); cnext = (r >= d->update + d->snapshot); #ifdef ICC while (stop == 0) { #else while (AO_load_full(&stop) == 0) { #endif /* ICC */ if (unext) { // update if (mnext) { // move if (last == -1) val = rand_range_re(&d->seed, d->range); val2 = rand_range_re(&d->seed, d->range); if (ht_move(d->set, val, val2, TRANSACTIONAL)) { d->nb_moved++; last = val2; } d->nb_move++; } else if (last < 0) { // add val = rand_range_re(&d->seed, d->range); if (ht_add(d->set, val, TRANSACTIONAL)) { d->nb_added++; last = val; } d->nb_add++; } else { // remove if (d->alternate) { // alternate mode if (ht_remove(d->set, last, TRANSACTIONAL)) { d->nb_removed++; last = -1; } } else { /* Random computation only in non-alternated cases */ val = rand_range_re(&d->seed, d->range); /* Remove one random value */ if (ht_remove(d->set, val, TRANSACTIONAL)) { d->nb_removed++; /* Repeat until successful, to avoid size variations */ last = -1; } } d->nb_remove++; } } else { // reads if (cnext) { // contains (no snapshot) if (d->alternate) { if (d->update == 0) { if (last < 0) { val = d->first; last = val; } else { // last >= 0 val = rand_range_re(&d->seed, d->range); last = -1; } } else { // update != 0 if (last < 0) { val = rand_range_re(&d->seed, d->range); //last = val; } else { val = last; } } } else val = rand_range_re(&d->seed, d->range); if (ht_contains(d->set, val, TRANSACTIONAL)) d->nb_found++; d->nb_contains++; } else { // snapshot if (ht_snapshot(d->set, TRANSACTIONAL)) d->nb_snapshoted++; d->nb_snapshot++; } } /* Is the next op an update, a move, a contains? */ if (d->effective) { // a failed remove/add is a read-only tx numtx = d->nb_contains + d->nb_add + d->nb_remove + d->nb_move + d->nb_snapshot; unext = ((100.0 * (d->nb_added + d->nb_removed + d->nb_moved)) < (d->update * numtx)); mnext = ((100.0 * d->nb_moved) < (d->move * numtx)); cnext = !((100.0 * d->nb_snapshoted) < (d->snapshot * numtx)); } else { // remove/add (even failed) is considered as an update r = rand_range_re(&d->seed, 100) - 1; unext = (r < d->update); mnext = (r < d->move); cnext = (r >= d->update + d->snapshot); } #ifdef ICC } #else } #endif /* ICC */ /* Free transaction */ TM_THREAD_EXIT(); return NULL; }
static int check_hash_value(struct node *node, ht_entry entry) { if (node->root_distance == 0) return 0; if (node[-1].forced_pv != 0 && node->alpha == -max_value && node->beta == max_value) return 0; if (node->depth > ht_depth(entry)) { if (ht_value_is_lower_bound(entry)) { if (ht_value(entry) >= mate_value) { if (!node->has_repetition_in_history) { node->value = ht_value(entry); node->best_move = ht_move(entry); return hash_cutoff; } else if (node->lower_bound < 0) { node->lower_bound = 0; if (0 >= node->beta) { node->value = node->beta; return hash_cutoff; } } } } if (ht_value_is_upper_bound(entry)) { if (ht_value(entry) <= -mate_value) { if (!node->has_repetition_in_history) { node->value = ht_value(entry); return hash_cutoff; } else if (node->upper_bound > 0) { node->upper_bound = 0; if (node->alpha >= 0) { node->value = node->alpha; return hash_cutoff; } } } } return 0; } if (ht_value_is_lower_bound(entry)) if (check_hash_value_lower_bound(node, entry) == hash_cutoff) return hash_cutoff; if (ht_value_is_upper_bound(entry)) if (check_hash_value_upper_bound(node, entry) == hash_cutoff) return hash_cutoff; if (node->lower_bound >= node->upper_bound) { node->value = node->lower_bound; return hash_cutoff; } return 0; }