[complement-svn] SF.net SVN: complement: [1504] trunk/complement/explore
Status: Pre-Alpha
Brought to you by:
complement
From: <com...@us...> - 2007-02-02 18:54:54
|
Revision: 1504 http://svn.sourceforge.net/complement/?rev=1504&view=rev Author: complement Date: 2007-02-02 10:54:52 -0800 (Fri, 02 Feb 2007) Log Message: ----------- remove _state field, unuseful; add thread id for RIP---_id used for living thread [and show that thread alive], while _rip_id used in join only libxmt: version 1.10.0 Modified Paths: -------------- trunk/complement/explore/include/mt/thr_mgr.h trunk/complement/explore/include/mt/xmt.h trunk/complement/explore/lib/mt/ChangeLog trunk/complement/explore/lib/mt/Makefile.inc trunk/complement/explore/lib/mt/thr_mgr.cc trunk/complement/explore/lib/mt/xmt.cc trunk/complement/explore/test/mt/mt_test.cc trunk/complement/explore/test/mt/mt_test.h trunk/complement/explore/test/mt/mt_test_suite.cc Modified: trunk/complement/explore/include/mt/thr_mgr.h =================================================================== --- trunk/complement/explore/include/mt/thr_mgr.h 2007-02-01 17:24:46 UTC (rev 1503) +++ trunk/complement/explore/include/mt/thr_mgr.h 2007-02-02 18:54:52 UTC (rev 1504) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <07/02/01 18:39:25 ptr> +// -*- C++ -*- Time-stamp: <07/02/02 20:54:44 ptr> /* * Copyright (c) 1997-1999, 2002, 2005, 2006 @@ -42,7 +42,7 @@ __FIT_DECLSPEC void join(); __FIT_DECLSPEC void signal( int ); - container_type::size_type size(); + container_type::size_type size() const; protected: _Sequence _M_c; Modified: trunk/complement/explore/include/mt/xmt.h =================================================================== --- trunk/complement/explore/include/mt/xmt.h 2007-02-01 17:24:46 UTC (rev 1503) +++ trunk/complement/explore/include/mt/xmt.h 2007-02-02 18:54:52 UTC (rev 1504) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <07/01/29 18:58:49 ptr> +// -*- C++ -*- Time-stamp: <07/02/02 21:32:58 ptr> /* * Copyright (c) 1997-1999, 2002-2007 @@ -1565,11 +1565,11 @@ static __FIT_DECLSPEC void signal_exit( int sig ); // signal handler bool good() const - { return (_state == goodbit) && (_id != bad_thread_id); } + { /* Locker lk( _llock ); */ return (_id != bad_thread_id); } bool bad() const - { return (_state != goodbit) || (_id == bad_thread_id); } - bool is_join_req() // if true, you can (and should) use join() - { return (_id != bad_thread_id) && ((_flags & (daemon | detached)) == 0); } + { /* Locker lk( _llock ); */ return (_id == bad_thread_id); } + bool is_join_req() const // if true, you can (and should) use join() + { /* Locker lk( _llock ); */ return (_rip_id != bad_thread_id) && ((_flags & (daemon | detached)) == 0); } __FIT_DECLSPEC bool is_self(); @@ -1597,6 +1597,8 @@ Thread( const Thread& ) { } + bool _not_run() const + { /* Locker lk( _llock ); */ return _id == bad_thread_id; } void _create( const void *p, size_t psz ) throw( std::runtime_error); static void *_call( void *p ); @@ -1617,12 +1619,11 @@ static int _idx; // user words index static int _self_idx; // user words index, that word point to self static Mutex _idx_lock; - static Mutex _start_lock; static thread_key_type& _mt_key; size_t uw_alloc_size; thread_id_type _id; - int _state; // state flags + thread_id_type _rip_id; #ifdef _PTHREADS # ifndef __hpux // sorry, POSIX threads don't have suspend/resume calls, so it should @@ -1641,7 +1642,7 @@ size_t _param_sz; unsigned _flags; size_t _stack_sz; // stack size, if not 0 - // Mutex _params_lock; --- no needs + // Mutex _llock; friend class Init; // extern "C", wrap for thread_create #ifdef __unix Modified: trunk/complement/explore/lib/mt/ChangeLog =================================================================== --- trunk/complement/explore/lib/mt/ChangeLog 2007-02-01 17:24:46 UTC (rev 1503) +++ trunk/complement/explore/lib/mt/ChangeLog 2007-02-02 18:54:52 UTC (rev 1504) @@ -1,3 +1,20 @@ +2007-02-02 Petr Ovtchenkov <pt...@is...> + + * xmt.h, xmt.cc: remove _state field, unuseful; add thread + id for RIP---_id used for living thread [and show that + thread alive], while _rip_id used in join only; this reflect + two independent [well, almost independent] states---thread + run/not run and thread require join/not require join. + When I trying to made all operations with _id and _rip_id + with MT guards, the speed of sockstreams was VERY slow, + so I remove ones; atomics in a few places? + Here remains one thing---what I should do, if I made few + Threads and then fork? + + * thr_mgr.cc: sync with changes in xmt[.h.cc]. + + * libxmt: version 1.10.0 + 2007-02-01 Petr Ovtchenkov <pt...@is...> * thr_mgr.cc: reduce amount of code; try to 'join' to already Modified: trunk/complement/explore/lib/mt/Makefile.inc =================================================================== --- trunk/complement/explore/lib/mt/Makefile.inc 2007-02-01 17:24:46 UTC (rev 1503) +++ trunk/complement/explore/lib/mt/Makefile.inc 2007-02-02 18:54:52 UTC (rev 1504) @@ -1,8 +1,8 @@ -# -*- Makefile -*- Time-stamp: <07/02/01 11:14:39 ptr> +# -*- Makefile -*- Time-stamp: <07/02/02 20:56:56 ptr> LIBNAME = xmt MAJOR = 1 -MINOR = 9 -PATCH = 5 +MINOR = 10 +PATCH = 0 SRC_CC = xmt.cc thr_mgr.cc time.cc uid.cc shm.cc SRC_C = fl.c Modified: trunk/complement/explore/lib/mt/thr_mgr.cc =================================================================== --- trunk/complement/explore/lib/mt/thr_mgr.cc 2007-02-01 17:24:46 UTC (rev 1503) +++ trunk/complement/explore/lib/mt/thr_mgr.cc 2007-02-02 18:54:52 UTC (rev 1504) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <07/02/01 20:17:50 ptr> +// -*- C++ -*- Time-stamp: <07/02/02 20:55:08 ptr> /* * Copyright (c) 1997-1999, 2002, 2005-2007 @@ -17,6 +17,8 @@ // #include <iostream> +// extern int my_thr_cnt; + namespace xmt { // int _supercount = 0; @@ -48,14 +50,29 @@ if ( __x == 0 ) { return true; } + // cerr << (void *)__x << " "; if ( __x->bad() ) { + // cerr << "delete\n"; // --_supercount; delete __x; return true; } + // cerr << "?\n"; return false; } +struct rm_thread : + public unary_function<Thread *,bool> +{ + bool operator()(Thread *__x); +}; + +bool rm_thread::operator()(Thread *__x) +{ + delete __x; + return true; +} + struct thread_signal : public binary_function<Thread *,int,void> { @@ -82,14 +99,20 @@ // xmt::block_signal( SIGCHLD ); // xmt::block_signal( SIGPOLL ); + /* + * This 'soft' variant better, than walk through _M_c and call 'delete' + * (that assume join); following approach remain chance to see size() + * somewhere else, and, may be make some action, because it not block + * on join within lock all the time. + */ _lock.lock(); _M_c.erase( remove_if( _M_c.begin(), _M_c.end(), rm_if_bad_thread() ), _M_c.end() ); while ( !_M_c.empty() ) { + // cerr << "### " << _supercount << " " << _M_c.size() << " " << my_thr_cnt << endl; _lock.unlock(); xmt::delay( xmt::timespec(0,50000000) ); _lock.lock(); _M_c.erase( remove_if( _M_c.begin(), _M_c.end(), rm_if_bad_thread() ), _M_c.end() ); - // cerr << "### " << _supercount << " " << _M_c.size() << endl; } // _supercount = 0; _lock.unlock(); @@ -100,6 +123,8 @@ { Locker lk( _lock ); _M_c.erase( remove_if( _M_c.begin(), _M_c.end(), rm_if_bad_thread() ), _M_c.end() ); + // Thread *t = new Thread( entrance, p, psz, flags, stack_sz ); + // cerr << (void *)t << " created\n"; _M_c.push_back( new Thread( entrance, p, psz, flags, stack_sz ) ); // ++_supercount; } @@ -111,7 +136,7 @@ _M_c.erase( remove_if( _M_c.begin(), _M_c.end(), rm_if_bad_thread() ), _M_c.end() ); } -ThreadMgr::container_type::size_type ThreadMgr::size() +ThreadMgr::container_type::size_type ThreadMgr::size() const { Locker lk( _lock ); // ThreadMgr::container_type::size_type sz = count_if( _M_c.begin(), _M_c.end(), good_thread() ); Modified: trunk/complement/explore/lib/mt/xmt.cc =================================================================== --- trunk/complement/explore/lib/mt/xmt.cc 2007-02-01 17:24:46 UTC (rev 1503) +++ trunk/complement/explore/lib/mt/xmt.cc 2007-02-02 18:54:52 UTC (rev 1504) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <07/02/01 19:35:59 ptr> +// -*- C++ -*- Time-stamp: <07/02/02 21:34:56 ptr> /* * Copyright (c) 1997-1999, 2002-2007 @@ -230,7 +230,6 @@ int Thread::_idx = 0; int Thread::_self_idx = 0; Mutex Thread::_idx_lock; -Mutex Thread::_start_lock; #ifdef __FIT_WIN32THREADS const Thread::thread_id_type Thread::bad_thread_id = INVALID_HANDLE_VALUE; @@ -350,7 +349,7 @@ __FIT_DECLSPEC Thread::Thread( unsigned __f ) : _id( bad_thread_id ), - _state( badbit ), + _rip_id( bad_thread_id ), _entrance( 0 ), _param( 0 ), _param_sz( 0 ), @@ -364,7 +363,7 @@ __FIT_DECLSPEC Thread::Thread( Thread::entrance_type entrance, const void *p, size_t psz, unsigned __f, size_t stack_sz ) : _id( bad_thread_id ), - _state( badbit ), + _rip_id( bad_thread_id ), _entrance( entrance ), _param( 0 ), _param_sz( 0 ), @@ -373,6 +372,7 @@ uw_alloc_size( 0 ) { new( Init_buf ) Init(); + // Locker lk( _llock ); _create( p, psz ); } @@ -380,6 +380,14 @@ Thread::~Thread() { Thread::join(); + + if ( (_flags & (daemon | detached)) != 0 ) { // not joinable + // Locker lk( _llock ); + if ( _id != bad_thread_id ) { // still run? + cerr << "Crash on daemon thread exit expected, threas id " << _id << endl; + } + } + ((Init *)Init_buf)->~Init(); // _STLP_ASSERT( _id == bad_thread_id ); @@ -390,14 +398,15 @@ __FIT_DECLSPEC bool Thread::is_self() { + // Locker lk( _llock ); #ifdef _PTHREADS - return good() && (_id == pthread_self()); + return (_id != bad_thread_id) && (_id == pthread_self()); #elif defined(__FIT_UITHREADS) - return good() && (_id == thr_self()); + return (_id != bad_thread_id) && (_id == thr_self()); #elif defined(__FIT_NOVELL_THREADS) - return good() && (_id == GetThreadID()); + return (_id != bad_thread_id) && (_id == GetThreadID()); #elif defined(__FIT_WIN32THREADS) - return good() && (_id == GetCurrentThread()); + return (_id != bad_thread_id) && (_id == GetCurrentThread()); #else # error "Fix me! (replace pthread_self())" #endif @@ -406,8 +415,9 @@ __FIT_DECLSPEC void Thread::launch( entrance_type entrance, const void *p, size_t psz, size_t stack_sz ) { + // Locker lk( _llock ); _stack_sz = stack_sz; - if ( _id == bad_thread_id ) { + if ( _not_run() ) { _entrance = entrance; _create( p, psz ); } @@ -420,31 +430,34 @@ #ifdef __FIT_WIN32THREADS rt.iword = 0; - if ( _id != bad_thread_id ) { + if ( !_not_run() ) { WaitForSingleObject( _id, -1 ); GetExitCodeThread( _id, &rt.iword ); CloseHandle( _id ); + // Locker lk( _llock ); _id = bad_thread_id; } #endif // __FIT_WIN32THREADS #if defined(__FIT_UITHREADS) || defined(_PTHREADS) rt.pword = 0; - if ( _id != bad_thread_id && (_flags & (daemon | detached) ) == 0 ) { + if ( is_join_req() ) { # ifdef _PTHREADS - pthread_join( _id, &rt.pword ); + pthread_join( _rip_id, &rt.pword ); # endif # ifdef __FIT_UITHREADS - thr_join( _id, 0, &rt.pword ); + thr_join( _rip_id, 0, &rt.pword ); # endif - _id = bad_thread_id; + // Locker lk( _llock ); + _rip_id = bad_thread_id; } #endif // __FIT_UITHREADS || PTHREADS #ifdef __FIT_NOVELL_THREADS rt.iword = 0; - if ( _id != bad_thread_id ) { + if ( !_not_run() ) { _thr_join.wait(); - _id = bad_thread_id; + // Locker lk( _llock ); + _rip_id = bad_thread_id; } #endif // __FIT_NOVELL_THREADS @@ -454,7 +467,8 @@ __FIT_DECLSPEC int Thread::suspend() { - if ( _id != bad_thread_id ) { + if ( good() ) { + // to do: fix possible race with _id, when it used here #ifdef __FIT_WIN32THREADS return SuspendThread( _id ); #endif @@ -484,7 +498,8 @@ __FIT_DECLSPEC int Thread::resume() { - if ( _id != bad_thread_id ) { + if ( good() ) { + // to do: fix possible race with _id, when it used here #ifdef __FIT_WIN32THREADS return ResumeThread( _id ); #endif @@ -514,6 +529,8 @@ __FIT_DECLSPEC int Thread::kill( int sig ) { + // Locker lk( _llock ); + if ( _id != bad_thread_id ) { #ifdef __FIT_UITHREADS return thr_kill( _id, sig ); @@ -576,9 +593,11 @@ Thread *me = reinterpret_cast<Thread *>(*reinterpret_cast<void **>(user_words)); // _STLP_ASSERT( me->is_self() ); - me->_state = badbit; // follow part of _call if ( (me->_flags & (daemon | detached)) != 0 ) { // otherwise join expected + // Locker lk( me->_llock ); // !!!!??? in the signal handler? + me->_rip_id = me->_id = bad_thread_id; + } else { me->_id = bad_thread_id; } me->_dealloc_uw(); // clear user words @@ -750,38 +769,33 @@ // pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED ); // pthread_attr_setschedpolicy(&attr,SCHED_OTHER); } - // _start_lock.lock(); // allow finish new thread creation before this - // thread will start to run err = pthread_create( &_id, _flags != 0 || _stack_sz != 0 ? &attr : 0, _xcall, this ); - if ( err == 0 ) { - _state = goodbit; + if ( err != 0 ) { + _rip_id = _id = bad_thread_id; + } else { + _rip_id = _id; } - // _start_lock.unlock(); if ( _flags != 0 || _stack_sz != 0 ) { pthread_attr_destroy( &attr ); } #endif #ifdef __FIT_UITHREADS - // _start_lock.lock(); err = thr_create( 0, 0, _xcall, this, _flags, &_id ); - // _start_lock.unlock(); #endif #ifdef __FIT_WIN32THREADS - // _start_lock.lock(); - _id = CreateThread( 0, 0, _xcall, this, (_flags & suspended), &_thr_id ); + _rip_id = _id = CreateThread( 0, 0, _xcall, this, (_flags & suspended), &_thr_id ); err = GetLastError(); - // _start_lock.unlock(); #endif #ifdef __FIT_NOVELL_THREADS - // _start_lock.lock(); _id = BeginThread( _xcall, 0, 65536, this ); if ( _id == bad_thread_id ) { err = errno; // not ::errno, due to #define errno *__get_errno_ptr() if ( (_flags & detached) == 0 ) { _thr_join.signal(); } + } else { + _rip_id = _id; } - // _start_lock.unlock(); #endif if ( err != 0 ) { @@ -821,9 +835,7 @@ void *Thread::_call( void *p ) { - // _start_lock.lock(); // allow finish thread creation in parent thread Thread *me = static_cast<Thread *>(p); - // me->_state = goodbit; // After exit of me->_entrance, there is may be no more *me itself, // so it's members may be unaccessible. Don't use me->"*" after call @@ -854,29 +866,37 @@ // In most cases for Linux there are problems with signals processing, // so I don't set it default more // signal_handler( SIGTERM, signal_exit ); // set handler for sanity - // _start_lock.unlock(); try { ret = me->_entrance( _param ); - me->_state = badbit; + // I should make me->_id = bad_thread_id; here... // This is in conflict what I say in the begin of this function. // So don't delete Thread before it termination! if ( (me->_flags & (daemon | detached)) != 0 ) { // otherwise join expected + // Locker lk( me->_llock ); #ifdef __FIT_WIN32THREADS CloseHandle( me->_id ); #endif me->_id = bad_thread_id; + me->_rip_id = bad_thread_id; + } else { + // Locker lk( me->_llock ); + me->_id = bad_thread_id; } me->_dealloc_uw(); // free user words } catch ( std::exception& e ) { - me->_state = badbit; if ( (me->_flags & (daemon | detached)) != 0 ) { // otherwise join expected + // Locker lk( me->_llock ); #ifdef __FIT_WIN32THREADS CloseHandle( me->_id ); #endif me->_id = bad_thread_id; + me->_rip_id = bad_thread_id; + } else { + // Locker lk( me->_llock ); + me->_id = bad_thread_id; } me->_dealloc_uw(); // free user words #ifndef _WIN32 @@ -885,13 +905,18 @@ ret.iword = -1; } catch ( int sig ) { - me->_state = badbit; if ( (me->_flags & (daemon | detached)) != 0 ) { // otherwise join expected + // Locker lk( me->_llock ); #ifdef __FIT_WIN32THREADS CloseHandle( me->_id ); #endif me->_id = bad_thread_id; + me->_rip_id = bad_thread_id; + } else { + // Locker lk( me->_llock ); + me->_id = bad_thread_id; } + me->_dealloc_uw(); // free user words // const char *_sig_ = strsignal( sig ); #ifndef _WIN32 @@ -900,12 +925,16 @@ ret.iword = sig; } catch ( ... ) { - me->_state = badbit; if ( (me->_flags & (daemon | detached)) != 0 ) { // otherwise join expected + // Locker lk( me->_llock ); #ifdef __FIT_WIN32THREADS CloseHandle( me->_id ); #endif me->_id = bad_thread_id; + me->_rip_id = bad_thread_id; + } else { + // Locker lk( me->_llock ); + me->_id = bad_thread_id; } me->_dealloc_uw(); // free user words #ifndef _WIN32 Modified: trunk/complement/explore/test/mt/mt_test.cc =================================================================== --- trunk/complement/explore/test/mt/mt_test.cc 2007-02-01 17:24:46 UTC (rev 1503) +++ trunk/complement/explore/test/mt/mt_test.cc 2007-02-02 18:54:52 UTC (rev 1504) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <07/01/29 15:35:05 ptr> +// -*- C++ -*- Time-stamp: <07/02/02 20:53:03 ptr> /* * Copyright (c) 2006 @@ -14,6 +14,7 @@ #include <mt/xmt.h> #include <mt/shm.h> +#include <mt/thr_mgr.h> #include <sys/shm.h> #include <sys/wait.h> @@ -422,3 +423,38 @@ BOOST_CHECK_MESSAGE( false, "error report: " << err.what() ); } } + + +static int my_thr_cnt = 0; +static xmt::Mutex lock; + +xmt::Thread::ret_code thread_mgr_entry_call( void * ) +{ + lock.lock(); + ++my_thr_cnt; + lock.unlock(); + + xmt::Thread::ret_code rt; + rt.iword = 0; + + lock.lock(); + --my_thr_cnt; + lock.unlock(); + + return rt; +} + +void mt_test::thr_mgr() +{ + xmt::ThreadMgr mgr; + + for ( int i = 0; i < 200; ++i ) { + mgr.launch( thread_mgr_entry_call, (void *)this, 0, 0, 0 ); + } + + // cerr << "Join!\n"; + mgr.join(); + + BOOST_CHECK( my_thr_cnt == 0 ); + BOOST_CHECK( mgr.size() == 0 ); +} Modified: trunk/complement/explore/test/mt/mt_test.h =================================================================== --- trunk/complement/explore/test/mt/mt_test.h 2007-02-01 17:24:46 UTC (rev 1503) +++ trunk/complement/explore/test/mt/mt_test.h 2007-02-02 18:54:52 UTC (rev 1504) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <07/01/29 13:49:41 ptr> +// -*- C++ -*- Time-stamp: <07/02/02 16:45:13 ptr> /* * Copyright (c) 2006 @@ -19,6 +19,7 @@ void shm_alloc(); void fork_shm(); void shm_named_obj(); + void thr_mgr(); }; #endif // __MT_TEST_H Modified: trunk/complement/explore/test/mt/mt_test_suite.cc =================================================================== --- trunk/complement/explore/test/mt/mt_test_suite.cc 2007-02-01 17:24:46 UTC (rev 1503) +++ trunk/complement/explore/test/mt/mt_test_suite.cc 2007-02-02 18:54:52 UTC (rev 1504) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <07/01/31 23:51:46 ptr> +// -*- C++ -*- Time-stamp: <07/02/02 17:15:47 ptr> /* * Copyright (c) 2006, 2007 @@ -25,6 +25,8 @@ test_case *fork_shm_tc = BOOST_CLASS_TEST_CASE( &mt_test::fork_shm, instance ); test_case *shm_nm_obj_tc = BOOST_CLASS_TEST_CASE( &mt_test::shm_named_obj, instance ); + test_case *thr_mgr_tc = BOOST_CLASS_TEST_CASE( &mt_test::thr_mgr, instance ); + pid_tc->depends_on( fork_tc ); shm_alloc_tc->depends_on( shm_segment_tc ); fork_shm_tc->depends_on( shm_alloc_tc ); @@ -36,4 +38,6 @@ add( shm_alloc_tc ); add( fork_shm_tc, 0, 5 ); add( shm_nm_obj_tc, 0, 5 ); + + add( thr_mgr_tc ); }; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |