Download Reference Manual
The Developer's Library for D
About Wiki Forums Source Search Contact

Ticket #1212: tango-atomic.patch

File tango-atomic.patch, 5.5 kB (added by ChristianK, 3 years ago)
  • tango/core/Atomic.d

    old new  
    270270 
    271271 
    272272//////////////////////////////////////////////////////////////////////////////// 
     273// LDC Atomics Implementation 
     274//////////////////////////////////////////////////////////////////////////////// 
     275 
     276 
     277else version( LDC ) 
     278{ 
     279    import ldc.intrinsics; 
     280 
     281 
     282    //////////////////////////////////////////////////////////////////////////// 
     283    // Atomic Load 
     284    //////////////////////////////////////////////////////////////////////////// 
     285 
     286 
     287    template atomicLoad( msync ms = msync.seq, T ) 
     288    { 
     289        T atomicLoad(ref T val) 
     290        { 
     291            llvm_memory_barrier( 
     292                ms == msync.hlb || ms == msync.acq || ms == msync.seq, 
     293                ms == msync.hsb || ms == msync.acq || ms == msync.seq, 
     294                ms == msync.slb || ms == msync.rel || ms == msync.seq, 
     295                ms == msync.ssb || ms == msync.rel || ms == msync.seq, 
     296                false); 
     297            static if (isPointerType!(T)) 
     298            { 
     299                return cast(T)llvm_atomic_load_add!(size_t)(cast(size_t*)&val, 0); 
     300            } 
     301            else static if (is(T == bool)) 
     302            { 
     303                return llvm_atomic_load_add!(ubyte)(cast(ubyte*)&val, cast(ubyte)0) ? 1 : 0; 
     304            } 
     305            else 
     306            { 
     307                return llvm_atomic_load_add!(T)(&val, cast(T)0); 
     308            } 
     309        } 
     310    } 
     311 
     312 
     313    //////////////////////////////////////////////////////////////////////////// 
     314    // Atomic Store 
     315    //////////////////////////////////////////////////////////////////////////// 
     316 
     317 
     318    template atomicStore( msync ms = msync.seq, T ) 
     319    { 
     320        void atomicStore( ref T val, T newval ) 
     321        { 
     322            llvm_memory_barrier( 
     323                ms == msync.hlb || ms == msync.acq || ms == msync.seq, 
     324                ms == msync.hsb || ms == msync.acq || ms == msync.seq, 
     325                ms == msync.slb || ms == msync.rel || ms == msync.seq, 
     326                ms == msync.ssb || ms == msync.rel || ms == msync.seq, 
     327                false); 
     328            static if (isPointerType!(T)) 
     329            { 
     330                llvm_atomic_swap!(size_t)(cast(size_t*)&val, cast(size_t)newval); 
     331            } 
     332            else static if (is(T == bool)) 
     333            { 
     334                llvm_atomic_swap!(ubyte)(cast(ubyte*)&val, newval?1:0); 
     335            } 
     336            else 
     337            { 
     338                llvm_atomic_swap!(T)(&val, newval); 
     339            } 
     340        } 
     341    } 
     342 
     343 
     344    //////////////////////////////////////////////////////////////////////////// 
     345    // Atomic Store If 
     346    //////////////////////////////////////////////////////////////////////////// 
     347 
     348 
     349    template atomicStoreIf( msync ms = msync.seq, T ) 
     350    { 
     351        bool atomicStoreIf( ref T val, T newval, T equalTo ) 
     352        { 
     353            llvm_memory_barrier( 
     354                ms == msync.hlb || ms == msync.acq || ms == msync.seq, 
     355                ms == msync.hsb || ms == msync.acq || ms == msync.seq, 
     356                ms == msync.slb || ms == msync.rel || ms == msync.seq, 
     357                ms == msync.ssb || ms == msync.rel || ms == msync.seq, 
     358                false); 
     359            T oldval = void; 
     360            static if (isPointerType!(T)) 
     361            { 
     362                oldval = cast(T)llvm_atomic_cmp_swap!(size_t)(cast(size_t*)&val, cast(size_t)equalTo, cast(size_t)newval); 
     363            } 
     364            else static if (is(T == bool)) 
     365            { 
     366                oldval = llvm_atomic_cmp_swap!(ubyte)(cast(ubyte*)&val, equalTo?1:0, newval?1:0)?0:1; 
     367            } 
     368            else 
     369            { 
     370                oldval = llvm_atomic_cmp_swap!(T)(&val, equalTo, newval); 
     371            } 
     372            return oldval == equalTo; 
     373        } 
     374    } 
     375     
     376     
     377    //////////////////////////////////////////////////////////////////////////// 
     378    // Atomic Increment 
     379    //////////////////////////////////////////////////////////////////////////// 
     380 
     381 
     382    template atomicIncrement( msync ms = msync.seq, T ) 
     383    { 
     384        // 
     385        // NOTE: This operation is only valid for integer or pointer types 
     386        // 
     387        static assert( isValidNumericType!(T) ); 
     388 
     389 
     390        T atomicIncrement( ref T val ) 
     391        { 
     392            static if (isPointerType!(T)) 
     393            { 
     394                llvm_atomic_load_add!(size_t)(cast(size_t*)&val, 1); 
     395            } 
     396            else 
     397            { 
     398                llvm_atomic_load_add!(T)(&val, cast(T)1); 
     399            } 
     400            return val; 
     401        } 
     402    } 
     403     
     404     
     405    //////////////////////////////////////////////////////////////////////////// 
     406    // Atomic Decrement 
     407    //////////////////////////////////////////////////////////////////////////// 
     408 
     409 
     410    template atomicDecrement( msync ms = msync.seq, T ) 
     411    { 
     412        // 
     413        // NOTE: This operation is only valid for integer or pointer types 
     414        // 
     415        static assert( isValidNumericType!(T) ); 
     416 
     417 
     418        T atomicDecrement( ref T val ) 
     419        { 
     420            static if (isPointerType!(T)) 
     421            { 
     422                llvm_atomic_load_sub!(size_t)(cast(size_t*)&val, 1); 
     423            } 
     424            else 
     425            { 
     426                llvm_atomic_load_sub!(T)(&val, cast(T)1); 
     427            } 
     428            return val; 
     429        } 
     430    } 
     431} 
     432 
     433//////////////////////////////////////////////////////////////////////////////// 
    273434// x86 Atomic Function Implementation 
    274435//////////////////////////////////////////////////////////////////////////////// 
    275436