diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index c60b452f724..c8d9d410926 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,17 @@ +2009-02-13 Chris Fairles + Benjamin Kosnik + + * include/std/thread (_Impl_base): Move _M_id out and into ... + (thread): ...here. Call _M_make_routine in body of constructors. + Adjust data member usage to reflect changes. + (_M_make_routine): From _M_make_shared_data. + (_M_start_thread): Add __shared_base_type argument. + * src/thread.cc: Fixups for above. + * config/abi/pre/gnu.ver: Adjust exports. + * testsuite/30_threads/thread/native_handle/typesizes.cc: Enable. + * testsuite/30_threads/thread/cons/assign_neg.cc: Adjust line numbers. + * testsuite/30_threads/thread/cons/copy_neg.cc: Same. + 2009-02-12 Benjamin Kosnik * testsuite/util/thread/all.h (compare_type_to_native_type_sizes): To... diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver index 1754f07e6bb..f5e6d2fbca6 100644 --- a/libstdc++-v3/config/abi/pre/gnu.ver +++ b/libstdc++-v3/config/abi/pre/gnu.ver @@ -897,9 +897,9 @@ GLIBCXX_3.4.11 { _ZNSt22condition_variable_anyD2Ev; # thread - _ZNSt6thread15_M_start_threadEv; _ZNSt6thread4joinEv; _ZNSt6thread6detachEv; + _ZNSt6thread15_M_start_threadESt10shared_ptrINS_10_Impl_baseEE; # system_error _ZSt15system_category; diff --git a/libstdc++-v3/include/std/thread b/libstdc++-v3/include/std/thread index b527d59caf7..8cd0e3a230f 100644 --- a/libstdc++-v3/include/std/thread +++ b/libstdc++-v3/include/std/thread @@ -57,14 +57,14 @@ namespace std class thread { public: - typedef __gthread_t native_handle_type; + typedef __gthread_t native_handle_type; struct _Impl_base; typedef shared_ptr<_Impl_base> __shared_base_type; /// thread::id class id { - native_handle_type _M_thread; + native_handle_type _M_thread; public: id() : _M_thread() { } @@ -88,35 +88,31 @@ namespace std operator<<(basic_ostream<_CharT, _Traits>&& __out, thread::id __id); }; + // Simple base type that the templatized, derived class containing + // an abitrary functor can be converted to and called. struct _Impl_base { - id _M_id; - __shared_base_type _M_this_ptr; - - _Impl_base() = default; + __shared_base_type _M_this_ptr; virtual ~_Impl_base() = default; - virtual void - _M_run() = 0; + virtual void _M_run() = 0; }; template - class _Impl : public _Impl_base + struct _Impl : public _Impl_base { - _Callable _M_func; + _Callable _M_func; - public: _Impl(_Callable&& __f) : _M_func(std::forward<_Callable>(__f)) { } - void + void _M_run() { _M_func(); } }; private: - // NB: Store the base type here. - __shared_base_type _M_data; + id _M_id; public: thread() = default; @@ -127,13 +123,11 @@ namespace std template explicit thread(_Callable __f) - : _M_data(_M_make_shared_data<_Callable>(__f)) - { _M_start_thread(); } + { _M_start_thread(_M_make_routine<_Callable>(__f)); } template thread(_Callable&& __f, _Args&&... __args) - : _M_data(_M_make_shared_data(std::bind(__f, __args...))) - { _M_start_thread(); } + { _M_start_thread(_M_make_routine(std::bind(__f, __args...))); } ~thread() { @@ -153,11 +147,11 @@ namespace std void swap(thread&& __t) - { std::swap(_M_data, __t._M_data); } + { std::swap(_M_id, __t._M_id); } bool joinable() const - { return _M_data; } + { return !(_M_id == id()); } void join(); @@ -167,18 +161,13 @@ namespace std thread::id get_id() const - { - if (_M_data) - return thread::id(_M_data->_M_id._M_thread); - else - return thread::id(); - } + { return _M_id; } /** @pre thread is joinable */ native_handle_type native_handle() - { return _M_data->_M_id._M_thread; } + { return _M_id._M_thread; } // Returns a value that hints at the number of hardware thread contexts. static unsigned int @@ -186,15 +175,16 @@ namespace std { return 0; } private: + void + _M_start_thread(__shared_base_type); + template shared_ptr<_Impl<_Callable>> - _M_make_shared_data(_Callable&& __f) + _M_make_routine(_Callable&& __f) { // Create and allocate full data structure, not base. return make_shared<_Impl<_Callable>>(std::forward<_Callable>(__f)); } - - void _M_start_thread(); }; inline void diff --git a/libstdc++-v3/src/thread.cc b/libstdc++-v3/src/thread.cc index 2c3b5dc5134..ad399254fba 100644 --- a/libstdc++-v3/src/thread.cc +++ b/libstdc++-v3/src/thread.cc @@ -61,16 +61,16 @@ namespace std { int __e = EINVAL; - if (_M_data) + if (_M_id != id()) { void* __r = 0; - __e = __gthread_join(_M_data->_M_id._M_thread, &__r); + __e = __gthread_join(_M_id._M_thread, &__r); } if (__e) __throw_system_error(__e); - _M_data.reset(); + _M_id = id(); } void @@ -78,24 +78,24 @@ namespace std { int __e = EINVAL; - if (_M_data) - __e = __gthread_detach(_M_data->_M_id._M_thread); + if (_M_id != id()) + __e = __gthread_detach(_M_id._M_thread); if (__e) __throw_system_error(__e); - _M_data.reset(); + _M_id = id(); } void - thread::_M_start_thread() + thread::_M_start_thread(__shared_base_type __b) { - _M_data->_M_this_ptr = _M_data; - int __e = __gthread_create(&_M_data->_M_id._M_thread, - &execute_native_thread_routine, _M_data.get()); + __b->_M_this_ptr = __b; + int __e = __gthread_create(&_M_id._M_thread, + &execute_native_thread_routine, __b.get()); if (__e) { - _M_data->_M_this_ptr.reset(); + __b->_M_this_ptr.reset(); __throw_system_error(__e); } } diff --git a/libstdc++-v3/testsuite/30_threads/thread/cons/assign_neg.cc b/libstdc++-v3/testsuite/30_threads/thread/cons/assign_neg.cc index 527c29ce639..12a2d550df7 100644 --- a/libstdc++-v3/testsuite/30_threads/thread/cons/assign_neg.cc +++ b/libstdc++-v3/testsuite/30_threads/thread/cons/assign_neg.cc @@ -33,4 +33,4 @@ void test01() } // { dg-error "used here" "" { target *-*-* } 32 } -// { dg-error "deleted function" "" { target *-*-* } 144 } +// { dg-error "deleted function" "" { target *-*-* } 138 } diff --git a/libstdc++-v3/testsuite/30_threads/thread/cons/copy_neg.cc b/libstdc++-v3/testsuite/30_threads/thread/cons/copy_neg.cc index 15ec77ea429..d94b92bec12 100644 --- a/libstdc++-v3/testsuite/30_threads/thread/cons/copy_neg.cc +++ b/libstdc++-v3/testsuite/30_threads/thread/cons/copy_neg.cc @@ -32,5 +32,5 @@ void test01() } // { dg-error "here" "" { target *-*-* } 31 } -// { dg-error "deleted function" "" { target *-*-* } 123 } +// { dg-error "deleted function" "" { target *-*-* } 119 } // { dg-excess-errors "In file included from" } diff --git a/libstdc++-v3/testsuite/30_threads/thread/native_handle/typesizes.cc b/libstdc++-v3/testsuite/30_threads/thread/native_handle/typesizes.cc index 2af81fb47cf..6f3f650df43 100644 --- a/libstdc++-v3/testsuite/30_threads/thread/native_handle/typesizes.cc +++ b/libstdc++-v3/testsuite/30_threads/thread/native_handle/typesizes.cc @@ -29,7 +29,6 @@ int main() { typedef std::thread test_type; - // XX disable for now - //__gnu_test::compare_type_to_native_type(); + __gnu_test::compare_type_to_native_type(); return 0; }