示例#1
0
bool
SIZE(libat_compare_exchange) (UTYPE *mptr, UTYPE *eptr, UTYPE newval,
			      int smodel, int fmodel UNUSED)
{
  if (maybe_specialcase_relaxed(smodel))
    return atomic_compare_exchange_n (mptr, eptr, newval, false,
				      __ATOMIC_RELAXED, __ATOMIC_RELAXED);
  else if (maybe_specialcase_acqrel(smodel))
    return atomic_compare_exchange_n (mptr, eptr, newval, false,
				      __ATOMIC_ACQ_REL, __ATOMIC_RELAXED);
  else
    return atomic_compare_exchange_n (mptr, eptr, newval, false,
				      __ATOMIC_SEQ_CST, __ATOMIC_RELAXED);
}
示例#2
0
static int atomic_hash_table_update_one_file(english_word *word){
  uint64_t hashv=fnv_hash(word->str,word->len);
  uint64_t index=hashv%global_hash_table_size;
  //this next line results in a lot of cache misses
  //for obvious reasons
  if(!global_hash_table[index]){//word isn't in the hash table, add it
    uint8_t *mem=xmalloc(word->len);
    word->str=(char*)my_strcpy(mem,(uint8_t*)word->str,word->len);
    void *prev=global_hash_table[index];
    int test=atomic_compare_exchange_n(global_hash_table+index,&prev,word);
    if(test){
      //we added the word
      //this needs to be atomic to prevent two threads writing different
      //values to the same index of indices
      uint64_t old_indices_index=atomic_fetch_add(&indices_index,1);
      //this doesn't need to be atomic, since indices_index will never be
      //decremented, so no one else will change this
      hash_table_indices[old_indices_index]=index;
      goto end1;
    }
    //else, someone else changed the value of global_hash_table[index] before us
  }
  while(1){
    do {
      //see if the value in the table is the same as our value
      //if so update the value already in the table
      if(string_compare(global_hash_table[index],word)){
        //atomically increment word count
        atomic_add(&global_hash_table[index]->count,1);
        goto end0;
      }
    } while(global_hash_table[++index]);
    //not in the table use next free index (if we can)
    void *prev=global_hash_table[index];
    int test=atomic_compare_exchange_n(global_hash_table+index,&prev,word);
    if(test){
      uint64_t old_indices_index=atomic_fetch_add(&indices_index,1);
      hash_table_indices[old_indices_index]=index;
      goto end1;
    }
    //if !test the compare exchange failed and we need to keep looping
  }
 end0:
  return 0;
 end1:
  return 1;
}
示例#3
0
文件: load_n.c 项目: ChaosJohn/gcc
UTYPE
SIZE(libat_load) (UTYPE *mptr, int smodel)
{
  UTYPE t = 0;

  if (maybe_specialcase_relaxed(smodel))
    atomic_compare_exchange_n (mptr, &t, 0, true,
			       __ATOMIC_RELAXED, __ATOMIC_RELAXED);
  else if (maybe_specialcase_acqrel(smodel))
    atomic_compare_exchange_n (mptr, &t, 0, true,
			       __ATOMIC_ACQ_REL, __ATOMIC_ACQ_REL);
  else
    atomic_compare_exchange_n (mptr, &t, 0, true,
                               __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);

  return t;
}
示例#4
0
void
SIZE(libat_store) (UTYPE *mptr, UTYPE newval, int smodel)
{
    UTYPE oldval;

    pre_barrier (smodel);

    oldval = *mptr;
    while (!atomic_compare_exchange_n (mptr, &oldval, newval, true,
                                       __ATOMIC_RELAXED, __ATOMIC_RELAXED))
        continue;

    post_barrier (smodel);
}
示例#5
0
文件: fop_n.c 项目: kostyll/gccpy
UTYPE
SIZE(C3(libat_,NAME,_fetch)) (UTYPE *mptr, UTYPE opval, int smodel)
{
    UTYPE oldval, t;

    pre_barrier (smodel);

    oldval = *mptr;
    do
    {
        t = OP(oldval, opval);
    }
    while (!atomic_compare_exchange_n (mptr, &oldval, t, true,
                                       __ATOMIC_RELAXED, __ATOMIC_RELAXED));

    post_barrier (smodel);
    return t;
}