51-refstring.patch 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. diff --git a/src/include/refstring.h b/src/include/refstring.h
  2. index 7845224..72daaef 100644
  3. --- a/src/include/refstring.h
  4. +++ b/src/include/refstring.h
  5. @@ -9,12 +9,18 @@
  6. #ifndef _LIBCPP_REFSTRING_H
  7. #define _LIBCPP_REFSTRING_H
  8. -#include "atomic_support.h"
  9. #include <__config>
  10. #include <cstddef>
  11. #include <cstring>
  12. #include <stdexcept>
  13. +#if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_USE_ATOMIC)
  14. +# define _LIBCPP_USE_ATOMIC
  15. +# include <atomic>
  16. +#else
  17. +# include "atomic_support.h"
  18. +#endif
  19. +
  20. // MacOS and iOS used to ship with libstdc++, and still support old applications
  21. // linking against libstdc++. The libc++ and libstdc++ exceptions are supposed
  22. // to be ABI compatible, such that they can be thrown from one library and caught
  23. @@ -40,7 +46,11 @@ typedef int count_t;
  24. struct _Rep_base {
  25. std::size_t len;
  26. std::size_t cap;
  27. +#ifdef _LIBCPP_USE_ATOMIC
  28. + std::atomic<count_t> count;
  29. +#else
  30. count_t count;
  31. +#endif
  32. };
  33. inline _Rep_base* rep_from_data(const char* data_) noexcept {
  34. @@ -88,7 +98,11 @@ inline __libcpp_refstring::__libcpp_refstring(const char* msg) {
  35. inline __libcpp_refstring::__libcpp_refstring(const __libcpp_refstring& s) noexcept : __imp_(s.__imp_) {
  36. if (__uses_refcount())
  37. +#ifdef _LIBCPP_USE_ATOMIC
  38. + rep_from_data(__imp_)->count.fetch_add(1);
  39. +#else
  40. __libcpp_atomic_add(&rep_from_data(__imp_)->count, 1);
  41. +#endif
  42. }
  43. inline __libcpp_refstring& __libcpp_refstring::operator=(__libcpp_refstring const& s) noexcept {
  44. @@ -96,9 +110,19 @@ inline __libcpp_refstring& __libcpp_refstring::operator=(__libcpp_refstring cons
  45. struct _Rep_base* old_rep = rep_from_data(__imp_);
  46. __imp_ = s.__imp_;
  47. if (__uses_refcount())
  48. +#ifdef _LIBCPP_USE_ATOMIC
  49. + rep_from_data(__imp_)->count.fetch_add(1);
  50. +#else
  51. __libcpp_atomic_add(&rep_from_data(__imp_)->count, 1);
  52. +#endif
  53. +
  54. if (adjust_old_count) {
  55. - if (__libcpp_atomic_add(&old_rep->count, count_t(-1)) < 0) {
  56. +#ifdef _LIBCPP_USE_ATOMIC
  57. + if (old_rep->count.fetch_sub(1) == 0)
  58. +#else
  59. + if (__libcpp_atomic_add(&old_rep->count, count_t(-1)) < 0)
  60. +#endif
  61. + {
  62. ::operator delete(old_rep);
  63. }
  64. }
  65. @@ -108,7 +132,11 @@ inline __libcpp_refstring& __libcpp_refstring::operator=(__libcpp_refstring cons
  66. inline __libcpp_refstring::~__libcpp_refstring() {
  67. if (__uses_refcount()) {
  68. _Rep_base* rep = rep_from_data(__imp_);
  69. +#ifdef _LIBCPP_USE_ATOMIC
  70. + if (rep->count.fetch_sub(1) == 0) {
  71. +#else
  72. if (__libcpp_atomic_add(&rep->count, count_t(-1)) < 0) {
  73. +#endif
  74. ::operator delete(rep);
  75. }
  76. }