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:
parent
2a59254a44
commit
adff4895b2
1
Makefile
1
Makefile
@ -7,6 +7,7 @@ DESTDIR = $(DSTROOT)
|
||||
|
||||
OBJROOT=.
|
||||
SYMROOT=.
|
||||
TRIPLE=-apple-
|
||||
|
||||
installsrc:: $(SRCROOT)
|
||||
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -34,6 +34,8 @@ Types:
|
||||
*/
|
||||
|
||||
#include <__config>
|
||||
#define __need_ptrdiff_t
|
||||
#define __need_size_t
|
||||
#include <stddef.h>
|
||||
|
||||
#pragma GCC system_header
|
||||
|
@ -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>
|
||||
|
166
include/locale
166
include/locale
@ -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);
|
||||
|
@ -358,6 +358,7 @@ template <> struct hash<wstring>;
|
||||
#include <__config>
|
||||
#include <iosfwd>
|
||||
#include <cstring>
|
||||
#include <cstdio> // For EOF.
|
||||
#include <cwchar>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
@ -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_;}
|
||||
|
@ -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
|
||||
{
|
||||
|
55
lib/buildit
55
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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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__ */
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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&
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user