void testShort1() { short l[2]; short cmp, repl; short *ptr = &(l[1]); int replaced; l[0] = 32; l[1] = 42; cmp = 42; repl = 3; replaced = __sync_val_compare_and_swap(ptr, cmp, repl); printf("%d\n", replaced); printf("%d\n", l[0]); printf("%d\n", l[1]); l[0] = 32; l[1] = 42; cmp = 1; repl = 3; replaced = __sync_val_compare_and_swap(ptr, cmp, repl); printf("%d\n", replaced); printf("%d\n", l[0]); printf("%d\n", l[1]); }
void* thread_func() { int i = 0; long long prev = 0; long long sum = 0; for (i = 0; i < num_iterations; i++) { switch (opt_sync) { case 'c': do { prev = counter; sum = prev + 1; if (opt_yield) { pthread_yield(); } } while (__sync_val_compare_and_swap(&counter, prev, sum) != prev); break; case 'm': pthread_mutex_lock(&add_mutex); add(&counter, 1); pthread_mutex_unlock(&add_mutex); break; case 's': while (__sync_lock_test_and_set(&add_spin, 1)); add(&counter, 1); __sync_lock_release(&add_spin); break; default: add(&counter, 1); break; } } for (i = 0; i < num_iterations; i++) { switch (opt_sync) { case 'c': do { prev = counter; sum = prev - 1; if (opt_yield) { pthread_yield(); } } while (__sync_val_compare_and_swap(&counter, prev, sum) != prev); break; case 'm': pthread_mutex_lock(&add_mutex); add(&counter, -1); pthread_mutex_unlock(&add_mutex); break; case 's': while (__sync_lock_test_and_set(&add_spin, 1)); add(&counter, -1); __sync_lock_release(&add_spin); break; default: add(&counter, -1); break; } } return NULL; }
void testByte1() { char l[4]; l[0] = 12; l[1] = 22; l[2] = 32; l[3] = 42; char cmp, repl; char *ptr = &(l[1]); int replaced; cmp = 22; repl = 3; replaced = __sync_val_compare_and_swap(ptr, cmp, repl); printf("%d\n", replaced); printf("%d\n", l[0]); printf("%d\n", l[1]); printf("%d\n", l[2]); printf("%d\n", l[3]); l[0] = 12; l[1] = 22; l[2] = 32; l[3] = 42; cmp = 1; repl = 3; replaced = __sync_val_compare_and_swap(ptr, cmp, repl); printf("%d\n", replaced); printf("%d\n", l[0]); printf("%d\n", l[1]); printf("%d\n", l[2]); printf("%d\n", l[3]); }
int sem_post(sem_t *sem) { while (1) { int64_t value = sem->__value; if (value == -1) { // set to 1, and wake up any waiters if successful if (__sync_val_compare_and_swap(&sem->__value, value, 1UL) == value) { if (__syscall(__SYS_unblock, &sem->__value) != 0) { errno = EINVAL; return -1; }; return 0; }; } else { if (__sync_val_compare_and_swap(&sem->__value, value, value+1) == value) { return 0; }; }; }; };
void write_hash_primejump_openmp_report_level_3(uint ic, ulong hashkey, int *hash){ int icount = 0; uint jump = 1+hashkey%hash_jump_prime; uint hashloc = (hashkey*AA+BB)%prime%hashtablesize; printf("%d: cell %d hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,ic,hashloc,hash[2*hashloc],hashkey,hashkey%hash_stride,hashkey/hash_stride); int MaxTries = 1000; int old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey); //printf("old_key is %d\n",old_key); for (icount = 1; old_key != hashkey && old_key != -1 && icount < MaxTries; icount++){ hashloc+=(icount*jump); hashloc %= hashtablesize; printf("%d: cell %d hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,ic,hashloc,hash[2*hashloc],hashkey,hashkey%hash_stride,hashkey/hash_stride); old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey); } if (icount < MaxTries) hash[2*hashloc+1] = ic; #pragma omp atomic write_hash_collisions += icount;; #pragma omp atomic hash_ncells++; }
int rain_ctx_run(struct rain_ctx *ctx) { struct rain_ctx_message msg; int ret = rain_message_queue_pop(ctx->msgQue,&msg); if(ret == 0){ if(msg.type & RAIN_MSG_REQ){ if(ctx->recv){ struct rainMsg tmpmsg; tmpmsg.data = msg.u_data.msg; tmpmsg.sz = msg.u_sz.sz; tmpmsg.type = msg.type & 0x0000ffff; ctx->recv(ctx->arg,msg.src,tmpmsg,msg.session); }else{ RAIN_LOG(0,"Rid:%d,no register recv",ctx->rid); free(msg.u_data.msg); } }else if(msg.type & RAIN_MSG_RSP){ if(ctx->recv_rsp){ struct rainMsg tmpmsg; tmpmsg.data = msg.u_data.msg; tmpmsg.sz = msg.u_sz.sz; tmpmsg.type = msg.type & 0x0000ffff; ctx->recv_rsp(ctx->arg,msg.src,tmpmsg,msg.session); }else{ RAIN_LOG(0,"Rid:%d,no register recv_responce",ctx->rid); free(msg.u_data.msg); } }else if(msg.type & RAIN_MSG_TIMER){ if(ctx->timeoutfn){ ctx->timeoutfn(ctx->arg,msg.u_data.time_data); }else{ RAIN_LOG(0,"Rid:%d,no register timeout",ctx->rid); } }else if(msg.type & RAIN_MSG_NEXTTICK){ if(ctx->nexttickfn){ ctx->nexttickfn(ctx->arg,msg.u_data.tick_data); }else{ RAIN_LOG(0,"Rid:%d,no register nexttick",ctx->rid); } }else if(msg.type & RAIN_MSG_EXIT){ if(ctx->link){ ctx->link(ctx->arg,msg.src,msg.u_sz.exitcode); }else{ RAIN_LOG(0,"Rid:%d,no register link",ctx->rid); } }else{ RAIN_LOG(0,"Rid:%d,Unkonw Message TYPE%x",ctx->rid,msg.type); } if(rain_message_queue_size(ctx->msgQue) == 0){ __sync_val_compare_and_swap(&ctx->bdis,1,0); return RAIN_ERROR; } }else{ __sync_val_compare_and_swap(&ctx->bdis,1,0); } return ret; }
static void Complete(alder_thread_casn_rdcss_t *d) { uint64_t v = *(d->a1); uint64_t d64 = (uint64_t)d | ALDER_THREAD_CASN_DESCRIPTOR_DCSS; if (v == d->o1) { __sync_val_compare_and_swap(d->a2, d64, d->n2); } else { __sync_val_compare_and_swap(d->a2, d64, d->o2); } }
static void futex_lock(futex* m) { futex c; if ((c = __sync_val_compare_and_swap(m, 0, 1)) != 0) { do { if ((c == 2) || __sync_val_compare_and_swap(m, 1, 2) != 0) syscall(SYS_futex, m, FUTEX_WAIT_PRIVATE, 2, NULL, NULL, 0); } while((c = __sync_val_compare_and_swap(m, 0, 2)) != 0); } }
void spring_futex::lock() { native_type c; if ((c = __sync_val_compare_and_swap(&mtx, 0, 1)) == 0) return; do { if ((c == 2) || __sync_val_compare_and_swap(&mtx, 1, 2) != 0) syscall(SYS_futex, &mtx, FUTEX_WAIT_PRIVATE, 2, NULL, NULL, 0); } while((c = __sync_val_compare_and_swap(&mtx, 0, 2)) != 0); }
int main() { // Small constants use immediate field printf("0x%08x\n", __sync_fetch_and_add(&foo, 1)); // CHECK: 0x5a5a5a5a printf("0x%08x\n", __sync_add_and_fetch(&foo, 1)); // CHECK: 0x5a5a5a5c printf("0x%08x\n", __sync_add_and_fetch(&foo, 1)); // CHECK: 0x5a5a5a5d printf("0x%08x\n", __sync_fetch_and_add(&foo, 1)); // CHECK: 0x5a5a5a5d // Large constants require a separate load. printf("0x%08x\n", __sync_add_and_fetch(&foo, 0x10000000)); // CHECK: 0x6a5a5a5e printf("0x%08x\n", __sync_sub_and_fetch(&foo, 0x20000000)); // CHECK: 0x4a5a5a5e printf("0x%08x\n", __sync_and_and_fetch(&foo, 0xf0ffffff)); // CHECK: 0x405a5a5e printf("0x%08x\n", __sync_or_and_fetch(&foo, 0x0f000000)); // CHECK: 0x4f5a5a5e printf("0x%08x\n", __sync_xor_and_fetch(&foo, 0x05000000)); // CHECK: 0x4a5a5a5e // Small constants. These will generate immediate instructions. Test for all forms. printf("0x%08x\n", __sync_sub_and_fetch(&foo, 1)); // CHECK: 0x4a5a5a5d printf("0x%08x\n", __sync_and_and_fetch(&foo, 1)); // CHECK: 0x00000001 printf("0x%08x\n", __sync_or_and_fetch(&foo, 2)); // CHECK: 0x00000003 printf("0x%08x\n", __sync_xor_and_fetch(&foo, 0xffffffff)); // CHECK: 0xfffffffc printf("0x%08x\n", __sync_nand_and_fetch(&foo, 0x5fffffff)); // CHECK: 0xa0000003 // Compare and swap foo = 2; // successful printf("0x%08x\n", __sync_val_compare_and_swap(&foo, 2, 3)); // CHECK: 0x00000002 printf("0x%08x\n", foo); // CHECK: 0x00000003 // not successful printf("0x%08x\n", __sync_val_compare_and_swap(&foo, 2, 4)); // CHECK: 0x00000003 printf("0x%08x\n", foo); // CHECK: 0x00000003 // not successful printf("0x%08x\n", __sync_bool_compare_and_swap(&foo, 2, 10)); // CHECK: 0x00000000 printf("0x%08x\n", foo); // CHECK: 0x00000003 // successful printf("0x%08x\n", __sync_bool_compare_and_swap(&foo, 3, 10)); // CHECK: 0x00000001 printf("0x%08x\n", foo); // CHECK: 0x0000000a // Unlock foo = 1; __sync_lock_release(&foo); printf("foo = %d\n", foo); // CHECK: foo = 0 // Swap foo = 0x12; printf("old value 0x%08x\n", __atomic_exchange_n(&foo, 0x17, __ATOMIC_RELEASE)); // CHECK: 0x00000012 printf("new value 0x%08x\n", foo); // CHECK: new value 0x00000017 return 0; }
inline T atomic_fetch_add( volatile T * const dest , typename Kokkos::Impl::enable_if< sizeof(T) != sizeof(int) && sizeof(T) == sizeof(long) , const T >::type val ) { #ifdef KOKKOS_HAVE_CXX11 union U { long i ; T t ; inline U() {}; } assume , oldval , newval ; #else union U { long i ; T t ; } assume , oldval , newval ; #endif oldval.t = *dest ; do { assume.i = oldval.i ; newval.t = assume.t + val ; oldval.i = __sync_val_compare_and_swap( (long*) dest , assume.i , newval.i ); } while ( assume.i != oldval.i ); return oldval.t ; }
static uint ringarray_number_cas(volatile int * key, uint _old, uint _new){ #ifdef EMC_WINDOWS return InterlockedCompareExchange((long*)key, _new, _old); #else return __sync_val_compare_and_swap(key, _old, _new); #endif }
extern "C" uint8_t Java_org_j3_mmtk_ObjectModel_attemptAvailableBits__Lorg_vmmagic_unboxed_ObjectReference_2Lorg_vmmagic_unboxed_Word_2Lorg_vmmagic_unboxed_Word_2( MMTkObject* OM, gc* obj, word_t oldValue, word_t newValue) { llvm_gcroot(obj, 0); word_t val = __sync_val_compare_and_swap(&(obj->header()), oldValue, newValue); return (val == oldValue); }
inline void atomic_assign( volatile T * const dest , typename Kokkos::Impl::enable_if< sizeof(T) == sizeof(int) || sizeof(T) == sizeof(long) , const T & >::type val ) { typedef typename Kokkos::Impl::if_c< sizeof(T) == sizeof(int) , int , long >::type type ; #if defined( KOKKOS_ENABLE_RFO_PREFETCH ) _mm_prefetch( (const char*) dest, _MM_HINT_ET0 ); #endif const type v = *((type*)&val); // Extract to be sure the value doesn't change type assumed ; union U { T val_T ; type val_type ; inline U() {}; } old ; old.val_T = *dest ; do { assumed = old.val_type ; old.val_type = __sync_val_compare_and_swap( (volatile type *) dest , assumed , v ); } while ( assumed != old.val_type ); }
static void fbt_memprotect_rescan() { /* * Loop over loaded shared objects to see if some additional ones * were loaded. If that is the case, add the new ones to the library list * and their sections to the tree. */ int i = 0; while (__sync_val_compare_and_swap(&rescan_lock, 0, 1)) { /* spin while waiting to acquire mutex */ i++; if (0 == (i % 10000)) { llprintf("waiting to acquire rescan lock: spinned %d times\n", i); } } int objcount = 0; dl_iterate_phdr(&fbt_memprotect_callback, (void*) &objcount); for (i = 0; i < lib_list_size; i++) { PRINT_DEBUG("%s from %p to %p\n", library_list[i].name, library_list[i].base_addr, library_list[i].base_addr + library_list[i].length); } // release mutex rescan_lock = 0; }
inline void atomic_assign( volatile T * const dest , typename Kokkos::Impl::enable_if< sizeof(T) == sizeof(int) || sizeof(T) == sizeof(long) , const T & >::type val ) { typedef typename Kokkos::Impl::if_c< sizeof(T) == sizeof(int) , int , long >::type type ; const type v = *((type*)&val); // Extract to be sure the value doesn't change type assumed ; #ifdef KOKKOS_HAVE_CXX11 union U { T val_T ; type val_type ; inline U() {}; } old ; #else union { T val_T ; type val_type ; } old ; #endif old.val_T = *dest ; do { assumed = old.val_type ; old.val_type = __sync_val_compare_and_swap( (volatile type *) dest , assumed , v ); } while ( assumed != old.val_type ); }
sLONG VInterlocked::CompareExchange( sLONG* inValue, sLONG inCompareValue, sLONG inNewValue) { #if VERSIONWIN sLONG val = ::InterlockedCompareExchange( inValue, inNewValue, inCompareValue); #elif VERSIONMAC sLONG val; do { if (::OSAtomicCompareAndSwap32Barrier((int32_t)inCompareValue, (int32_t) inNewValue, reinterpret_cast<int32_t*>(inValue))) { return inCompareValue; } // one must loop if a swap occured between reading the old val and a failed CAS // because if we return inCompareValue, the caller may assume that the CAS has succeeded. val = *inValue; } while(val == inCompareValue); #elif VERSION_LINUX sLONG val=__sync_val_compare_and_swap(inValue, inCompareValue, inNewValue); #endif return val; }
void wfl_insert(struct wfl *list, void *data) { struct wfl_entry *p = list->head; // list head is never null while (1) { if (p->data == NULL) { if (__sync_bool_compare_and_swap(&p->data, NULL, data)) return; } if (p->next == NULL) break; p = p->next; } struct wfl_entry *new_entry = malloc(sizeof(struct wfl_entry)); if (new_entry == NULL) abort(); new_entry->data = data; new_entry->next = NULL; wmb(); struct wfl_entry *next; while ((next = __sync_val_compare_and_swap(&p->next, NULL, new_entry))) p = next; }
bool cwlock_lock(cwlock_t *l) { uint32_t oldv; uint32_t newv; newv = ACCESS_ONCE(l->value); do { oldv = newv; if (!(oldv & CWLOCK_LOCKED)) { newv |= CWLOCK_LOCKED; } else if (!(oldv & CWLOCK_WAITER)) { newv |= CWLOCK_WAITER; } else { break; } /* Try to acquire the lock or flag that there's a waiter. */ newv = __sync_val_compare_and_swap(&l->value, oldv, newv); } while (oldv != newv); /* If the old value doesn't have the lock bit, we acquired the lock. */ if (!(oldv & CWLOCK_LOCKED)) { return true; } /* We didn't acquire the lock, so wait for it to be released. */ oldv |= CWLOCK_LOCKED | CWLOCK_WAITER; do { syscall(SYS_futex, &l->value, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, oldv, NULL, NULL, 0); newv = ACCESS_ONCE(l->value); } while (newv == oldv); return false; }
void mutex_t::lock() { int oval = __sync_val_compare_and_swap(&val, 0, 1); if(!oval) { } else { assert(oval == 1 || oval == 2); thr::tstate_t *tstate = thr::tstate; thr::state_t old_state; if(tstate) old_state = tstate->set(thr::locked); while(__sync_lock_test_and_set(&val, 2) != 0) futex_wait(&val, 2); if(tstate) tstate->set(old_state); } tid = thr::id; }
void *acl_atomic_cas(ACL_ATOMIC *self, void *cmp, void *value) { #ifndef HAS_ATOMIC void *old; acl_pthread_mutex_lock(&self->lock); old = self->value; if (self->value == cmp) self->value = value; acl_pthread_mutex_unlock(&self->lock); return old; #elif defined(ACL_WINDOWS) return InterlockedCompareExchangePointer( (volatile PVOID*)&self->value, value, cmp); #elif defined(ACL_LINUX) # if defined(__GNUC__) && (__GNUC__ >= 4) return __sync_val_compare_and_swap(&self->value, cmp, value); # else (void) self; (void) cmp; (void) value; acl_msg_error("%s(%d), %s: not support!", __FILE__, __LINE__, __FUNCTION__); return NULL; # endif #endif }
/** * @brief Try for cross lock (callable from fth thread ONLY). * * @param cross <IN> cross lock structure pointer * @param write <IN> Nonzero for write lock, zero for read lock */ int fthXTryLock(XLock_t *cross, int write) { // Wait for the fth lock to be free if (__sync_val_compare_and_swap(&cross->fthLock, 0, 1) != 0) { return (1); } // Now aquire the queing lock (should be free except for race) while (pthread_rwlock_trywrlock(&cross->qLock) != 0) { // Another fthread might be waiting for the lock - avoid race fthYield(0); // Avoid race between 2 fthreads } // Release the FTH lock now that we have the Q lock (void) __sync_fetch_and_sub(&cross->fthLock, 1); // Now we have the pthread queueing lock so everyone will wait behind us if (write) { if (pthread_rwlock_trywrlock(&cross->lock) != 0) { // Try to get it pthread_rwlock_unlock(&cross->qLock); // We failed - clean up return (2); // Try failed } } else { if (pthread_rwlock_tryrdlock(&cross->lock) != 0) { // Try to get it pthread_rwlock_unlock(&cross->qLock); // We failed - clean up return (2); // Try failed } } // Release the Q lock now that we have the full lock pthread_rwlock_unlock(&cross->qLock); return (0); }
void logCheckAndInit(){ int rc; rc = __sync_val_compare_and_swap(&logMainInfo.isStarted, LOG_STOPPED, LOG_STOPPED); if ( rc == LOG_STOPPED ){ rc = logInit( LOG_INFO , LOG_PRINT_LEVEL_DESCRIPTION | LOG_PRINT_FILE | LOG_PRINT_LINE , NULL); } }
/*++ Function: AllocateExceptionRecords Allocate EXCEPTION_RECORD and CONTEXT structures for an exception. Parameters: exceptionRecord - output pointer to the allocated exception record contextRecord - output pointer to the allocated context record --*/ VOID AllocateExceptionRecords(EXCEPTION_RECORD** exceptionRecord, CONTEXT** contextRecord) { ExceptionRecords* records; if (posix_memalign((void**)&records, alignof(ExceptionRecords), sizeof(ExceptionRecords)) != 0) { size_t bitmap; size_t newBitmap; int index; do { bitmap = s_allocatedContextsBitmap; index = __builtin_ffsl(~bitmap) - 1; if (index < 0) { PROCAbort(); } newBitmap = bitmap | ((size_t)1 << index); } while (__sync_val_compare_and_swap(&s_allocatedContextsBitmap, bitmap, newBitmap) != bitmap); records = &s_fallbackContexts[index]; } *contextRecord = &records->ContextRecord; *exceptionRecord = &records->ExceptionRecord; }
static inline void aquire(struct liblock_impl* impl) { while(__sync_val_compare_and_swap(&impl->lock, 0, 1)) { __monitor(&impl->lock, 0, 0); if(!impl->lock) __mwait(&impl->lock, 0); } }
inline T atomic_exchange( volatile T * const dest , typename Kokkos::Impl::enable_if< sizeof(T) == sizeof(int) || sizeof(T) == sizeof(long) , const T & >::type val ) { typedef typename Kokkos::Impl::if_c< sizeof(T) == sizeof(int) , int , long >::type type ; const type v = *((type*)&val); // Extract to be sure the value doesn't change type assumed ; union U { T val_T ; type val_type ; inline U() {}; } old ; old.val_T = *dest ; do { assumed = old.val_type ; old.val_type = __sync_val_compare_and_swap( (volatile type *) dest , assumed , v ); } while ( assumed != old.val_type ); return old.val_T ; }
inline sp_int32_t atomic_conditional_increment( sp_int32_t * pw ) { // long r = *pw; // if( r != 0 ) ++*pw; // return r; sp_int32_t r = *pw; for( ;; ) { if( r == 0 ) { return r; } sp_int32_t r2 = __sync_val_compare_and_swap( pw, r, r + 1 ); if( r2 == r ) { return r; } else { r = r2; } } }
gaspi_return_t pgaspi_notify_reset (const gaspi_segment_id_t segment_id_local, const gaspi_notification_id_t notification_id, gaspi_notification_t * const old_notification_val) { gaspi_verify_init("gaspi_notify_reset"); gaspi_verify_segment(segment_id_local); gaspi_verify_null_ptr(glb_gaspi_ctx.rrmd[segment_id_local]); #ifdef DEBUG if(old_notification_val == NULL) { gaspi_print_warning("NULL pointer on parameter old_notification_val (gaspi_notify_reset)."); } #endif volatile unsigned char *segPtr; #ifdef GPI2_CUDA if(glb_gaspi_ctx.rrmd[segment_id_local][glb_gaspi_ctx.rank].cudaDevId >= 0) segPtr = (volatile unsigned char*)glb_gaspi_ctx.rrmd[segment_id_local][glb_gaspi_ctx.rank].host_addr; else #endif segPtr = (volatile unsigned char *) glb_gaspi_ctx.rrmd[segment_id_local][glb_gaspi_ctx.rank].addr; volatile unsigned int *p = (volatile unsigned int *) segPtr; const unsigned int res = __sync_val_compare_and_swap (&p[notification_id], p[notification_id], 0); if(old_notification_val != NULL) *old_notification_val = res; return GASPI_SUCCESS; }
/* Perform 1 million atomic increments of the counter pointed to by * |data|, and checks the final result. Uses the increment strategy * specified by the |intrinsic| global. */ static void* WorkerThread(void *data) { volatile AtomicInt32* counter = (volatile AtomicInt32*) data; int ii; /* NB, gets stuck on ARM QEMU. */ while (!workers_begin) ; for (ii = 0; ii < 1000000; ++ii) { switch (intrinsic) { case COMPARE_AND_SWAP: /* NB, not atomic on ARM QEMU. */ for (;;) { AtomicInt32 prev = *counter; if (__sync_val_compare_and_swap(counter, prev, prev + 1) == prev) break; } break; case FETCH_AND_ADD: __sync_fetch_and_add(counter, 1); break; default: abort(); } } return NULL; }
void* process0(void* tid) { int i = (int) tid; int _cnt; int _sens; int _rel; int count1; int count2; count1 = 0; count2 = 0; _cnt=0; _sens=0; _rel=0; while(1) { if (count1++ >= COUNT1) break; _sens=sens; _cnt=cnt; //arw(cnt,_cnt,_cnt-1) __sync_val_compare_and_swap(&cnt,_cnt,_cnt-1); if(_cnt==1){ cnt=2; sens=!_sens; } else{ do{ if (count2++ >= COUNT2) break; _rel=sens; }while(_rel == _sens); } } return 0; }