diff options
Diffstat (limited to 'contrib/libc++/src')
-rw-r--r-- | contrib/libc++/src/chrono.cpp | 66 | ||||
-rw-r--r-- | contrib/libc++/src/config_elast.h | 36 | ||||
-rw-r--r-- | contrib/libc++/src/debug.cpp | 2 | ||||
-rw-r--r-- | contrib/libc++/src/exception.cpp | 32 | ||||
-rw-r--r-- | contrib/libc++/src/future.cpp | 5 | ||||
-rw-r--r-- | contrib/libc++/src/ios.cpp | 14 | ||||
-rw-r--r-- | contrib/libc++/src/iostream.cpp | 68 | ||||
-rw-r--r-- | contrib/libc++/src/locale.cpp | 206 | ||||
-rw-r--r-- | contrib/libc++/src/memory.cpp | 17 | ||||
-rw-r--r-- | contrib/libc++/src/mutex.cpp | 10 | ||||
-rw-r--r-- | contrib/libc++/src/new.cpp | 16 | ||||
-rw-r--r-- | contrib/libc++/src/random.cpp | 96 | ||||
-rw-r--r-- | contrib/libc++/src/shared_mutex.cpp | 25 | ||||
-rw-r--r-- | contrib/libc++/src/string.cpp | 2 | ||||
-rw-r--r-- | contrib/libc++/src/support/atomic_support.h | 142 | ||||
-rw-r--r-- | contrib/libc++/src/system_error.cpp | 9 | ||||
-rw-r--r-- | contrib/libc++/src/thread.cpp | 4 |
17 files changed, 562 insertions, 188 deletions
diff --git a/contrib/libc++/src/chrono.cpp b/contrib/libc++/src/chrono.cpp index 4569411..62149fb 100644 --- a/contrib/libc++/src/chrono.cpp +++ b/contrib/libc++/src/chrono.cpp @@ -8,14 +8,21 @@ //===----------------------------------------------------------------------===// #include "chrono" -#include <sys/time.h> //for gettimeofday and timeval -#ifdef __APPLE__ +#include "cerrno" // errno +#include "system_error" // __throw_system_error +#include <time.h> // clock_gettime, CLOCK_MONOTONIC and CLOCK_REALTIME + +#if !defined(CLOCK_REALTIME) +#include <sys/time.h> // for gettimeofday and timeval +#endif + +#if !defined(_LIBCPP_HAS_NO_MONOTONIC_CLOCK) && !defined(CLOCK_MONOTONIC) +#if __APPLE__ #include <mach/mach_time.h> // mach_absolute_time, mach_timebase_info_data_t -#else /* !__APPLE__ */ -#include <cerrno> // errno -#include <system_error> // __throw_system_error -#include <time.h> // clock_gettime, CLOCK_MONOTONIC -#endif // __APPLE__ +#else +#error "Monotonic clock not implemented" +#endif +#endif _LIBCPP_BEGIN_NAMESPACE_STD @@ -29,9 +36,16 @@ const bool system_clock::is_steady; system_clock::time_point system_clock::now() _NOEXCEPT { +#ifdef CLOCK_REALTIME + struct timespec tp; + if (0 != clock_gettime(CLOCK_REALTIME, &tp)) + __throw_system_error(errno, "clock_gettime(CLOCK_REALTIME) failed"); + return time_point(seconds(tp.tv_sec) + microseconds(tp.tv_nsec / 1000)); +#else // !CLOCK_REALTIME timeval tv; gettimeofday(&tv, 0); return time_point(seconds(tv.tv_sec) + microseconds(tv.tv_usec)); +#endif // CLOCK_REALTIME } time_t @@ -48,10 +62,26 @@ system_clock::from_time_t(time_t t) _NOEXCEPT #ifndef _LIBCPP_HAS_NO_MONOTONIC_CLOCK // steady_clock +// +// Warning: If this is not truly steady, then it is non-conforming. It is +// better for it to not exist and have the rest of libc++ use system_clock +// instead. const bool steady_clock::is_steady; -#ifdef __APPLE__ +#ifdef CLOCK_MONOTONIC + +steady_clock::time_point +steady_clock::now() _NOEXCEPT +{ + struct timespec tp; + if (0 != clock_gettime(CLOCK_MONOTONIC, &tp)) + __throw_system_error(errno, "clock_gettime(CLOCK_MONOTONIC) failed"); + return time_point(seconds(tp.tv_sec) + nanoseconds(tp.tv_nsec)); +} + +#elif defined(__APPLE__) + // mach_absolute_time() * MachInfo.numer / MachInfo.denom is the number of // nanoseconds since the computer booted up. MachInfo.numer and MachInfo.denom // are run time constants supplied by the OS. This clock has no relationship @@ -108,23 +138,9 @@ steady_clock::now() _NOEXCEPT return time_point(duration(fp())); } -#else // __APPLE__ -// FIXME: if _LIBCPP_HAS_NO_MONOTONIC_CLOCK, then clock_gettime isn't going to -// work. It may be possible to fall back on something else, depending on the system. - -// Warning: If this is not truly steady, then it is non-conforming. It is -// better for it to not exist and have the rest of libc++ use system_clock -// instead. - -steady_clock::time_point -steady_clock::now() _NOEXCEPT -{ - struct timespec tp; - if (0 != clock_gettime(CLOCK_MONOTONIC, &tp)) - __throw_system_error(errno, "clock_gettime(CLOCK_MONOTONIC) failed"); - return time_point(seconds(tp.tv_sec) + nanoseconds(tp.tv_nsec)); -} -#endif // __APPLE__ +#else +#error "Monotonic clock not implemented" +#endif #endif // !_LIBCPP_HAS_NO_MONOTONIC_CLOCK diff --git a/contrib/libc++/src/config_elast.h b/contrib/libc++/src/config_elast.h new file mode 100644 index 0000000..9d6a76b --- /dev/null +++ b/contrib/libc++/src/config_elast.h @@ -0,0 +1,36 @@ +//===----------------------- config_elast.h -------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_CONFIG_ELAST +#define _LIBCPP_CONFIG_ELAST + +#if defined(_WIN32) +#include <stdlib.h> +#else +#include <errno.h> +#endif + +#if defined(ELAST) +#define _LIBCPP_ELAST ELAST +#elif defined(_NEWLIB_VERSION) +#define _LIBCPP_ELAST __ELASTERROR +#elif defined(__linux__) +#define _LIBCPP_ELAST 4095 +#elif defined(__APPLE__) +// No _LIBCPP_ELAST needed on Apple +#elif defined(__sun__) +#define _LIBCPP_ELAST ESTALE +#elif defined(_WIN32) +#define _LIBCPP_ELAST _sys_nerr +#else +// Warn here so that the person doing the libcxx port has an easier time: +#warning ELAST for this platform not yet implemented +#endif + +#endif // _LIBCPP_CONFIG_ELAST diff --git a/contrib/libc++/src/debug.cpp b/contrib/libc++/src/debug.cpp index 60694a3..b1a16e6 100644 --- a/contrib/libc++/src/debug.cpp +++ b/contrib/libc++/src/debug.cpp @@ -214,10 +214,10 @@ __libcpp_db::__erase_i(void* __i) else q->__next_ = p->__next_; __c_node* c = p->__c_; - free(p); --__isz_; if (c != nullptr) c->__remove(p); + free(p); } } } diff --git a/contrib/libc++/src/exception.cpp b/contrib/libc++/src/exception.cpp index b5c46c0..2c16060 100644 --- a/contrib/libc++/src/exception.cpp +++ b/contrib/libc++/src/exception.cpp @@ -29,7 +29,7 @@ #define __terminate_handler __cxxabiapple::__cxa_terminate_handler #define __unexpected_handler __cxxabiapple::__cxa_unexpected_handler #endif // _LIBCPPABI_VERSION -#elif defined(LIBCXXRT) || __has_include(<cxxabi.h>) +#elif defined(LIBCXXRT) || defined(LIBCXX_BUILDING_LIBCXXABI) || __has_include(<cxxabi.h>) #include <cxxabi.h> using namespace __cxxabiv1; #if defined(LIBCXXRT) || defined(_LIBCPPABI_VERSION) @@ -90,14 +90,14 @@ terminate() _NOEXCEPT #endif // _LIBCPP_NO_EXCEPTIONS (*get_terminate())(); // handler should not return - printf("terminate_handler unexpectedly returned\n"); + fprintf(stderr, "terminate_handler unexpectedly returned\n"); ::abort(); #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) { // handler should not throw exception - printf("terminate_handler unexpectedly threw an exception\n"); + fprintf(stderr, "terminate_handler unexpectedly threw an exception\n"); ::abort(); } #endif // _LIBCPP_NO_EXCEPTIONS @@ -106,18 +106,24 @@ terminate() _NOEXCEPT #endif // !defined(LIBCXXRT) && !defined(_LIBCPPABI_VERSION) #if !defined(LIBCXXRT) && !defined(__GLIBCXX__) && !defined(__EMSCRIPTEN__) -bool uncaught_exception() _NOEXCEPT +bool uncaught_exception() _NOEXCEPT { return uncaught_exceptions() > 0; } + +int uncaught_exceptions() _NOEXCEPT { #if defined(__APPLE__) || defined(_LIBCPPABI_VERSION) - // on Darwin, there is a helper function so __cxa_get_globals is private - return __cxa_uncaught_exception(); + // on Darwin, there is a helper function so __cxa_get_globals is private +# if _LIBCPPABI_VERSION > 1101 + return __cxa_uncaught_exceptions(); +# else + return __cxa_uncaught_exception() ? 1 : 0; +# endif #else // __APPLE__ # if defined(_MSC_VER) && ! defined(__clang__) - _LIBCPP_WARNING("uncaught_exception not yet implemented") + _LIBCPP_WARNING("uncaught_exceptions not yet implemented") # else # warning uncaught_exception not yet implemented # endif - printf("uncaught_exception not yet implemented\n"); + fprintf(stderr, "uncaught_exceptions not yet implemented\n"); ::abort(); #endif // __APPLE__ } @@ -190,7 +196,7 @@ exception_ptr::~exception_ptr() _NOEXCEPT # else # warning exception_ptr not yet implemented # endif - printf("exception_ptr not yet implemented\n"); + fprintf(stderr, "exception_ptr not yet implemented\n"); ::abort(); #endif } @@ -209,7 +215,7 @@ exception_ptr::exception_ptr(const exception_ptr& other) _NOEXCEPT # else # warning exception_ptr not yet implemented # endif - printf("exception_ptr not yet implemented\n"); + fprintf(stderr, "exception_ptr not yet implemented\n"); ::abort(); #endif } @@ -234,7 +240,7 @@ exception_ptr& exception_ptr::operator=(const exception_ptr& other) _NOEXCEPT # else # warning exception_ptr not yet implemented # endif - printf("exception_ptr not yet implemented\n"); + fprintf(stderr, "exception_ptr not yet implemented\n"); ::abort(); #endif } @@ -278,7 +284,7 @@ exception_ptr current_exception() _NOEXCEPT # else # warning exception_ptr not yet implemented # endif - printf("exception_ptr not yet implemented\n"); + fprintf(stderr, "exception_ptr not yet implemented\n"); ::abort(); #endif } @@ -300,7 +306,7 @@ void rethrow_exception(exception_ptr p) # else # warning exception_ptr not yet implemented # endif - printf("exception_ptr not yet implemented\n"); + fprintf(stderr, "exception_ptr not yet implemented\n"); ::abort(); #endif } diff --git a/contrib/libc++/src/future.cpp b/contrib/libc++/src/future.cpp index 0c5c2c4..3132b18 100644 --- a/contrib/libc++/src/future.cpp +++ b/contrib/libc++/src/future.cpp @@ -98,7 +98,6 @@ __assoc_sub_state::set_value() #endif __state_ |= __constructed | ready; __cv_.notify_all(); - __lk.unlock(); } void @@ -111,7 +110,6 @@ __assoc_sub_state::set_value_at_thread_exit() #endif __state_ |= __constructed; __thread_local_data()->__make_ready_at_thread_exit(this); - __lk.unlock(); } void @@ -124,7 +122,6 @@ __assoc_sub_state::set_exception(exception_ptr __p) #endif __exception_ = __p; __state_ |= ready; - __lk.unlock(); __cv_.notify_all(); } @@ -138,7 +135,6 @@ __assoc_sub_state::set_exception_at_thread_exit(exception_ptr __p) #endif __exception_ = __p; __thread_local_data()->__make_ready_at_thread_exit(this); - __lk.unlock(); } void @@ -146,7 +142,6 @@ __assoc_sub_state::__make_ready() { unique_lock<mutex> __lk(__mut_); __state_ |= ready; - __lk.unlock(); __cv_.notify_all(); } diff --git a/contrib/libc++/src/ios.cpp b/contrib/libc++/src/ios.cpp index d879beb..90972c4 100644 --- a/contrib/libc++/src/ios.cpp +++ b/contrib/libc++/src/ios.cpp @@ -8,16 +8,20 @@ //===----------------------------------------------------------------------===// #include "__config" + #include "ios" -#include "streambuf" -#include "istream" -#include "string" + +#include <stdlib.h> + #include "__locale" #include "algorithm" +#include "config_elast.h" +#include "istream" +#include "limits" #include "memory" #include "new" -#include "limits" -#include <stdlib.h> +#include "streambuf" +#include "string" _LIBCPP_BEGIN_NAMESPACE_STD diff --git a/contrib/libc++/src/iostream.cpp b/contrib/libc++/src/iostream.cpp index 7102e43..e073aec 100644 --- a/contrib/libc++/src/iostream.cpp +++ b/contrib/libc++/src/iostream.cpp @@ -13,55 +13,75 @@ _LIBCPP_BEGIN_NAMESPACE_STD -static mbstate_t state_types[6] = {}; - +#ifndef _LIBCPP_HAS_NO_STDIN +_ALIGNAS_TYPE (istream) _LIBCPP_FUNC_VIS char cin [sizeof(istream)]; _ALIGNAS_TYPE (__stdinbuf<char> ) static char __cin [sizeof(__stdinbuf <char>)]; -_ALIGNAS_TYPE (__stdoutbuf<char>) static char __cout[sizeof(__stdoutbuf<char>)]; -_ALIGNAS_TYPE (__stdoutbuf<char>) static char __cerr[sizeof(__stdoutbuf<char>)]; +static mbstate_t mb_cin; +_ALIGNAS_TYPE (wistream) _LIBCPP_FUNC_VIS char wcin [sizeof(wistream)]; _ALIGNAS_TYPE (__stdinbuf<wchar_t> ) static char __wcin [sizeof(__stdinbuf <wchar_t>)]; -_ALIGNAS_TYPE (__stdoutbuf<wchar_t>) static char __wcout[sizeof(__stdoutbuf<wchar_t>)]; -_ALIGNAS_TYPE (__stdoutbuf<wchar_t>) static char __wcerr[sizeof(__stdoutbuf<wchar_t>)]; +static mbstate_t mb_wcin; +#endif -_ALIGNAS_TYPE (istream) _LIBCPP_FUNC_VIS char cin [sizeof(istream)]; +#ifndef _LIBCPP_HAS_NO_STDOUT _ALIGNAS_TYPE (ostream) _LIBCPP_FUNC_VIS char cout[sizeof(ostream)]; -_ALIGNAS_TYPE (ostream) _LIBCPP_FUNC_VIS char cerr[sizeof(ostream)]; -_ALIGNAS_TYPE (ostream) _LIBCPP_FUNC_VIS char clog[sizeof(ostream)]; -_ALIGNAS_TYPE (wistream) _LIBCPP_FUNC_VIS char wcin [sizeof(wistream)]; +_ALIGNAS_TYPE (__stdoutbuf<char>) static char __cout[sizeof(__stdoutbuf<char>)]; +static mbstate_t mb_cout; _ALIGNAS_TYPE (wostream) _LIBCPP_FUNC_VIS char wcout[sizeof(wostream)]; +_ALIGNAS_TYPE (__stdoutbuf<wchar_t>) static char __wcout[sizeof(__stdoutbuf<wchar_t>)]; +static mbstate_t mb_wcout; +#endif + +_ALIGNAS_TYPE (ostream) _LIBCPP_FUNC_VIS char cerr[sizeof(ostream)]; +_ALIGNAS_TYPE (__stdoutbuf<char>) static char __cerr[sizeof(__stdoutbuf<char>)]; +static mbstate_t mb_cerr; _ALIGNAS_TYPE (wostream) _LIBCPP_FUNC_VIS char wcerr[sizeof(wostream)]; +_ALIGNAS_TYPE (__stdoutbuf<wchar_t>) static char __wcerr[sizeof(__stdoutbuf<wchar_t>)]; +static mbstate_t mb_wcerr; + +_ALIGNAS_TYPE (ostream) _LIBCPP_FUNC_VIS char clog[sizeof(ostream)]; _ALIGNAS_TYPE (wostream) _LIBCPP_FUNC_VIS char wclog[sizeof(wostream)]; ios_base::Init __start_std_streams; ios_base::Init::Init() { - istream* cin_ptr = ::new(cin) istream(::new(__cin) __stdinbuf <char>(stdin, state_types+0) ); - ostream* cout_ptr = ::new(cout) ostream(::new(__cout) __stdoutbuf<char>(stdout, state_types+1)); - ostream* cerr_ptr = ::new(cerr) ostream(::new(__cerr) __stdoutbuf<char>(stderr, state_types+2)); +#ifndef _LIBCPP_HAS_NO_STDIN + istream* cin_ptr = ::new(cin) istream(::new(__cin) __stdinbuf <char>(stdin, &mb_cin)); + wistream* wcin_ptr = ::new(wcin) wistream(::new(__wcin) __stdinbuf <wchar_t>(stdin, &mb_wcin)); +#endif +#ifndef _LIBCPP_HAS_NO_STDOUT + ostream* cout_ptr = ::new(cout) ostream(::new(__cout) __stdoutbuf<char>(stdout, &mb_cout)); + wostream* wcout_ptr = ::new(wcout) wostream(::new(__wcout) __stdoutbuf<wchar_t>(stdout, &mb_wcout)); +#endif + ostream* cerr_ptr = ::new(cerr) ostream(::new(__cerr) __stdoutbuf<char>(stderr, &mb_cerr)); ::new(clog) ostream(cerr_ptr->rdbuf()); - cin_ptr->tie(cout_ptr); - _VSTD::unitbuf(*cerr_ptr); - cerr_ptr->tie(cout_ptr); - - wistream* wcin_ptr = ::new(wcin) wistream(::new(__wcin) __stdinbuf <wchar_t>(stdin, state_types+3) ); - wostream* wcout_ptr = ::new(wcout) wostream(::new(__wcout) __stdoutbuf<wchar_t>(stdout, state_types+4)); - wostream* wcerr_ptr = ::new(wcerr) wostream(::new(__wcerr) __stdoutbuf<wchar_t>(stderr, state_types+5)); + wostream* wcerr_ptr = ::new(wcerr) wostream(::new(__wcerr) __stdoutbuf<wchar_t>(stderr, &mb_wcerr)); ::new(wclog) wostream(wcerr_ptr->rdbuf()); + +#if !defined(_LIBCPP_HAS_NO_STDIN) && !defined(_LIBCPP_HAS_NO_STDOUT) + cin_ptr->tie(cout_ptr); wcin_ptr->tie(wcout_ptr); +#endif + _VSTD::unitbuf(*cerr_ptr); _VSTD::unitbuf(*wcerr_ptr); +#ifndef _LIBCPP_HAS_NO_STDOUT + cerr_ptr->tie(cout_ptr); wcerr_ptr->tie(wcout_ptr); +#endif } ios_base::Init::~Init() { +#ifndef _LIBCPP_HAS_NO_STDOUT ostream* cout_ptr = reinterpret_cast<ostream*>(cout); - ostream* clog_ptr = reinterpret_cast<ostream*>(clog); + wostream* wcout_ptr = reinterpret_cast<wostream*>(wcout); cout_ptr->flush(); - clog_ptr->flush(); + wcout_ptr->flush(); +#endif - wostream* wcout_ptr = reinterpret_cast<wostream*>(wcout); + ostream* clog_ptr = reinterpret_cast<ostream*>(clog); wostream* wclog_ptr = reinterpret_cast<wostream*>(wclog); - wcout_ptr->flush(); + clog_ptr->flush(); wclog_ptr->flush(); } diff --git a/contrib/libc++/src/locale.cpp b/contrib/libc++/src/locale.cpp index f21e35d..bdc73e1 100644 --- a/contrib/libc++/src/locale.cpp +++ b/contrib/libc++/src/locale.cpp @@ -27,7 +27,7 @@ #include "cwctype" #include "__sso_allocator" #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__) -#include <support/win32/locale_win32.h> +#include "support/win32/locale_win32.h" #elif !defined(__ANDROID__) #include <langinfo.h> #endif @@ -575,8 +575,10 @@ locale::global(const locale& loc) locale& g = __global(); locale r = g; g = loc; +#ifndef __CloudABI__ if (g.name() != "*") setlocale(LC_ALL, g.name().c_str()); +#endif return r; } @@ -813,7 +815,7 @@ ctype<wchar_t>::do_toupper(char_type c) const #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) return isascii(c) ? ctype<char>::__classic_upper_table()[c] : c; #else - return (isascii(c) && iswlower_l(c, __cloc())) ? c-L'a'+L'A' : c; + return (isascii(c) && iswlower_l(c, _LIBCPP_GET_C_LOCALE)) ? c-L'a'+L'A' : c; #endif } @@ -827,7 +829,7 @@ ctype<wchar_t>::do_toupper(char_type* low, const char_type* high) const *low = isascii(*low) ? ctype<char>::__classic_upper_table()[*low] : *low; #else - *low = (isascii(*low) && islower_l(*low, __cloc())) ? (*low-L'a'+L'A') : *low; + *low = (isascii(*low) && islower_l(*low, _LIBCPP_GET_C_LOCALE)) ? (*low-L'a'+L'A') : *low; #endif return low; } @@ -840,7 +842,7 @@ ctype<wchar_t>::do_tolower(char_type c) const #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) return isascii(c) ? ctype<char>::__classic_lower_table()[c] : c; #else - return (isascii(c) && isupper_l(c, __cloc())) ? c-L'A'+'a' : c; + return (isascii(c) && isupper_l(c, _LIBCPP_GET_C_LOCALE)) ? c-L'A'+'a' : c; #endif } @@ -854,7 +856,7 @@ ctype<wchar_t>::do_tolower(char_type* low, const char_type* high) const *low = isascii(*low) ? ctype<char>::__classic_lower_table()[*low] : *low; #else - *low = (isascii(*low) && isupper_l(*low, __cloc())) ? *low-L'A'+L'a' : *low; + *low = (isascii(*low) && isupper_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-L'A'+L'a' : *low; #endif return low; } @@ -923,7 +925,7 @@ ctype<char>::do_toupper(char_type c) const return isascii(c) ? static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]) : c; #else - return (isascii(c) && islower_l(c, __cloc())) ? c-'a'+'A' : c; + return (isascii(c) && islower_l(c, _LIBCPP_GET_C_LOCALE)) ? c-'a'+'A' : c; #endif } @@ -940,7 +942,7 @@ ctype<char>::do_toupper(char_type* low, const char_type* high) const *low = isascii(*low) ? static_cast<char>(__classic_upper_table()[static_cast<size_t>(*low)]) : *low; #else - *low = (isascii(*low) && islower_l(*low, __cloc())) ? *low-'a'+'A' : *low; + *low = (isascii(*low) && islower_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-'a'+'A' : *low; #endif return low; } @@ -957,7 +959,7 @@ ctype<char>::do_tolower(char_type c) const return isascii(c) ? static_cast<char>(__classic_lower_table()[static_cast<size_t>(c)]) : c; #else - return (isascii(c) && isupper_l(c, __cloc())) ? c-'A'+'a' : c; + return (isascii(c) && isupper_l(c, _LIBCPP_GET_C_LOCALE)) ? c-'A'+'a' : c; #endif } @@ -972,7 +974,7 @@ ctype<char>::do_tolower(char_type* low, const char_type* high) const #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) *low = isascii(*low) ? static_cast<char>(__classic_lower_table()[static_cast<size_t>(*low)]) : *low; #else - *low = (isascii(*low) && isupper_l(*low, __cloc())) ? *low-'A'+'a' : *low; + *low = (isascii(*low) && isupper_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-'A'+'a' : *low; #endif return low; } @@ -1016,6 +1018,87 @@ extern "C" const int ** __ctype_tolower_loc(); extern "C" const int ** __ctype_toupper_loc(); #endif +#ifdef _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE +const ctype<char>::mask* +ctype<char>::classic_table() _NOEXCEPT +{ + static _LIBCPP_CONSTEXPR const ctype<char>::mask builtin_table[table_size] = { + cntrl, cntrl, + cntrl, cntrl, + cntrl, cntrl, + cntrl, cntrl, + cntrl, cntrl | space | blank, + cntrl | space, cntrl | space, + cntrl | space, cntrl | space, + cntrl, cntrl, + cntrl, cntrl, + cntrl, cntrl, + cntrl, cntrl, + cntrl, cntrl, + cntrl, cntrl, + cntrl, cntrl, + cntrl, cntrl, + cntrl, cntrl, + space | blank | print, punct | print, + punct | print, punct | print, + punct | print, punct | print, + punct | print, punct | print, + punct | print, punct | print, + punct | print, punct | print, + punct | print, punct | print, + punct | print, punct | print, + digit | print | xdigit, digit | print | xdigit, + digit | print | xdigit, digit | print | xdigit, + digit | print | xdigit, digit | print | xdigit, + digit | print | xdigit, digit | print | xdigit, + digit | print | xdigit, digit | print | xdigit, + punct | print, punct | print, + punct | print, punct | print, + punct | print, punct | print, + punct | print, upper | xdigit | print | alpha, + upper | xdigit | print | alpha, upper | xdigit | print | alpha, + upper | xdigit | print | alpha, upper | xdigit | print | alpha, + upper | xdigit | print | alpha, upper | print | alpha, + upper | print | alpha, upper | print | alpha, + upper | print | alpha, upper | print | alpha, + upper | print | alpha, upper | print | alpha, + upper | print | alpha, upper | print | alpha, + upper | print | alpha, upper | print | alpha, + upper | print | alpha, upper | print | alpha, + upper | print | alpha, upper | print | alpha, + upper | print | alpha, upper | print | alpha, + upper | print | alpha, upper | print | alpha, + upper | print | alpha, punct | print, + punct | print, punct | print, + punct | print, punct | print, + punct | print, lower | xdigit | print | alpha, + lower | xdigit | print | alpha, lower | xdigit | print | alpha, + lower | xdigit | print | alpha, lower | xdigit | print | alpha, + lower | xdigit | print | alpha, lower | print | alpha, + lower | print | alpha, lower | print | alpha, + lower | print | alpha, lower | print | alpha, + lower | print | alpha, lower | print | alpha, + lower | print | alpha, lower | print | alpha, + lower | print | alpha, lower | print | alpha, + lower | print | alpha, lower | print | alpha, + lower | print | alpha, lower | print | alpha, + lower | print | alpha, lower | print | alpha, + lower | print | alpha, lower | print | alpha, + lower | print | alpha, punct | print, + punct | print, punct | print, + punct | print, cntrl, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + return builtin_table; +} +#else const ctype<char>::mask* ctype<char>::classic_table() _NOEXCEPT { @@ -1024,7 +1107,7 @@ ctype<char>::classic_table() _NOEXCEPT #elif defined(__NetBSD__) return _C_ctype_tab_ + 1; #elif defined(__GLIBC__) - return __cloc()->__ctype_b; + return _LIBCPP_GET_C_LOCALE->__ctype_b; #elif __sun__ return __ctype_mask; #elif defined(_LIBCPP_MSVCRT) || defined(__MINGW32__) @@ -1033,10 +1116,11 @@ ctype<char>::classic_table() _NOEXCEPT // going to end up dereferencing it later... #elif defined(__EMSCRIPTEN__) return *__ctype_b_loc(); +#elif defined(_NEWLIB_VERSION) + // Newlib has a 257-entry table in ctype_.c, where (char)0 starts at [1]. + return _ctype_ + 1; #elif defined(_AIX) return (const unsigned int *)__lc_ctype_ptr->obj->mask; -#elif defined(__ANDROID__) - return reinterpret_cast<const unsigned char*>(_ctype_) + 1; #else // Platform not supported: abort so the person doing the port knows what to // fix @@ -1046,18 +1130,19 @@ ctype<char>::classic_table() _NOEXCEPT return NULL; #endif } +#endif #if defined(__GLIBC__) const int* ctype<char>::__classic_lower_table() _NOEXCEPT { - return __cloc()->__ctype_tolower; + return _LIBCPP_GET_C_LOCALE->__ctype_tolower; } const int* ctype<char>::__classic_upper_table() _NOEXCEPT { - return __cloc()->__ctype_toupper; + return _LIBCPP_GET_C_LOCALE->__ctype_toupper; } #elif __NetBSD__ const short* @@ -1180,16 +1265,16 @@ ctype_byname<wchar_t>::do_is(mask m, char_type c) const #else bool result = false; wint_t ch = static_cast<wint_t>(c); - if (m & space) result |= (iswspace_l(ch, __l) != 0); - if (m & print) result |= (iswprint_l(ch, __l) != 0); - if (m & cntrl) result |= (iswcntrl_l(ch, __l) != 0); - if (m & upper) result |= (iswupper_l(ch, __l) != 0); - if (m & lower) result |= (iswlower_l(ch, __l) != 0); - if (m & alpha) result |= (iswalpha_l(ch, __l) != 0); - if (m & digit) result |= (iswdigit_l(ch, __l) != 0); - if (m & punct) result |= (iswpunct_l(ch, __l) != 0); - if (m & xdigit) result |= (iswxdigit_l(ch, __l) != 0); - if (m & blank) result |= (iswblank_l(ch, __l) != 0); + if ((m & space) == space) result |= (iswspace_l(ch, __l) != 0); + if ((m & print) == print) result |= (iswprint_l(ch, __l) != 0); + if ((m & cntrl) == cntrl) result |= (iswcntrl_l(ch, __l) != 0); + if ((m & upper) == upper) result |= (iswupper_l(ch, __l) != 0); + if ((m & lower) == lower) result |= (iswlower_l(ch, __l) != 0); + if ((m & alpha) == alpha) result |= (iswalpha_l(ch, __l) != 0); + if ((m & digit) == digit) result |= (iswdigit_l(ch, __l) != 0); + if ((m & punct) == punct) result |= (iswpunct_l(ch, __l) != 0); + if ((m & xdigit) == xdigit) result |= (iswxdigit_l(ch, __l) != 0); + if ((m & blank) == blank) result |= (iswblank_l(ch, __l) != 0); return result; #endif } @@ -1207,22 +1292,32 @@ ctype_byname<wchar_t>::do_is(const char_type* low, const char_type* high, mask* wint_t ch = static_cast<wint_t>(*low); if (iswspace_l(ch, __l)) *vec |= space; +#ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT if (iswprint_l(ch, __l)) *vec |= print; +#endif if (iswcntrl_l(ch, __l)) *vec |= cntrl; if (iswupper_l(ch, __l)) *vec |= upper; if (iswlower_l(ch, __l)) *vec |= lower; +#ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA if (iswalpha_l(ch, __l)) *vec |= alpha; +#endif if (iswdigit_l(ch, __l)) *vec |= digit; if (iswpunct_l(ch, __l)) *vec |= punct; +#ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT if (iswxdigit_l(ch, __l)) *vec |= xdigit; +#endif +#if !defined(__sun__) + if (iswblank_l(ch, __l)) + *vec |= blank; +#endif } } return low; @@ -1238,16 +1333,16 @@ ctype_byname<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* break; #else wint_t ch = static_cast<wint_t>(*low); - if (m & space && iswspace_l(ch, __l)) break; - if (m & print && iswprint_l(ch, __l)) break; - if (m & cntrl && iswcntrl_l(ch, __l)) break; - if (m & upper && iswupper_l(ch, __l)) break; - if (m & lower && iswlower_l(ch, __l)) break; - if (m & alpha && iswalpha_l(ch, __l)) break; - if (m & digit && iswdigit_l(ch, __l)) break; - if (m & punct && iswpunct_l(ch, __l)) break; - if (m & xdigit && iswxdigit_l(ch, __l)) break; - if (m & blank && iswblank_l(ch, __l)) break; + if ((m & space) == space && iswspace_l(ch, __l)) break; + if ((m & print) == print && iswprint_l(ch, __l)) break; + if ((m & cntrl) == cntrl && iswcntrl_l(ch, __l)) break; + if ((m & upper) == upper && iswupper_l(ch, __l)) break; + if ((m & lower) == lower && iswlower_l(ch, __l)) break; + if ((m & alpha) == alpha && iswalpha_l(ch, __l)) break; + if ((m & digit) == digit && iswdigit_l(ch, __l)) break; + if ((m & punct) == punct && iswpunct_l(ch, __l)) break; + if ((m & xdigit) == xdigit && iswxdigit_l(ch, __l)) break; + if ((m & blank) == blank && iswblank_l(ch, __l)) break; #endif } return low; @@ -1263,16 +1358,16 @@ ctype_byname<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type break; #else wint_t ch = static_cast<wint_t>(*low); - if (m & space && iswspace_l(ch, __l)) continue; - if (m & print && iswprint_l(ch, __l)) continue; - if (m & cntrl && iswcntrl_l(ch, __l)) continue; - if (m & upper && iswupper_l(ch, __l)) continue; - if (m & lower && iswlower_l(ch, __l)) continue; - if (m & alpha && iswalpha_l(ch, __l)) continue; - if (m & digit && iswdigit_l(ch, __l)) continue; - if (m & punct && iswpunct_l(ch, __l)) continue; - if (m & xdigit && iswxdigit_l(ch, __l)) continue; - if (m & blank && iswblank_l(ch, __l)) continue; + if ((m & space) == space && iswspace_l(ch, __l)) continue; + if ((m & print) == print && iswprint_l(ch, __l)) continue; + if ((m & cntrl) == cntrl && iswcntrl_l(ch, __l)) continue; + if ((m & upper) == upper && iswupper_l(ch, __l)) continue; + if ((m & lower) == lower && iswlower_l(ch, __l)) continue; + if ((m & alpha) == alpha && iswalpha_l(ch, __l)) continue; + if ((m & digit) == digit && iswdigit_l(ch, __l)) continue; + if ((m & punct) == punct && iswpunct_l(ch, __l)) continue; + if ((m & xdigit) == xdigit && iswxdigit_l(ch, __l)) continue; + if ((m & blank) == blank && iswblank_l(ch, __l)) continue; break; #endif } @@ -1564,7 +1659,7 @@ codecvt<wchar_t, char, mbstate_t>::do_in(state_type& st, frm_nxt = frm; return frm_nxt == frm_end ? ok : partial; } - if (n == 0) + if (n == size_t(-1)) return error; to_nxt += n; if (to_nxt == to_end) @@ -1614,22 +1709,23 @@ codecvt<wchar_t, char, mbstate_t>::do_unshift(state_type& st, int codecvt<wchar_t, char, mbstate_t>::do_encoding() const _NOEXCEPT { +#ifndef __CloudABI__ #ifdef _LIBCPP_LOCALE__L_EXTENSIONS - if (mbtowc_l(nullptr, nullptr, MB_LEN_MAX, __l) == 0) + if (mbtowc_l(nullptr, nullptr, MB_LEN_MAX, __l) != 0) #else - if (__mbtowc_l(nullptr, nullptr, MB_LEN_MAX, __l) == 0) + if (__mbtowc_l(nullptr, nullptr, MB_LEN_MAX, __l) != 0) #endif - { - // stateless encoding + return -1; +#endif + + // stateless encoding #ifdef _LIBCPP_LOCALE__L_EXTENSIONS - if (__l == 0 || MB_CUR_MAX_L(__l) == 1) // there are no known constant length encodings + if (__l == 0 || MB_CUR_MAX_L(__l) == 1) // there are no known constant length encodings #else - if (__l == 0 || __mb_cur_max_l(__l) == 1) // there are no known constant length encodings + if (__l == 0 || __mb_cur_max_l(__l) == 1) // there are no known constant length encodings #endif - return 1; // which take more than 1 char to form a wchar_t - return 0; - } - return -1; + return 1; // which take more than 1 char to form a wchar_t + return 0; } bool diff --git a/contrib/libc++/src/memory.cpp b/contrib/libc++/src/memory.cpp index 8a4eb34..66fb143 100644 --- a/contrib/libc++/src/memory.cpp +++ b/contrib/libc++/src/memory.cpp @@ -13,24 +13,28 @@ #include "mutex" #include "thread" #endif +#include "support/atomic_support.h" _LIBCPP_BEGIN_NAMESPACE_STD namespace { +// NOTE: Relaxed and acq/rel atomics (for increment and decrement respectively) +// should be sufficient for thread safety. +// See https://llvm.org/bugs/show_bug.cgi?id=22803 template <class T> inline T increment(T& t) _NOEXCEPT { - return __sync_add_and_fetch(&t, 1); + return __libcpp_atomic_add(&t, 1, _AO_Relaxed); } template <class T> inline T decrement(T& t) _NOEXCEPT { - return __sync_add_and_fetch(&t, -1); + return __libcpp_atomic_add(&t, -1, _AO_Acq_Rel); } } // namespace @@ -99,14 +103,13 @@ __shared_weak_count::__release_weak() _NOEXCEPT __shared_weak_count* __shared_weak_count::lock() _NOEXCEPT { - long object_owners = __shared_owners_; + long object_owners = __libcpp_atomic_load(&__shared_owners_); while (object_owners != -1) { - if (__sync_bool_compare_and_swap(&__shared_owners_, - object_owners, - object_owners+1)) + if (__libcpp_atomic_compare_exchange(&__shared_owners_, + &object_owners, + object_owners+1)) return this; - object_owners = __shared_owners_; } return 0; } diff --git a/contrib/libc++/src/mutex.cpp b/contrib/libc++/src/mutex.cpp index e56271d..5f8ba0a 100644 --- a/contrib/libc++/src/mutex.cpp +++ b/contrib/libc++/src/mutex.cpp @@ -12,6 +12,7 @@ #include "limits" #include "system_error" #include "cassert" +#include "support/atomic_support.h" _LIBCPP_BEGIN_NAMESPACE_STD #ifndef _LIBCPP_HAS_NO_THREADS @@ -220,6 +221,9 @@ static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t cv = PTHREAD_COND_INITIALIZER; #endif +/// NOTE: Changes to flag are done via relaxed atomic stores +/// even though the accesses are protected by a mutex because threads +/// just entering 'call_once` concurrently read from flag. void __call_once(volatile unsigned long& flag, void* arg, void(*func)(void*)) { @@ -252,11 +256,11 @@ __call_once(volatile unsigned long& flag, void* arg, void(*func)(void*)) try { #endif // _LIBCPP_NO_EXCEPTIONS - flag = 1; + __libcpp_relaxed_store(&flag, 1ul); pthread_mutex_unlock(&mut); func(arg); pthread_mutex_lock(&mut); - flag = ~0ul; + __libcpp_relaxed_store(&flag, ~0ul); pthread_mutex_unlock(&mut); pthread_cond_broadcast(&cv); #ifndef _LIBCPP_NO_EXCEPTIONS @@ -264,7 +268,7 @@ __call_once(volatile unsigned long& flag, void* arg, void(*func)(void*)) catch (...) { pthread_mutex_lock(&mut); - flag = 0ul; + __libcpp_relaxed_store(&flag, 0ul); pthread_mutex_unlock(&mut); pthread_cond_broadcast(&cv); throw; diff --git a/contrib/libc++/src/new.cpp b/contrib/libc++/src/new.cpp index a88d4cc..c28fcb5 100644 --- a/contrib/libc++/src/new.cpp +++ b/contrib/libc++/src/new.cpp @@ -133,9 +133,16 @@ operator delete(void* ptr, const std::nothrow_t&) _NOEXCEPT _LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS void +operator delete(void* ptr, size_t) _NOEXCEPT +{ + ::operator delete(ptr); +} + +_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS +void operator delete[] (void* ptr) _NOEXCEPT { - ::operator delete (ptr); + ::operator delete(ptr); } _LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS @@ -145,6 +152,13 @@ operator delete[] (void* ptr, const std::nothrow_t&) _NOEXCEPT ::operator delete[](ptr); } +_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS +void +operator delete[] (void* ptr, size_t) _NOEXCEPT +{ + ::operator delete[](ptr); +} + #endif // !__GLIBCXX__ namespace std diff --git a/contrib/libc++/src/random.cpp b/contrib/libc++/src/random.cpp index 15ed65b..4ab424e 100644 --- a/contrib/libc++/src/random.cpp +++ b/contrib/libc++/src/random.cpp @@ -7,11 +7,10 @@ // //===----------------------------------------------------------------------===// -#if defined(_WIN32) +#if defined(_LIBCPP_USING_WIN32_RANDOM) // Must be defined before including stdlib.h to enable rand_s(). #define _CRT_RAND_S -#include <stdio.h> -#endif // defined(_WIN32) +#endif // defined(_LIBCPP_USING_WIN32_RANDOM) #include "random" #include "system_error" @@ -19,21 +18,27 @@ #if defined(__sun__) #define rename solaris_headers_are_broken #endif // defined(__sun__) -#if !defined(_WIN32) + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> + +#if defined(_LIBCPP_USING_DEV_RANDOM) #include <fcntl.h> #include <unistd.h> -#endif // !defined(_WIN32) -#include <errno.h> -#if defined(_LIBCPP_USING_NACL_RANDOM) +#elif defined(_LIBCPP_USING_NACL_RANDOM) #include <nacl/nacl_random.h> -#endif // defined(_LIBCPP_USING_NACL_RANDOM) +#endif + _LIBCPP_BEGIN_NAMESPACE_STD -#if defined(_WIN32) +#if defined(_LIBCPP_USING_ARC4_RANDOM) -random_device::random_device(const string&) +random_device::random_device(const string& __token) { + if (__token != "/dev/urandom") + __throw_system_error(ENOENT, ("random device not supported " + __token).c_str()); } random_device::~random_device() @@ -43,10 +48,43 @@ random_device::~random_device() unsigned random_device::operator()() { + return arc4random(); +} + +#elif defined(_LIBCPP_USING_DEV_RANDOM) + +random_device::random_device(const string& __token) + : __f_(open(__token.c_str(), O_RDONLY)) +{ + if (__f_ < 0) + __throw_system_error(errno, ("random_device failed to open " + __token).c_str()); +} + +random_device::~random_device() +{ + close(__f_); +} + +unsigned +random_device::operator()() +{ unsigned r; - errno_t err = rand_s(&r); - if (err) - __throw_system_error(err, "random_device rand_s failed."); + size_t n = sizeof(r); + char* p = reinterpret_cast<char*>(&r); + while (n > 0) + { + ssize_t s = read(__f_, p, n); + if (s == 0) + __throw_system_error(ENODATA, "random_device got EOF"); + if (s == -1) + { + if (errno != EINTR) + __throw_system_error(errno, "random_device got an unexpected error"); + continue; + } + n -= static_cast<size_t>(s); + p += static_cast<size_t>(s); + } return r; } @@ -70,7 +108,6 @@ random_device::operator()() { unsigned r; size_t n = sizeof(r); - char* p = reinterpret_cast<char*>(&r); size_t bytes_written; int error = nacl_secure_random(&r, n, &bytes_written); if (error != 0) @@ -80,44 +117,31 @@ random_device::operator()() return r; } -#else // !defined(_WIN32) && !defined(_LIBCPP_USING_NACL_RANDOM) +#elif defined(_LIBCPP_USING_WIN32_RANDOM) random_device::random_device(const string& __token) - : __f_(open(__token.c_str(), O_RDONLY)) { - if (__f_ < 0) - __throw_system_error(errno, ("random_device failed to open " + __token).c_str()); + if (__token != "/dev/urandom") + __throw_system_error(ENOENT, ("random device not supported " + __token).c_str()); } random_device::~random_device() { - close(__f_); } unsigned random_device::operator()() { unsigned r; - size_t n = sizeof(r); - char* p = reinterpret_cast<char*>(&r); - while (n > 0) - { - ssize_t s = read(__f_, p, n); - if (s == 0) - __throw_system_error(ENODATA, "random_device got EOF"); - if (s == -1) - { - if (errno != EINTR) - __throw_system_error(errno, "random_device got an unexpected error"); - continue; - } - n -= static_cast<size_t>(s); - p += static_cast<size_t>(s); - } + errno_t err = rand_s(&r); + if (err) + __throw_system_error(err, "random_device rand_s failed."); return r; } -#endif // defined(_WIN32) || defined(_LIBCPP_USING_NACL_RANDOM) +#else +#error "Random device not implemented for this architecture" +#endif double random_device::entropy() const _NOEXCEPT diff --git a/contrib/libc++/src/shared_mutex.cpp b/contrib/libc++/src/shared_mutex.cpp index 2b78c1f..874aceb 100644 --- a/contrib/libc++/src/shared_mutex.cpp +++ b/contrib/libc++/src/shared_mutex.cpp @@ -15,7 +15,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD -shared_timed_mutex::shared_timed_mutex() +// Shared Mutex Base +__shared_mutex_base::__shared_mutex_base() : __state_(0) { } @@ -23,7 +24,7 @@ shared_timed_mutex::shared_timed_mutex() // Exclusive ownership void -shared_timed_mutex::lock() +__shared_mutex_base::lock() { unique_lock<mutex> lk(__mut_); while (__state_ & __write_entered_) @@ -34,7 +35,7 @@ shared_timed_mutex::lock() } bool -shared_timed_mutex::try_lock() +__shared_mutex_base::try_lock() { unique_lock<mutex> lk(__mut_); if (__state_ == 0) @@ -46,7 +47,7 @@ shared_timed_mutex::try_lock() } void -shared_timed_mutex::unlock() +__shared_mutex_base::unlock() { lock_guard<mutex> _(__mut_); __state_ = 0; @@ -56,7 +57,7 @@ shared_timed_mutex::unlock() // Shared ownership void -shared_timed_mutex::lock_shared() +__shared_mutex_base::lock_shared() { unique_lock<mutex> lk(__mut_); while ((__state_ & __write_entered_) || (__state_ & __n_readers_) == __n_readers_) @@ -67,7 +68,7 @@ shared_timed_mutex::lock_shared() } bool -shared_timed_mutex::try_lock_shared() +__shared_mutex_base::try_lock_shared() { unique_lock<mutex> lk(__mut_); unsigned num_readers = __state_ & __n_readers_; @@ -82,7 +83,7 @@ shared_timed_mutex::try_lock_shared() } void -shared_timed_mutex::unlock_shared() +__shared_mutex_base::unlock_shared() { lock_guard<mutex> _(__mut_); unsigned num_readers = (__state_ & __n_readers_) - 1; @@ -101,6 +102,16 @@ shared_timed_mutex::unlock_shared() } +// Shared Timed Mutex +// These routines are here for ABI stability +shared_timed_mutex::shared_timed_mutex() : __base() {} +void shared_timed_mutex::lock() { return __base.lock(); } +bool shared_timed_mutex::try_lock() { return __base.try_lock(); } +void shared_timed_mutex::unlock() { return __base.unlock(); } +void shared_timed_mutex::lock_shared() { return __base.lock_shared(); } +bool shared_timed_mutex::try_lock_shared() { return __base.try_lock_shared(); } +void shared_timed_mutex::unlock_shared() { return __base.unlock_shared(); } + _LIBCPP_END_NAMESPACE_STD #endif // !_LIBCPP_HAS_NO_THREADS diff --git a/contrib/libc++/src/string.cpp b/contrib/libc++/src/string.cpp index febc532..d3f29df 100644 --- a/contrib/libc++/src/string.cpp +++ b/contrib/libc++/src/string.cpp @@ -39,7 +39,7 @@ void throw_helper( const string& msg ) #ifndef _LIBCPP_NO_EXCEPTIONS throw T( msg ); #else - printf("%s\n", msg.c_str()); + fprintf(stderr, "%s\n", msg.c_str()); abort(); #endif } diff --git a/contrib/libc++/src/support/atomic_support.h b/contrib/libc++/src/support/atomic_support.h new file mode 100644 index 0000000..e738a51 --- /dev/null +++ b/contrib/libc++/src/support/atomic_support.h @@ -0,0 +1,142 @@ +#ifndef ATOMIC_SUPPORT_H +#define ATOMIC_SUPPORT_H + +#include "__config" +#include "memory" // for __libcpp_relaxed_load + +#if defined(__clang__) && __has_builtin(__atomic_load_n) \ + && __has_builtin(__atomic_store_n) \ + && __has_builtin(__atomic_add_fetch) \ + && __has_builtin(__atomic_compare_exchange_n) \ + && defined(__ATOMIC_RELAXED) \ + && defined(__ATOMIC_CONSUME) \ + && defined(__ATOMIC_ACQUIRE) \ + && defined(__ATOMIC_RELEASE) \ + && defined(__ATOMIC_ACQ_REL) \ + && defined(__ATOMIC_SEQ_CST) +# define _LIBCPP_HAS_ATOMIC_BUILTINS +#elif !defined(__clang__) && defined(_GNUC_VER) && _GNUC_VER >= 407 +# define _LIBCPP_HAS_ATOMIC_BUILTINS +#endif + +#if !defined(_LIBCPP_HAS_ATOMIC_BUILTINS) && !defined(_LIBCPP_HAS_NO_THREADS) +# if defined(_MSC_VER) && !defined(__clang__) + _LIBCPP_WARNING("Building libc++ without __atomic builtins is unsupported") +# else +# warning Building libc++ without __atomic builtins is unsupported +# endif +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace { + +#if defined(_LIBCPP_HAS_ATOMIC_BUILTINS) && !defined(_LIBCPP_HAS_NO_THREADS) + +enum __libcpp_atomic_order { + _AO_Relaxed = __ATOMIC_RELAXED, + _AO_Consume = __ATOMIC_CONSUME, + _AO_Aquire = __ATOMIC_ACQUIRE, + _AO_Release = __ATOMIC_RELEASE, + _AO_Acq_Rel = __ATOMIC_ACQ_REL, + _AO_Seq = __ATOMIC_SEQ_CST +}; + +template <class _ValueType, class _FromType> +inline _LIBCPP_INLINE_VISIBILITY +void __libcpp_atomic_store(_ValueType* __dest, _FromType __val, + int __order = _AO_Seq) +{ + __atomic_store_n(__dest, __val, __order); +} + +template <class _ValueType, class _FromType> +inline _LIBCPP_INLINE_VISIBILITY +void __libcpp_relaxed_store(_ValueType* __dest, _FromType __val) +{ + __atomic_store_n(__dest, __val, _AO_Relaxed); +} + +template <class _ValueType> +inline _LIBCPP_INLINE_VISIBILITY +_ValueType __libcpp_atomic_load(_ValueType const* __val, + int __order = _AO_Seq) +{ + return __atomic_load_n(__val, __order); +} + +template <class _ValueType, class _AddType> +inline _LIBCPP_INLINE_VISIBILITY +_ValueType __libcpp_atomic_add(_ValueType* __val, _AddType __a, + int __order = _AO_Seq) +{ + return __atomic_add_fetch(__val, __a, __order); +} + +template <class _ValueType> +inline _LIBCPP_INLINE_VISIBILITY +bool __libcpp_atomic_compare_exchange(_ValueType* __val, + _ValueType* __expected, _ValueType __after, + int __success_order = _AO_Seq, + int __fail_order = _AO_Seq) +{ + return __atomic_compare_exchange_n(__val, __expected, __after, true, + __success_order, __fail_order); +} + +#else // _LIBCPP_HAS_NO_THREADS + +enum __libcpp_atomic_order { + _AO_Relaxed, + _AO_Consume, + _AO_Acquire, + _AO_Release, + _AO_Acq_Rel, + _AO_Seq +}; + +template <class _ValueType, class _FromType> +inline _LIBCPP_INLINE_VISIBILITY +void __libcpp_atomic_store(_ValueType* __dest, _FromType __val, + int = 0) +{ + *__dest = __val; +} + +template <class _ValueType> +inline _LIBCPP_INLINE_VISIBILITY +_ValueType __libcpp_atomic_load(_ValueType const* __val, + int = 0) +{ + return *__val; +} + +template <class _ValueType, class _AddType> +inline _LIBCPP_INLINE_VISIBILITY +_ValueType __libcpp_atomic_add(_ValueType* __val, _AddType __a, + int = 0) +{ + return *__val += __a; +} + +template <class _ValueType> +inline _LIBCPP_INLINE_VISIBILITY +bool __libcpp_atomic_compare_exchange(_ValueType* __val, + _ValueType* __expected, _ValueType __after, + int = 0, int = 0) +{ + if (*__val == *__expected) { + *__val = __after; + return true; + } + *__expected = *__val; + return false; +} + +#endif // _LIBCPP_HAS_NO_THREADS + +} // end namespace + +_LIBCPP_END_NAMESPACE_STD + +#endif // ATOMIC_SUPPORT_H diff --git a/contrib/libc++/src/system_error.cpp b/contrib/libc++/src/system_error.cpp index 9c8adc4..18f668f 100644 --- a/contrib/libc++/src/system_error.cpp +++ b/contrib/libc++/src/system_error.cpp @@ -7,11 +7,14 @@ // //===----------------------------------------------------------------------===// -#define _LIBCPP_BUILDING_SYSTEM_ERROR #include "__config" + +#define _LIBCPP_BUILDING_SYSTEM_ERROR #include "system_error" -#include "string" + +#include "config_elast.h" #include "cstring" +#include "string" _LIBCPP_BEGIN_NAMESPACE_STD @@ -149,7 +152,7 @@ system_error::__init(const error_code& ec, string what_arg) what_arg += ": "; what_arg += ec.message(); } - return _VSTD::move(what_arg); + return what_arg; } system_error::system_error(error_code ec, const string& what_arg) diff --git a/contrib/libc++/src/thread.cpp b/contrib/libc++/src/thread.cpp index 6aad558..bd27f28 100644 --- a/contrib/libc++/src/thread.cpp +++ b/contrib/libc++/src/thread.cpp @@ -17,9 +17,9 @@ #include "limits" #include <sys/types.h> #if !defined(_WIN32) -# if !defined(__sun__) && !defined(__linux__) && !defined(_AIX) && !defined(__native_client__) +# if !defined(__sun__) && !defined(__linux__) && !defined(_AIX) && !defined(__native_client__) && !defined(__CloudABI__) # include <sys/sysctl.h> -# endif // !defined(__sun__) && !defined(__linux__) && !defined(_AIX) && !defined(__native_client__) +# endif // !defined(__sun__) && !defined(__linux__) && !defined(_AIX) && !defined(__native_client__) && !defined(__CloudABI__) # include <unistd.h> #endif // !_WIN32 |