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
This commit is contained in:
Howard Hinnant 2010-05-24 17:49:41 +00:00
parent 2a59254a44
commit adff4895b2
21 changed files with 308 additions and 120 deletions

View File

@ -7,6 +7,7 @@ DESTDIR = $(DSTROOT)
OBJROOT=.
SYMROOT=.
TRIPLE=-apple-
installsrc:: $(SRCROOT)

View File

@ -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

View File

@ -18,6 +18,7 @@
#include <mutex>
#include <cstdint>
#include <cctype>
#include <locale.h>
#include <xlocale.h>
#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();

View File

@ -552,16 +552,12 @@ template <class BidirectionalIterator, class Compare>
#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
{

View File

@ -34,6 +34,8 @@ Types:
*/
#include <__config>
#define __need_ptrdiff_t
#define __need_size_t
#include <stddef.h>
#pragma GCC system_header

View File

@ -86,7 +86,7 @@ typedef fpos<char_traits<wchar_t>::state_type> wstreampos;
*/
#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_ofstream<wchar_t> wofstream;
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>

View File

@ -137,6 +137,9 @@ template <class charT> class messages_byname;
#include <streambuf>
#include <iterator>
#include <limits>
#if !__APPLE__
#include <cstdarg>
#endif
#include <cstdlib>
#include <ctime>
#include <nl_types.h>
@ -145,6 +148,131 @@ template <class charT> 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 <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 @@ 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<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 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
+ ((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 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
+ ((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 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
+ ((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 @@ 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<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 @@ 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<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 @@ 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);

View File

@ -358,6 +358,7 @@ template <> struct hash<wstring>;
#include <__config>
#include <iosfwd>
#include <cstring>
#include <cstdio> // For EOF.
#include <cwchar>
#include <algorithm>
#include <iterator>

View File

@ -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_;}

View File

@ -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
{

View File

@ -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

View File

@ -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 @@ 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

View File

@ -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
}

View File

@ -106,7 +106,11 @@ __iostream_category::name() const
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");
}

View File

@ -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 @@ locale::id::__get()
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 codecvt_byname<char32_t, char, mbstate_t>;
template class __vector_base_common<true>;
_LIBCPP_END_NAMESPACE_STD
#endif /* __APPLE__ */

View File

@ -8,7 +8,6 @@
//===----------------------------------------------------------------------===//
#include "memory"
#include <libkern/OSAtomic.h>
_LIBCPP_BEGIN_NAMESPACE_STD
@ -16,57 +15,19 @@ namespace
{
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 @@ __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;

View File

@ -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<mutex> lk(__m_);
if (--__count_ == 0)
{
__id_ = nullptr;
__id_ = 0;
lk.unlock();
__cv_.notify_one();
}

View File

@ -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.

View File

@ -15,7 +15,6 @@
#include <cstdint>
#include <cstddef>
#include "system_error"
#include <libkern/OSAtomic.h>
// 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);
}

View File

@ -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&

View File

@ -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