--- /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 <boost/config.hpp>
+
+#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 <boost/shared_ptr.hpp>
+#include <boost/weak_ptr.hpp>
+#include <boost/bind.hpp>
+
+#include <vector>
+#include <memory>
+#include <stdexcept>
+
+#include <cstdio>
+#include <ctime>
+#include <cstdlib>
+#include <string>
+
+#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 <windows.h>
+#include <process.h>
+
+typedef HANDLE pthread_t;
+
+unsigned __stdcall common_thread_routine(void * pv)
+{
+ abstract_thread * pt = static_cast<abstract_thread *>(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 <pthread.h>
+
+extern "C" void * common_thread_routine(void * pv)
+{
+ abstract_thread * pt = static_cast<abstract_thread *>(pv);
+ pt->run();
+ delete pt;
+ return 0;
+}
+
+#endif
+
+//
+
+template<class F> class thread: public abstract_thread
+{
+public:
+
+ explicit thread(F f): f_(f)
+ {
+ }
+
+ void run()
+ {
+ f_();
+ }
+
+private:
+
+ F f_;
+};
+
+template<class F> pthread_t createThread(F f)
+{
+ std::auto_ptr<abstract_thread> p(new thread<F>(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<int> > & v )
+{
+ using namespace std; // printf, rand
+
+ std::vector< boost::weak_ptr<int> > 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<int> 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<int> > 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<double>(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;
+}