Пример #1
0
uintptr_t vlc_atomic_add (vlc_atomic_t *atom, uintptr_t v)
{
    return __sync_add_and_fetch (&atom->u, v);
}
Пример #2
0
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( );
    }
  }
}
Пример #3
0
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);
}
Пример #4
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;
}
Пример #5
0
/*
 * 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));
}
Пример #6
0
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);
  }
}