uintptr_t vlc_atomic_add (vlc_atomic_t *atom, uintptr_t v) { return __sync_add_and_fetch (&atom->u, v); }
void NANOS_atomic ( int op, int type, void * variable, void * operand ) { if ( ( type == 0 ) && ( op == 1 || op == 2 || op == 5 || op == 6 || op == 7) ) { // variable has integer type and the operation is some kind of the following compound assignments: // plus, minus, and, ior, xor printf("info: 'atomic' construct implemented using atomic builtins.\n"); int tmp = *((int *) operand); switch (op) { case 1: __sync_add_and_fetch((int *) variable, tmp); break; case 2: __sync_sub_and_fetch((int *) variable, tmp); break; case 5: __sync_and_and_fetch((int *) variable, tmp); break; case 6: __sync_or_and_fetch((int *) variable, tmp); break; case 7: __sync_xor_and_fetch((int *) variable, tmp); break; }; } else if ( ( type == 0 ) && ( op == 10 || op == 11) ) { // variable has integer type and the operation is a pre-/post- incr-/decr- ement printf("info: 'atomic' construct implemented using atomic builtins.\n"); if (op == 10) __sync_add_and_fetch((int *) variable, 1); else __sync_sub_and_fetch((int *) variable, 1); } else { // any other case printf("info: 'atomic' construct implemented using compare and exchange.\n"); if (type == 1) { // Float type // float tmp = *((float *) operand); printf("Nanos support for Atomic access to floats is not yet implemented\n"); abort(); } else if (type == 2) { // Double type double tmp = *((double *) operand); double oldval, newval; unsigned int sizeof_var = sizeof(variable); do { oldval = *((double *) variable); switch (op) { case 1: newval = oldval + tmp; break; case 2: newval = oldval - tmp; break; case 3: newval = oldval * tmp; break; case 4: newval = oldval / tmp; break; case 10: newval = oldval + 1; break; case 11: newval = oldval - 1; break; default: printf("Unhandled operation type while generating Nanos code for OpenMP atomic contruct."); abort(); } __sync_synchronize(); } while ( (sizeof_var == 4) ? !__sync_bool_compare_and_swap_4((double *) variable, *(unsigned int *) &oldval, *(unsigned int *) &newval) : (sizeof_var == 8) ? !__sync_bool_compare_and_swap_8((double *) variable, *(unsigned long *) &oldval, *(unsigned long *) &newval) : 0 ); } else { printf("Unhandled variable type while generating Nanos code for OpenMP atomic contruct."); abort( ); } } }
inline void intrusive_ptr_add_ref(data_buffer_t *buffer) { DEBUG_VAR int64_t res = __sync_add_and_fetch(&buffer->ref_count_, 1); rassert(res > 0); }
static mc_fbtrace_t* mc_fbtrace_incref(mc_fbtrace_t* fbt) { FBI_ASSERT(fbt); int newrefcount = __sync_add_and_fetch(&fbt->_refcount, 1); FBI_ASSERT(newrefcount > 0); return fbt; }
/* * call-seq: * rd.incr(index[, number]) -> result * * Increments the value referred to by the +index+ by +number+. * +number+ defaults to +1+ if unspecified. */ static VALUE incr(int argc, VALUE *argv, VALUE self) { unsigned long nr = incr_decr_arg(argc, argv); return ULONG2NUM(__sync_add_and_fetch(addr_of(self, argv[0]), nr)); }
int do_set_parent( dict *d, location *loc, void *key, void *val, set_spec *spec, rstat *stat ) { node *new_node = do_set_create( d, loc->epoch, key, val, CREATE_NODE, spec ); if ( new_node == NULL ) { *stat = rstat_mem; return 0; //do not try again } while ( 1 ) { node * volatile *branch = NULL; uint8_t error = 0; int dir = d->methods.cmp( loc->set->settings.meta, key, loc->parent->key->value, &error); if (error) { *stat = error( 1, 0, error + 100, "Application error in compare method" ); return 0; } switch( dir ) { case -1: branch = &(loc->parent->left); break; case 1: branch = &(loc->parent->right); break; case 0: dispose( d, (trash *)new_node ); *stat = error( 1, 0, DICT_UNKNOWN, "This should not be possible unless a nodes key has changed, which is not permitted." ); return 0; break; default: dispose( d, (trash *)new_node ); *stat = error( 1, 0, DICT_API_MISUSE, "The Compare method must return 1, 0, or -1" ); return 0; break; } // Insert the new node! if ( __sync_bool_compare_and_swap( branch, NULL, new_node )) { size_t count = __sync_add_and_fetch( &(loc->slot->item_count), 1 ); __sync_add_and_fetch( &(d->item_count), 1 ); loc->node = new_node; loc->usref = loc->node->usref; loc->sref = loc->usref->sref; if ( blocked_null( loc->sref )) loc->sref = NULL; loc->xtrn = loc->sref ? loc->sref->xtrn : NULL; loc->height++; *stat = balance_check( d, loc, count ); return 0; } // Prepare to try again... *stat = locate_key( d, key, &loc ); if ( stat->num ) { dispose( d, (trash *)new_node ); return 0; } // Matching node has been inserted :-( all that work for nothing, // retry... if ( loc->node ) { dispose( d, (trash *)new_node ); return 1; } } }
// =============================================== Back propagation. void threaded_run_bp(ThreadInfo *info, float black_moku, Stone next_player, int end_ply, BOOL board_on_child, BlockOffset child_offset, TreeBlock *b) { TreeHandle *s = info->s; TreePool *p = &s->p; // Dynkomi is adjusted if the win rate is too high. float komi = s->common_params->komi + s->common_variants->dynkomi; float black_count_playout = sigmoid(black_moku - komi); float black_count; // If there is network that predicts moku, then we should combine the results. if (b->has_score && s->params.use_cnn_final_score && end_ply >= s->params.min_ply_to_use_cnn_final_score) { // Final score = final_mixture_ratio * win_rate_prediction + (1.0 - final_mixture_ratio) * playout_result. float cnn_final_playout = sigmoid(b->score - komi); black_count = s->params.final_mixture_ratio * cnn_final_playout + (1 - s->params.final_mixture_ratio) * black_count_playout; } else { black_count = black_count_playout; } // Rave moves encoded in the board. int rave_moves[BOUND_COORD]; if (s->params.use_rave) memset(rave_moves, 0, sizeof(rave_moves)); TreeBlock *curr; BlockOffset curr_offset; if (board_on_child) { curr = b; curr_offset = child_offset; } else { curr = b->parent; curr_offset = b->parent_offset; } // Backprop from b. while (curr != NULL) { Stat* stat = &curr->data.stats[curr_offset]; // Add total first, otherwise the winning rate might go over 1. __sync_add_and_fetch(&stat->total, 1); inc_atomic_float(&stat->black_win, black_count); // stat->total += 1; // stat->black_win += black_count; // __sync_add_and_fetch(&stat->black_win, black_count); // Then update rave, if rave mode is open if (s->params.use_rave) { // Update rave moves. rave_moves[curr->data.moves[curr_offset]] = 1; // Loop over existing moves. for (int i = 0; i < curr->n; ++i) { Coord m = curr->data.moves[i]; if (rave_moves[m]) { Stat *rave_stat = &curr->data.rave_stats[i]; __sync_add_and_fetch(&rave_stat->total, 1); inc_atomic_float(&rave_stat->black_win, black_count); // __sync_add_and_fetch(&rave_stat->black_win, black_count); } } } curr_offset = curr->parent_offset; curr = curr->parent; } if (s->params.use_online_model) { // Update the online model. Stone player = (board_on_child ? OPPONENT(next_player) : next_player); update_online_model(info, player, b); } }