bool timed_lock(::boost::system_time const& wait_until) { if(!win32::interlocked_bit_test_and_set(&active_count,lock_flag_bit)) { return true; } long old_count=active_count; for(;;) { long const new_count=(old_count&lock_flag_value)?(old_count+1):(old_count|lock_flag_value); long const current=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&active_count,new_count,old_count); if(current==old_count) { break; } old_count=current; } if(old_count&lock_flag_value) { bool lock_acquired=false; void* const sem=get_event(); do { if(win32::WaitForSingleObject(sem,::boost::detail::get_milliseconds_until(wait_until))!=0) { BOOST_INTERLOCKED_DECREMENT(&active_count); return false; } old_count&=~lock_flag_value; old_count|=event_set_flag_value; for(;;) { long const new_count=((old_count&lock_flag_value)?old_count:((old_count-1)|lock_flag_value))&~event_set_flag_value; long const current=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&active_count,new_count,old_count); if(current==old_count) { break; } old_count=current; } lock_acquired=!(old_count&lock_flag_value); } while(!lock_acquired); } return true; }
T interlocked_compare_exchange(T* target,T new_value,T comparand) { BOOST_STATIC_ASSERT(sizeof(T)==sizeof(long)); long const res=BOOST_INTERLOCKED_COMPARE_EXCHANGE(reinterpret_cast<long*>(target), *reinterpret_cast<long*>(&new_value), *reinterpret_cast<long*>(&comparand)); return *reinterpret_cast<T const*>(&res); }
bool platform_cmpxchg32_strong(T & expected, T desired, volatile T * ptr) { T prev = expected; expected = (T)BOOST_INTERLOCKED_COMPARE_EXCHANGE((long *)(ptr), (long)desired, (long)expected); bool success = (prev==expected); return success; }
bool add_ref_lock() // true on success { for( ;; ) { long tmp = static_cast< long const volatile& >( use_count_ ); if( tmp == 0 ) return false; if( BOOST_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp + 1, tmp ) == tmp ) return true; } }
bool compare_exchange_strong( T &expected, T desired, memory_order success_order, memory_order failure_order) volatile { T prev=expected; expected=(T)BOOST_INTERLOCKED_COMPARE_EXCHANGE((long *)(&i), (long)desired, (long)expected); bool success=(prev==expected); return success; }
bool add_ref_lock() // true on success { for( ;; ) { long tmp = static_cast< long const volatile& >( use_count_ ); if( tmp == 0 ) return false; #if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1200 ) // work around a code generation bug long tmp2 = tmp + 1; if( BOOST_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp2, tmp ) == tmp2 - 1 ) return true; #else if( BOOST_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp + 1, tmp ) == tmp ) return true; #endif } }
//! Sets the object to a signalled state BOOST_LOG_API void winapi_based_event::set_signalled() { if (BOOST_INTERLOCKED_COMPARE_EXCHANGE(reinterpret_cast< long* >(&m_state), 1, 0) == 0) { if (SetEvent(m_event) == 0) { const DWORD err = GetLastError(); const_cast< volatile boost::uint32_t& >(m_state) = 0; BOOST_THROW_EXCEPTION(system::system_error( err, system::system_category(), "Failed to wake the blocked thread")); } } }
//! Atomically loads and stores the 64-bit value BOOST_FORCEINLINE void move64(const uint64_t* from, uint64_t* to) { while (BOOST_INTERLOCKED_COMPARE_EXCHANGE(&g_spin_lock, 1, 0) != 0); *to = *from; BOOST_INTERLOCKED_EXCHANGE(&g_spin_lock, 0); }
static inline long interlocked_compare_exchange(long volatile *addr, long val1, long val2) { return BOOST_INTERLOCKED_COMPARE_EXCHANGE(addr, val1, val2); }
void lock() { while(BOOST_INTERLOCKED_COMPARE_EXCHANGE(&locked, 1, 0) == 1); }
inline long interlocked_read_acquire(long volatile* x) { return BOOST_INTERLOCKED_COMPARE_EXCHANGE(x,0,0); }