patch by Jeffrey Yasskin for porting to Ubuntu Hardy. Everything was accepted except there were some bug fixes needed in <locale> 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
diff --git a/Makefile b/Makefile
index 804e5e4..b5c2e4c 100644
--- a/Makefile
+++ b/Makefile
@@ -7,6 +7,7 @@
OBJROOT=.
SYMROOT=.
+TRIPLE=-apple-
installsrc:: $(SRCROOT)
diff --git a/include/__config b/include/__config
index 7b66dfc..a3518d9 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 <endian.h>
+# 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 249e5b8..395cb26 100644
--- a/include/__locale
+++ b/include/__locale
@@ -18,6 +18,7 @@
#include <mutex>
#include <cstdint>
#include <cctype>
+#include <locale.h>
#include <xlocale.h>
#pragma GCC system_header
@@ -294,6 +295,7 @@
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 @@
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 @@
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 f3412f7..c53bf37 100644
--- a/include/algorithm
+++ b/include/algorithm
@@ -552,16 +552,12 @@
#ifdef _LIBCPP_DEBUG
#include <cassert>
#endif
-//#include <cstdlib>
-#define RAND_MAX 0x7fffffff // #include <cstdlib>
-extern "C" int rand(void); // #include <cstdlib>
+#include <cstdlib>
#pragma GCC system_header
_LIBCPP_BEGIN_NAMESPACE_STD
-using ::rand; // #include <cstdlib>
-
template <class _T1, class _T2 = _T1>
struct __equal_to
{
diff --git a/include/cstddef b/include/cstddef
index 11d07a2..efe0f61 100644
--- a/include/cstddef
+++ b/include/cstddef
@@ -34,6 +34,8 @@
*/
#include <__config>
+#define __need_ptrdiff_t
+#define __need_size_t
#include <stddef.h>
#pragma GCC system_header
diff --git a/include/iosfwd b/include/iosfwd
index e9a6a0f..32f679e 100644
--- a/include/iosfwd
+++ b/include/iosfwd
@@ -86,7 +86,7 @@
*/
#include <__config>
-#include <_types.h> // for __darwin_mbstate_t
+#include <wchar.h> // for mbstate_t
#pragma GCC system_header
@@ -153,11 +153,11 @@
typedef basic_fstream<wchar_t> wfstream;
template <class _State> class fpos;
-typedef fpos<__darwin_mbstate_t> streampos;
-typedef fpos<__darwin_mbstate_t> wstreampos;
+typedef fpos<mbstate_t> streampos;
+typedef fpos<mbstate_t> wstreampos;
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-typedef fpos<__darwin_mbstate_t> u16streampos;
-typedef fpos<__darwin_mbstate_t> u32streampos;
+typedef fpos<mbstate_t> u16streampos;
+typedef fpos<mbstate_t> u32streampos;
#endif
typedef long long streamoff; // for char_traits in <string>
diff --git a/include/locale b/include/locale
index 284184f..09faccd 100644
--- a/include/locale
+++ b/include/locale
@@ -137,6 +137,9 @@
#include <streambuf>
#include <iterator>
#include <limits>
+#if !__APPLE__
+#include <cstdarg>
+#endif
#include <cstdlib>
#include <ctime>
#include <nl_types.h>
@@ -145,6 +148,131 @@
_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 <class _Tp>
+inline
+int
+__nolocale_sprintf(char* __restrict __str,
+ const char* __restrict __format, _Tp __v)
+{
+ return sprintf_l(__str, 0, __format, __v);
+}
+
+template <class _Tp>
+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 <class _Tp>
+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 <class _Tp>
+inline
+int
+__nolocale_asprintf(char** __ret, const char* __restrict __format, _Tp __v)
+{
+ return asprintf_l(__ret, 0, __format, __v);
+}
+
+template <class _Tp>
+inline
+int
+__nolocale_asprintf(char** __ret, const char* __restrict __format, int __prec,
+ _Tp __v)
+{
+ return asprintf_l(__ret, 0, __format, __prec, __v);
+}
+
+template <class _Tp>
+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 @@
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 @@
*__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 @@
+ ((numeric_limits<long>::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 @@
+ ((numeric_limits<long long>::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 @@
+ ((numeric_limits<unsigned long>::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 @@
+ ((numeric_limits<unsigned long long>::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 @@
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<char, void(*)(void*)> __nbh(0, free);
if (__nc > static_cast<int>(__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 @@
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<char, void(*)(void*)> __nbh(0, free);
if (__nc > static_cast<int>(__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 @@
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 @@
// 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 6b11e02..15713f0 100644
--- a/include/string
+++ b/include/string
@@ -358,6 +358,7 @@
#include <__config>
#include <iosfwd>
#include <cstring>
+#include <cstdio> // For EOF.
#include <cwchar>
#include <algorithm>
#include <iterator>
diff --git a/include/thread b/include/thread
index 3c1cf99..16faed9 100644
--- a/include/thread
+++ b/include/thread
@@ -115,6 +115,9 @@
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 @@
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 a85d39a..e97e939 100644
--- a/include/vector
+++ b/include/vector
@@ -1118,7 +1118,7 @@
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 6cbe971..43341f9 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 b984f9d..d06fbf7 100644
--- a/src/chrono.cpp
+++ b/src/chrono.cpp
@@ -9,7 +9,13 @@
#include "chrono"
#include <sys/time.h> //for gettimeofday and timeval
+#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__ */
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -40,6 +46,7 @@
// 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 @@
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 336527d..e48e9c4 100644
--- a/src/exception.cpp
+++ b/src/exception.cpp
@@ -72,8 +72,11 @@
// 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 @@
::abort();
#endif
}
-
diff --git a/src/ios.cpp b/src/ios.cpp
index 3bf3cbc..4d1261e 100644
--- a/src/ios.cpp
+++ b/src/ios.cpp
@@ -106,7 +106,11 @@
string
__iostream_category::message(int ev) const
{
- if (ev != static_cast<int>(io_errc::stream) && ev <= ELAST)
+ if (ev != static_cast<int>(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 e219d98..a65d6ed 100644
--- a/src/locale.cpp
+++ b/src/locale.cpp
@@ -17,10 +17,11 @@
#include "cstring"
#include "cwctype"
#include "__sso_allocator"
-#include <libkern/OSAtomic.h>
#include <langinfo.h>
#include <stdlib.h>
+// FIXME: Locales are hard.
+#if __APPLE__
_LIBCPP_BEGIN_NAMESPACE_STD
namespace {
@@ -534,7 +535,7 @@
void
locale::id::__init()
{
- __id_ = OSAtomicIncrement32Barrier(&__next_id);
+ __id_ = __sync_add_and_fetch(&__next_id, 1);
}
// template <> class collate_byname<char>
@@ -3678,3 +3679,4 @@
template class __vector_base_common<true>;
_LIBCPP_END_NAMESPACE_STD
+#endif /* __APPLE__ */
diff --git a/src/memory.cpp b/src/memory.cpp
index e3075bc..f35b838 100644
--- a/src/memory.cpp
+++ b/src/memory.cpp
@@ -8,7 +8,6 @@
//===----------------------------------------------------------------------===//
#include "memory"
-#include <libkern/OSAtomic.h>
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -16,57 +15,19 @@
{
template <class T>
-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 <class T>
-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 <class T>
-inline
-typename enable_if
-<
- sizeof(T) * __CHAR_BIT__ == 64,
- T
->::type
-increment(T& t)
-{
- return OSAtomicIncrement64Barrier((volatile int64_t*)&t);
-}
-
-template <class T>
-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 @@
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 f98d725..7ea7349 100644
--- a/src/mutex.cpp
+++ b/src/mutex.cpp
@@ -148,7 +148,7 @@
recursive_timed_mutex::recursive_timed_mutex()
: __count_(0),
- __id_(nullptr)
+ __id_(0)
{
}
@@ -197,7 +197,7 @@
unique_lock<mutex> 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 9ad0612..964d87b 100644
--- a/src/new.cpp
+++ b/src/new.cpp
@@ -7,13 +7,13 @@
//
//===----------------------------------------------------------------------===//
-#include <stdlib.h>
-#include <cxxabi.h>
+#include <stdlib.h>
#include "new"
#if __APPLE__
+ #include <cxxabi.h>
// 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 e8960eb..5f3ffd7 100644
--- a/src/stdexcept.cpp
+++ b/src/stdexcept.cpp
@@ -15,7 +15,6 @@
#include <cstdint>
#include <cstddef>
#include "system_error"
-#include <libkern/OSAtomic.h>
// Note: optimize for size
@@ -59,7 +58,7 @@
__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 @@
{
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 @@
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 2e12aa8..3c1f000 100644
--- a/src/system_error.cpp
+++ b/src/system_error.cpp
@@ -64,9 +64,11 @@
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 @@
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 4a7904d..2a6b205 100644
--- a/src/thread.cpp
+++ b/src/thread.cpp
@@ -15,7 +15,7 @@
thread::~thread()
{
- if (__t_ != nullptr)
+ if (__t_ != 0)
terminate();
}
@@ -25,7 +25,7 @@
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 @@
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