--- 1.49beta\boost\smart_ptr\detail\spinlock_gcc_arm.hpp 2012-02-24 10:15:47.059733900 -0600 +++ 1.50maybe\boost\smart_ptr\detail\spinlock_gcc_arm.hpp 2012-02-24 10:53:14.384732200 -0600 @@ -41,16 +41,48 @@ bool try_lock() { +#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) + int lockValue; + int lockCurrent; + int lockFailed; + + __asm__ __volatile__( + "mov %0, #1\n\t" // pre-load our lock token value (the number 1) + "mov %2, #1\n\t" // pre-load lockFailed with 1 (assumes failure) + "ldrex %1, [%4]\n\t" // exclusive load of v_ into lockCurrent + "cmp %1, #0\n\t" // if lockCurrent is zero... + "strexeq %2, %0, [%4]\n\t" // attempt to claim the lock, if successful, lockFailed will be 0 + "dmb\n\t" // hardware memory barrier to ensure that prior loads and stores by + // clients get processed now, instead of at the processor's leisure + // === outputs === + :"=&r"( lockValue ), // %0: "=&r" means we have a write only variable + // that can be modified before we have finished tweaking inputs, + // and that this value should be stored in a register + "=&r"( lockCurrent ), // %1 + "=&r"( lockFailed ), // %2 + "+Qo"( v_ ) // %3: "+Qo" means we have an offsettable reference that is both read and modified + // === inputs === + :"r"( &v_ ) // %4 + :"cc", "memory"); // clobber list, changed condition codes, and invalidating all compiler + // loads and stores for a compiler memory barrier + + return lockFailed == 0; +#else int r; __asm__ __volatile__( - "swp %0, %1, [%2]\n\t" - BOOST_SP_ARM_BARRIER : - "=&r"( r ): // outputs - "r"( 1 ), "r"( &v_ ): // inputs - "memory", "cc" ); + "swp %0, %1, [%2]\n\t" // copy this->v_ to r as Int32 AND copy 1 into this->v_ as Int32 + BOOST_SP_ARM_BARRIER : + // === outputs === + "=&r"( r ): // %0: value of v; "=&r" means we have a write only variable + // inputs + "r"( 1 ), // %1: 1 as Int32; "r" means we have a read only variable + "r"( &v_ ): // %2: address of member this->v_; "r" means we have a read only variable + "memory", "cc" ); // clobber list, changed condition codes, and invalidating all compiler + // loads and stores for a compiler memory barrier return r == 0; +#endif } void lock() @@ -63,7 +95,7 @@ void unlock() { - __asm__ __volatile__( BOOST_SP_ARM_BARRIER ::: "memory" ); + __asm__ __volatile__( BOOST_SP_ARM_BARRIER ::: "memory" ); // force cached values to un-cache *const_cast< int volatile* >( &v_ ) = 0; }