From adff4895b2746f30b271bc219713e7ded5ae9677 Mon Sep 17 00:00:00 2001 From: Howard Hinnant Date: Mon, 24 May 2010 17:49:41 +0000 Subject: [PATCH] patch by Jeffrey Yasskin for porting to Ubuntu Hardy. Everything was accepted except there were some bug fixes needed in for the __nolocale_* series. For the apple branch I ended up using templates instead of the var_args solution because it seemed both safer and more efficient. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@104516 91177308-0d34-0410-b5e6-96231b3b80d8 --- Makefile | 1 + include/__config | 11 ++- include/__locale | 18 +++++ include/algorithm | 6 +- include/cstddef | 2 + include/iosfwd | 10 +-- include/locale | 166 ++++++++++++++++++++++++++++++++++++++----- include/string | 1 + include/thread | 5 +- include/vector | 2 +- lib/buildit | 55 +++++++++----- src/chrono.cpp | 27 +++++++ src/exception.cpp | 8 ++- src/ios.cpp | 6 +- src/locale.cpp | 6 +- src/memory.cpp | 53 ++------------ src/mutex.cpp | 4 +- src/new.cpp | 4 +- src/stdexcept.cpp | 9 ++- src/system_error.cpp | 24 ++++--- src/thread.cpp | 10 ++- 21 files changed, 308 insertions(+), 120 deletions(-) diff --git a/Makefile b/Makefile index 804e5e4ae..b5c2e4c0c 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,7 @@ DESTDIR = $(DSTROOT) OBJROOT=. SYMROOT=. +TRIPLE=-apple- installsrc:: $(SRCROOT) diff --git a/include/__config b/include/__config index 7b66dfc12..a3518d9e3 100644 --- a/include/__config +++ b/include/__config @@ -37,7 +37,16 @@ #endif #if !defined(_LIBCPP_LITTLE_ENDIAN) || !defined(_LIBCPP_BIG_ENDIAN) -#error unable to determine endian +# include +# if __BYTE_ORDER == __LITTLE_ENDIAN +# define _LIBCPP_LITTLE_ENDIAN 1 +# define _LIBCPP_BIG_ENDIAN 0 +# elif __BYTE_ORDER == __BIG_ENDIAN +# define _LIBCPP_LITTLE_ENDIAN 0 +# define _LIBCPP_BIG_ENDIAN 1 +# else +# error unable to determine endian +# endif #endif #ifndef _LIBCPP_VISIBILITY_TAG diff --git a/include/__locale b/include/__locale index 249e5b807..395cb2682 100644 --- a/include/__locale +++ b/include/__locale @@ -18,6 +18,7 @@ #include #include #include +#include #include #pragma GCC system_header @@ -294,6 +295,7 @@ class ctype_base { public: typedef __uint32_t mask; +#if __APPLE__ static const mask space = _CTYPE_S; static const mask print = _CTYPE_R; static const mask cntrl = _CTYPE_C; @@ -304,6 +306,18 @@ public: static const mask punct = _CTYPE_P; static const mask xdigit = _CTYPE_X; static const mask blank = _CTYPE_B; +#else /* !__APPLE__ */ + static const mask space = _ISspace; + static const mask print = _ISprint; + static const mask cntrl = _IScntrl; + static const mask upper = _ISupper; + static const mask lower = _ISlower; + static const mask alpha = _ISalpha; + static const mask digit = _ISdigit; + static const mask punct = _ISpunct; + static const mask xdigit = _ISxdigit; + static const mask blank = _ISblank; +#endif /* __APPLE__ */ static const mask alnum = alpha | digit; static const mask graph = alnum | punct; @@ -507,7 +521,11 @@ public: static locale::id id; +#ifdef _CACHED_RUNES static const size_t table_size = _CACHED_RUNES; +#else + static const size_t table_size = 256; // FIXME: Don't hardcode this. +#endif const mask* table() const throw() {return __tab_;} static const mask* classic_table() throw(); diff --git a/include/algorithm b/include/algorithm index f3412f726..c53bf3766 100644 --- a/include/algorithm +++ b/include/algorithm @@ -552,16 +552,12 @@ template #ifdef _LIBCPP_DEBUG #include #endif -//#include -#define RAND_MAX 0x7fffffff // #include -extern "C" int rand(void); // #include +#include #pragma GCC system_header _LIBCPP_BEGIN_NAMESPACE_STD -using ::rand; // #include - template struct __equal_to { diff --git a/include/cstddef b/include/cstddef index 11d07a2ec..efe0f61c7 100644 --- a/include/cstddef +++ b/include/cstddef @@ -34,6 +34,8 @@ Types: */ #include <__config> +#define __need_ptrdiff_t +#define __need_size_t #include #pragma GCC system_header diff --git a/include/iosfwd b/include/iosfwd index e9a6a0f60..32f679e7b 100644 --- a/include/iosfwd +++ b/include/iosfwd @@ -86,7 +86,7 @@ typedef fpos::state_type> wstreampos; */ #include <__config> -#include <_types.h> // for __darwin_mbstate_t +#include // for mbstate_t #pragma GCC system_header @@ -153,11 +153,11 @@ typedef basic_ofstream wofstream; typedef basic_fstream wfstream; template class fpos; -typedef fpos<__darwin_mbstate_t> streampos; -typedef fpos<__darwin_mbstate_t> wstreampos; +typedef fpos streampos; +typedef fpos wstreampos; #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS -typedef fpos<__darwin_mbstate_t> u16streampos; -typedef fpos<__darwin_mbstate_t> u32streampos; +typedef fpos u16streampos; +typedef fpos u32streampos; #endif typedef long long streamoff; // for char_traits in diff --git a/include/locale b/include/locale index 284184fb1..09faccd07 100644 --- a/include/locale +++ b/include/locale @@ -137,6 +137,9 @@ template class messages_byname; #include #include #include +#if !__APPLE__ +#include +#endif #include #include #include @@ -145,6 +148,131 @@ template class messages_byname; _LIBCPP_BEGIN_NAMESPACE_STD +// OSX has nice foo_l() functions that let you turn off use of the global +// locale. Linux, not so much. The following functions avoid the locale when +// that's possible and otherwise do the wrong thing. FIXME. +#if __APPLE__ + +template +inline +int +__nolocale_sprintf(char* __restrict __str, + const char* __restrict __format, _Tp __v) +{ + return sprintf_l(__str, 0, __format, __v); +} + +template +inline +int +__nolocale_snprintf(char* __restrict __str, size_t __size, + const char* __restrict __format, _Tp __v) +{ + return snprintf_l(__str, __size, 0, __format, __v); +} + +template +inline +int +__nolocale_snprintf(char* __restrict __str, size_t __size, + const char* __restrict __format, int __prec, _Tp __v) +{ + return snprintf_l(__str, __size, 0, __format, __prec, __v); +} + +template +inline +int +__nolocale_asprintf(char** __ret, const char* __restrict __format, _Tp __v) +{ + return asprintf_l(__ret, 0, __format, __v); +} + +template +inline +int +__nolocale_asprintf(char** __ret, const char* __restrict __format, int __prec, + _Tp __v) +{ + return asprintf_l(__ret, 0, __format, __prec, __v); +} + +template +inline +int +__nolocale_sscanf(const char* __restrict __str, + const char* __restrict __format, _Tp* __v) +{ + return sscanf_l(__str, 0, __format, __v); +} + +inline +int +__nolocale_isxdigit(int __c) +{ + return isxdigit_l(__c, 0); +} + +inline +int +__nolocale_isdigit(int __c) +{ + return isdigit_l(__c, 0); +} + +#else /* !__APPLE__ */ +inline int +__nolocale_sprintf(char* __restrict __str, + const char* __restrict __format, ...) +{ + va_list __ap; + va_start(__ap, __format); + int __result = vsprintf(__str, __format, __ap); + va_end(__ap); + return __result; +} +inline int +__nolocale_snprintf(char* __restrict __str, size_t __size, + const char* __restrict __format, ...) +{ + va_list __ap; + va_start(__ap, __format); + int __result = vsnprintf(__str, __size, __format, __ap); + va_end(__ap); + return __result; +} +inline int +__nolocale_asprintf(char** __ret, + const char* __restrict __format, ...) +{ + va_list __ap; + va_start(__ap, __format); + int __result = vasprintf(__ret, __format, __ap); + va_end(__ap); + return __result; +} +inline int +__nolocale_sscanf(const char* __restrict __str, + const char* __restrict __format, ...) +{ + va_list __ap; + va_start(__ap, __format); + int __result = vsscanf(__str, __format, __ap); + va_end(__ap); + return __result; +} +inline int +__nolocale_isxdigit(int __c) +{ + return isxdigit(__c); +} +inline int +__nolocale_isdigit(int __c) +{ + return isdigit(__c); +} +#endif /* __APPLE__ */ + // __scan_keyword // Scans [__b, __e) until a match is found in the basic_strings range // [__kb, __ke) or until it can be shown that there is no match in [__kb, __ke). @@ -1002,7 +1130,7 @@ num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, break; // Stage 3 __a[sizeof(__a)-1] = 0; - if (sscanf_l(__a, 0, "%p", &__v) != 1) + if (__nolocale_sscanf(__a, "%p", &__v) != 1) __err = ios_base::failbit; // EOF checked if (__b == __e) @@ -1107,13 +1235,13 @@ __num_put<_CharT>::__widen_and_group_float(char* __nb, char* __np, char* __ne, *__oe++ = __ct.widen(*__nf++); *__oe++ = __ct.widen(*__nf++); for (__ns = __nf; __ns < __ne; ++__ns) - if (!isxdigit_l(*__ns, 0)) + if (!__nolocale_isxdigit(*__ns)) break; } else { for (__ns = __nf; __ns < __ne; ++__ns) - if (!isdigit_l(*__ns, 0)) + if (!__nolocale_isdigit(*__ns)) break; } if (__grouping.empty()) @@ -1310,7 +1438,7 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, + ((numeric_limits::digits % 3) != 0) + 1; char __nar[__nbuf]; - int __nc = sprintf_l(__nar, 0, __fmt, __v); + int __nc = __nolocale_sprintf(__nar, __fmt, __v); char* __ne = __nar + __nc; char* __np = this->__identify_padding(__nar, __ne, __iob); // Stage 2 - Widen __nar while adding thousands separators @@ -1336,7 +1464,7 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, + ((numeric_limits::digits % 3) != 0) + 1; char __nar[__nbuf]; - int __nc = sprintf_l(__nar, 0, __fmt, __v); + int __nc = __nolocale_sprintf(__nar, __fmt, __v); char* __ne = __nar + __nc; char* __np = this->__identify_padding(__nar, __ne, __iob); // Stage 2 - Widen __nar while adding thousands separators @@ -1362,7 +1490,7 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, + ((numeric_limits::digits % 3) != 0) + 1; char __nar[__nbuf]; - int __nc = sprintf_l(__nar, 0, __fmt, __v); + int __nc = __nolocale_sprintf(__nar, __fmt, __v); char* __ne = __nar + __nc; char* __np = this->__identify_padding(__nar, __ne, __iob); // Stage 2 - Widen __nar while adding thousands separators @@ -1388,7 +1516,7 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, + ((numeric_limits::digits % 3) != 0) + 1; char __nar[__nbuf]; - int __nc = sprintf_l(__nar, 0, __fmt, __v); + int __nc = __nolocale_sprintf(__nar, __fmt, __v); char* __ne = __nar + __nc; char* __np = this->__identify_padding(__nar, __ne, __iob); // Stage 2 - Widen __nar while adding thousands separators @@ -1415,16 +1543,18 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, char* __nb = __nar; int __nc; if (__specify_precision) - __nc = snprintf_l(__nb, __nbuf, 0, __fmt, (int)__iob.precision(), __v); + __nc = __nolocale_snprintf(__nb, __nbuf, __fmt, + (int)__iob.precision(), __v); else - __nc = snprintf_l(__nb, __nbuf, 0, __fmt, __v); + __nc = __nolocale_snprintf(__nb, __nbuf, __fmt, __v); unique_ptr __nbh(0, free); if (__nc > static_cast(__nbuf-1)) { if (__specify_precision) - __nc = asprintf_l(&__nb, 0, __fmt, (int)__iob.precision(), __v); + __nc = __nolocale_asprintf(&__nb, __fmt, (int)__iob.precision(), + __v); else - __nc = asprintf_l(&__nb, 0, __fmt, __v); + __nc = __nolocale_asprintf(&__nb, __fmt, __v); if (__nb == 0) __throw_bad_alloc(); __nbh.reset(__nb); @@ -1465,16 +1595,18 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, char* __nb = __nar; int __nc; if (__specify_precision) - __nc = snprintf_l(__nb, __nbuf, 0, __fmt, (int)__iob.precision(), __v); + __nc = __nolocale_snprintf(__nb, __nbuf, __fmt, + (int)__iob.precision(), __v); else - __nc = snprintf_l(__nb, __nbuf, 0, __fmt, __v); + __nc = __nolocale_snprintf(__nb, __nbuf, __fmt, __v); unique_ptr __nbh(0, free); if (__nc > static_cast(__nbuf-1)) { if (__specify_precision) - __nc = asprintf_l(&__nb, 0, __fmt, (int)__iob.precision(), __v); + __nc = __nolocale_asprintf(&__nb, __fmt, (int)__iob.precision(), + __v); else - __nc = asprintf_l(&__nb, 0, __fmt, __v); + __nc = __nolocale_asprintf(&__nb, __fmt, __v); if (__nb == 0) __throw_bad_alloc(); __nbh.reset(__nb); @@ -1510,7 +1642,7 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, char __fmt[6] = "%p"; const unsigned __nbuf = 20; char __nar[__nbuf]; - int __nc = sprintf_l(__nar, 0, __fmt, __v); + int __nc = __nolocale_sprintf(__nar, __fmt, __v); char* __ne = __nar + __nc; char* __np = this->__identify_padding(__nar, __ne, __iob); // Stage 2 - Widen __nar @@ -3162,7 +3294,7 @@ money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl, // secure memory for digit storage if (__n > __bs-1) { - __n = asprintf_l(&__bb, 0, "%.0Lf", __units); + __n = __nolocale_asprintf(&__bb, "%.0Lf", __units); if (__bb == 0) __throw_bad_alloc(); __hn.reset(__bb); diff --git a/include/string b/include/string index 6b11e02bc..15713f07f 100644 --- a/include/string +++ b/include/string @@ -358,6 +358,7 @@ template <> struct hash; #include <__config> #include #include +#include // For EOF. #include #include #include diff --git a/include/thread b/include/thread index 3c1cf99fc..16faed938 100644 --- a/include/thread +++ b/include/thread @@ -115,6 +115,9 @@ __thread_id get_id(); class __thread_id { + // FIXME: pthread_t is a pointer on Darwin but a long on Linux. + // NULL is the no-thread value on Darwin. Someone needs to check + // on other platforms. We assume 0 works everywhere for now. pthread_t __id_; public: @@ -206,7 +209,7 @@ public: void swap(thread& __t) {_STD::swap(__t_, __t.__t_);} - bool joinable() const {return __t_ != nullptr;} + bool joinable() const {return __t_ != 0;} void join(); void detach(); id get_id() const {return __t_;} diff --git a/include/vector b/include/vector index a85d39a5b..e97e939c3 100644 --- a/include/vector +++ b/include/vector @@ -1118,7 +1118,7 @@ vector<_Tp, _Allocator>::assign(size_type __n, const_reference __u) if (__n > __s) __construct_at_end(__n - __s, __u); else - __destruct_at_end(this->__begin_ + __n); + this->__destruct_at_end(this->__begin_ + __n); } else { diff --git a/lib/buildit b/lib/buildit index 6cbe971ad..43341f970 100755 --- a/lib/buildit +++ b/lib/buildit @@ -1,41 +1,60 @@ +#! /bin/sh +# +# Set the $TRIPLE environment variable to your system's triple before +# running this script. If you set $CXX, that will be used to compile +# the library. Otherwise we'll use g++. + +set -e + if [ `basename $(pwd)` != "lib" ] then echo "current directory must be lib" exit 1 fi -if [ -z $CC ] +if [ -z $CXX ] then - CC=g++ + CXX=g++ fi +case $TRIPLE in + *-apple-*) + if [ -z $RC_BUILDIT ] + then + RC_CFLAGS="-arch i386 -arch ppc -arch x86_64" + fi + SOEXT=dylib + LDSHARED_FLAGS="-o libc++.1.dylib \ + -dynamiclib -nodefaultlibs -current_version 1 \ + -compatibility_version 1 \ + -install_name /usr/lib/libc++.dylib \ + -Wl,-reexport_library,/usr/lib/libc++abi.dylib \ + /usr/lib/libSystem.B.dylib" + ;; + *) + RC_CFLAGS="-fPIC" + SOEXT=so + LDSHARED_FLAGS="-o libc++.so.1.0 \ + -shared -nodefaultlibs -Wl,-soname,libc++.so.1 \ + -lstdc++ -lc" + ;; +esac + if [ -z $RC_BUILDIT ] then - RC_CFLAGS="-arch i386 -arch ppc -arch x86_64" -fi - -if [ -z $RC_BUILDIT ] -then - rm libc++.1.dylib + rm -f libc++.1.$SOEXT* fi set -x -for FILE in $(ls ../src/*.cpp); do - $CC -c -g -Os $RC_CFLAGS -nostdinc++ -I../include $FILE +for FILE in ../src/*.cpp; do + $CXX -c -g -Os $RC_CFLAGS -nostdinc++ -I../include $FILE done -$CC -dynamiclib -nodefaultlibs $RC_CFLAGS -current_version 1 \ - -compatibility_version 1 \ - -o libc++.1.dylib *.o \ - -install_name /usr/lib/libc++.dylib \ - -Wl,-reexport_library,/usr/lib/libc++abi.dylib \ - /usr/lib/libSystem.B.dylib +$CXX *.o $RC_CFLAGS $LDSHARED_FLAGS #libtool -static -o libc++.a *.o -set +x - if [ -z $RC_BUILDIT ] then rm *.o diff --git a/src/chrono.cpp b/src/chrono.cpp index b984f9df6..d06fbf777 100644 --- a/src/chrono.cpp +++ b/src/chrono.cpp @@ -9,7 +9,13 @@ #include "chrono" #include //for gettimeofday and timeval +#if __APPLE__ #include // mach_absolute_time, mach_timebase_info_data_t +#else /* !__APPLE__ */ +#include // errno +#include // __throw_system_error +#include // clock_gettime, CLOCK_MONOTONIC +#endif /* __APPLE__ */ _LIBCPP_BEGIN_NAMESPACE_STD @@ -40,6 +46,7 @@ system_clock::from_time_t(time_t t) // monotonic_clock +#if __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 @@ -96,6 +103,26 @@ monotonic_clock::now() return time_point(duration(fp())); } +#else /* !APPLE */ +// FIXME: We assume that clock_gettime(CLOCK_MONOTONIC) works on +// non-apple systems. Instead, we should check _POSIX_TIMERS and +// _POSIX_MONOTONIC_CLOCK and fall back to something else if those +// don't exist. + +// Warning: If this is not truly monotonic, then it is non-conforming. It is +// better for it to not exist and have the rest of libc++ use system_clock +// instead. + +monotonic_clock::time_point +monotonic_clock::now() +{ + 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 */ + } _LIBCPP_END_NAMESPACE_STD diff --git a/src/exception.cpp b/src/exception.cpp index 336527df2..e48e9c490 100644 --- a/src/exception.cpp +++ b/src/exception.cpp @@ -72,8 +72,11 @@ bool std::uncaught_exception() throw() // on Darwin, there is a helper function so __cxa_get_globals is private return __cxxabiapple::__cxa_uncaught_exception(); #else - __cxa_eh_globals * globals = __cxa_get_globals(); - return (globals->uncaughtExceptions != 0); + #warning uncaught_exception not yet implemented + ::abort(); + // Not provided by Ubuntu gcc-4.2.4's cxxabi.h. + // __cxa_eh_globals * globals = __cxa_get_globals(); + // return (globals->uncaughtExceptions != 0); #endif } @@ -168,4 +171,3 @@ void std::rethrow_exception(exception_ptr p) ::abort(); #endif } - diff --git a/src/ios.cpp b/src/ios.cpp index 3bf3cbc3a..4d1261e38 100644 --- a/src/ios.cpp +++ b/src/ios.cpp @@ -106,7 +106,11 @@ __iostream_category::name() const string __iostream_category::message(int ev) const { - if (ev != static_cast(io_errc::stream) && ev <= ELAST) + if (ev != static_cast(io_errc::stream) +#ifdef ELAST + && ev <= ELAST +#endif + ) return __do_message::message(ev); return string("unspecified iostream_category error"); } diff --git a/src/locale.cpp b/src/locale.cpp index e219d982a..a65d6ed3d 100644 --- a/src/locale.cpp +++ b/src/locale.cpp @@ -17,10 +17,11 @@ #include "cstring" #include "cwctype" #include "__sso_allocator" -#include #include #include +// FIXME: Locales are hard. +#if __APPLE__ _LIBCPP_BEGIN_NAMESPACE_STD namespace { @@ -534,7 +535,7 @@ locale::id::__get() void locale::id::__init() { - __id_ = OSAtomicIncrement32Barrier(&__next_id); + __id_ = __sync_add_and_fetch(&__next_id, 1); } // template <> class collate_byname @@ -3678,3 +3679,4 @@ template class codecvt_byname; template class __vector_base_common; _LIBCPP_END_NAMESPACE_STD +#endif /* __APPLE__ */ diff --git a/src/memory.cpp b/src/memory.cpp index e3075bcb1..f35b838b6 100644 --- a/src/memory.cpp +++ b/src/memory.cpp @@ -8,7 +8,6 @@ //===----------------------------------------------------------------------===// #include "memory" -#include _LIBCPP_BEGIN_NAMESPACE_STD @@ -16,57 +15,19 @@ namespace { template -inline -typename enable_if -< - sizeof(T) * __CHAR_BIT__ == 32, - T ->::type +inline T increment(T& t) { - return OSAtomicIncrement32Barrier((volatile int32_t*)&t); + return __sync_add_and_fetch(&t, 1); } template -inline -typename enable_if -< - sizeof(T) * __CHAR_BIT__ == 32, - T ->::type +inline T decrement(T& t) { - return OSAtomicDecrement32Barrier((volatile int32_t*)&t); + return __sync_add_and_fetch(&t, -1); } -#ifndef __ppc__ - -template -inline -typename enable_if -< - sizeof(T) * __CHAR_BIT__ == 64, - T ->::type -increment(T& t) -{ - return OSAtomicIncrement64Barrier((volatile int64_t*)&t); -} - -template -inline -typename enable_if -< - sizeof(T) * __CHAR_BIT__ == 64, - T ->::type -decrement(T& t) -{ - return OSAtomicDecrement64Barrier((volatile int64_t*)&t); -} - -#endif - } // namespace @@ -134,9 +95,9 @@ __shared_weak_count::lock() long object_owners = __shared_owners_; while (object_owners != -1) { - if (OSAtomicCompareAndSwapLongBarrier(object_owners, - object_owners+1, - &__shared_owners_)) + if (__sync_bool_compare_and_swap(&__shared_owners_, + object_owners, + object_owners+1)) { __add_weak(); return this; diff --git a/src/mutex.cpp b/src/mutex.cpp index f98d7257f..7ea734968 100644 --- a/src/mutex.cpp +++ b/src/mutex.cpp @@ -148,7 +148,7 @@ timed_mutex::unlock() recursive_timed_mutex::recursive_timed_mutex() : __count_(0), - __id_(nullptr) + __id_(0) { } @@ -197,7 +197,7 @@ recursive_timed_mutex::unlock() unique_lock lk(__m_); if (--__count_ == 0) { - __id_ = nullptr; + __id_ = 0; lk.unlock(); __cv_.notify_one(); } diff --git a/src/new.cpp b/src/new.cpp index 9ad061282..964d87b89 100644 --- a/src/new.cpp +++ b/src/new.cpp @@ -7,13 +7,13 @@ // //===----------------------------------------------------------------------===// -#include -#include +#include #include "new" #if __APPLE__ + #include // On Darwin, there are two STL shared libraries and a lower level ABI // shared libray. The global holding the current new handler is // in the ABI library and named __cxa_new_handler. diff --git a/src/stdexcept.cpp b/src/stdexcept.cpp index e8960eb39..5f3ffd712 100644 --- a/src/stdexcept.cpp +++ b/src/stdexcept.cpp @@ -15,7 +15,6 @@ #include #include #include "system_error" -#include // Note: optimize for size @@ -59,7 +58,7 @@ inline __libcpp_nmstr::__libcpp_nmstr(const __libcpp_nmstr& s) : str_(s.str_) { - OSAtomicIncrement32Barrier(&count()); + __sync_add_and_fetch(&count(), 1); } __libcpp_nmstr& @@ -67,8 +66,8 @@ __libcpp_nmstr::operator=(const __libcpp_nmstr& s) { const char* p = str_; str_ = s.str_; - OSAtomicIncrement32Barrier(&count()); - if (OSAtomicDecrement32((count_t*)(p-sizeof(count_t))) < 0) + __sync_add_and_fetch(&count(), 1); + if (__sync_add_and_fetch((count_t*)(p-sizeof(count_t)), -1) < 0) delete [] (p-offset); return *this; } @@ -76,7 +75,7 @@ __libcpp_nmstr::operator=(const __libcpp_nmstr& s) inline __libcpp_nmstr::~__libcpp_nmstr() { - if (OSAtomicDecrement32(&count()) < 0) + if (__sync_add_and_fetch(&count(), -1) < 0) delete [] (str_ - offset); } diff --git a/src/system_error.cpp b/src/system_error.cpp index 2e12aa8cb..3c1f0003a 100644 --- a/src/system_error.cpp +++ b/src/system_error.cpp @@ -64,9 +64,11 @@ __generic_error_category::name() const string __generic_error_category::message(int ev) const { - if (ev <= ELAST) - return __do_message::message(ev); - return string("unspecified generic_category error"); +#ifdef ELAST + if (ev > ELAST) + return string("unspecified generic_category error"); +#endif + return __do_message::message(ev); } const error_category& @@ -94,17 +96,21 @@ __system_error_category::name() const string __system_error_category::message(int ev) const { - if (ev <= ELAST) - return __do_message::message(ev); - return string("unspecified system_category error"); +#ifdef ELAST + if (ev > ELAST) + return string("unspecified system_category error"); +#endif + return __do_message::message(ev); } error_condition __system_error_category::default_error_condition(int ev) const { - if (ev <= ELAST) - return error_condition(ev, generic_category()); - return error_condition(ev, system_category()); +#ifdef ELAST + if (ev > ELAST) + return error_condition(ev, system_category()); +#endif + return error_condition(ev, generic_category()); } const error_category& diff --git a/src/thread.cpp b/src/thread.cpp index 4a7904dc5..2a6b2054e 100644 --- a/src/thread.cpp +++ b/src/thread.cpp @@ -15,7 +15,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD thread::~thread() { - if (__t_ != nullptr) + if (__t_ != 0) terminate(); } @@ -25,7 +25,7 @@ thread::join() int ec = pthread_join(__t_, 0); if (ec) throw system_error(error_code(ec, system_category()), "thread::join failed"); - __t_ = nullptr; + __t_ = 0; } void @@ -45,11 +45,17 @@ thread::detach() unsigned thread::hardware_concurrency() { +#if defined(CTL_HW) && defined(HW_NCPU) int n; int mib[2] = {CTL_HW, HW_NCPU}; std::size_t s = sizeof(n); sysctl(mib, 2, &n, &s, 0, 0); return n; +#else // !defined(CTL_HW && HW_NCPU) + // TODO: grovel through /proc or check cpuid on x86 and similar + // instructions on other architectures. + return 0; // Means not computable [thread.thread.static] +#endif } namespace this_thread