passenger 4.0.20 → 4.0.21

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of passenger might be problematic. Click here for more details.

Files changed (496) hide show
  1. checksums.yaml +8 -8
  2. checksums.yaml.gz.asc +7 -7
  3. data.tar.gz.asc +7 -7
  4. data/.gitignore +1 -0
  5. data/.travis.yml +1 -1
  6. data/NEWS +15 -0
  7. data/README.md +5 -3
  8. data/Rakefile +1 -0
  9. data/bin/passenger-config +1 -5
  10. data/bin/passenger-install-apache2-module +53 -5
  11. data/bin/passenger-install-nginx-module +19 -6
  12. data/bin/passenger-memory-stats +3 -3
  13. data/build/agents.rb +11 -8
  14. data/build/apache2.rb +9 -5
  15. data/build/basics.rb +15 -21
  16. data/build/common_library.rb +16 -6
  17. data/build/cplusplus_support.rb +5 -5
  18. data/build/cxx_tests.rb +3 -3
  19. data/build/documentation.rb +1 -1
  20. data/build/misc.rb +4 -37
  21. data/build/node_tests.rb +29 -0
  22. data/build/oxt_tests.rb +1 -1
  23. data/build/packaging.rb +29 -10
  24. data/build/preprocessor.rb +2 -1
  25. data/build/test_basics.rb +15 -6
  26. data/debian.template/locations.ini.template +1 -0
  27. data/debian.template/passenger.install.template +1 -0
  28. data/dev/copy_boost_headers.rb +7 -3
  29. data/dev/run_travis.sh +32 -16
  30. data/doc/Users guide Apache.idmap.txt +22 -34
  31. data/doc/Users guide Apache.txt +20 -234
  32. data/doc/Users guide Nginx.idmap.txt +84 -66
  33. data/doc/Users guide Nginx.txt +50 -1
  34. data/doc/Users guide Standalone.idmap.txt +74 -0
  35. data/doc/Users guide Standalone.txt +22 -9
  36. data/doc/Users guide.txt +51 -0
  37. data/doc/users_guide_snippets/environment_variables.txt +0 -3
  38. data/doc/users_guide_snippets/installation.txt +337 -380
  39. data/doc/users_guide_snippets/installation/run_installer.txt +58 -0
  40. data/doc/users_guide_snippets/installation/verify_running_epilogue.txt +6 -0
  41. data/doc/users_guide_snippets/support_information.txt +2 -9
  42. data/doc/users_guide_snippets/troubleshooting/default.txt +112 -0
  43. data/doc/users_guide_snippets/troubleshooting/rails.txt +56 -0
  44. data/doc/users_guide_snippets/where_to_get_support.txt +9 -0
  45. data/ext/apache2/Bucket.h +1 -1
  46. data/ext/apache2/Configuration.hpp +0 -44
  47. data/ext/apache2/CreateDirConfig.cpp +1 -1
  48. data/ext/apache2/CreateDirConfig.cpp.erb +1 -1
  49. data/ext/apache2/Hooks.cpp +28 -21
  50. data/ext/apache2/MergeDirConfig.cpp +1 -0
  51. data/ext/apache2/MergeDirConfig.cpp.erb +1 -1
  52. data/ext/apache2/SetHeaders.cpp +73 -0
  53. data/ext/apache2/SetHeaders.cpp.erb +88 -0
  54. data/ext/boost/algorithm/string/detail/find_format.hpp +5 -5
  55. data/ext/boost/algorithm/string/detail/find_format_all.hpp +5 -5
  56. data/ext/boost/algorithm/string/detail/finder.hpp +1 -1
  57. data/ext/boost/algorithm/string/formatter.hpp +2 -2
  58. data/ext/boost/assert.hpp +6 -1
  59. data/ext/boost/atomic.hpp +18 -0
  60. data/ext/boost/atomic/atomic.hpp +241 -0
  61. data/ext/boost/atomic/detail/base.hpp +585 -0
  62. data/ext/boost/atomic/detail/cas32strong.hpp +885 -0
  63. data/ext/boost/atomic/detail/cas32weak.hpp +947 -0
  64. data/ext/boost/atomic/detail/cas64strong.hpp +443 -0
  65. data/ext/boost/atomic/detail/config.hpp +54 -0
  66. data/ext/boost/atomic/detail/gcc-alpha.hpp +368 -0
  67. data/ext/boost/atomic/detail/gcc-armv6plus.hpp +252 -0
  68. data/ext/boost/atomic/detail/gcc-cas.hpp +157 -0
  69. data/ext/boost/atomic/detail/gcc-ppc.hpp +2850 -0
  70. data/ext/boost/atomic/detail/gcc-sparcv9.hpp +1259 -0
  71. data/ext/boost/atomic/detail/gcc-x86.hpp +1766 -0
  72. data/ext/boost/atomic/detail/generic-cas.hpp +206 -0
  73. data/ext/boost/atomic/detail/interlocked.hpp +200 -0
  74. data/ext/boost/atomic/detail/linux-arm.hpp +189 -0
  75. data/ext/boost/atomic/detail/lockpool.hpp +97 -0
  76. data/ext/boost/atomic/detail/platform.hpp +62 -0
  77. data/ext/boost/atomic/detail/type-classification.hpp +45 -0
  78. data/ext/boost/chrono/config.hpp +8 -3
  79. data/ext/boost/chrono/duration.hpp +9 -10
  80. data/ext/boost/chrono/system_clocks.hpp +1 -1
  81. data/ext/boost/chrono/time_point.hpp +4 -3
  82. data/ext/boost/config/auto_link.hpp +53 -52
  83. data/ext/boost/config/compiler/borland.hpp +1 -0
  84. data/ext/boost/config/compiler/clang.hpp +24 -1
  85. data/ext/boost/config/compiler/codegear.hpp +1 -0
  86. data/ext/boost/config/compiler/common_edg.hpp +1 -0
  87. data/ext/boost/config/compiler/cray.hpp +1 -0
  88. data/ext/boost/config/compiler/digitalmars.hpp +1 -0
  89. data/ext/boost/config/compiler/gcc.hpp +29 -3
  90. data/ext/boost/config/compiler/gcc_xml.hpp +2 -1
  91. data/ext/boost/config/compiler/hp_acc.hpp +1 -0
  92. data/ext/boost/config/compiler/intel.hpp +1 -1
  93. data/ext/boost/config/compiler/metrowerks.hpp +1 -0
  94. data/ext/boost/config/compiler/mpw.hpp +1 -0
  95. data/ext/boost/config/compiler/pathscale.hpp +1 -0
  96. data/ext/boost/config/compiler/pgi.hpp +1 -0
  97. data/ext/boost/config/compiler/sunpro_cc.hpp +1 -0
  98. data/ext/boost/config/compiler/vacpp.hpp +3 -2
  99. data/ext/boost/config/compiler/visualc.hpp +25 -11
  100. data/ext/boost/config/platform/vxworks.hpp +353 -15
  101. data/ext/boost/config/select_compiler_config.hpp +4 -4
  102. data/ext/boost/config/stdlib/dinkumware.hpp +10 -3
  103. data/ext/boost/config/stdlib/libstdcpp3.hpp +2 -1
  104. data/ext/boost/config/suffix.hpp +45 -19
  105. data/ext/boost/date_time/format_date_parser.hpp +1 -11
  106. data/ext/boost/date_time/strings_from_facet.hpp +5 -3
  107. data/ext/boost/detail/atomic_redef_macros.hpp +19 -0
  108. data/ext/boost/detail/atomic_undef_macros.hpp +39 -0
  109. data/ext/boost/detail/endian.hpp +52 -4
  110. data/ext/boost/detail/scoped_enum_emulation.hpp +10 -10
  111. data/ext/boost/detail/select_type.hpp +36 -0
  112. data/ext/boost/exception/current_exception_cast.hpp +1 -1
  113. data/ext/boost/exception/detail/error_info_impl.hpp +3 -5
  114. data/ext/boost/exception/detail/exception_ptr.hpp +3 -3
  115. data/ext/boost/exception/detail/is_output_streamable.hpp +1 -1
  116. data/ext/boost/exception/detail/object_hex_dump.hpp +1 -1
  117. data/ext/boost/exception/detail/type_info.hpp +1 -1
  118. data/ext/boost/exception/diagnostic_information.hpp +15 -14
  119. data/ext/boost/exception/exception.hpp +1 -1
  120. data/ext/boost/exception/get_error_info.hpp +1 -1
  121. data/ext/boost/exception/info.hpp +12 -13
  122. data/ext/boost/exception/to_string.hpp +6 -1
  123. data/ext/boost/exception/to_string_stub.hpp +9 -1
  124. data/ext/boost/foreach.hpp +5 -5
  125. data/ext/boost/function/function_template.hpp +6 -6
  126. data/ext/boost/functional/hash/detail/float_functions.hpp +90 -0
  127. data/ext/boost/functional/hash/detail/hash_float.hpp +11 -2
  128. data/ext/boost/functional/hash/extensions.hpp +14 -2
  129. data/ext/boost/functional/hash/hash.hpp +26 -5
  130. data/ext/boost/get_pointer.hpp +17 -2
  131. data/ext/boost/integer_traits.hpp +1 -1
  132. data/ext/boost/lexical_cast.hpp +615 -395
  133. data/ext/boost/libs/atomic/lockpool.cpp +24 -0
  134. data/ext/boost/libs/system/src/error_code.cpp +25 -18
  135. data/ext/boost/libs/thread/src/future.cpp +7 -5
  136. data/ext/boost/libs/thread/src/pthread/once.cpp +9 -3
  137. data/ext/boost/libs/thread/src/pthread/once_atomic.cpp +90 -0
  138. data/ext/boost/libs/thread/src/pthread/thread.cpp +129 -95
  139. data/ext/boost/libs/thread/src/pthread/timeconv.inl +20 -1
  140. data/ext/boost/limits.hpp +1 -1
  141. data/ext/boost/math/policies/policy.hpp +10 -0
  142. data/ext/boost/math/special_functions/detail/round_fwd.hpp +17 -4
  143. data/ext/boost/math/special_functions/fpclassify.hpp +114 -45
  144. data/ext/boost/math/special_functions/math_fwd.hpp +195 -83
  145. data/ext/boost/math/special_functions/sign.hpp +13 -8
  146. data/ext/boost/math/tools/config.hpp +38 -16
  147. data/ext/boost/move/algorithm.hpp +275 -0
  148. data/ext/boost/move/core.hpp +332 -0
  149. data/ext/boost/move/detail/config_begin.hpp +23 -0
  150. data/ext/boost/move/detail/config_end.hpp +20 -0
  151. data/ext/boost/move/detail/meta_utils.hpp +158 -0
  152. data/ext/boost/move/iterator.hpp +298 -0
  153. data/ext/boost/move/move.hpp +10 -1256
  154. data/ext/boost/move/traits.hpp +142 -0
  155. data/ext/boost/move/utility.hpp +194 -0
  156. data/ext/boost/mpl/assert.hpp +72 -4
  157. data/ext/boost/noncopyable.hpp +15 -3
  158. data/ext/boost/pointer_to_other.hpp +55 -0
  159. data/ext/boost/range/concepts.hpp +4 -4
  160. data/ext/boost/range/detail/extract_optional_type.hpp +1 -1
  161. data/ext/boost/range/empty.hpp +1 -1
  162. data/ext/boost/range/iterator_range_core.hpp +4 -1
  163. data/ext/boost/range/iterator_range_io.hpp +2 -2
  164. data/ext/boost/ratio/config.hpp +6 -0
  165. data/ext/boost/ratio/detail/overflow_helpers.hpp +2 -2
  166. data/ext/boost/smart_ptr/allocate_shared_array.hpp +250 -0
  167. data/ext/boost/smart_ptr/detail/allocate_array_helper.hpp +169 -0
  168. data/ext/boost/smart_ptr/detail/array_deleter.hpp +124 -0
  169. data/ext/boost/smart_ptr/detail/array_traits.hpp +53 -0
  170. data/ext/boost/smart_ptr/detail/array_utility.hpp +178 -0
  171. data/ext/boost/smart_ptr/detail/make_array_helper.hpp +157 -0
  172. data/ext/boost/smart_ptr/detail/operator_bool.hpp +16 -9
  173. data/ext/boost/smart_ptr/detail/shared_count.hpp +78 -7
  174. data/ext/boost/smart_ptr/detail/sp_convertible.hpp +15 -0
  175. data/ext/boost/smart_ptr/detail/sp_counted_base.hpp +12 -6
  176. data/ext/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp +1 -0
  177. data/ext/boost/smart_ptr/detail/sp_counted_base_aix.hpp +1 -0
  178. data/ext/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp +1 -0
  179. data/ext/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp +1 -0
  180. data/ext/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp +1 -0
  181. data/ext/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp +1 -0
  182. data/ext/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp +1 -0
  183. data/ext/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp +1 -0
  184. data/ext/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp +1 -0
  185. data/ext/boost/smart_ptr/detail/sp_counted_base_nt.hpp +1 -0
  186. data/ext/boost/smart_ptr/detail/sp_counted_base_pt.hpp +1 -0
  187. data/ext/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp +162 -0
  188. data/ext/boost/smart_ptr/detail/sp_counted_base_solaris.hpp +1 -0
  189. data/ext/boost/smart_ptr/detail/sp_counted_base_spin.hpp +1 -0
  190. data/ext/boost/smart_ptr/detail/sp_counted_base_sync.hpp +1 -0
  191. data/ext/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp +1 -0
  192. data/ext/boost/smart_ptr/detail/sp_counted_impl.hpp +15 -0
  193. data/ext/boost/smart_ptr/detail/sp_forward.hpp +39 -0
  194. data/ext/boost/smart_ptr/detail/sp_has_sync.hpp +19 -3
  195. data/ext/boost/smart_ptr/detail/sp_if_array.hpp +31 -0
  196. data/ext/boost/smart_ptr/detail/sp_nullptr_t.hpp +45 -0
  197. data/ext/boost/smart_ptr/detail/spinlock_gcc_arm.hpp +5 -12
  198. data/ext/boost/smart_ptr/enable_shared_from_this.hpp +4 -4
  199. data/ext/boost/smart_ptr/make_shared.hpp +5 -1060
  200. data/ext/boost/smart_ptr/make_shared_array.hpp +247 -0
  201. data/ext/boost/smart_ptr/make_shared_object.hpp +1128 -0
  202. data/ext/boost/smart_ptr/scoped_array.hpp +32 -7
  203. data/ext/boost/smart_ptr/scoped_ptr.hpp +31 -5
  204. data/ext/boost/smart_ptr/shared_array.hpp +135 -20
  205. data/ext/boost/smart_ptr/shared_ptr.hpp +444 -126
  206. data/ext/boost/smart_ptr/weak_ptr.hpp +39 -28
  207. data/ext/boost/static_assert.hpp +74 -17
  208. data/ext/boost/system/error_code.hpp +76 -68
  209. data/ext/boost/system/system_error.hpp +5 -1
  210. data/ext/boost/thread/barrier.hpp +6 -2
  211. data/ext/boost/thread/completion_latch.hpp +233 -0
  212. data/ext/boost/thread/condition.hpp +6 -1
  213. data/ext/boost/thread/detail/async_func.hpp +571 -0
  214. data/ext/boost/thread/detail/config.hpp +248 -40
  215. data/ext/boost/thread/detail/counter.hpp +93 -0
  216. data/ext/boost/thread/detail/delete.hpp +12 -0
  217. data/ext/boost/thread/detail/invoke.hpp +1351 -0
  218. data/ext/boost/thread/detail/is_convertible.hpp +48 -0
  219. data/ext/boost/thread/detail/lockable_wrapper.hpp +45 -0
  220. data/ext/boost/thread/detail/log.hpp +83 -0
  221. data/ext/boost/thread/detail/make_tuple_indices.hpp +224 -0
  222. data/ext/boost/thread/detail/move.hpp +32 -16
  223. data/ext/boost/thread/detail/thread.hpp +236 -41
  224. data/ext/boost/thread/detail/thread_group.hpp +55 -9
  225. data/ext/boost/thread/detail/thread_interruption.hpp +4 -1
  226. data/ext/boost/thread/exceptions.hpp +2 -0
  227. data/ext/boost/thread/externally_locked.hpp +351 -0
  228. data/ext/boost/thread/externally_locked_stream.hpp +170 -0
  229. data/ext/boost/thread/future.hpp +2517 -455
  230. data/ext/boost/thread/future_error_code.hpp +61 -0
  231. data/ext/boost/thread/is_locked_by_this_thread.hpp +39 -0
  232. data/ext/boost/thread/latch.hpp +142 -0
  233. data/ext/boost/thread/lock_algorithms.hpp +468 -0
  234. data/ext/boost/thread/lock_concepts.hpp +197 -0
  235. data/ext/boost/thread/lock_factories.hpp +78 -0
  236. data/ext/boost/thread/lock_guard.hpp +88 -0
  237. data/ext/boost/thread/lock_options.hpp +31 -0
  238. data/ext/boost/thread/lock_traits.hpp +45 -0
  239. data/ext/boost/thread/lock_types.hpp +1226 -0
  240. data/ext/boost/thread/lockable_adapter.hpp +226 -0
  241. data/ext/boost/thread/lockable_concepts.hpp +157 -0
  242. data/ext/boost/thread/lockable_traits.hpp +207 -0
  243. data/ext/boost/thread/locks.hpp +5 -1816
  244. data/ext/boost/thread/mutex.hpp +33 -1
  245. data/ext/boost/thread/null_mutex.hpp +243 -0
  246. data/ext/boost/thread/once.hpp +10 -1
  247. data/ext/boost/thread/poly_lockable.hpp +68 -0
  248. data/ext/boost/thread/poly_lockable_adapter.hpp +89 -0
  249. data/ext/boost/thread/poly_shared_lockable.hpp +135 -0
  250. data/ext/boost/thread/poly_shared_lockable_adapter.hpp +170 -0
  251. data/ext/boost/thread/pthread/condition_variable.hpp +74 -26
  252. data/ext/boost/thread/pthread/condition_variable_fwd.hpp +54 -27
  253. data/ext/boost/thread/pthread/mutex.hpp +101 -38
  254. data/ext/boost/thread/pthread/once.hpp +459 -44
  255. data/ext/boost/thread/pthread/once_atomic.hpp +313 -0
  256. data/ext/boost/thread/pthread/recursive_mutex.hpp +19 -10
  257. data/ext/boost/thread/pthread/shared_mutex.hpp +226 -61
  258. data/ext/boost/thread/pthread/shared_mutex_assert.hpp +724 -0
  259. data/ext/boost/thread/pthread/thread_data.hpp +53 -50
  260. data/ext/boost/thread/pthread/timespec.hpp +96 -12
  261. data/ext/boost/thread/recursive_mutex.hpp +44 -1
  262. data/ext/boost/thread/reverse_lock.hpp +3 -2
  263. data/ext/boost/thread/scoped_thread.hpp +285 -0
  264. data/ext/boost/thread/shared_lock_guard.hpp +2 -1
  265. data/ext/boost/thread/shared_mutex.hpp +23 -0
  266. data/ext/boost/thread/strict_lock.hpp +235 -0
  267. data/ext/boost/thread/sync_bounded_queue.hpp +594 -0
  268. data/ext/boost/thread/sync_queue.hpp +516 -0
  269. data/ext/boost/thread/synchronized_value.hpp +1001 -0
  270. data/ext/boost/thread/testable_mutex.hpp +148 -0
  271. data/ext/boost/thread/thread.hpp +1 -13
  272. data/ext/boost/thread/thread_functors.hpp +57 -0
  273. data/ext/boost/thread/thread_guard.hpp +46 -0
  274. data/ext/boost/thread/thread_only.hpp +29 -0
  275. data/ext/boost/thread/v2/shared_mutex.hpp +1062 -0
  276. data/ext/boost/thread/v2/thread.hpp +37 -10
  277. data/ext/boost/thread/xtime.hpp +2 -1
  278. data/ext/boost/token_functions.hpp +16 -16
  279. data/ext/boost/type_traits/add_lvalue_reference.hpp +26 -0
  280. data/ext/boost/type_traits/add_reference.hpp +1 -1
  281. data/ext/boost/type_traits/add_rvalue_reference.hpp +4 -4
  282. data/ext/boost/type_traits/aligned_storage.hpp +13 -0
  283. data/ext/boost/type_traits/common_type.hpp +11 -12
  284. data/ext/boost/type_traits/config.hpp +1 -1
  285. data/ext/boost/type_traits/detail/common_type_imp.hpp +1 -1
  286. data/ext/boost/type_traits/detail/has_binary_operator.hpp +1 -1
  287. data/ext/boost/type_traits/detail/is_function_ptr_tester.hpp +1 -1
  288. data/ext/boost/type_traits/has_left_shift.hpp +49 -0
  289. data/ext/boost/type_traits/has_right_shift.hpp +49 -0
  290. data/ext/boost/type_traits/has_trivial_move_assign.hpp +57 -0
  291. data/ext/boost/type_traits/has_trivial_move_constructor.hpp +57 -0
  292. data/ext/boost/type_traits/intrinsics.hpp +18 -2
  293. data/ext/boost/type_traits/is_abstract.hpp +1 -1
  294. data/ext/boost/type_traits/is_array.hpp +1 -1
  295. data/ext/boost/type_traits/is_const.hpp +1 -1
  296. data/ext/boost/type_traits/is_convertible.hpp +78 -17
  297. data/ext/boost/type_traits/is_function.hpp +6 -1
  298. data/ext/boost/type_traits/is_integral.hpp +6 -1
  299. data/ext/boost/type_traits/is_nothrow_move_assignable.hpp +84 -0
  300. data/ext/boost/type_traits/is_nothrow_move_constructible.hpp +84 -0
  301. data/ext/boost/type_traits/is_pod.hpp +3 -1
  302. data/ext/boost/type_traits/is_rvalue_reference.hpp +1 -1
  303. data/ext/boost/type_traits/is_volatile.hpp +1 -1
  304. data/ext/boost/type_traits/make_signed.hpp +153 -0
  305. data/ext/boost/type_traits/make_unsigned.hpp +16 -0
  306. data/ext/boost/type_traits/remove_const.hpp +1 -1
  307. data/ext/boost/type_traits/remove_cv.hpp +1 -1
  308. data/ext/boost/type_traits/remove_reference.hpp +1 -1
  309. data/ext/boost/type_traits/remove_volatile.hpp +1 -1
  310. data/ext/boost/unordered/detail/allocate.hpp +1120 -0
  311. data/ext/boost/unordered/detail/buckets.hpp +876 -0
  312. data/ext/boost/unordered/detail/equivalent.hpp +680 -0
  313. data/ext/boost/unordered/detail/extract_key.hpp +183 -0
  314. data/ext/boost/unordered/detail/fwd.hpp +23 -0
  315. data/ext/boost/unordered/detail/table.hpp +861 -0
  316. data/ext/boost/unordered/detail/unique.hpp +622 -0
  317. data/ext/boost/unordered/detail/util.hpp +260 -0
  318. data/ext/boost/unordered/unordered_map.hpp +1652 -0
  319. data/ext/boost/unordered/unordered_map_fwd.hpp +65 -0
  320. data/ext/boost/unordered/unordered_set.hpp +1549 -0
  321. data/ext/boost/unordered/unordered_set_fwd.hpp +63 -0
  322. data/ext/boost/unordered_map.hpp +18 -0
  323. data/ext/boost/unordered_set.hpp +18 -0
  324. data/ext/boost/utility/addressof.hpp +2 -2
  325. data/ext/boost/utility/result_of.hpp +8 -1
  326. data/ext/boost/version.hpp +2 -2
  327. data/ext/common/Account.h +1 -1
  328. data/ext/common/AccountsDatabase.h +1 -1
  329. data/ext/common/AgentsStarter.cpp +3 -1
  330. data/ext/common/AgentsStarter.h +2 -2
  331. data/ext/common/ApplicationPool2/AppTypes.cpp +24 -6
  332. data/ext/common/ApplicationPool2/AppTypes.h +17 -8
  333. data/ext/common/ApplicationPool2/Common.h +12 -12
  334. data/ext/common/ApplicationPool2/DirectSpawner.h +2 -2
  335. data/ext/common/ApplicationPool2/DummySpawner.h +3 -3
  336. data/ext/common/ApplicationPool2/Group.h +6 -6
  337. data/ext/common/ApplicationPool2/Implementation.cpp +19 -19
  338. data/ext/common/ApplicationPool2/PipeWatcher.h +5 -5
  339. data/ext/common/ApplicationPool2/Pool.h +21 -21
  340. data/ext/common/ApplicationPool2/Process.h +6 -6
  341. data/ext/common/ApplicationPool2/Session.h +1 -1
  342. data/ext/common/ApplicationPool2/SmartSpawner.h +24 -12
  343. data/ext/common/ApplicationPool2/Socket.h +2 -2
  344. data/ext/common/ApplicationPool2/Spawner.h +64 -14
  345. data/ext/common/ApplicationPool2/SpawnerFactory.h +7 -7
  346. data/ext/common/ApplicationPool2/SuperGroup.h +5 -5
  347. data/ext/common/BackgroundEventLoop.cpp +4 -4
  348. data/ext/common/BackgroundEventLoop.h +1 -1
  349. data/ext/common/Constants.h +13 -1
  350. data/ext/common/EventedBufferedInput.h +8 -8
  351. data/ext/common/Exceptions.cpp +71 -0
  352. data/ext/common/Exceptions.h +60 -7
  353. data/ext/common/FileDescriptor.h +4 -4
  354. data/ext/common/MessageClient.h +1 -1
  355. data/ext/common/MessageServer.h +5 -5
  356. data/ext/common/MultiLibeio.cpp +3 -3
  357. data/ext/common/MultiLibeio.h +2 -2
  358. data/ext/common/RandomGenerator.h +11 -11
  359. data/ext/common/ResourceLocator.h +8 -1
  360. data/ext/common/SafeLibev.h +12 -12
  361. data/ext/common/ServerInstanceDir.h +11 -3
  362. data/ext/common/UnionStation.h +10 -10
  363. data/ext/common/Utils.cpp +11 -13
  364. data/ext/common/Utils.h +9 -9
  365. data/ext/common/Utils/BlockingQueue.h +10 -10
  366. data/ext/common/Utils/BufferedIO.h +1 -1
  367. data/ext/common/Utils/CachedFileStat.hpp +2 -2
  368. data/ext/common/Utils/FileChangeChecker.h +1 -1
  369. data/ext/common/Utils/HashMap.h +13 -4
  370. data/ext/common/Utils/IOUtils.cpp +33 -10
  371. data/ext/common/Utils/IniFile.h +3 -3
  372. data/ext/common/Utils/Lock.h +2 -2
  373. data/ext/common/Utils/MessagePassing.h +10 -10
  374. data/ext/common/Utils/ProcessMetricsCollector.h +24 -6
  375. data/ext/common/Utils/ScopeGuard.h +5 -5
  376. data/ext/common/Utils/jsoncpp.cpp +2 -0
  377. data/ext/common/agents/HelperAgent/FileBackedPipe.h +26 -26
  378. data/ext/common/agents/HelperAgent/Main.cpp +18 -18
  379. data/ext/common/agents/HelperAgent/RequestHandler.cpp +4 -4
  380. data/ext/common/agents/HelperAgent/RequestHandler.h +30 -21
  381. data/ext/common/agents/LoggingAgent/AdminController.h +1 -1
  382. data/ext/common/agents/LoggingAgent/FilterSupport.h +13 -11
  383. data/ext/common/agents/LoggingAgent/LoggingServer.h +11 -11
  384. data/ext/common/agents/LoggingAgent/Main.cpp +9 -9
  385. data/ext/common/agents/LoggingAgent/RemoteSender.h +3 -3
  386. data/ext/common/agents/SpawnPreparer.cpp +1 -0
  387. data/ext/common/agents/Watchdog/AgentWatcher.cpp +8 -7
  388. data/ext/common/agents/Watchdog/Main.cpp +81 -73
  389. data/ext/common/agents/Watchdog/ServerInstanceDirToucher.cpp +1 -1
  390. data/ext/libev/Changes +57 -0
  391. data/ext/libev/LICENSE +2 -1
  392. data/ext/libev/Makefile.in +110 -50
  393. data/ext/libev/README +8 -8
  394. data/ext/libev/aclocal.m4 +1503 -861
  395. data/ext/libev/config.guess +290 -304
  396. data/ext/libev/config.sub +77 -198
  397. data/ext/libev/configure +1735 -890
  398. data/ext/libev/configure.ac +3 -2
  399. data/ext/libev/ev++.h +6 -6
  400. data/ext/libev/ev.c +541 -214
  401. data/ext/libev/ev.h +106 -100
  402. data/ext/libev/ev_epoll.c +1 -1
  403. data/ext/libev/ev_kqueue.c +20 -4
  404. data/ext/libev/ev_vars.h +15 -16
  405. data/ext/libev/ev_win32.c +12 -2
  406. data/ext/libev/ev_wrap.h +162 -160
  407. data/ext/libev/event.c +29 -6
  408. data/ext/libev/event.h +9 -2
  409. data/ext/libev/ltmain.sh +2632 -1384
  410. data/ext/nginx/ConfigurationCommands.c +1 -1
  411. data/ext/nginx/ConfigurationCommands.c.erb +3 -1
  412. data/ext/nginx/ContentHandler.c +25 -2
  413. data/ext/nginx/CreateLocationConfig.c +1 -0
  414. data/ext/nginx/CreateLocationConfig.c.erb +1 -1
  415. data/ext/nginx/MergeLocationConfig.c +1 -0
  416. data/ext/nginx/MergeLocationConfig.c.erb +1 -1
  417. data/ext/nginx/config +12 -0
  418. data/ext/oxt/dynamic_thread_group.hpp +7 -4
  419. data/ext/oxt/system_calls.cpp +5 -1
  420. data/ext/oxt/system_calls.hpp +3 -0
  421. data/helper-scripts/node-loader.js +117 -249
  422. data/lib/phusion_passenger.rb +27 -5
  423. data/lib/phusion_passenger/abstract_installer.rb +104 -9
  424. data/lib/phusion_passenger/admin_tools/memory_stats.rb +10 -9
  425. data/lib/phusion_passenger/apache2/config_options.rb +6 -3
  426. data/lib/phusion_passenger/common_library.rb +7 -1
  427. data/lib/phusion_passenger/constants.rb +6 -0
  428. data/lib/phusion_passenger/loader_shared_helpers.rb +7 -4
  429. data/lib/phusion_passenger/nginx/config_options.rb +2 -1
  430. data/lib/phusion_passenger/packaging.rb +3 -0
  431. data/lib/phusion_passenger/platform_info/apache.rb +43 -6
  432. data/lib/phusion_passenger/platform_info/apache_detector.rb +15 -5
  433. data/lib/phusion_passenger/platform_info/compiler.rb +167 -32
  434. data/lib/phusion_passenger/platform_info/cxx_portability.rb +133 -77
  435. data/lib/phusion_passenger/platform_info/depcheck.rb +17 -7
  436. data/lib/phusion_passenger/platform_info/depcheck_specs/apache2.rb +3 -3
  437. data/lib/phusion_passenger/platform_info/depcheck_specs/compiler_toolchain.rb +4 -4
  438. data/lib/phusion_passenger/platform_info/depcheck_specs/ruby.rb +5 -6
  439. data/lib/phusion_passenger/platform_info/linux.rb +2 -1
  440. data/lib/phusion_passenger/platform_info/operating_system.rb +1 -1
  441. data/lib/phusion_passenger/platform_info/ruby.rb +18 -3
  442. data/lib/phusion_passenger/standalone/runtime_installer.rb +6 -2
  443. data/lib/phusion_passenger/standalone/start_command.rb +8 -2
  444. data/lib/phusion_passenger/utils/ansi_colors.rb +9 -0
  445. data/lib/phusion_passenger/utils/hosts_file_parser.rb +4 -2
  446. data/node_lib/phusion_passenger/httplib_emulation.js +141 -0
  447. data/node_lib/phusion_passenger/line_reader.js +154 -0
  448. data/node_lib/phusion_passenger/request_handler.js +65 -0
  449. data/node_lib/phusion_passenger/session_protocol_parser.js +113 -0
  450. data/resources/templates/apache2/deployment_example.txt.erb +2 -1
  451. data/resources/templates/apache2/installing_against_a_different_apache.txt.erb +14 -0
  452. data/resources/templates/apache2/multiple_apache_installations_detected.txt.erb +15 -0
  453. data/resources/templates/apache2/possible_solutions_for_compilation_and_installation_problems.txt.erb +4 -5
  454. data/resources/templates/general_error_with_html.html.template +1 -1
  455. data/resources/templates/installer_common/gem_install_permission_problems.txt.erb +17 -0
  456. data/resources/templates/installer_common/low_amount_of_memory_warning.txt.erb +6 -4
  457. data/resources/templates/installer_common/world_inaccessible_directories.txt.erb +16 -0
  458. data/resources/templates/nginx/deployment_example.txt.erb +2 -1
  459. data/resources/templates/nginx/possible_solutions_for_compilation_and_installation_problems.txt.erb +4 -5
  460. data/resources/templates/standalone/config.erb +1 -0
  461. data/test/cxx/ApplicationPool2/DirectSpawnerTest.cpp +3 -3
  462. data/test/cxx/ApplicationPool2/PoolTest.cpp +4 -4
  463. data/test/cxx/ApplicationPool2/ProcessTest.cpp +5 -5
  464. data/test/cxx/ApplicationPool2/SmartSpawnerTest.cpp +5 -5
  465. data/test/cxx/ApplicationPool2/SpawnerTestCases.cpp +1 -1
  466. data/test/cxx/EventedBufferedInputTest.cpp +6 -6
  467. data/test/cxx/FileBackedPipeTest.cpp +1 -1
  468. data/test/cxx/MessagePassingTest.cpp +1 -1
  469. data/test/cxx/MessageServerTest.cpp +4 -4
  470. data/test/cxx/RequestHandlerTest.cpp +7 -7
  471. data/test/cxx/UnionStationTest.cpp +2 -2
  472. data/test/node/line_reader_spec.js +338 -0
  473. data/test/node/spec_helper.js +27 -0
  474. data/test/ruby/standalone/runtime_installer_spec.rb +2 -1
  475. metadata +131 -22
  476. metadata.gz.asc +7 -7
  477. data/ext/boost/functional/hash/detail/container_fwd_0x.hpp +0 -29
  478. data/ext/boost/lambda/core.hpp +0 -79
  479. data/ext/boost/lambda/detail/actions.hpp +0 -174
  480. data/ext/boost/lambda/detail/arity_code.hpp +0 -110
  481. data/ext/boost/lambda/detail/function_adaptors.hpp +0 -789
  482. data/ext/boost/lambda/detail/is_instance_of.hpp +0 -104
  483. data/ext/boost/lambda/detail/lambda_config.hpp +0 -48
  484. data/ext/boost/lambda/detail/lambda_functor_base.hpp +0 -615
  485. data/ext/boost/lambda/detail/lambda_functors.hpp +0 -324
  486. data/ext/boost/lambda/detail/lambda_fwd.hpp +0 -74
  487. data/ext/boost/lambda/detail/lambda_traits.hpp +0 -578
  488. data/ext/boost/lambda/detail/member_ptr.hpp +0 -737
  489. data/ext/boost/lambda/detail/operator_actions.hpp +0 -139
  490. data/ext/boost/lambda/detail/operator_lambda_func_base.hpp +0 -271
  491. data/ext/boost/lambda/detail/operator_return_type_traits.hpp +0 -917
  492. data/ext/boost/lambda/detail/operators.hpp +0 -370
  493. data/ext/boost/lambda/detail/ret.hpp +0 -325
  494. data/ext/boost/lambda/detail/return_type_traits.hpp +0 -282
  495. data/ext/boost/lambda/detail/select_functions.hpp +0 -74
  496. data/ext/boost/lambda/lambda.hpp +0 -34
@@ -0,0 +1,157 @@
1
+ // Copyright (c) 2011 Helge Bahmann
2
+ // Copyright (c) 2013 Tim Blechmann
3
+ //
4
+ // Distributed under the Boost Software License, Version 1.0.
5
+ // See accompanying file LICENSE_1_0.txt or copy at
6
+ // http://www.boost.org/LICENSE_1_0.txt)
7
+
8
+ // Use the gnu builtin __sync_val_compare_and_swap to build
9
+ // atomic operations for 32 bit and smaller.
10
+
11
+ #ifndef BOOST_ATOMIC_DETAIL_GENERIC_CAS_HPP
12
+ #define BOOST_ATOMIC_DETAIL_GENERIC_CAS_HPP
13
+
14
+ #include <cstddef>
15
+ #include <boost/cstdint.hpp>
16
+ #include <boost/atomic/detail/config.hpp>
17
+
18
+ #ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE
19
+ #pragma once
20
+ #endif
21
+
22
+ namespace boost {
23
+
24
+ #define BOOST_ATOMIC_THREAD_FENCE 2
25
+ inline void
26
+ atomic_thread_fence(memory_order order)
27
+ {
28
+ switch(order) {
29
+ case memory_order_relaxed:
30
+ break;
31
+ case memory_order_release:
32
+ case memory_order_consume:
33
+ case memory_order_acquire:
34
+ case memory_order_acq_rel:
35
+ case memory_order_seq_cst:
36
+ __sync_synchronize();
37
+ break;
38
+ }
39
+ }
40
+
41
+ namespace atomics {
42
+ namespace detail {
43
+
44
+ inline void
45
+ platform_fence_before(memory_order)
46
+ {
47
+ /* empty, as compare_and_swap is synchronizing already */
48
+ }
49
+
50
+ inline void
51
+ platform_fence_after(memory_order)
52
+ {
53
+ /* empty, as compare_and_swap is synchronizing already */
54
+ }
55
+
56
+ inline void
57
+ platform_fence_before_store(memory_order order)
58
+ {
59
+ switch(order) {
60
+ case memory_order_relaxed:
61
+ case memory_order_acquire:
62
+ case memory_order_consume:
63
+ break;
64
+ case memory_order_release:
65
+ case memory_order_acq_rel:
66
+ case memory_order_seq_cst:
67
+ __sync_synchronize();
68
+ break;
69
+ }
70
+ }
71
+
72
+ inline void
73
+ platform_fence_after_store(memory_order order)
74
+ {
75
+ if (order == memory_order_seq_cst)
76
+ __sync_synchronize();
77
+ }
78
+
79
+ inline void
80
+ platform_fence_after_load(memory_order order)
81
+ {
82
+ switch(order) {
83
+ case memory_order_relaxed:
84
+ case memory_order_release:
85
+ break;
86
+ case memory_order_consume:
87
+ case memory_order_acquire:
88
+ case memory_order_acq_rel:
89
+ case memory_order_seq_cst:
90
+ __sync_synchronize();
91
+ break;
92
+ }
93
+ }
94
+
95
+ template<typename T>
96
+ inline bool
97
+ platform_cmpxchg32_strong(T & expected, T desired, volatile T * ptr)
98
+ {
99
+ T found = __sync_val_compare_and_swap(ptr, expected, desired);
100
+ bool success = (found == expected);
101
+ expected = found;
102
+ return success;
103
+ }
104
+
105
+ class atomic_flag
106
+ {
107
+ private:
108
+ atomic_flag(const atomic_flag &) /* = delete */ ;
109
+ atomic_flag & operator=(const atomic_flag &) /* = delete */ ;
110
+ uint32_t v_;
111
+ public:
112
+ BOOST_CONSTEXPR atomic_flag(void) BOOST_NOEXCEPT : v_(0) {}
113
+
114
+ void
115
+ clear(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
116
+ {
117
+ atomics::detail::platform_fence_before_store(order);
118
+ const_cast<volatile uint32_t &>(v_) = 0;
119
+ atomics::detail::platform_fence_after_store(order);
120
+ }
121
+
122
+ bool
123
+ test_and_set(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
124
+ {
125
+ atomics::detail::platform_fence_before(order);
126
+ uint32_t expected = v_;
127
+ do {
128
+ if (expected == 1)
129
+ break;
130
+ } while (!atomics::detail::platform_cmpxchg32(expected, (uint32_t)1, &v_));
131
+ atomics::detail::platform_fence_after(order);
132
+ return expected;
133
+ }
134
+ };
135
+ #define BOOST_ATOMIC_FLAG_LOCK_FREE 2
136
+
137
+ }
138
+ }
139
+ }
140
+
141
+ #include <boost/atomic/detail/base.hpp>
142
+
143
+ #if !defined(BOOST_ATOMIC_FORCE_FALLBACK)
144
+
145
+ #define BOOST_ATOMIC_CHAR_LOCK_FREE 2
146
+ #define BOOST_ATOMIC_SHORT_LOCK_FREE 2
147
+ #define BOOST_ATOMIC_INT_LOCK_FREE 2
148
+ #define BOOST_ATOMIC_LONG_LOCK_FREE (sizeof(long) <= 4 ? 2 : 0)
149
+ #define BOOST_ATOMIC_LLONG_LOCK_FREE (sizeof(long long) <= 4 ? 2 : 0)
150
+ #define BOOST_ATOMIC_POINTER_LOCK_FREE (sizeof(void *) <= 4 ? 2 : 0)
151
+ #define BOOST_ATOMIC_BOOL_LOCK_FREE 2
152
+
153
+ #include <boost/atomic/detail/cas32strong.hpp>
154
+
155
+ #endif /* !defined(BOOST_ATOMIC_FORCE_FALLBACK) */
156
+
157
+ #endif
@@ -0,0 +1,2850 @@
1
+ #ifndef BOOST_ATOMIC_DETAIL_GCC_PPC_HPP
2
+ #define BOOST_ATOMIC_DETAIL_GCC_PPC_HPP
3
+
4
+ // Copyright (c) 2009 Helge Bahmann
5
+ // Copyright (c) 2013 Tim Blechmann
6
+ //
7
+ // Distributed under the Boost Software License, Version 1.0.
8
+ // See accompanying file LICENSE_1_0.txt or copy at
9
+ // http://www.boost.org/LICENSE_1_0.txt)
10
+
11
+ #include <cstddef>
12
+ #include <boost/cstdint.hpp>
13
+ #include <boost/atomic/detail/config.hpp>
14
+
15
+ #ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE
16
+ #pragma once
17
+ #endif
18
+
19
+ /*
20
+ Refer to: Motorola: "Programming Environments Manual for 32-Bit
21
+ Implementations of the PowerPC Architecture", Appendix E:
22
+ "Synchronization Programming Examples" for an explanation of what is
23
+ going on here (can be found on the web at various places by the
24
+ name "MPCFPE32B.pdf", Google is your friend...)
25
+
26
+ Most of the atomic operations map to instructions in a relatively
27
+ straight-forward fashion, but "load"s may at first glance appear
28
+ a bit strange as they map to:
29
+
30
+ lwz %rX, addr
31
+ cmpw %rX, %rX
32
+ bne- 1f
33
+ 1:
34
+
35
+ That is, the CPU is forced to perform a branch that "formally" depends
36
+ on the value retrieved from memory. This scheme has an overhead of
37
+ about 1-2 clock cycles per load, but it allows to map "acquire" to
38
+ the "isync" instruction instead of "sync" uniformly and for all type
39
+ of atomic operations. Since "isync" has a cost of about 15 clock
40
+ cycles, while "sync" hast a cost of about 50 clock cycles, the small
41
+ penalty to atomic loads more than compensates for this.
42
+
43
+ Byte- and halfword-sized atomic values are realized by encoding the
44
+ value to be represented into a word, performing sign/zero extension
45
+ as appropriate. This means that after add/sub operations the value
46
+ needs fixing up to accurately preserve the wrap-around semantic of
47
+ the smaller type. (Nothing special needs to be done for the bit-wise
48
+ and the "exchange type" operators as the compiler already sees to
49
+ it that values carried in registers are extended appropriately and
50
+ everything falls into place naturally).
51
+
52
+ The register constraint "b" instructs gcc to use any register
53
+ except r0; this is sometimes required because the encoding for
54
+ r0 is used to signify "constant zero" in a number of instructions,
55
+ making r0 unusable in this place. For simplicity this constraint
56
+ is used everywhere since I am to lazy to look this up on a
57
+ per-instruction basis, and ppc has enough registers for this not
58
+ to pose a problem.
59
+ */
60
+
61
+ namespace boost {
62
+ namespace atomics {
63
+ namespace detail {
64
+
65
+ inline void
66
+ ppc_fence_before(memory_order order)
67
+ {
68
+ switch(order) {
69
+ case memory_order_release:
70
+ case memory_order_acq_rel:
71
+ #if defined(__powerpc64__)
72
+ __asm__ __volatile__ ("lwsync" ::: "memory");
73
+ break;
74
+ #endif
75
+ case memory_order_seq_cst:
76
+ __asm__ __volatile__ ("sync" ::: "memory");
77
+ default:;
78
+ }
79
+ }
80
+
81
+ inline void
82
+ ppc_fence_after(memory_order order)
83
+ {
84
+ switch(order) {
85
+ case memory_order_acquire:
86
+ case memory_order_acq_rel:
87
+ case memory_order_seq_cst:
88
+ __asm__ __volatile__ ("isync");
89
+ case memory_order_consume:
90
+ __asm__ __volatile__ ("" ::: "memory");
91
+ default:;
92
+ }
93
+ }
94
+
95
+ inline void
96
+ ppc_fence_after_store(memory_order order)
97
+ {
98
+ switch(order) {
99
+ case memory_order_seq_cst:
100
+ __asm__ __volatile__ ("sync");
101
+ default:;
102
+ }
103
+ }
104
+
105
+ }
106
+ }
107
+
108
+ class atomic_flag
109
+ {
110
+ private:
111
+ atomic_flag(const atomic_flag &) /* = delete */ ;
112
+ atomic_flag & operator=(const atomic_flag &) /* = delete */ ;
113
+ uint32_t v_;
114
+ public:
115
+ BOOST_CONSTEXPR atomic_flag(void) BOOST_NOEXCEPT : v_(0) {}
116
+
117
+ void
118
+ clear(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
119
+ {
120
+ atomics::detail::ppc_fence_before(order);
121
+ const_cast<volatile uint32_t &>(v_) = 0;
122
+ atomics::detail::ppc_fence_after_store(order);
123
+ }
124
+
125
+ bool
126
+ test_and_set(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
127
+ {
128
+ uint32_t original;
129
+ atomics::detail::ppc_fence_before(order);
130
+ __asm__ (
131
+ "1:\n"
132
+ "lwarx %0,%y1\n"
133
+ "stwcx. %2,%y1\n"
134
+ "bne- 1b\n"
135
+ : "=&b" (original), "+Z"(v_)
136
+ : "b" (1)
137
+ : "cr0"
138
+ );
139
+ atomics::detail::ppc_fence_after(order);
140
+ return original;
141
+ }
142
+ };
143
+
144
+ } /* namespace boost */
145
+
146
+ #define BOOST_ATOMIC_FLAG_LOCK_FREE 2
147
+
148
+ #include <boost/atomic/detail/base.hpp>
149
+
150
+ #if !defined(BOOST_ATOMIC_FORCE_FALLBACK)
151
+
152
+ #define BOOST_ATOMIC_CHAR_LOCK_FREE 2
153
+ #define BOOST_ATOMIC_CHAR16_T_LOCK_FREE 2
154
+ #define BOOST_ATOMIC_CHAR32_T_LOCK_FREE 2
155
+ #define BOOST_ATOMIC_WCHAR_T_LOCK_FREE 2
156
+ #define BOOST_ATOMIC_SHORT_LOCK_FREE 2
157
+ #define BOOST_ATOMIC_INT_LOCK_FREE 2
158
+ #define BOOST_ATOMIC_LONG_LOCK_FREE 2
159
+ #define BOOST_ATOMIC_POINTER_LOCK_FREE 2
160
+ #if defined(__powerpc64__)
161
+ #define BOOST_ATOMIC_LLONG_LOCK_FREE 2
162
+ #else
163
+ #define BOOST_ATOMIC_LLONG_LOCK_FREE 0
164
+ #endif
165
+ #define BOOST_ATOMIC_BOOL_LOCK_FREE 2
166
+
167
+ /* Would like to move the slow-path of failed compare_exchange
168
+ (that clears the "success" bit) out-of-line. gcc can in
169
+ principle do that using ".subsection"/".previous", but Apple's
170
+ binutils seemingly does not understand that. Therefore wrap
171
+ the "clear" of the flag in a macro and let it remain
172
+ in-line for Apple
173
+ */
174
+
175
+ #if !defined(__APPLE__)
176
+
177
+ #define BOOST_ATOMIC_ASM_SLOWPATH_CLEAR \
178
+ "9:\n" \
179
+ ".subsection 2\n" \
180
+ "2: addi %1,0,0\n" \
181
+ "b 9b\n" \
182
+ ".previous\n" \
183
+
184
+ #else
185
+
186
+ #define BOOST_ATOMIC_ASM_SLOWPATH_CLEAR \
187
+ "b 9f\n" \
188
+ "2: addi %1,0,0\n" \
189
+ "9:\n" \
190
+
191
+ #endif
192
+
193
+ namespace boost {
194
+ namespace atomics {
195
+ namespace detail {
196
+
197
+ /* integral types */
198
+
199
+ template<typename T>
200
+ class base_atomic<T, int, 1, true>
201
+ {
202
+ typedef base_atomic this_type;
203
+ typedef T value_type;
204
+ typedef int32_t storage_type;
205
+ typedef T difference_type;
206
+ public:
207
+ BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
208
+ base_atomic(void) {}
209
+
210
+ void
211
+ store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
212
+ {
213
+ ppc_fence_before(order);
214
+ __asm__ (
215
+ "stw %1, %0\n"
216
+ : "+m"(v_)
217
+ : "r" (v)
218
+ );
219
+ ppc_fence_after_store(order);
220
+ }
221
+
222
+ value_type
223
+ load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
224
+ {
225
+ value_type v;
226
+ __asm__ __volatile__ (
227
+ "lwz %0, %1\n"
228
+ "cmpw %0, %0\n"
229
+ "bne- 1f\n"
230
+ "1:\n"
231
+ : "=&r" (v)
232
+ : "m" (v_)
233
+ );
234
+ ppc_fence_after(order);
235
+ return v;
236
+ }
237
+
238
+ value_type
239
+ exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
240
+ {
241
+ value_type original;
242
+ ppc_fence_before(order);
243
+ __asm__ (
244
+ "1:\n"
245
+ "lwarx %0,%y1\n"
246
+ "stwcx. %2,%y1\n"
247
+ "bne- 1b\n"
248
+ : "=&b" (original), "+Z"(v_)
249
+ : "b" (v)
250
+ : "cr0"
251
+ );
252
+ ppc_fence_after(order);
253
+ return original;
254
+ }
255
+
256
+ bool
257
+ compare_exchange_weak(
258
+ value_type & expected,
259
+ value_type desired,
260
+ memory_order success_order,
261
+ memory_order failure_order) volatile BOOST_NOEXCEPT
262
+ {
263
+ int success;
264
+ ppc_fence_before(success_order);
265
+ __asm__(
266
+ "lwarx %0,%y2\n"
267
+ "cmpw %0, %3\n"
268
+ "bne- 2f\n"
269
+ "stwcx. %4,%y2\n"
270
+ "bne- 2f\n"
271
+ "addi %1,0,1\n"
272
+ "1:"
273
+ BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
274
+ : "=&b" (expected), "=&b" (success), "+Z"(v_)
275
+ : "b" (expected), "b" (desired)
276
+ : "cr0"
277
+ );
278
+ if (success)
279
+ ppc_fence_after(success_order);
280
+ else
281
+ ppc_fence_after(failure_order);
282
+ return success;
283
+ }
284
+
285
+ bool
286
+ compare_exchange_strong(
287
+ value_type & expected,
288
+ value_type desired,
289
+ memory_order success_order,
290
+ memory_order failure_order) volatile BOOST_NOEXCEPT
291
+ {
292
+ int success;
293
+ ppc_fence_before(success_order);
294
+ __asm__(
295
+ "0: lwarx %0,%y2\n"
296
+ "cmpw %0, %3\n"
297
+ "bne- 2f\n"
298
+ "stwcx. %4,%y2\n"
299
+ "bne- 0b\n"
300
+ "addi %1,0,1\n"
301
+ "1:"
302
+
303
+ BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
304
+ : "=&b" (expected), "=&b" (success), "+Z"(v_)
305
+ : "b" (expected), "b" (desired)
306
+ : "cr0"
307
+ );
308
+ if (success)
309
+ ppc_fence_after(success_order);
310
+ else
311
+ ppc_fence_after(failure_order);
312
+ return success;
313
+ }
314
+
315
+ value_type
316
+ fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
317
+ {
318
+ value_type original, tmp;
319
+ ppc_fence_before(order);
320
+ __asm__ (
321
+ "1:\n"
322
+ "lwarx %0,%y2\n"
323
+ "add %1,%0,%3\n"
324
+ "extsb %1, %1\n"
325
+ "stwcx. %1,%y2\n"
326
+ "bne- 1b\n"
327
+ : "=&b" (original), "=&b" (tmp), "+Z"(v_)
328
+ : "b" (v)
329
+ : "cc");
330
+ ppc_fence_after(order);
331
+ return original;
332
+ }
333
+
334
+ value_type
335
+ fetch_sub(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
336
+ {
337
+ value_type original, tmp;
338
+ ppc_fence_before(order);
339
+ __asm__ (
340
+ "1:\n"
341
+ "lwarx %0,%y2\n"
342
+ "sub %1,%0,%3\n"
343
+ "extsb %1, %1\n"
344
+ "stwcx. %1,%y2\n"
345
+ "bne- 1b\n"
346
+ : "=&b" (original), "=&b" (tmp), "+Z"(v_)
347
+ : "b" (v)
348
+ : "cc");
349
+ ppc_fence_after(order);
350
+ return original;
351
+ }
352
+
353
+ value_type
354
+ fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
355
+ {
356
+ value_type original, tmp;
357
+ ppc_fence_before(order);
358
+ __asm__ (
359
+ "1:\n"
360
+ "lwarx %0,%y2\n"
361
+ "and %1,%0,%3\n"
362
+ "stwcx. %1,%y2\n"
363
+ "bne- 1b\n"
364
+ : "=&b" (original), "=&b" (tmp), "+Z"(v_)
365
+ : "b" (v)
366
+ : "cc");
367
+ ppc_fence_after(order);
368
+ return original;
369
+ }
370
+
371
+ value_type
372
+ fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
373
+ {
374
+ value_type original, tmp;
375
+ ppc_fence_before(order);
376
+ __asm__ (
377
+ "1:\n"
378
+ "lwarx %0,%y2\n"
379
+ "or %1,%0,%3\n"
380
+ "stwcx. %1,%y2\n"
381
+ "bne- 1b\n"
382
+ : "=&b" (original), "=&b" (tmp), "+Z"(v_)
383
+ : "b" (v)
384
+ : "cc");
385
+ ppc_fence_after(order);
386
+ return original;
387
+ }
388
+
389
+ value_type
390
+ fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
391
+ {
392
+ value_type original, tmp;
393
+ ppc_fence_before(order);
394
+ __asm__ (
395
+ "1:\n"
396
+ "lwarx %0,%y2\n"
397
+ "xor %1,%0,%3\n"
398
+ "stwcx. %1,%y2\n"
399
+ "bne- 1b\n"
400
+ : "=&b" (original), "=&b" (tmp), "+Z"(v_)
401
+ : "b" (v)
402
+ : "cc");
403
+ ppc_fence_after(order);
404
+ return original;
405
+ }
406
+
407
+ bool
408
+ is_lock_free(void) const volatile BOOST_NOEXCEPT
409
+ {
410
+ return true;
411
+ }
412
+
413
+ BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
414
+ private:
415
+ base_atomic(const base_atomic &) /* = delete */ ;
416
+ void operator=(const base_atomic &) /* = delete */ ;
417
+ storage_type v_;
418
+ };
419
+
420
+ template<typename T>
421
+ class base_atomic<T, int, 1, false>
422
+ {
423
+ typedef base_atomic this_type;
424
+ typedef T value_type;
425
+ typedef uint32_t storage_type;
426
+ typedef T difference_type;
427
+ public:
428
+ BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
429
+ base_atomic(void) {}
430
+
431
+ void
432
+ store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
433
+ {
434
+ ppc_fence_before(order);
435
+ __asm__ (
436
+ "stw %1, %0\n"
437
+ : "+m"(v_)
438
+ : "r" (v)
439
+ );
440
+ ppc_fence_after_store(order);
441
+ }
442
+
443
+ value_type
444
+ load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
445
+ {
446
+ value_type v;
447
+ __asm__ __volatile__ (
448
+ "lwz %0, %1\n"
449
+ "cmpw %0, %0\n"
450
+ "bne- 1f\n"
451
+ "1:\n"
452
+ : "=&r" (v)
453
+ : "m" (v_)
454
+ );
455
+ ppc_fence_after(order);
456
+ return v;
457
+ }
458
+
459
+ value_type
460
+ exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
461
+ {
462
+ value_type original;
463
+ ppc_fence_before(order);
464
+ __asm__ (
465
+ "1:\n"
466
+ "lwarx %0,%y1\n"
467
+ "stwcx. %2,%y1\n"
468
+ "bne- 1b\n"
469
+ : "=&b" (original), "+Z"(v_)
470
+ : "b" (v)
471
+ : "cr0"
472
+ );
473
+ ppc_fence_after(order);
474
+ return original;
475
+ }
476
+
477
+ bool
478
+ compare_exchange_weak(
479
+ value_type & expected,
480
+ value_type desired,
481
+ memory_order success_order,
482
+ memory_order failure_order) volatile BOOST_NOEXCEPT
483
+ {
484
+ int success;
485
+ ppc_fence_before(success_order);
486
+ __asm__(
487
+ "lwarx %0,%y2\n"
488
+ "cmpw %0, %3\n"
489
+ "bne- 2f\n"
490
+ "stwcx. %4,%y2\n"
491
+ "bne- 2f\n"
492
+ "addi %1,0,1\n"
493
+ "1:"
494
+
495
+ BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
496
+ : "=&b" (expected), "=&b" (success), "+Z"(v_)
497
+ : "b" (expected), "b" (desired)
498
+ : "cr0"
499
+ );
500
+ if (success)
501
+ ppc_fence_after(success_order);
502
+ else
503
+ ppc_fence_after(failure_order);
504
+ return success;
505
+ }
506
+
507
+ bool
508
+ compare_exchange_strong(
509
+ value_type & expected,
510
+ value_type desired,
511
+ memory_order success_order,
512
+ memory_order failure_order) volatile BOOST_NOEXCEPT
513
+ {
514
+ int success;
515
+ ppc_fence_before(success_order);
516
+ __asm__(
517
+ "0: lwarx %0,%y2\n"
518
+ "cmpw %0, %3\n"
519
+ "bne- 2f\n"
520
+ "stwcx. %4,%y2\n"
521
+ "bne- 0b\n"
522
+ "addi %1,0,1\n"
523
+ "1:"
524
+
525
+ BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
526
+ : "=&b" (expected), "=&b" (success), "+Z"(v_)
527
+ : "b" (expected), "b" (desired)
528
+ : "cr0"
529
+ );
530
+ if (success)
531
+ ppc_fence_after(success_order);
532
+ else
533
+ ppc_fence_after(failure_order);
534
+ return success;
535
+ }
536
+
537
+ value_type
538
+ fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
539
+ {
540
+ value_type original, tmp;
541
+ ppc_fence_before(order);
542
+ __asm__ (
543
+ "1:\n"
544
+ "lwarx %0,%y2\n"
545
+ "add %1,%0,%3\n"
546
+ "rlwinm %1, %1, 0, 0xff\n"
547
+ "stwcx. %1,%y2\n"
548
+ "bne- 1b\n"
549
+ : "=&b" (original), "=&b" (tmp), "+Z"(v_)
550
+ : "b" (v)
551
+ : "cc");
552
+ ppc_fence_after(order);
553
+ return original;
554
+ }
555
+
556
+ value_type
557
+ fetch_sub(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
558
+ {
559
+ value_type original, tmp;
560
+ ppc_fence_before(order);
561
+ __asm__ (
562
+ "1:\n"
563
+ "lwarx %0,%y2\n"
564
+ "sub %1,%0,%3\n"
565
+ "rlwinm %1, %1, 0, 0xff\n"
566
+ "stwcx. %1,%y2\n"
567
+ "bne- 1b\n"
568
+ : "=&b" (original), "=&b" (tmp), "+Z"(v_)
569
+ : "b" (v)
570
+ : "cc");
571
+ ppc_fence_after(order);
572
+ return original;
573
+ }
574
+
575
+ value_type
576
+ fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
577
+ {
578
+ value_type original, tmp;
579
+ ppc_fence_before(order);
580
+ __asm__ (
581
+ "1:\n"
582
+ "lwarx %0,%y2\n"
583
+ "and %1,%0,%3\n"
584
+ "stwcx. %1,%y2\n"
585
+ "bne- 1b\n"
586
+ : "=&b" (original), "=&b" (tmp), "+Z"(v_)
587
+ : "b" (v)
588
+ : "cc");
589
+ ppc_fence_after(order);
590
+ return original;
591
+ }
592
+
593
+ value_type
594
+ fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
595
+ {
596
+ value_type original, tmp;
597
+ ppc_fence_before(order);
598
+ __asm__ (
599
+ "1:\n"
600
+ "lwarx %0,%y2\n"
601
+ "or %1,%0,%3\n"
602
+ "stwcx. %1,%y2\n"
603
+ "bne- 1b\n"
604
+ : "=&b" (original), "=&b" (tmp), "+Z"(v_)
605
+ : "b" (v)
606
+ : "cc");
607
+ ppc_fence_after(order);
608
+ return original;
609
+ }
610
+
611
+ value_type
612
+ fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
613
+ {
614
+ value_type original, tmp;
615
+ ppc_fence_before(order);
616
+ __asm__ (
617
+ "1:\n"
618
+ "lwarx %0,%y2\n"
619
+ "xor %1,%0,%3\n"
620
+ "stwcx. %1,%y2\n"
621
+ "bne- 1b\n"
622
+ : "=&b" (original), "=&b" (tmp), "+Z"(v_)
623
+ : "b" (v)
624
+ : "cc");
625
+ ppc_fence_after(order);
626
+ return original;
627
+ }
628
+
629
+ bool
630
+ is_lock_free(void) const volatile BOOST_NOEXCEPT
631
+ {
632
+ return true;
633
+ }
634
+
635
+ BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
636
+ private:
637
+ base_atomic(const base_atomic &) /* = delete */ ;
638
+ void operator=(const base_atomic &) /* = delete */ ;
639
+ storage_type v_;
640
+ };
641
+
642
+ template<typename T>
643
+ class base_atomic<T, int, 2, true>
644
+ {
645
+ typedef base_atomic this_type;
646
+ typedef T value_type;
647
+ typedef int32_t storage_type;
648
+ typedef T difference_type;
649
+ public:
650
+ BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
651
+ base_atomic(void) {}
652
+
653
+ void
654
+ store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
655
+ {
656
+ ppc_fence_before(order);
657
+ __asm__ (
658
+ "stw %1, %0\n"
659
+ : "+m"(v_)
660
+ : "r" (v)
661
+ );
662
+ ppc_fence_after_store(order);
663
+ }
664
+
665
+ value_type
666
+ load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
667
+ {
668
+ value_type v;
669
+ __asm__ __volatile__ (
670
+ "lwz %0, %1\n"
671
+ "cmpw %0, %0\n"
672
+ "bne- 1f\n"
673
+ "1:\n"
674
+ : "=&r" (v)
675
+ : "m" (v_)
676
+ );
677
+ ppc_fence_after(order);
678
+ return v;
679
+ }
680
+
681
+ value_type
682
+ exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
683
+ {
684
+ value_type original;
685
+ ppc_fence_before(order);
686
+ __asm__ (
687
+ "1:\n"
688
+ "lwarx %0,%y1\n"
689
+ "stwcx. %2,%y1\n"
690
+ "bne- 1b\n"
691
+ : "=&b" (original), "+Z"(v_)
692
+ : "b" (v)
693
+ : "cr0"
694
+ );
695
+ ppc_fence_after(order);
696
+ return original;
697
+ }
698
+
699
+ bool
700
+ compare_exchange_weak(
701
+ value_type & expected,
702
+ value_type desired,
703
+ memory_order success_order,
704
+ memory_order failure_order) volatile BOOST_NOEXCEPT
705
+ {
706
+ int success;
707
+ ppc_fence_before(success_order);
708
+ __asm__(
709
+ "lwarx %0,%y2\n"
710
+ "cmpw %0, %3\n"
711
+ "bne- 2f\n"
712
+ "stwcx. %4,%y2\n"
713
+ "bne- 2f\n"
714
+ "addi %1,0,1\n"
715
+ "1:"
716
+
717
+ BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
718
+ : "=&b" (expected), "=&b" (success), "+Z"(v_)
719
+ : "b" (expected), "b" (desired)
720
+ : "cr0"
721
+ );
722
+ if (success)
723
+ ppc_fence_after(success_order);
724
+ else
725
+ ppc_fence_after(failure_order);
726
+ return success;
727
+ }
728
+
729
+ bool
730
+ compare_exchange_strong(
731
+ value_type & expected,
732
+ value_type desired,
733
+ memory_order success_order,
734
+ memory_order failure_order) volatile BOOST_NOEXCEPT
735
+ {
736
+ int success;
737
+ ppc_fence_before(success_order);
738
+ __asm__(
739
+ "0: lwarx %0,%y2\n"
740
+ "cmpw %0, %3\n"
741
+ "bne- 2f\n"
742
+ "stwcx. %4,%y2\n"
743
+ "bne- 0b\n"
744
+ "addi %1,0,1\n"
745
+ "1:"
746
+
747
+ BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
748
+ : "=&b" (expected), "=&b" (success), "+Z"(v_)
749
+ : "b" (expected), "b" (desired)
750
+ : "cr0"
751
+ );
752
+ if (success)
753
+ ppc_fence_after(success_order);
754
+ else
755
+ ppc_fence_after(failure_order);
756
+ return success;
757
+ }
758
+
759
+ value_type
760
+ fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
761
+ {
762
+ value_type original, tmp;
763
+ ppc_fence_before(order);
764
+ __asm__ (
765
+ "1:\n"
766
+ "lwarx %0,%y2\n"
767
+ "add %1,%0,%3\n"
768
+ "extsh %1, %1\n"
769
+ "stwcx. %1,%y2\n"
770
+ "bne- 1b\n"
771
+ : "=&b" (original), "=&b" (tmp), "+Z"(v_)
772
+ : "b" (v)
773
+ : "cc");
774
+ ppc_fence_after(order);
775
+ return original;
776
+ }
777
+
778
+ value_type
779
+ fetch_sub(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
780
+ {
781
+ value_type original, tmp;
782
+ ppc_fence_before(order);
783
+ __asm__ (
784
+ "1:\n"
785
+ "lwarx %0,%y2\n"
786
+ "sub %1,%0,%3\n"
787
+ "extsh %1, %1\n"
788
+ "stwcx. %1,%y2\n"
789
+ "bne- 1b\n"
790
+ : "=&b" (original), "=&b" (tmp), "+Z"(v_)
791
+ : "b" (v)
792
+ : "cc");
793
+ ppc_fence_after(order);
794
+ return original;
795
+ }
796
+
797
+ value_type
798
+ fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
799
+ {
800
+ value_type original, tmp;
801
+ ppc_fence_before(order);
802
+ __asm__ (
803
+ "1:\n"
804
+ "lwarx %0,%y2\n"
805
+ "and %1,%0,%3\n"
806
+ "stwcx. %1,%y2\n"
807
+ "bne- 1b\n"
808
+ : "=&b" (original), "=&b" (tmp), "+Z"(v_)
809
+ : "b" (v)
810
+ : "cc");
811
+ ppc_fence_after(order);
812
+ return original;
813
+ }
814
+
815
+ value_type
816
+ fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
817
+ {
818
+ value_type original, tmp;
819
+ ppc_fence_before(order);
820
+ __asm__ (
821
+ "1:\n"
822
+ "lwarx %0,%y2\n"
823
+ "or %1,%0,%3\n"
824
+ "stwcx. %1,%y2\n"
825
+ "bne- 1b\n"
826
+ : "=&b" (original), "=&b" (tmp), "+Z"(v_)
827
+ : "b" (v)
828
+ : "cc");
829
+ ppc_fence_after(order);
830
+ return original;
831
+ }
832
+
833
+ value_type
834
+ fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
835
+ {
836
+ value_type original, tmp;
837
+ ppc_fence_before(order);
838
+ __asm__ (
839
+ "1:\n"
840
+ "lwarx %0,%y2\n"
841
+ "xor %1,%0,%3\n"
842
+ "stwcx. %1,%y2\n"
843
+ "bne- 1b\n"
844
+ : "=&b" (original), "=&b" (tmp), "+Z"(v_)
845
+ : "b" (v)
846
+ : "cc");
847
+ ppc_fence_after(order);
848
+ return original;
849
+ }
850
+
851
+ bool
852
+ is_lock_free(void) const volatile BOOST_NOEXCEPT
853
+ {
854
+ return true;
855
+ }
856
+
857
+ BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
858
+ private:
859
+ base_atomic(const base_atomic &) /* = delete */ ;
860
+ void operator=(const base_atomic &) /* = delete */ ;
861
+ storage_type v_;
862
+ };
863
+
864
+ template<typename T>
865
+ class base_atomic<T, int, 2, false>
866
+ {
867
+ typedef base_atomic this_type;
868
+ typedef T value_type;
869
+ typedef uint32_t storage_type;
870
+ typedef T difference_type;
871
+ public:
872
+ BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
873
+ base_atomic(void) {}
874
+
875
+ void
876
+ store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
877
+ {
878
+ ppc_fence_before(order);
879
+ __asm__ (
880
+ "stw %1, %0\n"
881
+ : "+m"(v_)
882
+ : "r" (v)
883
+ );
884
+ ppc_fence_after_store(order);
885
+ }
886
+
887
+ value_type
888
+ load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
889
+ {
890
+ value_type v;
891
+ __asm__ __volatile__ (
892
+ "lwz %0, %1\n"
893
+ "cmpw %0, %0\n"
894
+ "bne- 1f\n"
895
+ "1:\n"
896
+ : "=&r" (v)
897
+ : "m" (v_)
898
+ );
899
+ ppc_fence_after(order);
900
+ return v;
901
+ }
902
+
903
+ value_type
904
+ exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
905
+ {
906
+ value_type original;
907
+ ppc_fence_before(order);
908
+ __asm__ (
909
+ "1:\n"
910
+ "lwarx %0,%y1\n"
911
+ "stwcx. %2,%y1\n"
912
+ "bne- 1b\n"
913
+ : "=&b" (original), "+Z"(v_)
914
+ : "b" (v)
915
+ : "cr0"
916
+ );
917
+ ppc_fence_after(order);
918
+ return original;
919
+ }
920
+
921
+ bool
922
+ compare_exchange_weak(
923
+ value_type & expected,
924
+ value_type desired,
925
+ memory_order success_order,
926
+ memory_order failure_order) volatile BOOST_NOEXCEPT
927
+ {
928
+ int success;
929
+ ppc_fence_before(success_order);
930
+ __asm__(
931
+ "lwarx %0,%y2\n"
932
+ "cmpw %0, %3\n"
933
+ "bne- 2f\n"
934
+ "stwcx. %4,%y2\n"
935
+ "bne- 2f\n"
936
+ "addi %1,0,1\n"
937
+ "1:"
938
+
939
+ BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
940
+ : "=&b" (expected), "=&b" (success), "+Z"(v_)
941
+ : "b" (expected), "b" (desired)
942
+ : "cr0"
943
+ );
944
+ if (success)
945
+ ppc_fence_after(success_order);
946
+ else
947
+ ppc_fence_after(failure_order);
948
+ return success;
949
+ }
950
+
951
+ bool
952
+ compare_exchange_strong(
953
+ value_type & expected,
954
+ value_type desired,
955
+ memory_order success_order,
956
+ memory_order failure_order) volatile BOOST_NOEXCEPT
957
+ {
958
+ int success;
959
+ ppc_fence_before(success_order);
960
+ __asm__(
961
+ "0: lwarx %0,%y2\n"
962
+ "cmpw %0, %3\n"
963
+ "bne- 2f\n"
964
+ "stwcx. %4,%y2\n"
965
+ "bne- 0b\n"
966
+ "addi %1,0,1\n"
967
+ "1:"
968
+
969
+ BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
970
+ : "=&b" (expected), "=&b" (success), "+Z"(v_)
971
+ : "b" (expected), "b" (desired)
972
+ : "cr0"
973
+ );
974
+ if (success)
975
+ ppc_fence_after(success_order);
976
+ else
977
+ ppc_fence_after(failure_order);
978
+ return success;
979
+ }
980
+
981
+ value_type
982
+ fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
983
+ {
984
+ value_type original, tmp;
985
+ ppc_fence_before(order);
986
+ __asm__ (
987
+ "1:\n"
988
+ "lwarx %0,%y2\n"
989
+ "add %1,%0,%3\n"
990
+ "rlwinm %1, %1, 0, 0xffff\n"
991
+ "stwcx. %1,%y2\n"
992
+ "bne- 1b\n"
993
+ : "=&b" (original), "=&b" (tmp), "+Z"(v_)
994
+ : "b" (v)
995
+ : "cc");
996
+ ppc_fence_after(order);
997
+ return original;
998
+ }
999
+
1000
+ value_type
1001
+ fetch_sub(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1002
+ {
1003
+ value_type original, tmp;
1004
+ ppc_fence_before(order);
1005
+ __asm__ (
1006
+ "1:\n"
1007
+ "lwarx %0,%y2\n"
1008
+ "sub %1,%0,%3\n"
1009
+ "rlwinm %1, %1, 0, 0xffff\n"
1010
+ "stwcx. %1,%y2\n"
1011
+ "bne- 1b\n"
1012
+ : "=&b" (original), "=&b" (tmp), "+Z"(v_)
1013
+ : "b" (v)
1014
+ : "cc");
1015
+ ppc_fence_after(order);
1016
+ return original;
1017
+ }
1018
+
1019
+ value_type
1020
+ fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1021
+ {
1022
+ value_type original, tmp;
1023
+ ppc_fence_before(order);
1024
+ __asm__ (
1025
+ "1:\n"
1026
+ "lwarx %0,%y2\n"
1027
+ "and %1,%0,%3\n"
1028
+ "stwcx. %1,%y2\n"
1029
+ "bne- 1b\n"
1030
+ : "=&b" (original), "=&b" (tmp), "+Z"(v_)
1031
+ : "b" (v)
1032
+ : "cc");
1033
+ ppc_fence_after(order);
1034
+ return original;
1035
+ }
1036
+
1037
+ value_type
1038
+ fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1039
+ {
1040
+ value_type original, tmp;
1041
+ ppc_fence_before(order);
1042
+ __asm__ (
1043
+ "1:\n"
1044
+ "lwarx %0,%y2\n"
1045
+ "or %1,%0,%3\n"
1046
+ "stwcx. %1,%y2\n"
1047
+ "bne- 1b\n"
1048
+ : "=&b" (original), "=&b" (tmp), "+Z"(v_)
1049
+ : "b" (v)
1050
+ : "cc");
1051
+ ppc_fence_after(order);
1052
+ return original;
1053
+ }
1054
+
1055
+ value_type
1056
+ fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1057
+ {
1058
+ value_type original, tmp;
1059
+ ppc_fence_before(order);
1060
+ __asm__ (
1061
+ "1:\n"
1062
+ "lwarx %0,%y2\n"
1063
+ "xor %1,%0,%3\n"
1064
+ "stwcx. %1,%y2\n"
1065
+ "bne- 1b\n"
1066
+ : "=&b" (original), "=&b" (tmp), "+Z"(v_)
1067
+ : "b" (v)
1068
+ : "cc");
1069
+ ppc_fence_after(order);
1070
+ return original;
1071
+ }
1072
+
1073
+ bool
1074
+ is_lock_free(void) const volatile BOOST_NOEXCEPT
1075
+ {
1076
+ return true;
1077
+ }
1078
+
1079
+ BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
1080
+ private:
1081
+ base_atomic(const base_atomic &) /* = delete */ ;
1082
+ void operator=(const base_atomic &) /* = delete */ ;
1083
+ storage_type v_;
1084
+ };
1085
+
1086
+ template<typename T, bool Sign>
1087
+ class base_atomic<T, int, 4, Sign>
1088
+ {
1089
+ typedef base_atomic this_type;
1090
+ typedef T value_type;
1091
+ typedef T difference_type;
1092
+ public:
1093
+ BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
1094
+ base_atomic(void) {}
1095
+
1096
+ void
1097
+ store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1098
+ {
1099
+ ppc_fence_before(order);
1100
+ const_cast<volatile value_type &>(v_) = v;
1101
+ ppc_fence_after_store(order);
1102
+ }
1103
+
1104
+ value_type
1105
+ load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
1106
+ {
1107
+ value_type v = const_cast<const volatile value_type &>(v_);
1108
+ __asm__ __volatile__ (
1109
+ "cmpw %0, %0\n"
1110
+ "bne- 1f\n"
1111
+ "1:\n"
1112
+ : "+b"(v)
1113
+ :
1114
+ : "cr0"
1115
+ );
1116
+ ppc_fence_after(order);
1117
+ return v;
1118
+ }
1119
+
1120
+ value_type
1121
+ exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1122
+ {
1123
+ value_type original;
1124
+ ppc_fence_before(order);
1125
+ __asm__ (
1126
+ "1:\n"
1127
+ "lwarx %0,%y1\n"
1128
+ "stwcx. %2,%y1\n"
1129
+ "bne- 1b\n"
1130
+ : "=&b" (original), "+Z"(v_)
1131
+ : "b" (v)
1132
+ : "cr0"
1133
+ );
1134
+ ppc_fence_after(order);
1135
+ return original;
1136
+ }
1137
+
1138
+ bool
1139
+ compare_exchange_weak(
1140
+ value_type & expected,
1141
+ value_type desired,
1142
+ memory_order success_order,
1143
+ memory_order failure_order) volatile BOOST_NOEXCEPT
1144
+ {
1145
+ int success;
1146
+ ppc_fence_before(success_order);
1147
+ __asm__(
1148
+ "lwarx %0,%y2\n"
1149
+ "cmpw %0, %3\n"
1150
+ "bne- 2f\n"
1151
+ "stwcx. %4,%y2\n"
1152
+ "bne- 2f\n"
1153
+ "addi %1,0,1\n"
1154
+ "1:"
1155
+
1156
+ BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
1157
+ : "=&b" (expected), "=&b" (success), "+Z"(v_)
1158
+ : "b" (expected), "b" (desired)
1159
+ : "cr0"
1160
+ );
1161
+ if (success)
1162
+ ppc_fence_after(success_order);
1163
+ else
1164
+ ppc_fence_after(failure_order);
1165
+ return success;
1166
+ }
1167
+
1168
+ bool
1169
+ compare_exchange_strong(
1170
+ value_type & expected,
1171
+ value_type desired,
1172
+ memory_order success_order,
1173
+ memory_order failure_order) volatile BOOST_NOEXCEPT
1174
+ {
1175
+ int success;
1176
+ ppc_fence_before(success_order);
1177
+ __asm__(
1178
+ "0: lwarx %0,%y2\n"
1179
+ "cmpw %0, %3\n"
1180
+ "bne- 2f\n"
1181
+ "stwcx. %4,%y2\n"
1182
+ "bne- 0b\n"
1183
+ "addi %1,0,1\n"
1184
+ "1:"
1185
+
1186
+ BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
1187
+ : "=&b" (expected), "=&b" (success), "+Z"(v_)
1188
+ : "b" (expected), "b" (desired)
1189
+ : "cr0"
1190
+ );
1191
+ if (success)
1192
+ ppc_fence_after(success_order);
1193
+ else
1194
+ ppc_fence_after(failure_order);
1195
+ return success;
1196
+ }
1197
+
1198
+ value_type
1199
+ fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1200
+ {
1201
+ value_type original, tmp;
1202
+ ppc_fence_before(order);
1203
+ __asm__ (
1204
+ "1:\n"
1205
+ "lwarx %0,%y2\n"
1206
+ "add %1,%0,%3\n"
1207
+ "stwcx. %1,%y2\n"
1208
+ "bne- 1b\n"
1209
+ : "=&b" (original), "=&b" (tmp), "+Z"(v_)
1210
+ : "b" (v)
1211
+ : "cc");
1212
+ ppc_fence_after(order);
1213
+ return original;
1214
+ }
1215
+
1216
+ value_type
1217
+ fetch_sub(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1218
+ {
1219
+ value_type original, tmp;
1220
+ ppc_fence_before(order);
1221
+ __asm__ (
1222
+ "1:\n"
1223
+ "lwarx %0,%y2\n"
1224
+ "sub %1,%0,%3\n"
1225
+ "stwcx. %1,%y2\n"
1226
+ "bne- 1b\n"
1227
+ : "=&b" (original), "=&b" (tmp), "+Z"(v_)
1228
+ : "b" (v)
1229
+ : "cc");
1230
+ ppc_fence_after(order);
1231
+ return original;
1232
+ }
1233
+
1234
+ value_type
1235
+ fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1236
+ {
1237
+ value_type original, tmp;
1238
+ ppc_fence_before(order);
1239
+ __asm__ (
1240
+ "1:\n"
1241
+ "lwarx %0,%y2\n"
1242
+ "and %1,%0,%3\n"
1243
+ "stwcx. %1,%y2\n"
1244
+ "bne- 1b\n"
1245
+ : "=&b" (original), "=&b" (tmp), "+Z"(v_)
1246
+ : "b" (v)
1247
+ : "cc");
1248
+ ppc_fence_after(order);
1249
+ return original;
1250
+ }
1251
+
1252
+ value_type
1253
+ fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1254
+ {
1255
+ value_type original, tmp;
1256
+ ppc_fence_before(order);
1257
+ __asm__ (
1258
+ "1:\n"
1259
+ "lwarx %0,%y2\n"
1260
+ "or %1,%0,%3\n"
1261
+ "stwcx. %1,%y2\n"
1262
+ "bne- 1b\n"
1263
+ : "=&b" (original), "=&b" (tmp), "+Z"(v_)
1264
+ : "b" (v)
1265
+ : "cc");
1266
+ ppc_fence_after(order);
1267
+ return original;
1268
+ }
1269
+
1270
+ value_type
1271
+ fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1272
+ {
1273
+ value_type original, tmp;
1274
+ ppc_fence_before(order);
1275
+ __asm__ (
1276
+ "1:\n"
1277
+ "lwarx %0,%y2\n"
1278
+ "xor %1,%0,%3\n"
1279
+ "stwcx. %1,%y2\n"
1280
+ "bne- 1b\n"
1281
+ : "=&b" (original), "=&b" (tmp), "+Z"(v_)
1282
+ : "b" (v)
1283
+ : "cc");
1284
+ ppc_fence_after(order);
1285
+ return original;
1286
+ }
1287
+
1288
+ bool
1289
+ is_lock_free(void) const volatile BOOST_NOEXCEPT
1290
+ {
1291
+ return true;
1292
+ }
1293
+
1294
+ BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
1295
+ private:
1296
+ base_atomic(const base_atomic &) /* = delete */ ;
1297
+ void operator=(const base_atomic &) /* = delete */ ;
1298
+ value_type v_;
1299
+ };
1300
+
1301
+ #if defined(__powerpc64__)
1302
+
1303
+ template<typename T, bool Sign>
1304
+ class base_atomic<T, int, 8, Sign>
1305
+ {
1306
+ typedef base_atomic this_type;
1307
+ typedef T value_type;
1308
+ typedef T difference_type;
1309
+ public:
1310
+ BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
1311
+ base_atomic(void) {}
1312
+
1313
+ void
1314
+ store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1315
+ {
1316
+ ppc_fence_before(order);
1317
+ const_cast<volatile value_type &>(v_) = v;
1318
+ ppc_fence_after_store(order);
1319
+ }
1320
+
1321
+ value_type
1322
+ load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
1323
+ {
1324
+ value_type v = const_cast<const volatile value_type &>(v_);
1325
+ __asm__ __volatile__ (
1326
+ "cmpd %0, %0\n"
1327
+ "bne- 1f\n"
1328
+ "1:\n"
1329
+ : "+b"(v)
1330
+ :
1331
+ : "cr0"
1332
+ );
1333
+ ppc_fence_after(order);
1334
+ return v;
1335
+ }
1336
+
1337
+ value_type
1338
+ exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1339
+ {
1340
+ value_type original;
1341
+ ppc_fence_before(order);
1342
+ __asm__ (
1343
+ "1:\n"
1344
+ "ldarx %0,%y1\n"
1345
+ "stdcx. %2,%y1\n"
1346
+ "bne- 1b\n"
1347
+ : "=&b" (original), "+Z"(v_)
1348
+ : "b" (v)
1349
+ : "cr0"
1350
+ );
1351
+ ppc_fence_after(order);
1352
+ return original;
1353
+ }
1354
+
1355
+ bool
1356
+ compare_exchange_weak(
1357
+ value_type & expected,
1358
+ value_type desired,
1359
+ memory_order success_order,
1360
+ memory_order failure_order) volatile BOOST_NOEXCEPT
1361
+ {
1362
+ int success;
1363
+ ppc_fence_before(success_order);
1364
+ __asm__(
1365
+ "ldarx %0,%y2\n"
1366
+ "cmpd %0, %3\n"
1367
+ "bne- 2f\n"
1368
+ "stdcx. %4,%y2\n"
1369
+ "bne- 2f\n"
1370
+ "addi %1,0,1\n"
1371
+ "1:"
1372
+
1373
+ BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
1374
+ : "=&b" (expected), "=&b" (success), "+Z"(v_)
1375
+ : "b" (expected), "b" (desired)
1376
+ : "cr0"
1377
+ );
1378
+ if (success)
1379
+ ppc_fence_after(success_order);
1380
+ else
1381
+ ppc_fence_after(failure_order);
1382
+ return success;
1383
+ }
1384
+
1385
+ bool
1386
+ compare_exchange_strong(
1387
+ value_type & expected,
1388
+ value_type desired,
1389
+ memory_order success_order,
1390
+ memory_order failure_order) volatile BOOST_NOEXCEPT
1391
+ {
1392
+ int success;
1393
+ ppc_fence_before(success_order);
1394
+ __asm__(
1395
+ "0: ldarx %0,%y2\n"
1396
+ "cmpd %0, %3\n"
1397
+ "bne- 2f\n"
1398
+ "stdcx. %4,%y2\n"
1399
+ "bne- 0b\n"
1400
+ "addi %1,0,1\n"
1401
+ "1:"
1402
+
1403
+ BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
1404
+ : "=&b" (expected), "=&b" (success), "+Z"(v_)
1405
+ : "b" (expected), "b" (desired)
1406
+ : "cr0"
1407
+ );
1408
+ if (success)
1409
+ ppc_fence_after(success_order);
1410
+ else
1411
+ ppc_fence_after(failure_order);
1412
+ return success;
1413
+ }
1414
+
1415
+ value_type
1416
+ fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1417
+ {
1418
+ value_type original, tmp;
1419
+ ppc_fence_before(order);
1420
+ __asm__ (
1421
+ "1:\n"
1422
+ "ldarx %0,%y2\n"
1423
+ "add %1,%0,%3\n"
1424
+ "stdcx. %1,%y2\n"
1425
+ "bne- 1b\n"
1426
+ : "=&b" (original), "=&b" (tmp), "+Z"(v_)
1427
+ : "b" (v)
1428
+ : "cc");
1429
+ ppc_fence_after(order);
1430
+ return original;
1431
+ }
1432
+
1433
+ value_type
1434
+ fetch_sub(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1435
+ {
1436
+ value_type original, tmp;
1437
+ ppc_fence_before(order);
1438
+ __asm__ (
1439
+ "1:\n"
1440
+ "ldarx %0,%y2\n"
1441
+ "sub %1,%0,%3\n"
1442
+ "stdcx. %1,%y2\n"
1443
+ "bne- 1b\n"
1444
+ : "=&b" (original), "=&b" (tmp), "+Z"(v_)
1445
+ : "b" (v)
1446
+ : "cc");
1447
+ ppc_fence_after(order);
1448
+ return original;
1449
+ }
1450
+
1451
+ value_type
1452
+ fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1453
+ {
1454
+ value_type original, tmp;
1455
+ ppc_fence_before(order);
1456
+ __asm__ (
1457
+ "1:\n"
1458
+ "ldarx %0,%y2\n"
1459
+ "and %1,%0,%3\n"
1460
+ "stdcx. %1,%y2\n"
1461
+ "bne- 1b\n"
1462
+ : "=&b" (original), "=&b" (tmp), "+Z"(v_)
1463
+ : "b" (v)
1464
+ : "cc");
1465
+ ppc_fence_after(order);
1466
+ return original;
1467
+ }
1468
+
1469
+ value_type
1470
+ fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1471
+ {
1472
+ value_type original, tmp;
1473
+ ppc_fence_before(order);
1474
+ __asm__ (
1475
+ "1:\n"
1476
+ "ldarx %0,%y2\n"
1477
+ "or %1,%0,%3\n"
1478
+ "stdcx. %1,%y2\n"
1479
+ "bne- 1b\n"
1480
+ : "=&b" (original), "=&b" (tmp), "+Z"(v_)
1481
+ : "b" (v)
1482
+ : "cc");
1483
+ ppc_fence_after(order);
1484
+ return original;
1485
+ }
1486
+
1487
+ value_type
1488
+ fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1489
+ {
1490
+ value_type original, tmp;
1491
+ ppc_fence_before(order);
1492
+ __asm__ (
1493
+ "1:\n"
1494
+ "ldarx %0,%y2\n"
1495
+ "xor %1,%0,%3\n"
1496
+ "stdcx. %1,%y2\n"
1497
+ "bne- 1b\n"
1498
+ : "=&b" (original), "=&b" (tmp), "+Z"(v_)
1499
+ : "b" (v)
1500
+ : "cc");
1501
+ ppc_fence_after(order);
1502
+ return original;
1503
+ }
1504
+
1505
+ bool
1506
+ is_lock_free(void) const volatile BOOST_NOEXCEPT
1507
+ {
1508
+ return true;
1509
+ }
1510
+
1511
+ BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
1512
+ private:
1513
+ base_atomic(const base_atomic &) /* = delete */ ;
1514
+ void operator=(const base_atomic &) /* = delete */ ;
1515
+ value_type v_;
1516
+ };
1517
+
1518
+ #endif
1519
+
1520
+ /* pointer types */
1521
+
1522
+ #if !defined(__powerpc64__)
1523
+
1524
+ template<bool Sign>
1525
+ class base_atomic<void *, void *, 4, Sign>
1526
+ {
1527
+ typedef base_atomic this_type;
1528
+ typedef ptrdiff_t difference_type;
1529
+ typedef void * value_type;
1530
+ public:
1531
+ BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
1532
+ base_atomic(void) {}
1533
+
1534
+ void
1535
+ store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1536
+ {
1537
+ ppc_fence_before(order);
1538
+ __asm__ (
1539
+ "stw %1, %0\n"
1540
+ : "+m" (v_)
1541
+ : "r" (v)
1542
+ );
1543
+ ppc_fence_after_store(order);
1544
+ }
1545
+
1546
+ value_type
1547
+ load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
1548
+ {
1549
+ value_type v;
1550
+ __asm__ (
1551
+ "lwz %0, %1\n"
1552
+ "cmpw %0, %0\n"
1553
+ "bne- 1f\n"
1554
+ "1:\n"
1555
+ : "=r"(v)
1556
+ : "m"(v_)
1557
+ : "cr0"
1558
+ );
1559
+ ppc_fence_after(order);
1560
+ return v;
1561
+ }
1562
+
1563
+ value_type
1564
+ exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1565
+ {
1566
+ value_type original;
1567
+ ppc_fence_before(order);
1568
+ __asm__ (
1569
+ "1:\n"
1570
+ "lwarx %0,%y1\n"
1571
+ "stwcx. %2,%y1\n"
1572
+ "bne- 1b\n"
1573
+ : "=&b" (original), "+Z"(v_)
1574
+ : "b" (v)
1575
+ : "cr0"
1576
+ );
1577
+ ppc_fence_after(order);
1578
+ return original;
1579
+ }
1580
+
1581
+ bool
1582
+ compare_exchange_weak(
1583
+ value_type & expected,
1584
+ value_type desired,
1585
+ memory_order success_order,
1586
+ memory_order failure_order) volatile BOOST_NOEXCEPT
1587
+ {
1588
+ int success;
1589
+ ppc_fence_before(success_order);
1590
+ __asm__(
1591
+ "lwarx %0,%y2\n"
1592
+ "cmpw %0, %3\n"
1593
+ "bne- 2f\n"
1594
+ "stwcx. %4,%y2\n"
1595
+ "bne- 2f\n"
1596
+ "addi %1,0,1\n"
1597
+ "1:"
1598
+
1599
+ BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
1600
+ : "=&b" (expected), "=&b" (success), "+Z"(v_)
1601
+ : "b" (expected), "b" (desired)
1602
+ : "cr0"
1603
+ );
1604
+ if (success)
1605
+ ppc_fence_after(success_order);
1606
+ else
1607
+ ppc_fence_after(failure_order);
1608
+ return success;
1609
+ }
1610
+
1611
+ bool
1612
+ compare_exchange_strong(
1613
+ value_type & expected,
1614
+ value_type desired,
1615
+ memory_order success_order,
1616
+ memory_order failure_order) volatile BOOST_NOEXCEPT
1617
+ {
1618
+ int success;
1619
+ ppc_fence_before(success_order);
1620
+ __asm__(
1621
+ "0: lwarx %0,%y2\n"
1622
+ "cmpw %0, %3\n"
1623
+ "bne- 2f\n"
1624
+ "stwcx. %4,%y2\n"
1625
+ "bne- 0b\n"
1626
+ "addi %1,0,1\n"
1627
+ "1:"
1628
+
1629
+ BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
1630
+ : "=&b" (expected), "=&b" (success), "+Z"(v_)
1631
+ : "b" (expected), "b" (desired)
1632
+ : "cr0"
1633
+ );
1634
+ if (success)
1635
+ ppc_fence_after(success_order);
1636
+ else
1637
+ ppc_fence_after(failure_order);
1638
+ return success;
1639
+ }
1640
+
1641
+ bool
1642
+ is_lock_free(void) const volatile BOOST_NOEXCEPT
1643
+ {
1644
+ return true;
1645
+ }
1646
+
1647
+ value_type
1648
+ fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1649
+ {
1650
+ value_type original, tmp;
1651
+ ppc_fence_before(order);
1652
+ __asm__ (
1653
+ "1:\n"
1654
+ "lwarx %0,%y2\n"
1655
+ "add %1,%0,%3\n"
1656
+ "stwcx. %1,%y2\n"
1657
+ "bne- 1b\n"
1658
+ : "=&b" (original), "=&b" (tmp), "+Z"(v_)
1659
+ : "b" (v)
1660
+ : "cc");
1661
+ ppc_fence_after(order);
1662
+ return original;
1663
+ }
1664
+
1665
+ value_type
1666
+ fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1667
+ {
1668
+ value_type original, tmp;
1669
+ ppc_fence_before(order);
1670
+ __asm__ (
1671
+ "1:\n"
1672
+ "lwarx %0,%y2\n"
1673
+ "sub %1,%0,%3\n"
1674
+ "stwcx. %1,%y2\n"
1675
+ "bne- 1b\n"
1676
+ : "=&b" (original), "=&b" (tmp), "+Z"(v_)
1677
+ : "b" (v)
1678
+ : "cc");
1679
+ ppc_fence_after(order);
1680
+ return original;
1681
+ }
1682
+
1683
+ BOOST_ATOMIC_DECLARE_VOID_POINTER_OPERATORS
1684
+ private:
1685
+ base_atomic(const base_atomic &) /* = delete */ ;
1686
+ void operator=(const base_atomic &) /* = delete */ ;
1687
+ value_type v_;
1688
+ };
1689
+
1690
+ template<typename T, bool Sign>
1691
+ class base_atomic<T *, void *, 4, Sign>
1692
+ {
1693
+ typedef base_atomic this_type;
1694
+ typedef T * value_type;
1695
+ typedef ptrdiff_t difference_type;
1696
+ public:
1697
+ BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
1698
+ base_atomic(void) {}
1699
+
1700
+ void
1701
+ store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1702
+ {
1703
+ ppc_fence_before(order);
1704
+ __asm__ (
1705
+ "stw %1, %0\n"
1706
+ : "+m" (v_)
1707
+ : "r" (v)
1708
+ );
1709
+ ppc_fence_after_store(order);
1710
+ }
1711
+
1712
+ value_type
1713
+ load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
1714
+ {
1715
+ value_type v;
1716
+ __asm__ (
1717
+ "lwz %0, %1\n"
1718
+ "cmpw %0, %0\n"
1719
+ "bne- 1f\n"
1720
+ "1:\n"
1721
+ : "=r"(v)
1722
+ : "m"(v_)
1723
+ : "cr0"
1724
+ );
1725
+ ppc_fence_after(order);
1726
+ return v;
1727
+ }
1728
+
1729
+ value_type
1730
+ exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1731
+ {
1732
+ value_type original;
1733
+ ppc_fence_before(order);
1734
+ __asm__ (
1735
+ "1:\n"
1736
+ "lwarx %0,%y1\n"
1737
+ "stwcx. %2,%y1\n"
1738
+ "bne- 1b\n"
1739
+ : "=&b" (original), "+Z"(v_)
1740
+ : "b" (v)
1741
+ : "cr0"
1742
+ );
1743
+ ppc_fence_after(order);
1744
+ return original;
1745
+ }
1746
+
1747
+ bool
1748
+ compare_exchange_weak(
1749
+ value_type & expected,
1750
+ value_type desired,
1751
+ memory_order success_order,
1752
+ memory_order failure_order) volatile BOOST_NOEXCEPT
1753
+ {
1754
+ int success;
1755
+ ppc_fence_before(success_order);
1756
+ __asm__(
1757
+ "lwarx %0,%y2\n"
1758
+ "cmpw %0, %3\n"
1759
+ "bne- 2f\n"
1760
+ "stwcx. %4,%y2\n"
1761
+ "bne- 2f\n"
1762
+ "addi %1,0,1\n"
1763
+ "1:"
1764
+
1765
+ BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
1766
+ : "=&b" (expected), "=&b" (success), "+Z"(v_)
1767
+ : "b" (expected), "b" (desired)
1768
+ : "cr0"
1769
+ );
1770
+ if (success)
1771
+ ppc_fence_after(success_order);
1772
+ else
1773
+ ppc_fence_after(failure_order);
1774
+ return success;
1775
+ }
1776
+
1777
+ bool
1778
+ compare_exchange_strong(
1779
+ value_type & expected,
1780
+ value_type desired,
1781
+ memory_order success_order,
1782
+ memory_order failure_order) volatile BOOST_NOEXCEPT
1783
+ {
1784
+ int success;
1785
+ ppc_fence_before(success_order);
1786
+ __asm__(
1787
+ "0: lwarx %0,%y2\n"
1788
+ "cmpw %0, %3\n"
1789
+ "bne- 2f\n"
1790
+ "stwcx. %4,%y2\n"
1791
+ "bne- 0b\n"
1792
+ "addi %1,0,1\n"
1793
+ "1:"
1794
+
1795
+ BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
1796
+ : "=&b" (expected), "=&b" (success), "+Z"(v_)
1797
+ : "b" (expected), "b" (desired)
1798
+ : "cr0"
1799
+ );
1800
+ if (success)
1801
+ ppc_fence_after(success_order);
1802
+ else
1803
+ ppc_fence_after(failure_order);
1804
+ return success;
1805
+ }
1806
+
1807
+ value_type
1808
+ fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1809
+ {
1810
+ v = v * sizeof(*v_);
1811
+ value_type original, tmp;
1812
+ ppc_fence_before(order);
1813
+ __asm__ (
1814
+ "1:\n"
1815
+ "lwarx %0,%y2\n"
1816
+ "add %1,%0,%3\n"
1817
+ "stwcx. %1,%y2\n"
1818
+ "bne- 1b\n"
1819
+ : "=&b" (original), "=&b" (tmp), "+Z"(v_)
1820
+ : "b" (v)
1821
+ : "cc");
1822
+ ppc_fence_after(order);
1823
+ return original;
1824
+ }
1825
+
1826
+ value_type
1827
+ fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1828
+ {
1829
+ v = v * sizeof(*v_);
1830
+ value_type original, tmp;
1831
+ ppc_fence_before(order);
1832
+ __asm__ (
1833
+ "1:\n"
1834
+ "lwarx %0,%y2\n"
1835
+ "sub %1,%0,%3\n"
1836
+ "stwcx. %1,%y2\n"
1837
+ "bne- 1b\n"
1838
+ : "=&b" (original), "=&b" (tmp), "+Z"(v_)
1839
+ : "b" (v)
1840
+ : "cc");
1841
+ ppc_fence_after(order);
1842
+ return original;
1843
+ }
1844
+
1845
+ bool
1846
+ is_lock_free(void) const volatile BOOST_NOEXCEPT
1847
+ {
1848
+ return true;
1849
+ }
1850
+
1851
+ BOOST_ATOMIC_DECLARE_POINTER_OPERATORS
1852
+ private:
1853
+ base_atomic(const base_atomic &) /* = delete */ ;
1854
+ void operator=(const base_atomic &) /* = delete */ ;
1855
+ value_type v_;
1856
+ };
1857
+
1858
+ #else
1859
+
1860
+ template<bool Sign>
1861
+ class base_atomic<void *, void *, 8, Sign>
1862
+ {
1863
+ typedef base_atomic this_type;
1864
+ typedef ptrdiff_t difference_type;
1865
+ typedef void * value_type;
1866
+ public:
1867
+ BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
1868
+ base_atomic(void) {}
1869
+
1870
+ void
1871
+ store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1872
+ {
1873
+ ppc_fence_before(order);
1874
+ __asm__ (
1875
+ "std %1, %0\n"
1876
+ : "+m" (v_)
1877
+ : "r" (v)
1878
+ );
1879
+ ppc_fence_after_store(order);
1880
+ }
1881
+
1882
+ value_type
1883
+ load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
1884
+ {
1885
+ value_type v;
1886
+ __asm__ (
1887
+ "ld %0, %1\n"
1888
+ "cmpd %0, %0\n"
1889
+ "bne- 1f\n"
1890
+ "1:\n"
1891
+ : "=r"(v)
1892
+ : "m"(v_)
1893
+ : "cr0"
1894
+ );
1895
+ ppc_fence_after(order);
1896
+ return v;
1897
+ }
1898
+
1899
+ value_type
1900
+ exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1901
+ {
1902
+ value_type original;
1903
+ ppc_fence_before(order);
1904
+ __asm__ (
1905
+ "1:\n"
1906
+ "ldarx %0,%y1\n"
1907
+ "stdcx. %2,%y1\n"
1908
+ "bne- 1b\n"
1909
+ : "=&b" (original), "+Z"(v_)
1910
+ : "b" (v)
1911
+ : "cr0"
1912
+ );
1913
+ ppc_fence_after(order);
1914
+ return original;
1915
+ }
1916
+
1917
+ bool
1918
+ compare_exchange_weak(
1919
+ value_type & expected,
1920
+ value_type desired,
1921
+ memory_order success_order,
1922
+ memory_order failure_order) volatile BOOST_NOEXCEPT
1923
+ {
1924
+ int success;
1925
+ ppc_fence_before(success_order);
1926
+ __asm__(
1927
+ "ldarx %0,%y2\n"
1928
+ "cmpd %0, %3\n"
1929
+ "bne- 2f\n"
1930
+ "stdcx. %4,%y2\n"
1931
+ "bne- 2f\n"
1932
+ "addi %1,0,1\n"
1933
+ "1:"
1934
+
1935
+ BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
1936
+ : "=&b" (expected), "=&b" (success), "+Z"(v_)
1937
+ : "b" (expected), "b" (desired)
1938
+ : "cr0"
1939
+ );
1940
+ if (success)
1941
+ ppc_fence_after(success_order);
1942
+ else
1943
+ ppc_fence_after(failure_order);
1944
+ return success;
1945
+ }
1946
+
1947
+ bool
1948
+ compare_exchange_strong(
1949
+ value_type & expected,
1950
+ value_type desired,
1951
+ memory_order success_order,
1952
+ memory_order failure_order) volatile BOOST_NOEXCEPT
1953
+ {
1954
+ int success;
1955
+ ppc_fence_before(success_order);
1956
+ __asm__(
1957
+ "0: ldarx %0,%y2\n"
1958
+ "cmpd %0, %3\n"
1959
+ "bne- 2f\n"
1960
+ "stdcx. %4,%y2\n"
1961
+ "bne- 0b\n"
1962
+ "addi %1,0,1\n"
1963
+ "1:"
1964
+
1965
+ BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
1966
+ : "=&b" (expected), "=&b" (success), "+Z"(v_)
1967
+ : "b" (expected), "b" (desired)
1968
+ : "cr0"
1969
+ );
1970
+ if (success)
1971
+ ppc_fence_after(success_order);
1972
+ else
1973
+ ppc_fence_after(failure_order);
1974
+ return success;
1975
+ }
1976
+
1977
+ bool
1978
+ is_lock_free(void) const volatile BOOST_NOEXCEPT
1979
+ {
1980
+ return true;
1981
+ }
1982
+
1983
+ value_type
1984
+ fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1985
+ {
1986
+ value_type original, tmp;
1987
+ ppc_fence_before(order);
1988
+ __asm__ (
1989
+ "1:\n"
1990
+ "ldarx %0,%y2\n"
1991
+ "add %1,%0,%3\n"
1992
+ "stdcx. %1,%y2\n"
1993
+ "bne- 1b\n"
1994
+ : "=&b" (original), "=&b" (tmp), "+Z"(v_)
1995
+ : "b" (v)
1996
+ : "cc");
1997
+ ppc_fence_after(order);
1998
+ return original;
1999
+ }
2000
+
2001
+ value_type
2002
+ fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
2003
+ {
2004
+ value_type original, tmp;
2005
+ ppc_fence_before(order);
2006
+ __asm__ (
2007
+ "1:\n"
2008
+ "ldarx %0,%y2\n"
2009
+ "sub %1,%0,%3\n"
2010
+ "stdcx. %1,%y2\n"
2011
+ "bne- 1b\n"
2012
+ : "=&b" (original), "=&b" (tmp), "+Z"(v_)
2013
+ : "b" (v)
2014
+ : "cc");
2015
+ ppc_fence_after(order);
2016
+ return original;
2017
+ }
2018
+
2019
+ BOOST_ATOMIC_DECLARE_VOID_POINTER_OPERATORS
2020
+ private:
2021
+ base_atomic(const base_atomic &) /* = delete */ ;
2022
+ void operator=(const base_atomic &) /* = delete */ ;
2023
+ value_type v_;
2024
+ };
2025
+
2026
+ template<typename T, bool Sign>
2027
+ class base_atomic<T *, void *, 8, Sign>
2028
+ {
2029
+ typedef base_atomic this_type;
2030
+ typedef T * value_type;
2031
+ typedef ptrdiff_t difference_type;
2032
+ public:
2033
+ BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
2034
+ base_atomic(void) {}
2035
+
2036
+ void
2037
+ store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
2038
+ {
2039
+ ppc_fence_before(order);
2040
+ __asm__ (
2041
+ "std %1, %0\n"
2042
+ : "+m" (v_)
2043
+ : "r" (v)
2044
+ );
2045
+ ppc_fence_after_store(order);
2046
+ }
2047
+
2048
+ value_type
2049
+ load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
2050
+ {
2051
+ value_type v;
2052
+ __asm__ (
2053
+ "ld %0, %1\n"
2054
+ "cmpd %0, %0\n"
2055
+ "bne- 1f\n"
2056
+ "1:\n"
2057
+ : "=r"(v)
2058
+ : "m"(v_)
2059
+ : "cr0"
2060
+ );
2061
+ ppc_fence_after(order);
2062
+ return v;
2063
+ }
2064
+
2065
+ value_type
2066
+ exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
2067
+ {
2068
+ value_type original;
2069
+ ppc_fence_before(order);
2070
+ __asm__ (
2071
+ "1:\n"
2072
+ "ldarx %0,%y1\n"
2073
+ "stdcx. %2,%y1\n"
2074
+ "bne- 1b\n"
2075
+ : "=&b" (original), "+Z"(v_)
2076
+ : "b" (v)
2077
+ : "cr0"
2078
+ );
2079
+ ppc_fence_after(order);
2080
+ return original;
2081
+ }
2082
+
2083
+ bool
2084
+ compare_exchange_weak(
2085
+ value_type & expected,
2086
+ value_type desired,
2087
+ memory_order success_order,
2088
+ memory_order failure_order) volatile BOOST_NOEXCEPT
2089
+ {
2090
+ int success;
2091
+ ppc_fence_before(success_order);
2092
+ __asm__(
2093
+ "ldarx %0,%y2\n"
2094
+ "cmpd %0, %3\n"
2095
+ "bne- 2f\n"
2096
+ "stdcx. %4,%y2\n"
2097
+ "bne- 2f\n"
2098
+ "addi %1,0,1\n"
2099
+ "1:"
2100
+
2101
+ BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
2102
+ : "=&b" (expected), "=&b" (success), "+Z"(v_)
2103
+ : "b" (expected), "b" (desired)
2104
+ : "cr0"
2105
+ );
2106
+ if (success)
2107
+ ppc_fence_after(success_order);
2108
+ else
2109
+ ppc_fence_after(failure_order);
2110
+ return success;
2111
+ }
2112
+
2113
+ bool
2114
+ compare_exchange_strong(
2115
+ value_type & expected,
2116
+ value_type desired,
2117
+ memory_order success_order,
2118
+ memory_order failure_order) volatile BOOST_NOEXCEPT
2119
+ {
2120
+ int success;
2121
+ ppc_fence_before(success_order);
2122
+ __asm__(
2123
+ "0: ldarx %0,%y2\n"
2124
+ "cmpd %0, %3\n"
2125
+ "bne- 2f\n"
2126
+ "stdcx. %4,%y2\n"
2127
+ "bne- 0b\n"
2128
+ "addi %1,0,1\n"
2129
+ "1:"
2130
+
2131
+ BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
2132
+ : "=&b" (expected), "=&b" (success), "+Z"(v_)
2133
+ : "b" (expected), "b" (desired)
2134
+ : "cr0"
2135
+ );
2136
+ if (success)
2137
+ ppc_fence_after(success_order);
2138
+ else
2139
+ ppc_fence_after(failure_order);
2140
+ return success;
2141
+ }
2142
+
2143
+ value_type
2144
+ fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
2145
+ {
2146
+ v = v * sizeof(*v_);
2147
+ value_type original, tmp;
2148
+ ppc_fence_before(order);
2149
+ __asm__ (
2150
+ "1:\n"
2151
+ "ldarx %0,%y2\n"
2152
+ "add %1,%0,%3\n"
2153
+ "stdcx. %1,%y2\n"
2154
+ "bne- 1b\n"
2155
+ : "=&b" (original), "=&b" (tmp), "+Z"(v_)
2156
+ : "b" (v)
2157
+ : "cc");
2158
+ ppc_fence_after(order);
2159
+ return original;
2160
+ }
2161
+
2162
+ value_type
2163
+ fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
2164
+ {
2165
+ v = v * sizeof(*v_);
2166
+ value_type original, tmp;
2167
+ ppc_fence_before(order);
2168
+ __asm__ (
2169
+ "1:\n"
2170
+ "ldarx %0,%y2\n"
2171
+ "sub %1,%0,%3\n"
2172
+ "stdcx. %1,%y2\n"
2173
+ "bne- 1b\n"
2174
+ : "=&b" (original), "=&b" (tmp), "+Z"(v_)
2175
+ : "b" (v)
2176
+ : "cc");
2177
+ ppc_fence_after(order);
2178
+ return original;
2179
+ }
2180
+
2181
+ bool
2182
+ is_lock_free(void) const volatile BOOST_NOEXCEPT
2183
+ {
2184
+ return true;
2185
+ }
2186
+
2187
+ BOOST_ATOMIC_DECLARE_POINTER_OPERATORS
2188
+ private:
2189
+ base_atomic(const base_atomic &) /* = delete */ ;
2190
+ void operator=(const base_atomic &) /* = delete */ ;
2191
+ value_type v_;
2192
+ };
2193
+
2194
+ #endif
2195
+
2196
+ /* generic */
2197
+
2198
+ template<typename T, bool Sign>
2199
+ class base_atomic<T, void, 1, Sign>
2200
+ {
2201
+ typedef base_atomic this_type;
2202
+ typedef T value_type;
2203
+ typedef uint32_t storage_type;
2204
+ public:
2205
+ explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0)
2206
+ {
2207
+ memcpy(&v_, &v, sizeof(value_type));
2208
+ }
2209
+ base_atomic(void) {}
2210
+
2211
+ void
2212
+ store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
2213
+ {
2214
+ storage_type tmp = 0;
2215
+ memcpy(&tmp, &v, sizeof(value_type));
2216
+ ppc_fence_before(order);
2217
+ __asm__ (
2218
+ "stw %1, %0\n"
2219
+ : "+m" (v_)
2220
+ : "r" (tmp)
2221
+ );
2222
+ ppc_fence_after_store(order);
2223
+ }
2224
+
2225
+ value_type
2226
+ load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
2227
+ {
2228
+ storage_type tmp;
2229
+ __asm__ __volatile__ (
2230
+ "lwz %0, %1\n"
2231
+ "cmpw %0, %0\n"
2232
+ "bne- 1f\n"
2233
+ "1:\n"
2234
+ : "=r"(tmp)
2235
+ : "m"(v_)
2236
+ : "cr0"
2237
+ );
2238
+ ppc_fence_after(order);
2239
+
2240
+ value_type v;
2241
+ memcpy(&v, &tmp, sizeof(value_type));
2242
+ return v;
2243
+ }
2244
+
2245
+ value_type
2246
+ exchange(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
2247
+ {
2248
+ storage_type tmp = 0, original;
2249
+ memcpy(&tmp, &v, sizeof(value_type));
2250
+ ppc_fence_before(order);
2251
+ __asm__ (
2252
+ "1:\n"
2253
+ "lwarx %0,%y1\n"
2254
+ "stwcx. %2,%y1\n"
2255
+ "bne- 1b\n"
2256
+ : "=&b" (original), "+Z"(v_)
2257
+ : "b" (tmp)
2258
+ : "cr0"
2259
+ );
2260
+ ppc_fence_after(order);
2261
+ value_type res;
2262
+ memcpy(&res, &original, sizeof(value_type));
2263
+ return res;
2264
+ }
2265
+
2266
+ bool
2267
+ compare_exchange_weak(
2268
+ value_type & expected,
2269
+ value_type const& desired,
2270
+ memory_order success_order,
2271
+ memory_order failure_order) volatile BOOST_NOEXCEPT
2272
+ {
2273
+ storage_type expected_s = 0, desired_s = 0;
2274
+ memcpy(&expected_s, &expected, sizeof(value_type));
2275
+ memcpy(&desired_s, &desired, sizeof(value_type));
2276
+
2277
+ int success;
2278
+ ppc_fence_before(success_order);
2279
+ __asm__(
2280
+ "lwarx %0,%y2\n"
2281
+ "cmpw %0, %3\n"
2282
+ "bne- 2f\n"
2283
+ "stwcx. %4,%y2\n"
2284
+ "bne- 2f\n"
2285
+ "addi %1,0,1\n"
2286
+ "1:"
2287
+
2288
+ BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
2289
+ : "=&b" (expected_s), "=&b" (success), "+Z"(v_)
2290
+ : "b" (expected_s), "b" (desired_s)
2291
+ : "cr0"
2292
+ );
2293
+ if (success)
2294
+ ppc_fence_after(success_order);
2295
+ else
2296
+ ppc_fence_after(failure_order);
2297
+ memcpy(&expected, &expected_s, sizeof(value_type));
2298
+ return success;
2299
+ }
2300
+
2301
+ bool
2302
+ compare_exchange_strong(
2303
+ value_type & expected,
2304
+ value_type const& desired,
2305
+ memory_order success_order,
2306
+ memory_order failure_order) volatile BOOST_NOEXCEPT
2307
+ {
2308
+ storage_type expected_s = 0, desired_s = 0;
2309
+ memcpy(&expected_s, &expected, sizeof(value_type));
2310
+ memcpy(&desired_s, &desired, sizeof(value_type));
2311
+
2312
+ int success;
2313
+ ppc_fence_before(success_order);
2314
+ __asm__(
2315
+ "0: lwarx %0,%y2\n"
2316
+ "cmpw %0, %3\n"
2317
+ "bne- 2f\n"
2318
+ "stwcx. %4,%y2\n"
2319
+ "bne- 0b\n"
2320
+ "addi %1,0,1\n"
2321
+ "1:"
2322
+
2323
+ BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
2324
+ : "=&b" (expected_s), "=&b" (success), "+Z"(v_)
2325
+ : "b" (expected_s), "b" (desired_s)
2326
+ : "cr0"
2327
+ );
2328
+ if (success)
2329
+ ppc_fence_after(success_order);
2330
+ else
2331
+ ppc_fence_after(failure_order);
2332
+ memcpy(&expected, &expected_s, sizeof(value_type));
2333
+ return success;
2334
+ }
2335
+
2336
+ bool
2337
+ is_lock_free(void) const volatile BOOST_NOEXCEPT
2338
+ {
2339
+ return true;
2340
+ }
2341
+
2342
+ BOOST_ATOMIC_DECLARE_BASE_OPERATORS
2343
+ private:
2344
+ base_atomic(const base_atomic &) /* = delete */ ;
2345
+ void operator=(const base_atomic &) /* = delete */ ;
2346
+ storage_type v_;
2347
+ };
2348
+
2349
+ template<typename T, bool Sign>
2350
+ class base_atomic<T, void, 2, Sign>
2351
+ {
2352
+ typedef base_atomic this_type;
2353
+ typedef T value_type;
2354
+ typedef uint32_t storage_type;
2355
+ public:
2356
+ explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0)
2357
+ {
2358
+ memcpy(&v_, &v, sizeof(value_type));
2359
+ }
2360
+
2361
+ base_atomic(void) {}
2362
+
2363
+ void
2364
+ store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
2365
+ {
2366
+ storage_type tmp = 0;
2367
+ memcpy(&tmp, &v, sizeof(value_type));
2368
+ ppc_fence_before(order);
2369
+ __asm__ (
2370
+ "stw %1, %0\n"
2371
+ : "+m" (v_)
2372
+ : "r" (tmp)
2373
+ );
2374
+ ppc_fence_after_store(order);
2375
+ }
2376
+
2377
+ value_type
2378
+ load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
2379
+ {
2380
+ storage_type tmp;
2381
+ __asm__ __volatile__ (
2382
+ "lwz %0, %1\n"
2383
+ "cmpw %0, %0\n"
2384
+ "bne- 1f\n"
2385
+ "1:\n"
2386
+ : "=r"(tmp)
2387
+ : "m"(v_)
2388
+ : "cr0"
2389
+ );
2390
+ ppc_fence_after(order);
2391
+
2392
+ value_type v;
2393
+ memcpy(&v, &tmp, sizeof(value_type));
2394
+ return v;
2395
+ }
2396
+
2397
+ value_type
2398
+ exchange(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
2399
+ {
2400
+ storage_type tmp = 0, original;
2401
+ memcpy(&tmp, &v, sizeof(value_type));
2402
+ ppc_fence_before(order);
2403
+ __asm__ (
2404
+ "1:\n"
2405
+ "lwarx %0,%y1\n"
2406
+ "stwcx. %2,%y1\n"
2407
+ "bne- 1b\n"
2408
+ : "=&b" (original), "+Z"(v_)
2409
+ : "b" (tmp)
2410
+ : "cr0"
2411
+ );
2412
+ ppc_fence_after(order);
2413
+ value_type res;
2414
+ memcpy(&res, &original, sizeof(value_type));
2415
+ return res;
2416
+ }
2417
+
2418
+ bool
2419
+ compare_exchange_weak(
2420
+ value_type & expected,
2421
+ value_type const& desired,
2422
+ memory_order success_order,
2423
+ memory_order failure_order) volatile BOOST_NOEXCEPT
2424
+ {
2425
+ storage_type expected_s = 0, desired_s = 0;
2426
+ memcpy(&expected_s, &expected, sizeof(value_type));
2427
+ memcpy(&desired_s, &desired, sizeof(value_type));
2428
+
2429
+ int success;
2430
+ ppc_fence_before(success_order);
2431
+ __asm__(
2432
+ "lwarx %0,%y2\n"
2433
+ "cmpw %0, %3\n"
2434
+ "bne- 2f\n"
2435
+ "stwcx. %4,%y2\n"
2436
+ "bne- 2f\n"
2437
+ "addi %1,0,1\n"
2438
+ "1:"
2439
+
2440
+ BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
2441
+ : "=&b" (expected_s), "=&b" (success), "+Z"(v_)
2442
+ : "b" (expected_s), "b" (desired_s)
2443
+ : "cr0"
2444
+ );
2445
+ if (success)
2446
+ ppc_fence_after(success_order);
2447
+ else
2448
+ ppc_fence_after(failure_order);
2449
+ memcpy(&expected, &expected_s, sizeof(value_type));
2450
+ return success;
2451
+ }
2452
+
2453
+ bool
2454
+ compare_exchange_strong(
2455
+ value_type & expected,
2456
+ value_type const& desired,
2457
+ memory_order success_order,
2458
+ memory_order failure_order) volatile BOOST_NOEXCEPT
2459
+ {
2460
+ storage_type expected_s = 0, desired_s = 0;
2461
+ memcpy(&expected_s, &expected, sizeof(value_type));
2462
+ memcpy(&desired_s, &desired, sizeof(value_type));
2463
+
2464
+ int success;
2465
+ ppc_fence_before(success_order);
2466
+ __asm__(
2467
+ "0: lwarx %0,%y2\n"
2468
+ "cmpw %0, %3\n"
2469
+ "bne- 2f\n"
2470
+ "stwcx. %4,%y2\n"
2471
+ "bne- 0b\n"
2472
+ "addi %1,0,1\n"
2473
+ "1:"
2474
+
2475
+ BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
2476
+ : "=&b" (expected_s), "=&b" (success), "+Z"(v_)
2477
+ : "b" (expected_s), "b" (desired_s)
2478
+ : "cr0"
2479
+ );
2480
+ if (success)
2481
+ ppc_fence_after(success_order);
2482
+ else
2483
+ ppc_fence_after(failure_order);
2484
+ memcpy(&expected, &expected_s, sizeof(value_type));
2485
+ return success;
2486
+ }
2487
+
2488
+ bool
2489
+ is_lock_free(void) const volatile BOOST_NOEXCEPT
2490
+ {
2491
+ return true;
2492
+ }
2493
+
2494
+ BOOST_ATOMIC_DECLARE_BASE_OPERATORS
2495
+ private:
2496
+ base_atomic(const base_atomic &) /* = delete */ ;
2497
+ void operator=(const base_atomic &) /* = delete */ ;
2498
+ storage_type v_;
2499
+ };
2500
+
2501
+ template<typename T, bool Sign>
2502
+ class base_atomic<T, void, 4, Sign>
2503
+ {
2504
+ typedef base_atomic this_type;
2505
+ typedef T value_type;
2506
+ typedef uint32_t storage_type;
2507
+ public:
2508
+ explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0)
2509
+ {
2510
+ memcpy(&v_, &v, sizeof(value_type));
2511
+ }
2512
+
2513
+ base_atomic(void) {}
2514
+
2515
+ void
2516
+ store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
2517
+ {
2518
+ storage_type tmp = 0;
2519
+ memcpy(&tmp, &v, sizeof(value_type));
2520
+ ppc_fence_before(order);
2521
+ __asm__ (
2522
+ "stw %1, %0\n"
2523
+ : "+m" (v_)
2524
+ : "r" (tmp)
2525
+ );
2526
+ ppc_fence_after_store(order);
2527
+ }
2528
+
2529
+ value_type
2530
+ load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
2531
+ {
2532
+ storage_type tmp;
2533
+ __asm__ __volatile__ (
2534
+ "lwz %0, %1\n"
2535
+ "cmpw %0, %0\n"
2536
+ "bne- 1f\n"
2537
+ "1:\n"
2538
+ : "=r"(tmp)
2539
+ : "m"(v_)
2540
+ : "cr0"
2541
+ );
2542
+ ppc_fence_after(order);
2543
+
2544
+ value_type v;
2545
+ memcpy(&v, &tmp, sizeof(value_type));
2546
+ return v;
2547
+ }
2548
+
2549
+ value_type
2550
+ exchange(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
2551
+ {
2552
+ storage_type tmp = 0, original;
2553
+ memcpy(&tmp, &v, sizeof(value_type));
2554
+ ppc_fence_before(order);
2555
+ __asm__ (
2556
+ "1:\n"
2557
+ "lwarx %0,%y1\n"
2558
+ "stwcx. %2,%y1\n"
2559
+ "bne- 1b\n"
2560
+ : "=&b" (original), "+Z"(v_)
2561
+ : "b" (tmp)
2562
+ : "cr0"
2563
+ );
2564
+ ppc_fence_after(order);
2565
+ value_type res;
2566
+ memcpy(&res, &original, sizeof(value_type));
2567
+ return res;
2568
+ }
2569
+
2570
+ bool
2571
+ compare_exchange_weak(
2572
+ value_type & expected,
2573
+ value_type const& desired,
2574
+ memory_order success_order,
2575
+ memory_order failure_order) volatile BOOST_NOEXCEPT
2576
+ {
2577
+ storage_type expected_s = 0, desired_s = 0;
2578
+ memcpy(&expected_s, &expected, sizeof(value_type));
2579
+ memcpy(&desired_s, &desired, sizeof(value_type));
2580
+
2581
+ int success;
2582
+ ppc_fence_before(success_order);
2583
+ __asm__(
2584
+ "lwarx %0,%y2\n"
2585
+ "cmpw %0, %3\n"
2586
+ "bne- 2f\n"
2587
+ "stwcx. %4,%y2\n"
2588
+ "bne- 2f\n"
2589
+ "addi %1,0,1\n"
2590
+ "1:"
2591
+
2592
+ BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
2593
+ : "=&b" (expected_s), "=&b" (success), "+Z"(v_)
2594
+ : "b" (expected_s), "b" (desired_s)
2595
+ : "cr0"
2596
+ );
2597
+ if (success)
2598
+ ppc_fence_after(success_order);
2599
+ else
2600
+ ppc_fence_after(failure_order);
2601
+ memcpy(&expected, &expected_s, sizeof(value_type));
2602
+ return success;
2603
+ }
2604
+
2605
+ bool
2606
+ compare_exchange_strong(
2607
+ value_type & expected,
2608
+ value_type const& desired,
2609
+ memory_order success_order,
2610
+ memory_order failure_order) volatile BOOST_NOEXCEPT
2611
+ {
2612
+ storage_type expected_s = 0, desired_s = 0;
2613
+ memcpy(&expected_s, &expected, sizeof(value_type));
2614
+ memcpy(&desired_s, &desired, sizeof(value_type));
2615
+
2616
+ int success;
2617
+ ppc_fence_before(success_order);
2618
+ __asm__(
2619
+ "0: lwarx %0,%y2\n"
2620
+ "cmpw %0, %3\n"
2621
+ "bne- 2f\n"
2622
+ "stwcx. %4,%y2\n"
2623
+ "bne- 0b\n"
2624
+ "addi %1,0,1\n"
2625
+ "1:"
2626
+
2627
+ BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
2628
+ : "=&b" (expected_s), "=&b" (success), "+Z"(v_)
2629
+ : "b" (expected_s), "b" (desired_s)
2630
+ : "cr0"
2631
+ );
2632
+ if (success)
2633
+ ppc_fence_after(success_order);
2634
+ else
2635
+ ppc_fence_after(failure_order);
2636
+ memcpy(&expected, &expected_s, sizeof(value_type));
2637
+ return success;
2638
+ }
2639
+
2640
+ bool
2641
+ is_lock_free(void) const volatile BOOST_NOEXCEPT
2642
+ {
2643
+ return true;
2644
+ }
2645
+
2646
+ BOOST_ATOMIC_DECLARE_BASE_OPERATORS
2647
+ private:
2648
+ base_atomic(const base_atomic &) /* = delete */ ;
2649
+ void operator=(const base_atomic &) /* = delete */ ;
2650
+ storage_type v_;
2651
+ };
2652
+
2653
+ #if defined(__powerpc64__)
2654
+
2655
+ template<typename T, bool Sign>
2656
+ class base_atomic<T, void, 8, Sign>
2657
+ {
2658
+ typedef base_atomic this_type;
2659
+ typedef T value_type;
2660
+ typedef uint64_t storage_type;
2661
+ public:
2662
+ explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0)
2663
+ {
2664
+ memcpy(&v_, &v, sizeof(value_type));
2665
+ }
2666
+
2667
+ base_atomic(void) {}
2668
+
2669
+ void
2670
+ store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
2671
+ {
2672
+ storage_type tmp;
2673
+ memcpy(&tmp, &v, sizeof(value_type));
2674
+ ppc_fence_before(order);
2675
+ __asm__ (
2676
+ "std %1, %0\n"
2677
+ : "+m" (v_)
2678
+ : "r" (tmp)
2679
+ );
2680
+ ppc_fence_after_store(order);
2681
+ }
2682
+
2683
+ value_type
2684
+ load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
2685
+ {
2686
+ storage_type tmp;
2687
+ __asm__ __volatile__ (
2688
+ "ld %0, %1\n"
2689
+ "cmpd %0, %0\n"
2690
+ "bne- 1f\n"
2691
+ "1:\n"
2692
+ : "=r"(tmp)
2693
+ : "m"(v_)
2694
+ : "cr0"
2695
+ );
2696
+ ppc_fence_after(order);
2697
+
2698
+ value_type v;
2699
+ memcpy(&v, &tmp, sizeof(value_type));
2700
+ return v;
2701
+ }
2702
+
2703
+ value_type
2704
+ exchange(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
2705
+ {
2706
+ storage_type tmp = 0, original;
2707
+ memcpy(&tmp, &v, sizeof(value_type));
2708
+ ppc_fence_before(order);
2709
+ __asm__ (
2710
+ "1:\n"
2711
+ "ldarx %0,%y1\n"
2712
+ "stdcx. %2,%y1\n"
2713
+ "bne- 1b\n"
2714
+ : "=&b" (original), "+Z"(v_)
2715
+ : "b" (tmp)
2716
+ : "cr0"
2717
+ );
2718
+ ppc_fence_after(order);
2719
+ value_type res;
2720
+ memcpy(&res, &original, sizeof(value_type));
2721
+ return res;
2722
+ }
2723
+
2724
+ bool
2725
+ compare_exchange_weak(
2726
+ value_type & expected,
2727
+ value_type const& desired,
2728
+ memory_order success_order,
2729
+ memory_order failure_order) volatile BOOST_NOEXCEPT
2730
+ {
2731
+ storage_type expected_s, desired_s;
2732
+ memcpy(&expected_s, &expected, sizeof(value_type));
2733
+ memcpy(&desired_s, &desired, sizeof(value_type));
2734
+
2735
+ int success;
2736
+ ppc_fence_before(success_order);
2737
+ __asm__(
2738
+ "ldarx %0,%y2\n"
2739
+ "cmpd %0, %3\n"
2740
+ "bne- 2f\n"
2741
+ "stdcx. %4,%y2\n"
2742
+ "bne- 2f\n"
2743
+ "addi %1,0,1\n"
2744
+ "1:"
2745
+
2746
+ BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
2747
+ : "=&b" (expected_s), "=&b" (success), "+Z"(v_)
2748
+ : "b" (expected_s), "b" (desired_s)
2749
+ : "cr0"
2750
+ );
2751
+ if (success)
2752
+ ppc_fence_after(success_order);
2753
+ else
2754
+ ppc_fence_after(failure_order);
2755
+ memcpy(&expected, &expected_s, sizeof(value_type));
2756
+ return success;
2757
+ }
2758
+
2759
+ bool
2760
+ compare_exchange_strong(
2761
+ value_type & expected,
2762
+ value_type const& desired,
2763
+ memory_order success_order,
2764
+ memory_order failure_order) volatile BOOST_NOEXCEPT
2765
+ {
2766
+ storage_type expected_s, desired_s;
2767
+ memcpy(&expected_s, &expected, sizeof(value_type));
2768
+ memcpy(&desired_s, &desired, sizeof(value_type));
2769
+
2770
+ int success;
2771
+ ppc_fence_before(success_order);
2772
+ __asm__(
2773
+ "0: ldarx %0,%y2\n"
2774
+ "cmpd %0, %3\n"
2775
+ "bne- 2f\n"
2776
+ "stdcx. %4,%y2\n"
2777
+ "bne- 0b\n"
2778
+ "addi %1,0,1\n"
2779
+ "1:"
2780
+
2781
+ BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
2782
+ : "=&b" (expected_s), "=&b" (success), "+Z"(v_)
2783
+ : "b" (expected_s), "b" (desired_s)
2784
+ : "cr0"
2785
+ );
2786
+ if (success)
2787
+ ppc_fence_after(success_order);
2788
+ else
2789
+ ppc_fence_after(failure_order);
2790
+ memcpy(&expected, &expected_s, sizeof(value_type));
2791
+ return success;
2792
+ }
2793
+
2794
+ bool
2795
+ is_lock_free(void) const volatile BOOST_NOEXCEPT
2796
+ {
2797
+ return true;
2798
+ }
2799
+
2800
+ BOOST_ATOMIC_DECLARE_BASE_OPERATORS
2801
+ private:
2802
+ base_atomic(const base_atomic &) /* = delete */ ;
2803
+ void operator=(const base_atomic &) /* = delete */ ;
2804
+ storage_type v_;
2805
+ };
2806
+ #endif
2807
+
2808
+ }
2809
+ }
2810
+
2811
+ #define BOOST_ATOMIC_THREAD_FENCE 2
2812
+ inline void
2813
+ atomic_thread_fence(memory_order order)
2814
+ {
2815
+ switch(order) {
2816
+ case memory_order_acquire:
2817
+ __asm__ __volatile__ ("isync" ::: "memory");
2818
+ break;
2819
+ case memory_order_release:
2820
+ #if defined(__powerpc64__)
2821
+ __asm__ __volatile__ ("lwsync" ::: "memory");
2822
+ break;
2823
+ #endif
2824
+ case memory_order_acq_rel:
2825
+ case memory_order_seq_cst:
2826
+ __asm__ __volatile__ ("sync" ::: "memory");
2827
+ default:;
2828
+ }
2829
+ }
2830
+
2831
+ #define BOOST_ATOMIC_SIGNAL_FENCE 2
2832
+ inline void
2833
+ atomic_signal_fence(memory_order order)
2834
+ {
2835
+ switch(order) {
2836
+ case memory_order_acquire:
2837
+ case memory_order_release:
2838
+ case memory_order_acq_rel:
2839
+ case memory_order_seq_cst:
2840
+ __asm__ __volatile__ ("" ::: "memory");
2841
+ break;
2842
+ default:;
2843
+ }
2844
+ }
2845
+
2846
+ }
2847
+
2848
+ #endif /* !defined(BOOST_ATOMIC_FORCE_FALLBACK) */
2849
+
2850
+ #endif