README.txt 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. Usage:
  2. 0) If possible, do this on a multiprocessor, especially if you are planning
  3. on modifying or enhancing the package. It will work on a uniprocessor,
  4. but the tests are much more likely to pass in the presence of serious problems.
  5. 1) Type ./configure --prefix=<install dir>; make; make check
  6. in the directory containing unpacked source. The usual GNU build machinery
  7. is used, except that only static, but position-independent, libraries
  8. are normally built. On Windows, read README_win32.txt instead.
  9. 2) Applications should include atomic_ops.h. Nearly all operations
  10. are implemented by header files included from it. It is sometimes
  11. necessary, and always recommended to also link against libatomic_ops.a.
  12. To use the almost non-blocking stack or malloc implementations,
  13. see the corresponding README files, and also link against libatomic_gpl.a
  14. before linking against libatomic_ops.a.
  15. OVERVIEW:
  16. Atomic_ops.h defines a large collection of operations, each one of which is
  17. a combination of an (optional) atomic memory operation, and a memory barrier.
  18. Also defines associated feature-test macros to determine whether a particular
  19. operation is available on the current target hardware (either directly or
  20. by synthesis). This is an attempt to replace various existing files with
  21. similar goals, since they usually do not handle differences in memory
  22. barrier styles with sufficient generality.
  23. If this is included after defining AO_REQUIRE_CAS, then the package
  24. will make an attempt to emulate compare-and-swap in a way that (at least
  25. on Linux) should still be async-signal-safe. As a result, most other
  26. atomic operations will then be defined using the compare-and-swap
  27. emulation. This emulation is slow, since it needs to disable signals.
  28. And it needs to block in case of contention. If you care about performance
  29. on a platform that can't directly provide compare-and-swap, there are
  30. probably better alternatives. But this allows easy ports to some such
  31. platforms (e.g. PA_RISC). The option is ignored if compare-and-swap
  32. can be implemented directly.
  33. If atomic_ops.h is included after defining AO_USE_PTHREAD_DEFS, then all
  34. atomic operations will be emulated with pthread locking. This is NOT
  35. async-signal-safe. And it is slow. It is intended primarily for debugging
  36. of the atomic_ops package itself.
  37. Note that the implementation reflects our understanding of real processor
  38. behavior. This occasionally diverges from the documented behavior. (E.g.
  39. the documented X86 behavior seems to be weak enough that it is impractical
  40. to use. Current real implementations appear to be much better behaved.)
  41. We of course are in no position to guarantee that future processors
  42. (even HPs) will continue to behave this way, though we hope they will.
  43. This is a work in progress. Corrections/additions for other platforms are
  44. greatly appreciated. It passes rudimentary tests on X86, Itanium, and
  45. Alpha.
  46. OPERATIONS:
  47. Most operations operate on values of type AO_t, which are unsigned integers
  48. whose size matches that of pointers on the given architecture. Exceptions
  49. are:
  50. - AO_test_and_set operates on AO_TS_t, which is whatever size the hardware
  51. supports with good performance. In some cases this is the length of a cache
  52. line. In some cases it is a byte. In many cases it is equivalent to AO_t.
  53. - A few operations are implemented on smaller or larger size integers.
  54. Such operations are indicated by the appropriate prefix:
  55. AO_char_... Operates on unsigned char values.
  56. AO_short_... Operates on unsigned short values.
  57. AO_int_... Operates on unsigned int values.
  58. (Currently a very limited selection of these is implemented. We're
  59. working on it.)
  60. The defined operations are all of the form AO_[<size>_]<op><barrier>(<args>).
  61. The <op> component specifies an atomic memory operation. It may be
  62. one of the following, where the corresponding argument and result types
  63. are also specified:
  64. void nop()
  65. No atomic operation. The barrier may still be useful.
  66. AO_t load(const volatile AO_t * addr)
  67. Atomic load of *addr.
  68. void store(volatile AO_t * addr, AO_t new_val)
  69. Atomically store new_val to *addr.
  70. AO_t fetch_and_add(volatile AO_t *addr, AO_t incr)
  71. Atomically add incr to *addr, and return the original value of *addr.
  72. AO_t fetch_and_add1(volatile AO_t *addr)
  73. Equivalent to AO_fetch_and_add(addr, 1).
  74. AO_t fetch_and_sub1(volatile AO_t *addr)
  75. Equivalent to AO_fetch_and_add(addr, (AO_t)(-1)).
  76. void and(volatile AO_t *addr, AO_t value)
  77. Atomically 'and' value into *addr.
  78. void or(volatile AO_t *addr, AO_t value)
  79. Atomically 'or' value into *addr.
  80. void xor(volatile AO_t *addr, AO_t value)
  81. Atomically 'xor' value into *addr.
  82. int compare_and_swap(volatile AO_t * addr, AO_t old_val, AO_t new_val)
  83. Atomically compare *addr to old_val, and replace *addr by new_val
  84. if the first comparison succeeds. Returns nonzero if the comparison
  85. succeeded and *addr was updated.
  86. AO_t fetch_compare_and_swap(volatile AO_t * addr, AO_t old_val, AO_t new_val)
  87. Atomically compare *addr to old_val, and replace *addr by new_val
  88. if the first comparison succeeds; returns the original value of *addr.
  89. AO_TS_VAL_t test_and_set(volatile AO_TS_t * addr)
  90. Atomically read the binary value at *addr, and set it. AO_TS_VAL_t
  91. is an enumeration type which includes two values AO_TS_SET and
  92. AO_TS_CLEAR. An AO_TS_t location is capable of holding an
  93. AO_TS_VAL_t, but may be much larger, as dictated by hardware
  94. constraints. Test_and_set logically sets the value to AO_TS_SET.
  95. It may be reset to AO_TS_CLEAR with the AO_CLEAR(AO_TS_t *) macro.
  96. AO_TS_t locations should be initialized to AO_TS_INITIALIZER.
  97. The values of AO_TS_SET and AO_TS_CLEAR are hardware dependent.
  98. (On PA-RISC, AO_TS_SET is zero!)
  99. Test_and_set is a more limited version of compare_and_swap. Its only
  100. advantage is that it is more easily implementable on some hardware. It
  101. should thus be used if only binary test-and-set functionality is needed.
  102. If available, we also provide compare_and_swap operations that operate
  103. on wider values. Since standard data types for double width values
  104. may not be available, these explicitly take pairs of arguments for the
  105. new and/or old value. Unfortunately, there are two common variants,
  106. neither of which can easily and efficiently emulate the other.
  107. The first performs a comparison against the entire value being replaced,
  108. where the second replaces a double-width replacement, but performs
  109. a single-width comparison:
  110. int compare_double_and_swap_double(volatile AO_double_t * addr,
  111. AO_t old_val1, AO_t old_val2,
  112. AO_t new_val1, AO_t new_val2);
  113. int compare_and_swap_double(volatile AO_double_t * addr,
  114. AO_t old_val1,
  115. AO_t new_val1, AO_t new_val2);
  116. where AO_double_t is a structure containing AO_val1 and AO_val2 fields,
  117. both of type AO_t. For compare_and_swap_double, we compare against
  118. the val1 field. AO_double_t exists only if AO_HAVE_double_t
  119. is defined.
  120. ORDERING CONSTRAINTS:
  121. Each operation name also includes a suffix that specifies the associated
  122. ordering semantics. The ordering constraint limits reordering of this
  123. operation with respect to other atomic operations and ordinary memory
  124. references. The current implementation assumes that all memory references
  125. are to ordinary cacheable memory; the ordering guarantee is with respect
  126. to other threads or processes, not I/O devices. (Whether or not this
  127. distinction is important is platform-dependent.)
  128. Ordering suffixes are one of the following:
  129. <none>: No memory barrier. A plain AO_nop() really does nothing.
  130. _release: Earlier operations must become visible to other threads
  131. before the atomic operation.
  132. _acquire: Later operations must become visible after this operation.
  133. _read: Subsequent reads must become visible after reads included in
  134. the atomic operation or preceding it. Rarely useful for clients?
  135. _write: Earlier writes become visible before writes during or after
  136. the atomic operation. Rarely useful for clients?
  137. _full: Ordered with respect to both earlier and later memory ops.
  138. AO_store_full or AO_nop_full are the normal ways to force a store
  139. to be ordered with respect to a later load.
  140. _release_write: Ordered with respect to earlier writes. This is
  141. normally implemented as either a _write or _release
  142. barrier.
  143. _acquire_read: Ordered with respect to later reads. This is
  144. normally implemented as either a _read or _acquire barrier.
  145. _dd_acquire_read: Ordered with respect to later reads that are data
  146. dependent on this one. This is needed on
  147. a pointer read, which is later dereferenced to read a
  148. second value, with the expectation that the second
  149. read is ordered after the first one. On most architectures,
  150. this is equivalent to no barrier. (This is very
  151. hard to define precisely. It should probably be avoided.
  152. A major problem is that optimizers tend to try to
  153. eliminate dependencies from the generated code, since
  154. dependencies force the hardware to execute the code
  155. serially.)
  156. We assume that if a store is data-dependent on a previous load, then
  157. the two are always implicitly ordered.
  158. It is possible to test whether AO_<op><barrier> is available on the
  159. current platform by checking whether AO_HAVE_<op>_<barrier> is defined
  160. as a macro.
  161. Note that we generally don't implement operations that are either
  162. meaningless (e.g. AO_nop_acquire, AO_nop_release) or which appear to
  163. have no clear use (e.g. AO_load_release, AO_store_acquire, AO_load_write,
  164. AO_store_read). On some platforms (e.g. PA-RISC) many operations
  165. will remain undefined unless AO_REQUIRE_CAS is defined before including
  166. the package.
  167. When typed in the package build directory, the following command
  168. will print operations that are unimplemented on the platform:
  169. make test_atomic; ./test_atomic
  170. The following command generates a file "list_atomic.i" containing the
  171. macro expansions of all implemented operations on the platform:
  172. make list_atomic.i
  173. Future directions:
  174. It currently appears that something roughly analogous to this is very likely
  175. to become part of the C++0x standard. That effort has pointed out a number
  176. of issues that we expect to address there. Since some of the solutions
  177. really require compiler support, they may not be completely addressed here.
  178. Known issues include:
  179. We should be more precise in defining the semantics of the ordering
  180. constraints, and if and how we can guarantee sequential consistency.
  181. Dd_acquire_read is very hard or impossible to define in a way that cannot
  182. be invalidated by reasonably standard compiler transformations.
  183. There is probably no good reason to provide operations on standard
  184. integer types, since those may have the wrong alignment constraints.
  185. Example:
  186. If you want to initialize an object, and then "publish" a pointer to it
  187. in a global location p, such that other threads reading the new value of
  188. p are guaranteed to see an initialized object, it suffices to use
  189. AO_release_write(p, ...) to write the pointer to the object, and to
  190. retrieve it in other threads with AO_acquire_read(p).
  191. Platform notes:
  192. All X86: We quietly assume 486 or better.
  193. Microsoft compilers:
  194. Define AO_ASSUME_WINDOWS98 to get access to hardware compare-and-swap
  195. functionality. This relies on the InterlockedCompareExchange() function
  196. which was apparently not supported in Windows95. (There may be a better
  197. way to get access to this.)
  198. Gcc on x86:
  199. Define AO_USE_PENTIUM4_INSTRS to use the Pentium 4 mfence instruction.
  200. Currently this is appears to be of marginal benefit.