org.qbicc.graph.atomic.AccessModes Maven / Gradle / Ivy
package org.qbicc.graph.atomic;
/**
* The set of allowed access modes for various operations.
*
*
Access Mode Categories
*
* Access modes each fall into zero or more of the following categories:
*
* - Global access modes which implement {@link GlobalAccessMode} or one of its subtypes and may be applied to fence operations
* - Read access modes, which implement {@link ReadAccessMode} or one of its subtypes and may be applied to read operations
* - Write access modes, which implement {@link WriteAccessMode} or one of its subtypes and may be applied to write operations
*
* For any given access mode, it is possible to acquire the equivalent-or-stronger {@linkplain AccessMode#getGlobalAccess() global access mode},
* the equivalent-or-stronger {@linkplain AccessMode#getReadAccess() read access mode}, and the equivalent-or-stronger
* {@linkplain AccessMode#getWriteAccess() write access mode}. The return type of these methods preserve the categorization of the original access mode,
* so for example, given a read access mode, the corresponding global access mode will also be a valid read access mode.
* Access modes which do not fall into any of the three basic categories may still be used to derive other usable access modes.
*
* Access modes which are not global (i.e. do not implement the {@link GlobalAccessMode} interface) are considered "single".
* These modes are only guaranteed to affect a single location in memory (some CPUs may strengthen this guarantee to
* apply to some local memory area or domain).
*
*
Global Access Modes
*
* The set of global access modes is based on definitions given {@linkplain java.lang.invoke.VarHandle in the JDK specification}
* as well as in the JLS, with additional
* references to background material such as Using JDK 9 Memory Order Modes
* by Doug Lea and Java Memory Model Pragmatics by Aleksey Shipilëv.
*
* Most of the possible global access modes are compositions of these four fundamental modes:
*
* - {@link #GlobalLoadLoad}
* - {@link #GlobalStoreLoad}
* - {@link #GlobalLoadStore}
* - {@link #GlobalStoreStore}
*
* These modes are only usable in fence operations, but since they are included in all other global access modes, they can
* be strengthened to read or write operations using the {@link AccessMode#getReadAccess()} and {@link AccessMode#getWriteAccess()}
* methods.
*
* The following table illustrates which of the fundamental global access modes are included in which composed global
* access modes:
*
* Derived Access Mode Fundamental Access Mode
* {@link #GlobalStoreStore} {@link #GlobalLoadStore} {@link #GlobalLoadLoad} {@link #GlobalStoreLoad}
* {@link #GlobalAcquire} ● ●
* {@link #GlobalRelease} ● ●
* {@link #GlobalAcqRel} ● ● ●
* {@link #GlobalSeqCst} ● ● ● ●
*
*
* Consequently, each fundamental barrier type can be strengthened to any of the modes which include that type.
*
* The remaining global access modes — {@link #GlobalUnshared} and {@link #GlobalPlain} — are exactly equivalent to the
* correspondingly-named single access modes, and exist to prevent useless fences from being emitted when the corresponding
* single access mode is strengthened to a global access mode.
*
*
Single Access Modes
*
* Single access modes only affect the memory directly associated with the operation that utilizes that mode, rather than
* applying to all program memory operations as global access modes do. As such, they are not composed of fundamental barrier
* types like the global modes are, since those types are predicated on global ordering.
*
* Instead, the single access types generally compose sequentially with only one exception. The following table illustrates
* how each mode generally includes the next-weaker mode:
*
*
* Access Mode Included Access Modes
* {@link #SingleUnshared} {@link #SinglePlain} {@link #SingleOpaque} {@link #SingleAcquire} {@link #SingleRelease} {@link #SingleAcqRel} {@link #SingleSeqCst}
* {@link #SingleUnshared} ●
* {@link #SinglePlain} ● ●
* {@link #SingleOpaque} ● ● ●
* {@link #SingleAcquire} ● ● ● ●
* {@link #SingleRelease} ● ● ● ●
* {@link #SingleAcqRel} ● ● ● ● ● ●
* {@link #SingleSeqCst} ● ● ● ● ● ● ●
*
*
* Apart from {@link #SingleAcquire} and {@link #SingleRelease} — which do not include one another — every mode includes
* all of the preceding modes.
*
* Additionally, every single-access mode can be strengthened into a corresponding global access mode which includes at
* least the behavior of the single-access mode when applied to the same memory operation.
*
*
* Single Access Mode Global Access mode
* {@link #SingleUnshared} {@link #GlobalUnshared}
* {@link #SinglePlain} {@link #GlobalPlain}
* {@link #SingleOpaque} {@link #GlobalSeqCst}
* {@link #SingleAcquire} {@link #GlobalAcquire}
* {@link #SingleRelease} {@link #GlobalRelease}
* {@link #SingleAcqRel} {@link #GlobalAcqRel}
* {@link #SingleSeqCst} {@link #GlobalSeqCst}
*
*
*/
public final class AccessModes {
private AccessModes() {}
/**
* The global unshared access mode. This mode is exactly equivalent to {@link #SingleUnshared}, and
* does nothing when used as a fence argument.
*/
public static final GlobalReadWriteAccessMode GlobalUnshared = FullFences.GlobalUnshared;
/**
* The global plain access mode. This mode is exactly equivalent to {@link #SinglePlain}, and
* does nothing when used as a fence argument.
*/
public static final GlobalReadWriteAccessMode GlobalPlain = FullFences.GlobalPlain;
/**
* The load-load global access mode. When used as a fence, this mode
* prevents any loads which precede the fence from being moved after the fence, and
* prevents global loads which succeed the fence from being moved before the fence, as follows:
*
* {@code AnyLoad ≺ GlobalLoadLoad ≺ AnyGlobalLoad}
*/
public static final GlobalAccessMode GlobalLoadLoad = PureFences.GlobalLoadLoad;
/**
* The store-load global access mode. When used as a fence, this mode
* prevents global stores which precede the fence from being moved after the fence, and
* prevents global loads which succeed the fence from being moved before the fence, as follows:
*
* {@code AnyGlobalStore ≺ GlobalStoreLoad < AnyGlobalLoad}
*/
public static final GlobalAccessMode GlobalStoreLoad = PureFences.GlobalStoreLoad;
/**
* The load-store global access mode. When used as a fence, this mode
* prevents any loads which precede the fence from being moved after the fence, and
* prevents global stores which succeed the fence from being moved before the fence, as follows:
*
* {@code AnyLoad ≺ GlobalLoadStore < AnyGlobalStore}
*/
public static final GlobalAccessMode GlobalLoadStore = PureFences.GlobalLoadStore;
/**
* The store-store global access mode. When used as a fence, this mode
* prevents any stores which precede the fence from being moved after the fence, and
* prevents any global stores which succeed the fence from being moved before the fence, as follows:
*
* {@code AnyStore ≺ GlobalStoreStore < AnyGlobalStore}
*/
public static final GlobalAccessMode GlobalStoreStore = PureFences.GlobalStoreStore;
/**
* The acquire global access mode. This mode includes {@link #GlobalLoadLoad} and {@link #GlobalLoadStore} and
* may be used with read and fence operations.
*/
public static final GlobalReadAccessMode GlobalAcquire = ReadFences.GlobalAcquire;
/**
* The release global access mode. This mode includes {@link #GlobalStoreStore} and {@link #GlobalLoadStore} and
* may be used with write and fence operations.
*/
public static final GlobalWriteAccessMode GlobalRelease = WriteFences.GlobalRelease;
/**
* The acquire-release global access mode. This mode includes both {@link #GlobalAcquire} and {@link #GlobalRelease}
* and may be used only with fence operations.
*/
public static final GlobalAccessMode GlobalAcqRel = PureFences.GlobalAcqRel;
/**
* The sequentially-consistent global access mode, also known as {@code volatile}.
* This mode includes both {@link #GlobalAcqRel} and {@link #GlobalStoreLoad}
* and may be used with read, write, and fence operations.
*/
public static final GlobalReadWriteAccessMode GlobalSeqCst = FullFences.GlobalSeqCst;
/**
* The unshared single access mode. This is a non-atomic mode which provides no guarantees against
* tearing or invalid values when not protected with an appropriate synchronization structure.
* This mode may be used for read and write operations.
*/
public static final ReadWriteAccessMode SingleUnshared = ReadWriteModes.SingleUnshared;
/**
* The plain single access mode, also known as unordered. This is a mode which only guarantees
* that the value will not be invalid in the presence of data races.
* This mode may be used for read and write operations.
*/
public static final ReadWriteAccessMode SinglePlain = ReadWriteModes.SinglePlain;
/**
* The opaque single access mode, also known as relaxed or monotonic.
* This is a mode has all of the guarantees of {@link #SinglePlain} but also enforces a single total order
* for all operations on a given memory address.
* This mode may be used for read and write operations.
*/
public static final ReadWriteAccessMode SingleOpaque = ReadWriteModes.SingleOpaque;
/**
* The acquire single access mode.
* This is a mode has all of the guarantees of {@link #SingleOpaque} but also synchronizes-with
* any release operation on the same memory address.
* This mode may only be used for read operations.
*/
public static final ReadAccessMode SingleAcquire = ReadModes.SingleAcquire;
/**
* The release single access mode.
* This is a mode has all of the guarantees of {@link #SingleOpaque} but also synchronizes-with
* any acquire operation on the same memory address.
* This mode may only be used for write operations.
*/
public static final WriteAccessMode SingleRelease = WriteModes.SingleRelease;
/**
* The acquire-release single access mode.
* This mode combines {@link #SingleAcquire} with {@link #SingleRelease}. It is not usable by itself
* but is useful for compatibility with the previous scheme.
*/
public static final AccessMode SingleAcqRel = PureModes.SingleAcqRel;
/**
* The sequentially-consistent single access mode.
* This is a mode has all of the guarantees of {@link #SingleAcquire} and {@link #SingleRelease}
* but also guarantees a global total order on all of the memory affected by this operation.
* This mode may be used for read and write operations.
*/
public static final ReadWriteAccessMode SingleSeqCst = ReadWriteModes.SingleSeqCst;
}