summaryrefslogtreecommitdiffstats
path: root/contrib/libc++/src
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/libc++/src')
-rw-r--r--contrib/libc++/src/chrono.cpp66
-rw-r--r--contrib/libc++/src/config_elast.h36
-rw-r--r--contrib/libc++/src/debug.cpp2
-rw-r--r--contrib/libc++/src/exception.cpp32
-rw-r--r--contrib/libc++/src/future.cpp5
-rw-r--r--contrib/libc++/src/ios.cpp14
-rw-r--r--contrib/libc++/src/iostream.cpp68
-rw-r--r--contrib/libc++/src/locale.cpp206
-rw-r--r--contrib/libc++/src/memory.cpp17
-rw-r--r--contrib/libc++/src/mutex.cpp10
-rw-r--r--contrib/libc++/src/new.cpp16
-rw-r--r--contrib/libc++/src/random.cpp96
-rw-r--r--contrib/libc++/src/shared_mutex.cpp25
-rw-r--r--contrib/libc++/src/string.cpp2
-rw-r--r--contrib/libc++/src/support/atomic_support.h142
-rw-r--r--contrib/libc++/src/system_error.cpp9
-rw-r--r--contrib/libc++/src/thread.cpp4
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
OpenPOWER on IntegriCloud