summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '3rdParty/Boost/src/libs/atomic/doc/platform.qbk')
-rw-r--r--3rdParty/Boost/src/libs/atomic/doc/platform.qbk312
1 files changed, 312 insertions, 0 deletions
diff --git a/3rdParty/Boost/src/libs/atomic/doc/platform.qbk b/3rdParty/Boost/src/libs/atomic/doc/platform.qbk
new file mode 100644
index 0000000..6b9a9ec
--- /dev/null
+++ b/3rdParty/Boost/src/libs/atomic/doc/platform.qbk
@@ -0,0 +1,312 @@
+[/
+ / Copyright (c) 2009 Helge Bahmann
+ /
+ / Distributed under the Boost Software License, Version 1.0. (See accompanying
+ / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ /]
+
+[section:template_organization Organization of class template layers]
+
+The implementation uses multiple layers of template classes that
+inherit from the next lower level each and refine or adapt the respective
+underlying class:
+
+* [^boost::atomic<T>] is the topmost-level, providing
+ the external interface. Implementation-wise, it does not add anything
+ (except for hiding copy constructor and assignment operator).
+
+* [^boost::detail::atomic::internal_atomic&<T,S=sizeof(T),I=is_integral_type<T> >]:
+ This layer is mainly responsible for providing the overloaded operators
+ mapping to API member functions (e.g. [^+=] to [^fetch_add]).
+ The defaulted template parameter [^I] allows
+ to expose the correct API functions (via partial template
+ specialization): For non-integral types, it only
+ publishes the various [^exchange] functions
+ as well as load and store, for integral types it
+ additionally exports arithmetic and logic operations.
+ [br]
+ Depending on whether the given type is integral, it
+ inherits from either [^boost::detail::atomic::platform_atomic<T,S=sizeof(T)>]
+ or [^boost::detail::atomic::platform_atomic_integral<T,S=sizeof(T)>].
+ There is however some special-casing: for non-integral types
+ of size 1, 2, 4 or 8, it will coerce the datatype into an integer representation
+ and delegate to [^boost::detail::atomic::platform_atomic_integral<T,S=sizeof(T)>]
+ -- the rationale is that platform implementors only need to provide
+ integer-type operations.
+
+* [^boost::detail::atomic::platform_atomic_integral<T,S=sizeof(T)>]
+ must provide the full set of operations for an integral type T
+ (i.e. [^load], [^store], [^exchange],
+ [^compare_exchange_weak], [^compare_exchange_strong],
+ [^fetch_add], [^fetch_sub], [^fetch_and],
+ [^fetch_or], [^fetch_xor], [^is_lock_free]).
+ The default implementation uses locking to emulate atomic operations, so
+ this is the level at which implementors should provide template specializations
+ to add support for platform-specific atomic operations.
+ [br]
+ The two separate template parameters allow separate specialization
+ on size and type (which, with fixed size, cannot
+ specify more than signedness/unsignedness). The rationale is that
+ most platform-specific atomic operations usually depend only on the
+ operand size, so that common implementations for signed/unsigned
+ types are possible. Signedness allows to properly to choose sign-extending
+ instructions for the [^load] operation, avoiding later
+ conversion. The expectation is that in most implementations this will
+ be a normal assignment in C, possibly accompanied by memory
+ fences, so that the compiler can automatically choose the correct
+ instruction.
+
+* At the lowest level, [^boost::detail::atomic::platform_atomic<T,S=sizeof(T)>]
+ provides the most basic atomic operations ([^load], [^store],
+ [^exchange], [^compare_exchange_weak],
+ [^compare_exchange_strong]) for arbitrarily generic data types.
+ The default implementation uses locking as a fallback mechanism.
+ Implementors generally do not have to specialize at this level
+ (since these will not be used for the common integral type sizes
+ of 1, 2, 4 and 8 bytes), but if s/he can if s/he so wishes to
+ provide truly atomic operations for "odd" data type sizes.
+ Some amount of care must be taken as the "raw" data type
+ passed in from the user through [^boost::atomic<T>]
+ is visible here -- it thus needs to be type-punned or otherwise
+ manipulated byte-by-byte to avoid using overloaded assignment,
+ comparison operators and copy constructors.
+
+[endsect]
+
+
+[section:platform_atomic_implementation Implementing platform-specific atomic operations]
+
+In principle implementors are responsible for providing the
+full range of named member functions of an atomic object
+(i.e. [^load], [^store], [^exchange],
+[^compare_exchange_weak], [^compare_exchange_strong],
+[^fetch_add], [^fetch_sub], [^fetch_and],
+[^fetch_or], [^fetch_xor], [^is_lock_free]).
+These must be implemented as partial template specializations for
+[^boost::detail::atomic::platform_atomic_integral<T,S=sizeof(T)>]:
+
+[c++]
+
+ template<typename T>
+ class platform_atomic_integral<T, 4>
+ {
+ public:
+ explicit platform_atomic_integral(T v) : i(v) {}
+ platform_atomic_integral(void) {}
+
+ T load(memory_order order=memory_order_seq_cst) const volatile
+ {
+ // platform-specific code
+ }
+ void store(T v, memory_order order=memory_order_seq_cst) volatile
+ {
+ // platform-specific code
+ }
+
+ private:
+ volatile T i;
+ };
+
+As noted above, it will usually suffice to specialize on the second
+template argument, indicating the size of the data type in bytes.
+
+[section:automatic_buildup Templates for automatic build-up]
+
+Often only a portion of the required operations can be
+usefully mapped to machine instructions. Several helper template
+classes are provided that can automatically synthesize missing methods to
+complete an implementation.
+
+At the minimum, an implementor must provide the
+[^load], [^store],
+[^compare_exchange_weak] and
+[^is_lock_free] methods:
+
+[c++]
+
+ template<typename T>
+ class my_atomic_32 {
+ public:
+ my_atomic_32() {}
+ my_atomic_32(T initial_value) : value(initial_value) {}
+
+ T load(memory_order order=memory_order_seq_cst) volatile const
+ {
+ // platform-specific code
+ }
+ void store(T new_value, memory_order order=memory_order_seq_cst) volatile
+ {
+ // platform-specific code
+ }
+ bool compare_exchange_weak(T &expected, T desired,
+ memory_order success_order,
+ memory_order_failure_order) volatile
+ {
+ // platform-specific code
+ }
+ bool is_lock_free() const volatile {return true;}
+ protected:
+ // typedef is required for classes inheriting from this
+ typedef T integral_type;
+ private:
+ T value;
+ };
+
+The template [^boost::detail::atomic::build_atomic_from_minimal]
+can then take care of the rest:
+
+[c++]
+
+ template<typename T>
+ class platform_atomic_integral<T, 4>
+ : public boost::detail::atomic::build_atomic_from_minimal<my_atomic_32<T> >
+ {
+ public:
+ typedef build_atomic_from_minimal<my_atomic_32<T> > super;
+
+ explicit platform_atomic_integral(T v) : super(v) {}
+ platform_atomic_integral(void) {}
+ };
+
+There are several helper classes to assist in building "complete"
+atomic implementations from different starting points:
+
+* [^build_atomic_from_minimal] requires
+ * [^load]
+ * [^store]
+ * [^compare_exchange_weak] (4-operand version)
+
+* [^build_atomic_from_exchange] requires
+ * [^load]
+ * [^store]
+ * [^compare_exchange_weak] (4-operand version)
+ * [^compare_exchange_strong] (4-operand version)
+ * [^exchange]
+
+* [^build_atomic_from_add] requires
+ * [^load]
+ * [^store]
+ * [^compare_exchange_weak] (4-operand version)
+ * [^compare_exchange_strong] (4-operand version)
+ * [^exchange]
+ * [^fetch_add]
+
+* [^build_atomic_from_typical] (<I>supported on gcc only</I>) requires
+ * [^load]
+ * [^store]
+ * [^compare_exchange_weak] (4-operand version)
+ * [^compare_exchange_strong] (4-operand version)
+ * [^exchange]
+ * [^fetch_add_var] (protected method)
+ * [^fetch_inc] (protected method)
+ * [^fetch_dec] (protected method)
+
+ This will generate a [^fetch_add] method
+ that calls [^fetch_inc]/[^fetch_dec]
+ when the given parameter is a compile-time constant
+ equal to +1 or -1 respectively, and [^fetch_add_var]
+ in all other cases. This provides a mechanism for
+ optimizing the extremely common case of an atomic
+ variable being used as a counter.
+
+ The prototypes for these methods to be implemented is:
+ [c++]
+
+ template<typename T>
+ class my_atomic {
+ public:
+ T fetch_inc(memory_order order) volatile;
+ T fetch_dec(memory_order order) volatile;
+ T fetch_add_var(T counter, memory_order order) volatile;
+ };
+
+These helper templates are defined in [^boost/atomic/detail/builder.hpp].
+
+[endsect]
+
+[section:automatic_buildup_small Build sub-word-sized atomic data types]
+
+There is one other helper template that can build sub-word-sized
+atomic data types even though the underlying architecture allows
+only word-sized atomic operations:
+
+[c++]
+
+ template<typename T>
+ class platform_atomic_integral<T, 1> :
+ public build_atomic_from_larger_type<my_atomic_32<uint32_t>, T>
+ {
+ public:
+ typedef build_atomic_from_larger_type<my_atomic_32<uint32_t>, T> super;
+
+ explicit platform_atomic_integral(T v) : super(v) {}
+ platform_atomic_integral(void) {}
+ };
+
+The above would create an atomic data type of 1 byte size, and
+use masking and shifts to map it to 32-bit atomic operations.
+The base type must implement [^load], [^store]
+and [^compare_exchange_weak] for this to work.
+
+[endsect]
+
+[section:other_sizes Atomic data types for unusual object sizes]
+
+In unusual circumstances, an implementor may also opt to specialize
+[^public boost::detail::atomic::platform_atomic<T,S=sizeof(T)>]
+to provide support for atomic objects not fitting an integral size.
+If you do that, keep the following things in mind:
+
+* There is no reason to ever do this for object sizes
+ of 1, 2, 4 and 8
+* Only the following methods need to be implemented:
+ * [^load]
+ * [^store]
+ * [^compare_exchange_weak] (4-operand version)
+ * [^compare_exchange_strong] (4-operand version)
+ * [^exchange]
+
+The type of the data to be stored in the atomic
+variable (template parameter [^T])
+is exposed to this class, and the type may have
+overloaded assignment and comparison operators --
+using these overloaded operators however will result
+in an error. The implementor is responsible for
+accessing the objects in a way that does not
+invoke either of these operators (using e.g.
+[^memcpy] or type-casts).
+
+[endsect]
+
+[endsect]
+
+[section:platform_atomic_fences Fences]
+
+Platform implementors need to provide a function performing
+the action required for [funcref boost::atomic_thread_fence atomic_thread_fence]
+(the fallback implementation will just perform an atomic operation
+on an integer object). This is achieved by specializing the
+[^boost::detail::atomic::platform_atomic_thread_fence] template
+function in the following way:
+
+[c++]
+
+ template<>
+ void platform_atomic_thread_fence(memory_order order)
+ {
+ // platform-specific code here
+ }
+
+[endsect]
+
+[section:platform_atomic_puttogether Putting it altogether]
+
+The template specializations should be put into a header file
+in the [^boost/atomic/detail] directory, preferably
+specifying supported compiler and architecture in its name.
+
+The file [^boost/atomic/detail/platform.hpp] must
+subsequently be modified to conditionally include the new
+header.
+
+[endsect]