[Threading] Create new threading library and use it.

Moved all the threading code to one place.  Added explicit support for
Darwin, Linux, Pthreads, C11 threads and Win32 threads, including new
implementations of Once for Linux, Pthreads, C11 and Win32.

rdar://90776105
This commit is contained in:
Alastair Houghton
2022-04-15 13:50:33 +01:00
parent 66b9d21000
commit f5bdb858e0
98 changed files with 2286 additions and 1410 deletions

View File

@@ -162,4 +162,20 @@
#define SWIFT_ASM_LABEL_WITH_PREFIX(STRING) \
SWIFT_ASM_LABEL_RAW(SWIFT_SYMBOL_PREFIX_STRING STRING)
// SWIFT_FORMAT(fmt,first) marks a function as taking a format string argument
// at argument `fmt`, with the first argument for the format string as `first`.
#if __has_attribute(format)
#define SWIFT_FORMAT(fmt,first) __attribute__((format(printf, fmt, first)))
#else
#define SWIFT_FORMAT(fmt,first)
#endif
// SWIFT_VFORMAT(fmt) marks a function as taking a format string argument at
// argument `fmt`, with the arguments in a `va_list`.
#if __has_attribute(format)
#define SWIFT_VFORMAT(fmt) __attribute__((format(printf, fmt, 0)))
#else
#define SWIFT_VFORMAT(fmt)
#endif
#endif // SWIFT_BASIC_COMPILER_H

View File

@@ -15,55 +15,26 @@
#include <memory>
#if SWIFT_STDLIB_THREADING_NONE
// No dependencies on single-threaded environments.
#elif SWIFT_STDLIB_THREADING_DARWIN
#include <dispatch/dispatch.h>
#else
#include <mutex>
#endif
#include "swift/Basic/Malloc.h"
#include "swift/Basic/type_traits.h"
#include "swift/Threading/Once.h"
namespace swift {
#if SWIFT_STDLIB_THREADING_NONE
using OnceToken_t = bool;
# define SWIFT_ONCE_F(TOKEN, FUNC, CONTEXT) \
do { if (!TOKEN) { TOKEN = true; (FUNC)(CONTEXT); } } while (0)
#elif SWIFT_STDLIB_THREADING_DARWIN
using OnceToken_t = ::dispatch_once_t;
# define SWIFT_ONCE_F(TOKEN, FUNC, CONTEXT) \
::dispatch_once_f(&TOKEN, CONTEXT, FUNC)
#elif defined(__CYGWIN__)
// _swift_once_f() is declared in Private.h.
// This prototype is copied instead including the header file.
void _swift_once_f(uintptr_t *predicate, void *context,
void (*function)(void *));
using OnceToken_t = unsigned long;
# define SWIFT_ONCE_F(TOKEN, FUNC, CONTEXT) \
_swift_once_f(&TOKEN, CONTEXT, FUNC)
#else
using OnceToken_t = std::once_flag;
# define SWIFT_ONCE_F(TOKEN, FUNC, CONTEXT) \
::std::call_once(TOKEN, FUNC, CONTEXT)
#endif
/// A template for lazily-constructed, zero-initialized, leaked-on-exit
/// global objects.
template <class T> class Lazy {
alignas(T) char Value[sizeof(T)] = { 0 };
OnceToken_t OnceToken = {};
swift::once_t OnceToken = {};
static void defaultInitCallback(void *ValueAddr) {
::new (ValueAddr) T();
}
public:
using Type = T;
T &get(void (*initCallback)(void *) = defaultInitCallback);
template<typename Arg1>
@@ -87,7 +58,7 @@ template <typename T> inline T &Lazy<T>::get(void (*initCallback)(void*)) {
static_assert(std::is_literal_type<Lazy<T>>::value,
"Lazy<T> must be a literal type");
SWIFT_ONCE_F(OnceToken, initCallback, &Value);
swift::once(OnceToken, initCallback, &Value);
return unsafeGetAlreadyInitialized();
}
@@ -103,7 +74,7 @@ template <typename Arg1> inline T &Lazy<T>::getWithInit(Arg1 &&arg1) {
}
} data{&Value, static_cast<Arg1&&>(arg1)};
SWIFT_ONCE_F(OnceToken, &Data::init, &data);
swift::once(OnceToken, &Data::init, &data);
return unsafeGetAlreadyInitialized();
}