Some fixes for open breaks on MacOS and UBSan
Cr-Mirrored-From: https://chromium.googlesource.com/external/github.com/llvm/llvm-project
Cr-Mirrored-Commit: 621388468b5125f05d649262681676bed2faefe6
diff --git a/include/__threading_support b/include/__threading_support
index 50f65fe..e9c727e 100644
--- a/include/__threading_support
+++ b/include/__threading_support
@@ -26,18 +26,12 @@
#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
# include <pthread.h>
# include <sched.h>
-// FIXME: On Apple, <semaphore.h> transitively includes <sys/param.h>, which
-// is not well behaved because it defines several macros. This causes
-// name collisions in some downstream projects. Instead, <sys/semaphore.h>
-// gives us the declarations we need without the bad stuff.
-#ifdef __APPLE__
-# include <sys/semaphore.h>
-#else
-# include <semaphore.h>
-#endif
# ifdef __APPLE__
# define _LIBCPP_NO_NATIVE_SEMAPHORES
# endif
+# ifndef _LIBCPP_NO_NATIVE_SEMAPHORES
+# include <semaphore.h>
+# endif
#elif defined(_LIBCPP_HAS_THREAD_API_C11)
# include <threads.h>
#endif
@@ -77,9 +71,11 @@
typedef pthread_cond_t __libcpp_condvar_t;
#define _LIBCPP_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER
+#ifndef _LIBCPP_NO_NATIVE_SEMAPHORES
// Semaphore
typedef sem_t __libcpp_semaphore_t;
-#define _LIBCPP_SEMAPHORE_MAX SEM_VALUE_MAX
+# define _LIBCPP_SEMAPHORE_MAX SEM_VALUE_MAX
+#endif
// Execute once
typedef pthread_once_t __libcpp_exec_once_flag;
@@ -210,6 +206,8 @@
_LIBCPP_THREAD_ABI_VISIBILITY
int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv);
+#ifndef _LIBCPP_NO_NATIVE_SEMAPHORES
+
// Semaphore
_LIBCPP_THREAD_ABI_VISIBILITY
bool __libcpp_semaphore_init(__libcpp_semaphore_t* __sem, int __init);
@@ -226,6 +224,8 @@
_LIBCPP_THREAD_ABI_VISIBILITY
bool __libcpp_semaphore_wait_timed(__libcpp_semaphore_t* __sem, chrono::nanoseconds const& __ns);
+#endif // _LIBCPP_NO_NATIVE_SEMAPHORES
+
// Execute once
_LIBCPP_THREAD_ABI_VISIBILITY
int __libcpp_execute_once(__libcpp_exec_once_flag *flag,
diff --git a/include/semaphore b/include/semaphore
index cd27534..8a2e778 100644
--- a/include/semaphore
+++ b/include/semaphore
@@ -172,6 +172,8 @@
using __semaphore_base =
__atomic_semaphore_base;
+#define _LIBCPP_SEMAPHORE_MAX (numeric_limits<ptrdiff_t>::max())
+
#endif //_LIBCPP_NO_NATIVE_SEMAPHORES
template<ptrdiff_t __least_max_value = _LIBCPP_SEMAPHORE_MAX>
diff --git a/src/barrier.cpp b/src/barrier.cpp
index 4edc2d0..c5e33cb 100644
--- a/src/barrier.cpp
+++ b/src/barrier.cpp
@@ -26,13 +26,21 @@
} __tickets[64];
};
- ptrdiff_t& __expected;
- unique_ptr<__state_t[]> __state;
+ ptrdiff_t& __expected;
+ unique_ptr<char[]> __state_allocation;
+ __state_t* __state;
_LIBCPP_HIDDEN
__barrier_algorithm_base(ptrdiff_t& __expected)
- : __expected(__expected), __state(new __barrier_algorithm_base::__state_t[(__expected + 1) >> 1])
+ : __expected(__expected)
{
+ size_t const __count = (__expected + 1) >> 1;
+ size_t const __size = sizeof(__state_t) * __count;
+ size_t __allocation_size = __size + alignof(__state_t);
+ __state_allocation = unique_ptr<char[]>(new char[__allocation_size]);
+ void* __allocation = __state_allocation.get();
+ void* const __state_ = align(alignof(__state_t), __size, __allocation, __allocation_size);
+ __state = new (__state_) __barrier_algorithm_base::__state_t[__count];
}
_LIBCPP_HIDDEN
bool __arrive(__barrier_phase_t __old_phase)
diff --git a/test/std/thread/thread.semaphore/max.pass.cpp b/test/std/thread/thread.semaphore/max.pass.cpp
index 9ed70ef..82fa666 100644
--- a/test/std/thread/thread.semaphore/max.pass.cpp
+++ b/test/std/thread/thread.semaphore/max.pass.cpp
@@ -21,7 +21,6 @@
static_assert(std::counting_semaphore<>::max() > 0, "");
static_assert(std::counting_semaphore<1>::max() >= 1, "");
static_assert(std::counting_semaphore<std::numeric_limits<int>::max()>::max() >= 1, "");
- static_assert(std::counting_semaphore<std::numeric_limits<unsigned>::max()>::max() >= 1, "");
static_assert(std::counting_semaphore<std::numeric_limits<ptrdiff_t>::max()>::max() >= 1, "");
static_assert(std::counting_semaphore<1>::max() == std::binary_semaphore::max(), "");
return 0;