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,1766 @@
1
+ #ifndef BOOST_ATOMIC_DETAIL_GCC_X86_HPP
2
+ #define BOOST_ATOMIC_DETAIL_GCC_X86_HPP
3
+
4
+ // Copyright (c) 2009 Helge Bahmann
5
+ // Copyright (c) 2012 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
+ namespace boost {
20
+ namespace atomics {
21
+ namespace detail {
22
+
23
+ #if defined(__x86_64__) || defined(__SSE2__)
24
+ # define BOOST_ATOMIC_X86_FENCE_INSTR "mfence\n"
25
+ #else
26
+ # define BOOST_ATOMIC_X86_FENCE_INSTR "lock ; addl $0, (%%esp)\n"
27
+ #endif
28
+
29
+ #define BOOST_ATOMIC_X86_PAUSE() __asm__ __volatile__ ("pause\n")
30
+
31
+ #if defined(__i386__) &&\
32
+ (\
33
+ defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8) ||\
34
+ defined(__i586__) || defined(__i686__) || defined(__pentium4__) || defined(__nocona__) || defined(__core2__) || defined(__corei7__) ||\
35
+ defined(__k6__) || defined(__athlon__) || defined(__k8__) || defined(__amdfam10__) || defined(__bdver1__) || defined(__bdver2__) || defined(__bdver3__) || defined(__btver1__) || defined(__btver2__)\
36
+ )
37
+ #define BOOST_ATOMIC_X86_HAS_CMPXCHG8B 1
38
+ #endif
39
+
40
+ inline void
41
+ platform_fence_before(memory_order order)
42
+ {
43
+ switch(order)
44
+ {
45
+ case memory_order_relaxed:
46
+ case memory_order_acquire:
47
+ case memory_order_consume:
48
+ break;
49
+ case memory_order_release:
50
+ case memory_order_acq_rel:
51
+ __asm__ __volatile__ ("" ::: "memory");
52
+ /* release */
53
+ break;
54
+ case memory_order_seq_cst:
55
+ __asm__ __volatile__ ("" ::: "memory");
56
+ /* seq */
57
+ break;
58
+ default:;
59
+ }
60
+ }
61
+
62
+ inline void
63
+ platform_fence_after(memory_order order)
64
+ {
65
+ switch(order)
66
+ {
67
+ case memory_order_relaxed:
68
+ case memory_order_release:
69
+ break;
70
+ case memory_order_acquire:
71
+ case memory_order_acq_rel:
72
+ __asm__ __volatile__ ("" ::: "memory");
73
+ /* acquire */
74
+ break;
75
+ case memory_order_consume:
76
+ /* consume */
77
+ break;
78
+ case memory_order_seq_cst:
79
+ __asm__ __volatile__ ("" ::: "memory");
80
+ /* seq */
81
+ break;
82
+ default:;
83
+ }
84
+ }
85
+
86
+ inline void
87
+ platform_fence_after_load(memory_order order)
88
+ {
89
+ switch(order)
90
+ {
91
+ case memory_order_relaxed:
92
+ case memory_order_release:
93
+ break;
94
+ case memory_order_acquire:
95
+ case memory_order_acq_rel:
96
+ __asm__ __volatile__ ("" ::: "memory");
97
+ break;
98
+ case memory_order_consume:
99
+ break;
100
+ case memory_order_seq_cst:
101
+ __asm__ __volatile__ ("" ::: "memory");
102
+ break;
103
+ default:;
104
+ }
105
+ }
106
+
107
+ inline void
108
+ platform_fence_before_store(memory_order order)
109
+ {
110
+ switch(order)
111
+ {
112
+ case memory_order_relaxed:
113
+ case memory_order_acquire:
114
+ case memory_order_consume:
115
+ break;
116
+ case memory_order_release:
117
+ case memory_order_acq_rel:
118
+ __asm__ __volatile__ ("" ::: "memory");
119
+ /* release */
120
+ break;
121
+ case memory_order_seq_cst:
122
+ __asm__ __volatile__ ("" ::: "memory");
123
+ /* seq */
124
+ break;
125
+ default:;
126
+ }
127
+ }
128
+
129
+ inline void
130
+ platform_fence_after_store(memory_order order)
131
+ {
132
+ switch(order)
133
+ {
134
+ case memory_order_relaxed:
135
+ case memory_order_release:
136
+ break;
137
+ case memory_order_acquire:
138
+ case memory_order_acq_rel:
139
+ __asm__ __volatile__ ("" ::: "memory");
140
+ /* acquire */
141
+ break;
142
+ case memory_order_consume:
143
+ /* consume */
144
+ break;
145
+ case memory_order_seq_cst:
146
+ __asm__ __volatile__ ("" ::: "memory");
147
+ /* seq */
148
+ break;
149
+ default:;
150
+ }
151
+ }
152
+
153
+ }
154
+ }
155
+
156
+ class atomic_flag
157
+ {
158
+ private:
159
+ atomic_flag(const atomic_flag &) /* = delete */ ;
160
+ atomic_flag & operator=(const atomic_flag &) /* = delete */ ;
161
+ uint32_t v_;
162
+ public:
163
+ BOOST_CONSTEXPR atomic_flag(void) BOOST_NOEXCEPT : v_(0) {}
164
+
165
+ bool
166
+ test_and_set(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
167
+ {
168
+ uint32_t v = 1;
169
+ atomics::detail::platform_fence_before(order);
170
+ __asm__ __volatile__ (
171
+ "xchgl %0, %1"
172
+ : "+r" (v), "+m" (v_)
173
+ );
174
+ atomics::detail::platform_fence_after(order);
175
+ return v;
176
+ }
177
+
178
+ void
179
+ clear(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
180
+ {
181
+ if (order == memory_order_seq_cst) {
182
+ uint32_t v = 0;
183
+ __asm__ __volatile__ (
184
+ "xchgl %0, %1"
185
+ : "+r" (v), "+m" (v_)
186
+ );
187
+ } else {
188
+ atomics::detail::platform_fence_before(order);
189
+ v_ = 0;
190
+ }
191
+ }
192
+ };
193
+
194
+ } /* namespace boost */
195
+
196
+ #define BOOST_ATOMIC_FLAG_LOCK_FREE 2
197
+
198
+ #include <boost/atomic/detail/base.hpp>
199
+
200
+ #if !defined(BOOST_ATOMIC_FORCE_FALLBACK)
201
+
202
+ #define BOOST_ATOMIC_CHAR_LOCK_FREE 2
203
+ #define BOOST_ATOMIC_CHAR16_T_LOCK_FREE 2
204
+ #define BOOST_ATOMIC_CHAR32_T_LOCK_FREE 2
205
+ #define BOOST_ATOMIC_WCHAR_T_LOCK_FREE 2
206
+ #define BOOST_ATOMIC_SHORT_LOCK_FREE 2
207
+ #define BOOST_ATOMIC_INT_LOCK_FREE 2
208
+ #define BOOST_ATOMIC_LONG_LOCK_FREE 2
209
+
210
+ #if defined(__x86_64__) || defined(BOOST_ATOMIC_X86_HAS_CMPXCHG8B)
211
+ #define BOOST_ATOMIC_LLONG_LOCK_FREE 2
212
+ #else
213
+ #define BOOST_ATOMIC_LLONG_LOCK_FREE 0
214
+ #endif
215
+
216
+ #define BOOST_ATOMIC_POINTER_LOCK_FREE 2
217
+ #define BOOST_ATOMIC_BOOL_LOCK_FREE 2
218
+
219
+ namespace boost {
220
+
221
+ #define BOOST_ATOMIC_THREAD_FENCE 2
222
+ inline void
223
+ atomic_thread_fence(memory_order order)
224
+ {
225
+ switch(order)
226
+ {
227
+ case memory_order_relaxed:
228
+ break;
229
+ case memory_order_release:
230
+ __asm__ __volatile__ ("" ::: "memory");
231
+ break;
232
+ case memory_order_acquire:
233
+ __asm__ __volatile__ ("" ::: "memory");
234
+ break;
235
+ case memory_order_acq_rel:
236
+ __asm__ __volatile__ ("" ::: "memory");
237
+ break;
238
+ case memory_order_consume:
239
+ break;
240
+ case memory_order_seq_cst:
241
+ __asm__ __volatile__ (BOOST_ATOMIC_X86_FENCE_INSTR ::: "memory");
242
+ break;
243
+ default:;
244
+ }
245
+ }
246
+
247
+ #define BOOST_ATOMIC_SIGNAL_FENCE 2
248
+ inline void
249
+ atomic_signal_fence(memory_order)
250
+ {
251
+ __asm__ __volatile__ ("" ::: "memory");
252
+ }
253
+
254
+ namespace atomics {
255
+ namespace detail {
256
+
257
+ template<typename T, bool Sign>
258
+ class base_atomic<T, int, 1, Sign>
259
+ {
260
+ typedef base_atomic this_type;
261
+ typedef T value_type;
262
+ typedef T difference_type;
263
+ public:
264
+ BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
265
+ base_atomic(void) {}
266
+
267
+ void
268
+ store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
269
+ {
270
+ if (order != memory_order_seq_cst) {
271
+ platform_fence_before(order);
272
+ const_cast<volatile value_type &>(v_) = v;
273
+ } else {
274
+ exchange(v, order);
275
+ }
276
+ }
277
+
278
+ value_type
279
+ load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
280
+ {
281
+ value_type v = const_cast<const volatile value_type &>(v_);
282
+ platform_fence_after_load(order);
283
+ return v;
284
+ }
285
+
286
+ value_type
287
+ fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
288
+ {
289
+ platform_fence_before(order);
290
+ __asm__ (
291
+ "lock ; xaddb %0, %1"
292
+ : "+q" (v), "+m" (v_)
293
+ );
294
+ platform_fence_after(order);
295
+ return v;
296
+ }
297
+
298
+ value_type
299
+ fetch_sub(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
300
+ {
301
+ return fetch_add(-v, order);
302
+ }
303
+
304
+ value_type
305
+ exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
306
+ {
307
+ platform_fence_before(order);
308
+ __asm__ (
309
+ "xchgb %0, %1"
310
+ : "+q" (v), "+m" (v_)
311
+ );
312
+ platform_fence_after(order);
313
+ return v;
314
+ }
315
+
316
+ bool
317
+ compare_exchange_strong(
318
+ value_type & expected,
319
+ value_type desired,
320
+ memory_order success_order,
321
+ memory_order failure_order) volatile BOOST_NOEXCEPT
322
+ {
323
+ value_type previous = expected;
324
+ platform_fence_before(success_order);
325
+ __asm__ (
326
+ "lock ; cmpxchgb %2, %1"
327
+ : "+a" (previous), "+m" (v_)
328
+ : "q" (desired)
329
+ );
330
+ bool success = (previous == expected);
331
+ if (success)
332
+ platform_fence_after(success_order);
333
+ else
334
+ platform_fence_after(failure_order);
335
+ expected = previous;
336
+ return success;
337
+ }
338
+
339
+ bool
340
+ compare_exchange_weak(
341
+ value_type & expected,
342
+ value_type desired,
343
+ memory_order success_order,
344
+ memory_order failure_order) volatile BOOST_NOEXCEPT
345
+ {
346
+ return compare_exchange_strong(expected, desired, success_order, failure_order);
347
+ }
348
+
349
+ value_type
350
+ fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
351
+ {
352
+ value_type tmp = load(memory_order_relaxed);
353
+ for(; !compare_exchange_weak(tmp, tmp & v, order, memory_order_relaxed);)
354
+ {
355
+ BOOST_ATOMIC_X86_PAUSE();
356
+ }
357
+ return tmp;
358
+ }
359
+
360
+ value_type
361
+ fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
362
+ {
363
+ value_type tmp = load(memory_order_relaxed);
364
+ for (; !compare_exchange_weak(tmp, tmp | v, order, memory_order_relaxed);)
365
+ {
366
+ BOOST_ATOMIC_X86_PAUSE();
367
+ }
368
+ return tmp;
369
+ }
370
+
371
+ value_type
372
+ fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
373
+ {
374
+ value_type tmp = load(memory_order_relaxed);
375
+ for (; !compare_exchange_weak(tmp, tmp ^ v, order, memory_order_relaxed);)
376
+ {
377
+ BOOST_ATOMIC_X86_PAUSE();
378
+ }
379
+ return tmp;
380
+ }
381
+
382
+ bool
383
+ is_lock_free(void) const volatile BOOST_NOEXCEPT
384
+ {
385
+ return true;
386
+ }
387
+
388
+ BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
389
+ private:
390
+ base_atomic(const base_atomic &) /* = delete */ ;
391
+ void operator=(const base_atomic &) /* = delete */ ;
392
+ value_type v_;
393
+ };
394
+
395
+ template<typename T, bool Sign>
396
+ class base_atomic<T, int, 2, Sign>
397
+ {
398
+ typedef base_atomic this_type;
399
+ typedef T value_type;
400
+ typedef T difference_type;
401
+ public:
402
+ BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
403
+ base_atomic(void) {}
404
+
405
+ void
406
+ store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
407
+ {
408
+ if (order != memory_order_seq_cst) {
409
+ platform_fence_before(order);
410
+ const_cast<volatile value_type &>(v_) = v;
411
+ } else {
412
+ exchange(v, order);
413
+ }
414
+ }
415
+
416
+ value_type
417
+ load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
418
+ {
419
+ value_type v = const_cast<const volatile value_type &>(v_);
420
+ platform_fence_after_load(order);
421
+ return v;
422
+ }
423
+
424
+ value_type
425
+ fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
426
+ {
427
+ platform_fence_before(order);
428
+ __asm__ (
429
+ "lock ; xaddw %0, %1"
430
+ : "+q" (v), "+m" (v_)
431
+ );
432
+ platform_fence_after(order);
433
+ return v;
434
+ }
435
+
436
+ value_type
437
+ fetch_sub(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
438
+ {
439
+ return fetch_add(-v, order);
440
+ }
441
+
442
+ value_type
443
+ exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
444
+ {
445
+ platform_fence_before(order);
446
+ __asm__ (
447
+ "xchgw %0, %1"
448
+ : "+q" (v), "+m" (v_)
449
+ );
450
+ platform_fence_after(order);
451
+ return v;
452
+ }
453
+
454
+ bool
455
+ compare_exchange_strong(
456
+ value_type & expected,
457
+ value_type desired,
458
+ memory_order success_order,
459
+ memory_order failure_order) volatile BOOST_NOEXCEPT
460
+ {
461
+ value_type previous = expected;
462
+ platform_fence_before(success_order);
463
+ __asm__ (
464
+ "lock ; cmpxchgw %2, %1"
465
+ : "+a" (previous), "+m" (v_)
466
+ : "q" (desired)
467
+ );
468
+ bool success = (previous == expected);
469
+ if (success)
470
+ platform_fence_after(success_order);
471
+ else
472
+ platform_fence_after(failure_order);
473
+ expected = previous;
474
+ return success;
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
+ return compare_exchange_strong(expected, desired, success_order, failure_order);
485
+ }
486
+
487
+ value_type
488
+ fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
489
+ {
490
+ value_type tmp = load(memory_order_relaxed);
491
+ for (; !compare_exchange_weak(tmp, tmp & v, order, memory_order_relaxed);)
492
+ {
493
+ BOOST_ATOMIC_X86_PAUSE();
494
+ }
495
+ return tmp;
496
+ }
497
+
498
+ value_type
499
+ fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
500
+ {
501
+ value_type tmp = load(memory_order_relaxed);
502
+ for (; !compare_exchange_weak(tmp, tmp | v, order, memory_order_relaxed);)
503
+ {
504
+ BOOST_ATOMIC_X86_PAUSE();
505
+ }
506
+ return tmp;
507
+ }
508
+
509
+ value_type
510
+ fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
511
+ {
512
+ value_type tmp = load(memory_order_relaxed);
513
+ for (; !compare_exchange_weak(tmp, tmp ^ v, order, memory_order_relaxed);)
514
+ {
515
+ BOOST_ATOMIC_X86_PAUSE();
516
+ }
517
+ return tmp;
518
+ }
519
+
520
+ bool
521
+ is_lock_free(void) const volatile BOOST_NOEXCEPT
522
+ {
523
+ return true;
524
+ }
525
+
526
+ BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
527
+ private:
528
+ base_atomic(const base_atomic &) /* = delete */ ;
529
+ void operator=(const base_atomic &) /* = delete */ ;
530
+ value_type v_;
531
+ };
532
+
533
+ template<typename T, bool Sign>
534
+ class base_atomic<T, int, 4, Sign>
535
+ {
536
+ typedef base_atomic this_type;
537
+ typedef T value_type;
538
+ typedef T difference_type;
539
+ public:
540
+ BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
541
+ base_atomic(void) {}
542
+
543
+ void
544
+ store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
545
+ {
546
+ if (order != memory_order_seq_cst) {
547
+ platform_fence_before(order);
548
+ const_cast<volatile value_type &>(v_) = v;
549
+ } else {
550
+ exchange(v, order);
551
+ }
552
+ }
553
+
554
+ value_type
555
+ load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
556
+ {
557
+ value_type v = const_cast<const volatile value_type &>(v_);
558
+ platform_fence_after_load(order);
559
+ return v;
560
+ }
561
+
562
+ value_type
563
+ fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
564
+ {
565
+ platform_fence_before(order);
566
+ __asm__ (
567
+ "lock ; xaddl %0, %1"
568
+ : "+r" (v), "+m" (v_)
569
+ );
570
+ platform_fence_after(order);
571
+ return v;
572
+ }
573
+
574
+ value_type
575
+ fetch_sub(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
576
+ {
577
+ return fetch_add(-v, order);
578
+ }
579
+
580
+ value_type
581
+ exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
582
+ {
583
+ platform_fence_before(order);
584
+ __asm__ (
585
+ "xchgl %0, %1"
586
+ : "+r" (v), "+m" (v_)
587
+ );
588
+ platform_fence_after(order);
589
+ return v;
590
+ }
591
+
592
+ bool
593
+ compare_exchange_strong(
594
+ value_type & expected,
595
+ value_type desired,
596
+ memory_order success_order,
597
+ memory_order failure_order) volatile BOOST_NOEXCEPT
598
+ {
599
+ value_type previous = expected;
600
+ platform_fence_before(success_order);
601
+ __asm__ (
602
+ "lock ; cmpxchgl %2, %1"
603
+ : "+a" (previous), "+m" (v_)
604
+ : "r" (desired)
605
+ );
606
+ bool success = (previous == expected);
607
+ if (success)
608
+ platform_fence_after(success_order);
609
+ else
610
+ platform_fence_after(failure_order);
611
+ expected = previous;
612
+ return success;
613
+ }
614
+
615
+ bool
616
+ compare_exchange_weak(
617
+ value_type & expected,
618
+ value_type desired,
619
+ memory_order success_order,
620
+ memory_order failure_order) volatile BOOST_NOEXCEPT
621
+ {
622
+ return compare_exchange_strong(expected, desired, success_order, failure_order);
623
+ }
624
+
625
+ value_type
626
+ fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
627
+ {
628
+ value_type tmp = load(memory_order_relaxed);
629
+ for (; !compare_exchange_weak(tmp, tmp & v, order, memory_order_relaxed);)
630
+ {
631
+ BOOST_ATOMIC_X86_PAUSE();
632
+ }
633
+ return tmp;
634
+ }
635
+
636
+ value_type
637
+ fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
638
+ {
639
+ value_type tmp = load(memory_order_relaxed);
640
+ for (; !compare_exchange_weak(tmp, tmp | v, order, memory_order_relaxed);)
641
+ {
642
+ BOOST_ATOMIC_X86_PAUSE();
643
+ }
644
+ return tmp;
645
+ }
646
+
647
+ value_type
648
+ fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
649
+ {
650
+ value_type tmp = load(memory_order_relaxed);
651
+ for (; !compare_exchange_weak(tmp, tmp ^ v, order, memory_order_relaxed);)
652
+ {
653
+ BOOST_ATOMIC_X86_PAUSE();
654
+ }
655
+ return tmp;
656
+ }
657
+
658
+ bool
659
+ is_lock_free(void) const volatile BOOST_NOEXCEPT
660
+ {
661
+ return true;
662
+ }
663
+
664
+ BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
665
+ private:
666
+ base_atomic(const base_atomic &) /* = delete */ ;
667
+ void operator=(const base_atomic &) /* = delete */ ;
668
+ value_type v_;
669
+ };
670
+
671
+ #if defined(__x86_64__)
672
+ template<typename T, bool Sign>
673
+ class base_atomic<T, int, 8, Sign>
674
+ {
675
+ typedef base_atomic this_type;
676
+ typedef T value_type;
677
+ typedef T difference_type;
678
+ public:
679
+ BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
680
+ base_atomic(void) {}
681
+
682
+ void
683
+ store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
684
+ {
685
+ if (order != memory_order_seq_cst) {
686
+ platform_fence_before(order);
687
+ const_cast<volatile value_type &>(v_) = v;
688
+ } else {
689
+ exchange(v, order);
690
+ }
691
+ }
692
+
693
+ value_type
694
+ load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
695
+ {
696
+ value_type v = const_cast<const volatile value_type &>(v_);
697
+ platform_fence_after_load(order);
698
+ return v;
699
+ }
700
+
701
+ value_type
702
+ fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
703
+ {
704
+ platform_fence_before(order);
705
+ __asm__ (
706
+ "lock ; xaddq %0, %1"
707
+ : "+r" (v), "+m" (v_)
708
+ );
709
+ platform_fence_after(order);
710
+ return v;
711
+ }
712
+
713
+ value_type
714
+ fetch_sub(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
715
+ {
716
+ return fetch_add(-v, order);
717
+ }
718
+
719
+ value_type
720
+ exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
721
+ {
722
+ platform_fence_before(order);
723
+ __asm__ (
724
+ "xchgq %0, %1"
725
+ : "+r" (v), "+m" (v_)
726
+ );
727
+ platform_fence_after(order);
728
+ return v;
729
+ }
730
+
731
+ bool
732
+ compare_exchange_strong(
733
+ value_type & expected,
734
+ value_type desired,
735
+ memory_order success_order,
736
+ memory_order failure_order) volatile BOOST_NOEXCEPT
737
+ {
738
+ value_type previous = expected;
739
+ platform_fence_before(success_order);
740
+ __asm__ (
741
+ "lock ; cmpxchgq %2, %1"
742
+ : "+a" (previous), "+m" (v_)
743
+ : "r" (desired)
744
+ );
745
+ bool success = (previous == expected);
746
+ if (success)
747
+ platform_fence_after(success_order);
748
+ else
749
+ platform_fence_after(failure_order);
750
+ expected = previous;
751
+ return success;
752
+ }
753
+
754
+ bool
755
+ compare_exchange_weak(
756
+ value_type & expected,
757
+ value_type desired,
758
+ memory_order success_order,
759
+ memory_order failure_order) volatile BOOST_NOEXCEPT
760
+ {
761
+ return compare_exchange_strong(expected, desired, success_order, failure_order);
762
+ }
763
+
764
+ value_type
765
+ fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
766
+ {
767
+ value_type tmp = load(memory_order_relaxed);
768
+ for (; !compare_exchange_weak(tmp, tmp & v, order, memory_order_relaxed);)
769
+ {
770
+ BOOST_ATOMIC_X86_PAUSE();
771
+ }
772
+ return tmp;
773
+ }
774
+
775
+ value_type
776
+ fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
777
+ {
778
+ value_type tmp = load(memory_order_relaxed);
779
+ for (; !compare_exchange_weak(tmp, tmp | v, order, memory_order_relaxed);)
780
+ {
781
+ BOOST_ATOMIC_X86_PAUSE();
782
+ }
783
+ return tmp;
784
+ }
785
+
786
+ value_type
787
+ fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
788
+ {
789
+ value_type tmp = load(memory_order_relaxed);
790
+ for (; !compare_exchange_weak(tmp, tmp ^ v, order, memory_order_relaxed);)
791
+ {
792
+ BOOST_ATOMIC_X86_PAUSE();
793
+ }
794
+ return tmp;
795
+ }
796
+
797
+ bool
798
+ is_lock_free(void) const volatile BOOST_NOEXCEPT
799
+ {
800
+ return true;
801
+ }
802
+
803
+ BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
804
+ private:
805
+ base_atomic(const base_atomic &) /* = delete */ ;
806
+ void operator=(const base_atomic &) /* = delete */ ;
807
+ value_type v_;
808
+ };
809
+
810
+ #endif
811
+
812
+ /* pointers */
813
+
814
+ #if !defined(__x86_64__)
815
+
816
+ template<bool Sign>
817
+ class base_atomic<void *, void *, 4, Sign>
818
+ {
819
+ typedef base_atomic this_type;
820
+ typedef ptrdiff_t difference_type;
821
+ typedef void * value_type;
822
+ public:
823
+ BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
824
+ base_atomic(void) {}
825
+
826
+ void
827
+ store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
828
+ {
829
+ if (order != memory_order_seq_cst) {
830
+ platform_fence_before(order);
831
+ const_cast<volatile value_type &>(v_) = v;
832
+ } else {
833
+ exchange(v, order);
834
+ }
835
+ }
836
+
837
+ value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
838
+ {
839
+ value_type v = const_cast<const volatile value_type &>(v_);
840
+ platform_fence_after_load(order);
841
+ return v;
842
+ }
843
+
844
+ value_type exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
845
+ {
846
+ platform_fence_before(order);
847
+ __asm__ (
848
+ "xchgl %0, %1"
849
+ : "+r" (v), "+m" (v_)
850
+ );
851
+ platform_fence_after(order);
852
+ return v;
853
+ }
854
+
855
+ bool compare_exchange_strong(value_type & expected, value_type desired,
856
+ memory_order success_order,
857
+ memory_order failure_order) volatile BOOST_NOEXCEPT
858
+ {
859
+ value_type previous = expected;
860
+ platform_fence_before(success_order);
861
+ __asm__ (
862
+ "lock ; cmpxchgl %2, %1"
863
+ : "+a" (previous), "+m" (v_)
864
+ : "r" (desired)
865
+ );
866
+ bool success = (previous == expected);
867
+ if (success)
868
+ platform_fence_after(success_order);
869
+ else
870
+ platform_fence_after(failure_order);
871
+ expected = previous;
872
+ return success;
873
+ }
874
+
875
+ bool compare_exchange_weak(value_type & expected, value_type desired,
876
+ memory_order success_order,
877
+ memory_order failure_order) volatile BOOST_NOEXCEPT
878
+ {
879
+ return compare_exchange_strong(expected, desired, success_order, failure_order);
880
+ }
881
+
882
+ bool
883
+ is_lock_free(void) const volatile BOOST_NOEXCEPT
884
+ {
885
+ return true;
886
+ }
887
+
888
+ value_type
889
+ fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
890
+ {
891
+ platform_fence_before(order);
892
+ __asm__ (
893
+ "lock ; xaddl %0, %1"
894
+ : "+r" (v), "+m" (v_)
895
+ );
896
+ platform_fence_after(order);
897
+ return reinterpret_cast<value_type>(v);
898
+ }
899
+
900
+ value_type
901
+ fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
902
+ {
903
+ return fetch_add(-v, order);
904
+ }
905
+
906
+ BOOST_ATOMIC_DECLARE_VOID_POINTER_OPERATORS
907
+ private:
908
+ base_atomic(const base_atomic &) /* = delete */ ;
909
+ void operator=(const base_atomic &) /* = delete */ ;
910
+ value_type v_;
911
+ };
912
+
913
+ template<typename T, bool Sign>
914
+ class base_atomic<T *, void *, 4, Sign>
915
+ {
916
+ typedef base_atomic this_type;
917
+ typedef T * value_type;
918
+ typedef ptrdiff_t difference_type;
919
+ public:
920
+ BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
921
+ base_atomic(void) {}
922
+
923
+ void
924
+ store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
925
+ {
926
+ if (order != memory_order_seq_cst) {
927
+ platform_fence_before(order);
928
+ const_cast<volatile value_type &>(v_) = v;
929
+ } else {
930
+ exchange(v, order);
931
+ }
932
+ }
933
+
934
+ value_type
935
+ load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
936
+ {
937
+ value_type v = const_cast<const volatile value_type &>(v_);
938
+ platform_fence_after_load(order);
939
+ return v;
940
+ }
941
+
942
+ value_type
943
+ exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
944
+ {
945
+ platform_fence_before(order);
946
+ __asm__ (
947
+ "xchgl %0, %1"
948
+ : "+r" (v), "+m" (v_)
949
+ );
950
+ platform_fence_after(order);
951
+ return v;
952
+ }
953
+
954
+ bool
955
+ compare_exchange_strong(
956
+ value_type & expected,
957
+ value_type desired,
958
+ memory_order success_order,
959
+ memory_order failure_order) volatile BOOST_NOEXCEPT
960
+ {
961
+ value_type previous = expected;
962
+ platform_fence_before(success_order);
963
+ __asm__ (
964
+ "lock ; cmpxchgl %2, %1"
965
+ : "+a" (previous), "+m" (v_)
966
+ : "r" (desired)
967
+ );
968
+ bool success = (previous == expected);
969
+ if (success)
970
+ platform_fence_after(success_order);
971
+ else
972
+ platform_fence_after(failure_order);
973
+ expected = previous;
974
+ return success;
975
+ }
976
+
977
+ bool
978
+ compare_exchange_weak(
979
+ value_type & expected,
980
+ value_type desired,
981
+ memory_order success_order,
982
+ memory_order failure_order) volatile BOOST_NOEXCEPT
983
+ {
984
+ return compare_exchange_strong(expected, desired, success_order, failure_order);
985
+ }
986
+
987
+ value_type
988
+ fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
989
+ {
990
+ v = v * sizeof(*v_);
991
+ platform_fence_before(order);
992
+ __asm__ (
993
+ "lock ; xaddl %0, %1"
994
+ : "+r" (v), "+m" (v_)
995
+ );
996
+ platform_fence_after(order);
997
+ return reinterpret_cast<value_type>(v);
998
+ }
999
+
1000
+ value_type
1001
+ fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1002
+ {
1003
+ return fetch_add(-v, order);
1004
+ }
1005
+
1006
+ bool
1007
+ is_lock_free(void) const volatile BOOST_NOEXCEPT
1008
+ {
1009
+ return true;
1010
+ }
1011
+
1012
+ BOOST_ATOMIC_DECLARE_POINTER_OPERATORS
1013
+ private:
1014
+ base_atomic(const base_atomic &) /* = delete */ ;
1015
+ void operator=(const base_atomic &) /* = delete */ ;
1016
+ value_type v_;
1017
+ };
1018
+
1019
+ #else
1020
+
1021
+ template<bool Sign>
1022
+ class base_atomic<void *, void *, 8, Sign>
1023
+ {
1024
+ typedef base_atomic this_type;
1025
+ typedef ptrdiff_t difference_type;
1026
+ typedef void * value_type;
1027
+ public:
1028
+ BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
1029
+ base_atomic(void) {}
1030
+
1031
+ void
1032
+ store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1033
+ {
1034
+ if (order != memory_order_seq_cst) {
1035
+ platform_fence_before(order);
1036
+ const_cast<volatile value_type &>(v_) = v;
1037
+ } else {
1038
+ exchange(v, order);
1039
+ }
1040
+ }
1041
+
1042
+ value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
1043
+ {
1044
+ value_type v = const_cast<const volatile value_type &>(v_);
1045
+ platform_fence_after_load(order);
1046
+ return v;
1047
+ }
1048
+
1049
+ value_type exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1050
+ {
1051
+ platform_fence_before(order);
1052
+ __asm__ (
1053
+ "xchgq %0, %1"
1054
+ : "+r" (v), "+m" (v_)
1055
+ );
1056
+ platform_fence_after(order);
1057
+ return v;
1058
+ }
1059
+
1060
+ bool compare_exchange_strong(value_type & expected, value_type desired,
1061
+ memory_order success_order,
1062
+ memory_order failure_order) volatile BOOST_NOEXCEPT
1063
+ {
1064
+ value_type previous = expected;
1065
+ platform_fence_before(success_order);
1066
+ __asm__ (
1067
+ "lock ; cmpxchgq %2, %1"
1068
+ : "+a" (previous), "+m" (v_)
1069
+ : "r" (desired)
1070
+ );
1071
+ bool success = (previous == expected);
1072
+ if (success)
1073
+ platform_fence_after(success_order);
1074
+ else
1075
+ platform_fence_after(failure_order);
1076
+ expected = previous;
1077
+ return success;
1078
+ }
1079
+
1080
+ bool compare_exchange_weak(value_type & expected, value_type desired,
1081
+ memory_order success_order,
1082
+ memory_order failure_order) volatile BOOST_NOEXCEPT
1083
+ {
1084
+ return compare_exchange_strong(expected, desired, success_order, failure_order);
1085
+ }
1086
+
1087
+ bool
1088
+ is_lock_free(void) const volatile BOOST_NOEXCEPT
1089
+ {
1090
+ return true;
1091
+ }
1092
+
1093
+ value_type
1094
+ fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1095
+ {
1096
+ platform_fence_before(order);
1097
+ __asm__ (
1098
+ "lock ; xaddq %0, %1"
1099
+ : "+r" (v), "+m" (v_)
1100
+ );
1101
+ platform_fence_after(order);
1102
+ return reinterpret_cast<value_type>(v);
1103
+ }
1104
+
1105
+ value_type
1106
+ fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1107
+ {
1108
+ return fetch_add(-v, order);
1109
+ }
1110
+
1111
+ BOOST_ATOMIC_DECLARE_VOID_POINTER_OPERATORS
1112
+ private:
1113
+ base_atomic(const base_atomic &) /* = delete */ ;
1114
+ void operator=(const base_atomic &) /* = delete */ ;
1115
+ value_type v_;
1116
+ };
1117
+
1118
+ template<typename T, bool Sign>
1119
+ class base_atomic<T *, void *, 8, Sign>
1120
+ {
1121
+ typedef base_atomic this_type;
1122
+ typedef T * value_type;
1123
+ typedef ptrdiff_t difference_type;
1124
+ public:
1125
+ BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
1126
+ base_atomic(void) {}
1127
+
1128
+ void
1129
+ store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1130
+ {
1131
+ if (order != memory_order_seq_cst) {
1132
+ platform_fence_before(order);
1133
+ const_cast<volatile value_type &>(v_) = v;
1134
+ } else {
1135
+ exchange(v, order);
1136
+ }
1137
+ }
1138
+
1139
+ value_type
1140
+ load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
1141
+ {
1142
+ value_type v = const_cast<const volatile value_type &>(v_);
1143
+ platform_fence_after_load(order);
1144
+ return v;
1145
+ }
1146
+
1147
+ value_type
1148
+ exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1149
+ {
1150
+ platform_fence_before(order);
1151
+ __asm__ (
1152
+ "xchgq %0, %1"
1153
+ : "+r" (v), "+m" (v_)
1154
+ );
1155
+ platform_fence_after(order);
1156
+ return v;
1157
+ }
1158
+
1159
+ bool
1160
+ compare_exchange_strong(
1161
+ value_type & expected,
1162
+ value_type desired,
1163
+ memory_order success_order,
1164
+ memory_order failure_order) volatile BOOST_NOEXCEPT
1165
+ {
1166
+ value_type previous = expected;
1167
+ platform_fence_before(success_order);
1168
+ __asm__ (
1169
+ "lock ; cmpxchgq %2, %1"
1170
+ : "+a" (previous), "+m" (v_)
1171
+ : "r" (desired)
1172
+ );
1173
+ bool success = (previous == expected);
1174
+ if (success)
1175
+ platform_fence_after(success_order);
1176
+ else
1177
+ platform_fence_after(failure_order);
1178
+ expected = previous;
1179
+ return success;
1180
+ }
1181
+
1182
+ bool
1183
+ compare_exchange_weak(
1184
+ value_type & expected,
1185
+ value_type desired,
1186
+ memory_order success_order,
1187
+ memory_order failure_order) volatile BOOST_NOEXCEPT
1188
+ {
1189
+ return compare_exchange_strong(expected, desired, success_order, failure_order);
1190
+ }
1191
+
1192
+ value_type
1193
+ fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1194
+ {
1195
+ v = v * sizeof(*v_);
1196
+ platform_fence_before(order);
1197
+ __asm__ (
1198
+ "lock ; xaddq %0, %1"
1199
+ : "+r" (v), "+m" (v_)
1200
+ );
1201
+ platform_fence_after(order);
1202
+ return reinterpret_cast<value_type>(v);
1203
+ }
1204
+
1205
+ value_type
1206
+ fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1207
+ {
1208
+ return fetch_add(-v, order);
1209
+ }
1210
+
1211
+ bool
1212
+ is_lock_free(void) const volatile BOOST_NOEXCEPT
1213
+ {
1214
+ return true;
1215
+ }
1216
+
1217
+ BOOST_ATOMIC_DECLARE_POINTER_OPERATORS
1218
+ private:
1219
+ base_atomic(const base_atomic &) /* = delete */ ;
1220
+ void operator=(const base_atomic &) /* = delete */ ;
1221
+ value_type v_;
1222
+ };
1223
+
1224
+ #endif
1225
+
1226
+ template<typename T, bool Sign>
1227
+ class base_atomic<T, void, 1, Sign>
1228
+ {
1229
+ typedef base_atomic this_type;
1230
+ typedef T value_type;
1231
+ typedef uint8_t storage_type;
1232
+ public:
1233
+ BOOST_CONSTEXPR explicit base_atomic(value_type const& v) BOOST_NOEXCEPT :
1234
+ v_(reinterpret_cast<storage_type const&>(v))
1235
+ {}
1236
+ base_atomic(void) {}
1237
+
1238
+ void
1239
+ store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1240
+ {
1241
+ if (order != memory_order_seq_cst) {
1242
+ storage_type tmp;
1243
+ memcpy(&tmp, &v, sizeof(value_type));
1244
+ platform_fence_before(order);
1245
+ const_cast<volatile storage_type &>(v_) = tmp;
1246
+ } else {
1247
+ exchange(v, order);
1248
+ }
1249
+ }
1250
+
1251
+ value_type
1252
+ load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
1253
+ {
1254
+ storage_type tmp = const_cast<volatile storage_type &>(v_);
1255
+ platform_fence_after_load(order);
1256
+ value_type v;
1257
+ memcpy(&v, &tmp, sizeof(value_type));
1258
+ return v;
1259
+ }
1260
+
1261
+ value_type
1262
+ exchange(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1263
+ {
1264
+ storage_type tmp;
1265
+ memcpy(&tmp, &v, sizeof(value_type));
1266
+ platform_fence_before(order);
1267
+ __asm__ (
1268
+ "xchgb %0, %1"
1269
+ : "+q" (tmp), "+m" (v_)
1270
+ );
1271
+ platform_fence_after(order);
1272
+ value_type res;
1273
+ memcpy(&res, &tmp, sizeof(value_type));
1274
+ return res;
1275
+ }
1276
+
1277
+ bool
1278
+ compare_exchange_strong(
1279
+ value_type & expected,
1280
+ value_type const& desired,
1281
+ memory_order success_order,
1282
+ memory_order failure_order) volatile BOOST_NOEXCEPT
1283
+ {
1284
+ storage_type expected_s, desired_s;
1285
+ memcpy(&expected_s, &expected, sizeof(value_type));
1286
+ memcpy(&desired_s, &desired, sizeof(value_type));
1287
+ storage_type previous_s = expected_s;
1288
+ platform_fence_before(success_order);
1289
+ __asm__ (
1290
+ "lock ; cmpxchgb %2, %1"
1291
+ : "+a" (previous_s), "+m" (v_)
1292
+ : "q" (desired_s)
1293
+ );
1294
+ bool success = (previous_s == expected_s);
1295
+ if (success)
1296
+ platform_fence_after(success_order);
1297
+ else
1298
+ platform_fence_after(failure_order);
1299
+ memcpy(&expected, &previous_s, sizeof(value_type));
1300
+ return success;
1301
+ }
1302
+
1303
+ bool
1304
+ compare_exchange_weak(
1305
+ value_type & expected,
1306
+ value_type const& desired,
1307
+ memory_order success_order,
1308
+ memory_order failure_order) volatile BOOST_NOEXCEPT
1309
+ {
1310
+ return compare_exchange_strong(expected, desired, success_order, failure_order);
1311
+ }
1312
+
1313
+ bool
1314
+ is_lock_free(void) const volatile BOOST_NOEXCEPT
1315
+ {
1316
+ return true;
1317
+ }
1318
+
1319
+ BOOST_ATOMIC_DECLARE_BASE_OPERATORS
1320
+ private:
1321
+ base_atomic(const base_atomic &) /* = delete */ ;
1322
+ void operator=(const base_atomic &) /* = delete */ ;
1323
+ storage_type v_;
1324
+ };
1325
+
1326
+ template<typename T, bool Sign>
1327
+ class base_atomic<T, void, 2, Sign>
1328
+ {
1329
+ typedef base_atomic this_type;
1330
+ typedef T value_type;
1331
+ typedef uint16_t storage_type;
1332
+ public:
1333
+ BOOST_CONSTEXPR explicit base_atomic(value_type const& v) BOOST_NOEXCEPT :
1334
+ v_(reinterpret_cast<storage_type const&>(v))
1335
+ {}
1336
+ base_atomic(void) {}
1337
+
1338
+ void
1339
+ store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1340
+ {
1341
+ if (order != memory_order_seq_cst) {
1342
+ storage_type tmp;
1343
+ memcpy(&tmp, &v, sizeof(value_type));
1344
+ platform_fence_before(order);
1345
+ const_cast<volatile storage_type &>(v_) = tmp;
1346
+ } else {
1347
+ exchange(v, order);
1348
+ }
1349
+ }
1350
+
1351
+ value_type
1352
+ load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
1353
+ {
1354
+ storage_type tmp = const_cast<volatile storage_type &>(v_);
1355
+ platform_fence_after_load(order);
1356
+ value_type v;
1357
+ memcpy(&v, &tmp, sizeof(value_type));
1358
+ return v;
1359
+ }
1360
+
1361
+ value_type
1362
+ exchange(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1363
+ {
1364
+ storage_type tmp;
1365
+ memcpy(&tmp, &v, sizeof(value_type));
1366
+ platform_fence_before(order);
1367
+ __asm__ (
1368
+ "xchgw %0, %1"
1369
+ : "+q" (tmp), "+m" (v_)
1370
+ );
1371
+ platform_fence_after(order);
1372
+ value_type res;
1373
+ memcpy(&res, &tmp, sizeof(value_type));
1374
+ return res;
1375
+ }
1376
+
1377
+ bool
1378
+ compare_exchange_strong(
1379
+ value_type & expected,
1380
+ value_type const& desired,
1381
+ memory_order success_order,
1382
+ memory_order failure_order) volatile BOOST_NOEXCEPT
1383
+ {
1384
+ storage_type expected_s, desired_s;
1385
+ memcpy(&expected_s, &expected, sizeof(value_type));
1386
+ memcpy(&desired_s, &desired, sizeof(value_type));
1387
+ storage_type previous_s = expected_s;
1388
+ platform_fence_before(success_order);
1389
+ __asm__ (
1390
+ "lock ; cmpxchgw %2, %1"
1391
+ : "+a" (previous_s), "+m" (v_)
1392
+ : "q" (desired_s)
1393
+ );
1394
+ bool success = (previous_s == expected_s);
1395
+ if (success)
1396
+ platform_fence_after(success_order);
1397
+ else
1398
+ platform_fence_after(failure_order);
1399
+ memcpy(&expected, &previous_s, sizeof(value_type));
1400
+ return success;
1401
+ }
1402
+
1403
+ bool
1404
+ compare_exchange_weak(
1405
+ value_type & expected,
1406
+ value_type const& desired,
1407
+ memory_order success_order,
1408
+ memory_order failure_order) volatile BOOST_NOEXCEPT
1409
+ {
1410
+ return compare_exchange_strong(expected, desired, success_order, failure_order);
1411
+ }
1412
+
1413
+ bool
1414
+ is_lock_free(void) const volatile BOOST_NOEXCEPT
1415
+ {
1416
+ return true;
1417
+ }
1418
+
1419
+ BOOST_ATOMIC_DECLARE_BASE_OPERATORS
1420
+ private:
1421
+ base_atomic(const base_atomic &) /* = delete */ ;
1422
+ void operator=(const base_atomic &) /* = delete */ ;
1423
+ storage_type v_;
1424
+ };
1425
+
1426
+ template<typename T, bool Sign>
1427
+ class base_atomic<T, void, 4, Sign>
1428
+ {
1429
+ typedef base_atomic this_type;
1430
+ typedef T value_type;
1431
+ typedef uint32_t storage_type;
1432
+ public:
1433
+ explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0)
1434
+ {
1435
+ memcpy(&v_, &v, sizeof(value_type));
1436
+ }
1437
+ base_atomic(void) {}
1438
+
1439
+ void
1440
+ store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1441
+ {
1442
+ if (order != memory_order_seq_cst) {
1443
+ storage_type tmp = 0;
1444
+ memcpy(&tmp, &v, sizeof(value_type));
1445
+ platform_fence_before(order);
1446
+ const_cast<volatile storage_type &>(v_) = tmp;
1447
+ } else {
1448
+ exchange(v, order);
1449
+ }
1450
+ }
1451
+
1452
+ value_type
1453
+ load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
1454
+ {
1455
+ storage_type tmp = const_cast<volatile storage_type &>(v_);
1456
+ platform_fence_after_load(order);
1457
+ value_type v;
1458
+ memcpy(&v, &tmp, sizeof(value_type));
1459
+ return v;
1460
+ }
1461
+
1462
+ value_type
1463
+ exchange(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1464
+ {
1465
+ storage_type tmp = 0;
1466
+ memcpy(&tmp, &v, sizeof(value_type));
1467
+ platform_fence_before(order);
1468
+ __asm__ (
1469
+ "xchgl %0, %1"
1470
+ : "+q" (tmp), "+m" (v_)
1471
+ );
1472
+ platform_fence_after(order);
1473
+ value_type res;
1474
+ memcpy(&res, &tmp, sizeof(value_type));
1475
+ return res;
1476
+ }
1477
+
1478
+ bool
1479
+ compare_exchange_strong(
1480
+ value_type & expected,
1481
+ value_type const& desired,
1482
+ memory_order success_order,
1483
+ memory_order failure_order) volatile BOOST_NOEXCEPT
1484
+ {
1485
+ storage_type expected_s = 0, desired_s = 0;
1486
+ memcpy(&expected_s, &expected, sizeof(value_type));
1487
+ memcpy(&desired_s, &desired, sizeof(value_type));
1488
+ storage_type previous_s = expected_s;
1489
+ platform_fence_before(success_order);
1490
+ __asm__ (
1491
+ "lock ; cmpxchgl %2, %1"
1492
+ : "+a" (previous_s), "+m" (v_)
1493
+ : "q" (desired_s)
1494
+ );
1495
+ bool success = (previous_s == expected_s);
1496
+ if (success)
1497
+ platform_fence_after(success_order);
1498
+ else
1499
+ platform_fence_after(failure_order);
1500
+ memcpy(&expected, &previous_s, sizeof(value_type));
1501
+ return success;
1502
+ }
1503
+
1504
+ bool
1505
+ compare_exchange_weak(
1506
+ value_type & expected,
1507
+ value_type const& desired,
1508
+ memory_order success_order,
1509
+ memory_order failure_order) volatile BOOST_NOEXCEPT
1510
+ {
1511
+ return compare_exchange_strong(expected, desired, success_order, failure_order);
1512
+ }
1513
+
1514
+ bool
1515
+ is_lock_free(void) const volatile BOOST_NOEXCEPT
1516
+ {
1517
+ return true;
1518
+ }
1519
+
1520
+ BOOST_ATOMIC_DECLARE_BASE_OPERATORS
1521
+ private:
1522
+ base_atomic(const base_atomic &) /* = delete */ ;
1523
+ void operator=(const base_atomic &) /* = delete */ ;
1524
+ storage_type v_;
1525
+ };
1526
+
1527
+ #if defined(__x86_64__)
1528
+ template<typename T, bool Sign>
1529
+ class base_atomic<T, void, 8, Sign>
1530
+ {
1531
+ typedef base_atomic this_type;
1532
+ typedef T value_type;
1533
+ typedef uint64_t storage_type;
1534
+ public:
1535
+ explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0)
1536
+ {
1537
+ memcpy(&v_, &v, sizeof(value_type));
1538
+ }
1539
+ base_atomic(void) {}
1540
+
1541
+ void
1542
+ store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1543
+ {
1544
+ if (order != memory_order_seq_cst) {
1545
+ storage_type tmp = 0;
1546
+ memcpy(&tmp, &v, sizeof(value_type));
1547
+ platform_fence_before(order);
1548
+ const_cast<volatile storage_type &>(v_) = tmp;
1549
+ } else {
1550
+ exchange(v, order);
1551
+ }
1552
+ }
1553
+
1554
+ value_type
1555
+ load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
1556
+ {
1557
+ storage_type tmp = const_cast<volatile storage_type &>(v_);
1558
+ platform_fence_after_load(order);
1559
+ value_type v;
1560
+ memcpy(&v, &tmp, sizeof(value_type));
1561
+ return v;
1562
+ }
1563
+
1564
+ value_type
1565
+ exchange(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
1566
+ {
1567
+ storage_type tmp = 0;
1568
+ memcpy(&tmp, &v, sizeof(value_type));
1569
+ platform_fence_before(order);
1570
+ __asm__ (
1571
+ "xchgq %0, %1"
1572
+ : "+q" (tmp), "+m" (v_)
1573
+ );
1574
+ platform_fence_after(order);
1575
+ value_type res;
1576
+ memcpy(&res, &tmp, sizeof(value_type));
1577
+ return res;
1578
+ }
1579
+
1580
+ bool
1581
+ compare_exchange_strong(
1582
+ value_type & expected,
1583
+ value_type const& desired,
1584
+ memory_order success_order,
1585
+ memory_order failure_order) volatile BOOST_NOEXCEPT
1586
+ {
1587
+ storage_type expected_s = 0, desired_s = 0;
1588
+ memcpy(&expected_s, &expected, sizeof(value_type));
1589
+ memcpy(&desired_s, &desired, sizeof(value_type));
1590
+ storage_type previous_s = expected_s;
1591
+ platform_fence_before(success_order);
1592
+ __asm__ (
1593
+ "lock ; cmpxchgq %2, %1"
1594
+ : "+a" (previous_s), "+m" (v_)
1595
+ : "q" (desired_s)
1596
+ );
1597
+ bool success = (previous_s == expected_s);
1598
+ if (success)
1599
+ platform_fence_after(success_order);
1600
+ else
1601
+ platform_fence_after(failure_order);
1602
+ memcpy(&expected, &previous_s, sizeof(value_type));
1603
+ return success;
1604
+ }
1605
+
1606
+ bool
1607
+ compare_exchange_weak(
1608
+ value_type & expected,
1609
+ value_type const& desired,
1610
+ memory_order success_order,
1611
+ memory_order failure_order) volatile BOOST_NOEXCEPT
1612
+ {
1613
+ return compare_exchange_strong(expected, desired, success_order, failure_order);
1614
+ }
1615
+
1616
+ bool
1617
+ is_lock_free(void) const volatile BOOST_NOEXCEPT
1618
+ {
1619
+ return true;
1620
+ }
1621
+
1622
+ BOOST_ATOMIC_DECLARE_BASE_OPERATORS
1623
+ private:
1624
+ base_atomic(const base_atomic &) /* = delete */ ;
1625
+ void operator=(const base_atomic &) /* = delete */ ;
1626
+ storage_type v_;
1627
+ };
1628
+ #endif
1629
+
1630
+ #if !defined(__x86_64__) && defined(BOOST_ATOMIC_X86_HAS_CMPXCHG8B)
1631
+
1632
+ template<typename T>
1633
+ inline bool
1634
+ platform_cmpxchg64_strong(T & expected, T desired, volatile T * ptr) BOOST_NOEXCEPT
1635
+ {
1636
+ #ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8
1637
+ const T oldval = __sync_val_compare_and_swap(ptr, expected, desired);
1638
+ const bool result = (oldval == expected);
1639
+ expected = oldval;
1640
+ return result;
1641
+ #else
1642
+ uint32_t scratch;
1643
+ T prev = expected;
1644
+ /* Make sure ebx is saved and restored properly in case
1645
+ this object is compiled as "position independent". Since
1646
+ programmers on x86 tend to forget specifying -DPIC or
1647
+ similar, always assume PIC.
1648
+
1649
+ To make this work uniformly even in the non-PIC case,
1650
+ setup register constraints such that ebx can not be
1651
+ used by accident e.g. as base address for the variable
1652
+ to be modified. Accessing "scratch" should always be okay,
1653
+ as it can only be placed on the stack (and therefore
1654
+ accessed through ebp or esp only).
1655
+
1656
+ In theory, could push/pop ebx onto/off the stack, but movs
1657
+ to a prepared stack slot turn out to be faster. */
1658
+ __asm__ __volatile__ (
1659
+ "movl %%ebx, %1\n"
1660
+ "movl %2, %%ebx\n"
1661
+ "lock; cmpxchg8b 0(%4)\n"
1662
+ "movl %1, %%ebx\n"
1663
+ : "=A" (prev), "=m" (scratch)
1664
+ : "D" ((uint32_t)desired), "c" ((uint32_t)(desired >> 32)), "S" (ptr), "0" (prev)
1665
+ : "memory");
1666
+ bool success = (prev == expected);
1667
+ expected = prev;
1668
+ return success;
1669
+ #endif
1670
+ }
1671
+
1672
+ // Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 3A, 8.1.1. Guaranteed Atomic Operations:
1673
+ //
1674
+ // The Pentium processor (and newer processors since) guarantees that the following additional memory operations will always be carried out atomically:
1675
+ // * Reading or writing a quadword aligned on a 64-bit boundary
1676
+ //
1677
+ // Luckily, the memory is almost always 8-byte aligned in our case because atomic<> uses 64 bit native types for storage and dynamic memory allocations
1678
+ // have at least 8 byte alignment. The only unfortunate case is when atomic is placeod on the stack and it is not 8-byte aligned (like on 32 bit Windows).
1679
+
1680
+ template<typename T>
1681
+ inline void
1682
+ platform_store64(T value, volatile T * ptr) BOOST_NOEXCEPT
1683
+ {
1684
+ if (((uint32_t)ptr & 0x00000007) == 0)
1685
+ {
1686
+ #if defined(__SSE2__)
1687
+ __asm__ __volatile__
1688
+ (
1689
+ "movq %1, %%xmm0\n\t"
1690
+ "movq %%xmm0, %0\n\t"
1691
+ : "=m" (*ptr)
1692
+ : "m" (value)
1693
+ : "memory", "xmm0"
1694
+ );
1695
+ #else
1696
+ __asm__ __volatile__
1697
+ (
1698
+ "fildll %1\n\t"
1699
+ "fistpll %0\n\t"
1700
+ : "=m" (*ptr)
1701
+ : "m" (value)
1702
+ : "memory"
1703
+ );
1704
+ #endif
1705
+ }
1706
+ else
1707
+ {
1708
+ T expected = *ptr;
1709
+ while (!platform_cmpxchg64_strong(expected, value, ptr))
1710
+ {
1711
+ BOOST_ATOMIC_X86_PAUSE();
1712
+ }
1713
+ }
1714
+ }
1715
+
1716
+ template<typename T>
1717
+ inline T
1718
+ platform_load64(const volatile T * ptr) BOOST_NOEXCEPT
1719
+ {
1720
+ T value = T();
1721
+
1722
+ if (((uint32_t)ptr & 0x00000007) == 0)
1723
+ {
1724
+ #if defined(__SSE2__)
1725
+ __asm__ __volatile__
1726
+ (
1727
+ "movq %1, %%xmm0\n\t"
1728
+ "movq %%xmm0, %0\n\t"
1729
+ : "=m" (value)
1730
+ : "m" (*ptr)
1731
+ : "memory", "xmm0"
1732
+ );
1733
+ #else
1734
+ __asm__ __volatile__
1735
+ (
1736
+ "fildll %1\n\t"
1737
+ "fistpll %0\n\t"
1738
+ : "=m" (value)
1739
+ : "m" (*ptr)
1740
+ : "memory"
1741
+ );
1742
+ #endif
1743
+ }
1744
+ else
1745
+ {
1746
+ // We don't care for comparison result here; the previous value will be stored into value anyway.
1747
+ platform_cmpxchg64_strong(value, value, const_cast<volatile T*>(ptr));
1748
+ }
1749
+
1750
+ return value;
1751
+ }
1752
+
1753
+ #endif
1754
+
1755
+ }
1756
+ }
1757
+ }
1758
+
1759
+ /* pull in 64-bit atomic type using cmpxchg8b above */
1760
+ #if !defined(__x86_64__) && defined(BOOST_ATOMIC_X86_HAS_CMPXCHG8B)
1761
+ #include <boost/atomic/detail/cas64strong.hpp>
1762
+ #endif
1763
+
1764
+ #endif /* !defined(BOOST_ATOMIC_FORCE_FALLBACK) */
1765
+
1766
+ #endif