Home | History | Annotate | Line # | Download | only in core
      1 /**
      2  * This module declares intrinsics for volatile operations.
      3  *
      4  * Copyright: Copyright  2019, The D Language Foundation
      5  * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
      6  * Authors:   Walter Bright, Ernesto Castellotti
      7  * Source:    $(DRUNTIMESRC core/volatile.d)
      8  */
      9 
     10 module core.volatile;
     11 
     12 nothrow:
     13 @safe:
     14 @nogc:
     15 
     16 /*************************************
     17  * Read/write value from/to the memory location indicated by ptr.
     18  *
     19  * These functions are recognized by the compiler, and calls to them are guaranteed
     20  * to not be removed (as dead assignment elimination or presumed to have no effect)
     21  * or reordered in the same thread.
     22  *
     23  * These reordering guarantees are only made with regards to other
     24  * operations done through these functions; the compiler is free to reorder regular
     25  * loads/stores with regards to loads/stores done through these functions.
     26  *
     27  * This is useful when dealing with memory-mapped I/O (MMIO) where a store can
     28  * have an effect other than just writing a value, or where sequential loads
     29  * with no intervening stores can retrieve
     30  * different values from the same location due to external stores to the location.
     31  *
     32  * These functions will, when possible, do the load/store as a single operation. In
     33  * general, this is possible when the size of the operation is less than or equal to
     34  * $(D (void*).sizeof), although some targets may support larger operations. If the
     35  * load/store cannot be done as a single operation, multiple smaller operations will be used.
     36  *
     37  * These are not to be conflated with atomic operations. They do not guarantee any
     38  * atomicity. This may be provided by coincidence as a result of the instructions
     39  * used on the target, but this should not be relied on for portable programs.
     40  * Further, no memory fences are implied by these functions.
     41  * They should not be used for communication between threads.
     42  * They may be used to guarantee a write or read cycle occurs at a specified address.
     43  */
     44 
     45 ubyte  volatileLoad(ubyte * ptr);
     46 ushort volatileLoad(ushort* ptr);  /// ditto
     47 uint   volatileLoad(uint  * ptr);  /// ditto
     48 ulong  volatileLoad(ulong * ptr);  /// ditto
     49 
     50 void volatileStore(ubyte * ptr, ubyte  value);   /// ditto
     51 void volatileStore(ushort* ptr, ushort value);   /// ditto
     52 void volatileStore(uint  * ptr, uint   value);   /// ditto
     53 void volatileStore(ulong * ptr, ulong  value);   /// ditto
     54 
     55 @system unittest
     56 {
     57     alias TT(T...) = T;
     58 
     59     foreach (T; TT!(ubyte, ushort, uint, ulong))
     60     {
     61         T u;
     62         T* p = &u;
     63         volatileStore(p, 1);
     64         T r = volatileLoad(p);
     65         assert(r == u);
     66     }
     67 }
     68