xref: /netbsd-src/external/gpl3/gcc/dist/libphobos/libdruntime/core/volatile.d (revision 0a3071956a3a9fdebdbf7f338cf2d439b45fc728)
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