diff -r 000000000000 -r e4d67989cc36 stdcpp/tsrc/Boost_test/smart_ptr/src/weak_ptr_mt_test.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stdcpp/tsrc/Boost_test/smart_ptr/src/weak_ptr_mt_test.cpp Tue Feb 02 02:01:42 2010 +0200 @@ -0,0 +1,233 @@ +#include + +#if defined(BOOST_MSVC) +#pragma warning(disable: 4786) // identifier truncated in debug info +#pragma warning(disable: 4710) // function not inlined +#pragma warning(disable: 4711) // function selected for automatic inline expansion +#pragma warning(disable: 4514) // unreferenced inline removed +#endif + +// +// weak_ptr_mt_test.cpp +// +// Copyright (c) 2002 Peter Dimov and Multi Media Ltd. +// Copyright 2005 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +/* + * © Portions copyright (c) 2006-2007 Nokia Corporation. All rights reserved. +*/ + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#ifdef __SYMBIAN32__ +#include "std_log_result.h" +#define LOG_FILENAME_LINE __FILE__, __LINE__ +#endif + +// 'portable' thread framework + +class abstract_thread +{ +public: + + virtual ~abstract_thread() {} + virtual void run() = 0; +}; + +#if !defined(BOOST_HAS_PTHREADS) && defined(BOOST_HAS_WINTHREADS) + +char const * title = "Using Windows threads"; + +#include +#include + +typedef HANDLE pthread_t; + +unsigned __stdcall common_thread_routine(void * pv) +{ + abstract_thread * pt = static_cast(pv); + pt->run(); + delete pt; + return 0; +} + +int pthread_create(pthread_t * thread, void const *, unsigned (__stdcall * start_routine) (void*), void* arg) +{ + HANDLE h = (HANDLE)_beginthreadex(0, 0, start_routine, arg, 0, 0); + + if(h != 0) + { + *thread = h; + return 0; + } + else + { + return 1; // return errno; + } +} + +int pthread_join(pthread_t thread, void ** /*value_ptr*/) +{ + ::WaitForSingleObject(thread, INFINITE); + ::CloseHandle(thread); + return 0; +} + +#else + +char const * title = "Using POSIX threads"; + +#include + +extern "C" void * common_thread_routine(void * pv) +{ + abstract_thread * pt = static_cast(pv); + pt->run(); + delete pt; + return 0; +} + +#endif + +// + +template class thread: public abstract_thread +{ +public: + + explicit thread(F f): f_(f) + { + } + + void run() + { + f_(); + } + +private: + + F f_; +}; + +template pthread_t createThread(F f) +{ + std::auto_ptr p(new thread(f)); + + pthread_t r; + + if(pthread_create(&r, 0, common_thread_routine, p.get()) == 0) + { + p.release(); + return r; + } + + throw std::runtime_error("createThread failed."); +} + +// +#ifdef __SYMBIAN32__ +int const n = 1024; +#else +int const n = 16384; +#endif +int const k = 512; // vector size +int const m = 16; // threads + +void test( std::vector< boost::shared_ptr > & v ) +{ + using namespace std; // printf, rand + + std::vector< boost::weak_ptr > w( v.begin(), v.end() ); + + int s = 0, f = 0, r = 0; + + for( int i = 0; i < n; ++i ) + { + // randomly kill a pointer + + v[ rand() % k ].reset(); + ++s; + + for( int j = 0; j < k; ++j ) + { + if( boost::shared_ptr px = w[ j ].lock() ) + { + ++s; + + if( rand() & 4 ) + { + continue; + } + + // rebind anyway with prob. 50% for add_ref_lock() against weak_release() contention + ++f; + } + else + { + ++r; + } + + w[ j ] = v[ rand() % k ]; + } + } + + printf( "\n%d locks, %d forced rebinds, %d normal rebinds.", s, f, r ); +} + +int main() +{ + std_log(LOG_FILENAME_LINE,"[Test Case for weak_ptr_mt_test]"); + using namespace std; // printf, clock_t, clock + + printf("%s: %d threads, %d * %d iterations: ", title, m, n, k ); + + std::vector< boost::shared_ptr > v( k ); + + for( int i = 0; i < k; ++i ) + { + v[ i ].reset( new int( 0 ) ); + } + + clock_t t = clock(); + + pthread_t a[m]; + + for(int i = 0; i < m; ++i) + { + a[i] = createThread( boost::bind( test, v ) ); + } + + v.resize( 0 ); // kill original copies + + for(int j = 0; j < m; ++j) + { + pthread_join( a[j], 0 ); + } + + t = clock() - t; + + printf("\n\n%.3f seconds.\n", static_cast(t) / CLK_TCK); + +#ifdef __SYMBIAN32__ + std_log(LOG_FILENAME_LINE,"Result : Passed"); + std_log(LOG_FILENAME_LINE,"[End Test Case ]"); +#endif + testResultXml("weak_ptr_mt_test"); + close_log_file(); + return 0; +}