diff options
author | Andreas Schlüns <as@openoffice.org> | 2002-05-21 05:05:46 +0000 |
---|---|---|
committer | Andreas Schlüns <as@openoffice.org> | 2002-05-21 05:05:46 +0000 |
commit | 04c8711c322051b00e5a26bab8719676dbc3f952 (patch) | |
tree | 3340c4871e7847e00cb63f44b323210136a8d49c /framework/test/threadtest | |
parent | 7e666de63aeb481a4396867dd913ca1886955565 (diff) |
implement new tests in java
Diffstat (limited to 'framework/test/threadtest')
-rw-r--r-- | framework/test/threadtest/makefile.mk | 109 | ||||
-rw-r--r-- | framework/test/threadtest/test.btm | 29 | ||||
-rw-r--r-- | framework/test/threadtest/threadtest.cxx | 806 |
3 files changed, 0 insertions, 944 deletions
diff --git a/framework/test/threadtest/makefile.mk b/framework/test/threadtest/makefile.mk deleted file mode 100644 index 885d1b0f5c6a..000000000000 --- a/framework/test/threadtest/makefile.mk +++ /dev/null @@ -1,109 +0,0 @@ -#************************************************************************* -# -# $RCSfile: makefile.mk,v $ -# -# $Revision: 1.1 $ -# -# last change: $Author: as $ $Date: 2001-06-11 10:48:00 $ -# -# The Contents of this file are made available subject to the terms of -# either of the following licenses -# -# - GNU Lesser General Public License Version 2.1 -# - Sun Industry Standards Source License Version 1.1 -# -# Sun Microsystems Inc., October, 2000 -# -# GNU Lesser General Public License Version 2.1 -# ============================================= -# Copyright 2000 by Sun Microsystems, Inc. -# 901 San Antonio Road, Palo Alto, CA 94303, USA -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License version 2.1, as published by the Free Software Foundation. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# -# -# Sun Industry Standards Source License Version 1.1 -# ================================================= -# The contents of this file are subject to the Sun Industry Standards -# Source License Version 1.1 (the "License"); You may not use this file -# except in compliance with the License. You may obtain a copy of the -# License at http://www.openoffice.org/license.html. -# -# Software provided under this License is provided on an "AS IS" basis, -# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, -# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, -# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. -# See the License for the specific provisions governing your rights and -# obligations concerning the Software. -# -# The Initial Developer of the Original Code is: Sun Microsystems, Inc. -# -# Copyright: 2000 by Sun Microsystems, Inc. -# -# All Rights Reserved. -# -# Contributor(s): _______________________________________ -# -# -# -#************************************************************************* -PRJ=..$/.. - -PRJNAME= framework -TARGET= threadtest -LIBTARGET= NO -ENABLE_EXCEPTIONS= TRUE -USE_DEFFILE= TRUE -NO_BSYMBOLIC= TRUE - -# --- Settings ----------------------------------------------------- - -.INCLUDE : svpre.mk -.INCLUDE : settings.mk -.INCLUDE : sv.mk - -.IF "$(COM)"=="ICC" -LINKFLAGS+=/SEGMENTS:1024 /PACKD:32768 -.ENDIF - -# --- application: "threadtest" -------------------------------------------------- - -APP1TARGET= threadtest - -APP1OBJS= $(SLO)$/threadtest.obj \ - $(SLO)$/lockhelper.obj - -APP1STDLIBS= $(CPPULIB) \ - $(CPPUHELPERLIB) \ - $(OSLLIB) \ - $(SALLIB) \ - $(VOSLIB) \ - $(SVLIB) - -APP1DEPN= $(INC)$/threadhelp$/threadhelpbase.hxx \ - $(INC)$/threadhelp$/transactionbase.hxx \ - $(INC)$/threadhelp$/transactionmanager.hxx \ - $(INC)$/threadhelp$/transactionguard.hxx \ - $(INC)$/threadhelp$/resetableguard.hxx \ - $(INC)$/threadhelp$/readguard.hxx \ - $(INC)$/threadhelp$/writeguard.hxx - -.IF "$(GUI)"=="WIN" || "$(GUI)"=="OS2" -APP1DEF= $(MISC)$/threadtest.def -.ENDIF - -# --- Targets ------------------------------------------------------ - -.INCLUDE : target.mk diff --git a/framework/test/threadtest/test.btm b/framework/test/threadtest/test.btm deleted file mode 100644 index 627c756893bf..000000000000 --- a/framework/test/threadtest/test.btm +++ /dev/null @@ -1,29 +0,0 @@ -@echo off -pushd - -rem TESTCOUNT = Anzahl von Test-Durchlaeufen -rem THREADCOUNT = Anzahl konk. Threads -rem LOOPS = Anzahl Durchlaeufe pro Test -rem OWNER = Numer des Threads, welcher Testklasse "besitzt" ... er muss diese initialisieren und deinitialisieren! - -echo "set test parameter ..." -set _TESTCOUNT=100 -set _THREADCOUNT=30 -set _LOOPS=50 -set _OWNER=10 - -cd bin - -echo "delete old log files ..." -*del .\threadtest_statistic.csv -*del .\threadtest.log - -echo "start test ..." -.\threadtest.exe %_TESTCOUNT% %_THREADCOUNT% %_LOOPS% %_OWNER% - -echo "show log files ..." -edit .\threadtest_statistic.csv -edit .\threadtest.log - -popd -echo on diff --git a/framework/test/threadtest/threadtest.cxx b/framework/test/threadtest/threadtest.cxx deleted file mode 100644 index 6f46a5f57ea3..000000000000 --- a/framework/test/threadtest/threadtest.cxx +++ /dev/null @@ -1,806 +0,0 @@ -/************************************************************************* - * - * $RCSfile: threadtest.cxx,v $ - * - * $Revision: 1.1 $ - * - * last change: $Author: as $ $Date: 2001-06-11 10:48:00 $ - * - * The Contents of this file are made available subject to the terms of - * either of the following licenses - * - * - GNU Lesser General Public License Version 2.1 - * - Sun Industry Standards Source License Version 1.1 - * - * Sun Microsystems Inc., October, 2000 - * - * GNU Lesser General Public License Version 2.1 - * ============================================= - * Copyright 2000 by Sun Microsystems, Inc. - * 901 San Antonio Road, Palo Alto, CA 94303, USA - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - * - * Sun Industry Standards Source License Version 1.1 - * ================================================= - * The contents of this file are subject to the Sun Industry Standards - * Source License Version 1.1 (the "License"); You may not use this file - * except in compliance with the License. You may obtain a copy of the - * License at http://www.openoffice.org/license.html. - * - * Software provided under this License is provided on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, - * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, - * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. - * See the License for the specific provisions governing your rights and - * obligations concerning the Software. - * - * The Initial Developer of the Original Code is: Sun Microsystems, Inc. - * - * Copyright: 2000 by Sun Microsystems, Inc. - * - * All Rights Reserved. - * - * Contributor(s): _______________________________________ - * - * - ************************************************************************/ - -//_________________________________________________________________________________________________________________ -// my own includes -//_________________________________________________________________________________________________________________ - -#ifndef __FRAMEWORK_THREADHELP_THREADHELPBASE_HXX_ -#include <threadhelp/threadhelpbase.hxx> -#endif - -#ifndef __FRAMEWORK_THREADHELP_TRANSACTIONBASE_HXX_ -#include <threadhelp/transactionbase.hxx> -#endif - -#ifndef __FRAMEWORK_THREADHELP_RESETABLEGUARD_HXX_ -#include <threadhelp/resetableguard.hxx> -#endif - -#ifndef __FRAMEWORK_THREADHELP_READGUARD_HXX_ -#include <threadhelp/readguard.hxx> -#endif - -#ifndef __FRAMEWORK_THREADHELP_WRITEGUARD_HXX_ -#include <threadhelp/writeguard.hxx> -#endif - -#ifndef __FRAMEWORK_THREADHELP_TRANSACTIONGUARD_HXX_ -#include <threadhelp/transactionguard.hxx> -#endif - -#ifndef __FRAMEWORK_MACROS_GENERIC_HXX_ -#include <macros/generic.hxx> -#endif - -#ifndef __FRAMEWORK_MACROS_DEBUG_HXX_ -#include <macros/debug.hxx> -#endif - -//_________________________________________________________________________________________________________________ -// interface includes -//_________________________________________________________________________________________________________________ - -//_________________________________________________________________________________________________________________ -// other includes -//_________________________________________________________________________________________________________________ - -#ifndef _RTL_RANDOM_H_ -#include <rtl/random.h> -#endif - -#ifndef _VOS_PROCESS_HXX_ -#include <vos/process.hxx> -#endif - -#ifndef _VOS_THREAD_HXX_ -#include <vos/thread.hxx> -#endif - -#ifndef _RTL_USTRING_ -#include <rtl/ustring.hxx> -#endif - -#ifndef _RTL_USTRBUF_HXX_ -#include <rtl/ustrbuf.hxx> -#endif - -#ifndef _OSL_TIME_H_ -#include <osl/time.h> -#endif - -#ifndef _OSL_INTERLOCK_H_ -#include <osl/interlock.h> -#endif - -#include <vcl/event.hxx> -#include <vcl/svapp.hxx> -#include <vcl/wrkwin.hxx> -#include <vcl/msgbox.hxx> -#include <stdio.h> - -//_________________________________________________________________________________________________________________ -// const -//_________________________________________________________________________________________________________________ - -#define LOGFILE "threadtest.log" -#define STATISTICS_FILE "threadtest_statistic.csv" - -//_________________________________________________________________________________________________________________ -// namespace -//_________________________________________________________________________________________________________________ - -using namespace ::rtl ; -using namespace ::osl ; -using namespace ::vos ; -using namespace ::framework ; - -//_________________________________________________________________________________________________________________ -// defines -//_________________________________________________________________________________________________________________ - -/*---------------- Use follow defines to enable/disable some special features of this little test program! -------*/ - -#define ENABLE_LOG -//#define ENABLE_THREADDELAY -#define ENABLE_REQUESTCOUNT - -/*----------------------------------------------------------------------------------------------------------------*/ - -#ifdef ENABLE_LOG - #define LOG_SETA_START( NA, NID ) \ - { \ - sal_uInt32 nTimeStamp = osl_getGlobalTimer(); \ - ::osl::MutexGuard aLogGuard( m_aLogMutex ); \ - OStringBuffer sLog(256); \ - sLog.append( (sal_Int32)nTimeStamp ); \ - sLog.append( ": Thread[ " ); \ - sLog.append( NID ); \ - sLog.append( " ] call setA( " ); \ - sLog.append( NA ); \ - sLog.append( " )\n" ); \ - WRITE_LOGFILE( LOGFILE, sLog.makeStringAndClear() ) \ - } - - #define LOG_SETA_END( NA, EREASON, NID ) \ - { \ - sal_uInt32 nTimeStamp = osl_getGlobalTimer(); \ - ::osl::MutexGuard aLogGuard( m_aLogMutex ); \ - OStringBuffer sLog(256); \ - sLog.append( (sal_Int32)nTimeStamp ); \ - sLog.append( ": Thread[ " ); \ - sLog.append( NID ); \ - if( EREASON == E_NOREASON ) \ - sLog.append( " ] finish setA( " ); \ - else \ - sLog.append( " ] was refused at setA( "); \ - sLog.append( NA ); \ - sLog.append( " )\n" ); \ - WRITE_LOGFILE( LOGFILE, sLog.makeStringAndClear() ) \ - } - - #define LOG_GETA_START( NID ) \ - { \ - sal_uInt32 nTimeStamp = osl_getGlobalTimer(); \ - ::osl::MutexGuard aLogGuard( m_aLogMutex ); \ - OStringBuffer sLog(256); \ - sLog.append( (sal_Int32)nTimeStamp ); \ - sLog.append( ": Thread[ " ); \ - sLog.append( NID ); \ - sLog.append( " ] call getA()\n" ); \ - WRITE_LOGFILE( LOGFILE, sLog.makeStringAndClear() ) \ - } - - #define LOG_GETA_END( NRETURN, EREASON, NID ) \ - { \ - sal_uInt32 nTimeStamp = osl_getGlobalTimer(); \ - ::osl::MutexGuard aLogGuard( m_aLogMutex ); \ - OStringBuffer sLog(256); \ - sLog.append( (sal_Int32)nTimeStamp ); \ - sLog.append( ": Thread[ " ); \ - sLog.append( NID ); \ - if( EREASON == E_NOREASON ) \ - sLog.append( " ] finish getA() with " ); \ - else \ - sLog.append( " ] was refused at getA() with " ); \ - sLog.append( NRETURN ); \ - sLog.append( "\n" ); \ - WRITE_LOGFILE( LOGFILE, sLog.makeStringAndClear() ) \ - } - - #define LOG_WORKA_START( NA, NID ) \ - { \ - sal_uInt32 nTimeStamp = osl_getGlobalTimer(); \ - ::osl::MutexGuard aLogGuard( m_aLogMutex ); \ - OStringBuffer sLog(256); \ - sLog.append( (sal_Int32)nTimeStamp ); \ - sLog.append( ": Thread[ " ); \ - sLog.append( NID ); \ - sLog.append( " ] call workA( " ); \ - sLog.append( NA ); \ - sLog.append( " )\n" ); \ - WRITE_LOGFILE( LOGFILE, sLog.makeStringAndClear() ) \ - } - - #define LOG_WORKA_END( NRETURN, EREASON, NID ) \ - { \ - sal_uInt32 nTimeStamp = osl_getGlobalTimer(); \ - ::osl::MutexGuard aLogGuard( m_aLogMutex ); \ - OStringBuffer sLog(256); \ - sLog.append( (sal_Int32)nTimeStamp ); \ - sLog.append( ": Thread[ " ); \ - sLog.append( NID ); \ - if( EREASON == E_NOREASON ) \ - sLog.append( " ] finish workA() with " ); \ - else \ - sLog.append( " ] was refused at workA() with " ); \ - sLog.append( NRETURN ); \ - sLog.append( "\n" ); \ - WRITE_LOGFILE( LOGFILE, sLog.makeStringAndClear() ) \ - } - - #define LOG_INITEXCEPTION( SMETHOD, NID ) \ - { \ - sal_uInt32 nTimeStamp = osl_getGlobalTimer(); \ - ::osl::MutexGuard aLogGuard( m_aLogMutex ); \ - OStringBuffer sLog(256); \ - sLog.append( (sal_Int32)nTimeStamp ); \ - sLog.append( ": Thread[ " ); \ - sLog.append( NID ); \ - sLog.append( " ] get EInitException from \"" ); \ - sLog.append( SMETHOD ); \ - sLog.append( "\"\n" ); \ - WRITE_LOGFILE( LOGFILE, sLog.makeStringAndClear() ) \ - } - - #define LOG_CLOSEEXCEPTION( SMETHOD, NID ) \ - { \ - sal_uInt32 nTimeStamp = osl_getGlobalTimer(); \ - ::osl::MutexGuard aLogGuard( m_aLogMutex ); \ - OStringBuffer sLog(256); \ - sLog.append( (sal_Int32)nTimeStamp ); \ - sLog.append( ": Thread[ " ); \ - sLog.append( NID ); \ - sLog.append( " ] get ECloseException from \"" ); \ - sLog.append( SMETHOD ); \ - sLog.append( "\"\n" ); \ - WRITE_LOGFILE( LOGFILE, sLog.makeStringAndClear() ) \ - } - - #define LOG_INIT( NA, NID ) \ - { \ - sal_uInt32 nTimeStamp = osl_getGlobalTimer(); \ - ::osl::MutexGuard aLogGuard( m_aLogMutex ); \ - OStringBuffer sLog(256); \ - sLog.append( (sal_Int32)nTimeStamp ); \ - sLog.append( ": Thread[ " ); \ - sLog.append( NID ); \ - sLog.append( " ] initialize me with " ); \ - sLog.append( NA ); \ - sLog.append( "\n" ); \ - WRITE_LOGFILE( LOGFILE, sLog.makeStringAndClear() ) \ - } - - #define LOG_CLOSE( NID ) \ - { \ - sal_uInt32 nTimeStamp = osl_getGlobalTimer(); \ - ::osl::MutexGuard aLogGuard( m_aLogMutex ); \ - OStringBuffer sLog(256); \ - sLog.append( (sal_Int32)nTimeStamp ); \ - sLog.append( ": Thread[ " ); \ - sLog.append( NID ); \ - sLog.append( " ] close me\n" ); \ - WRITE_LOGFILE( LOGFILE, sLog.makeStringAndClear() ) \ - } -#else - #define LOG_SETA_START( NA, NID ) - #define LOG_SETA_END( NA, EREASON, NID ) - #define LOG_GETA_START( NID ) - #define LOG_GETA_END( NRETURN, EREASON, NID ) - #define LOG_WORKA_START( NA, NID ) - #define LOG_WORKA_END( NRETURN, EREASON, NID ) - #define LOG_INITEXCEPTION( SMETHOD, NID ) - #define LOG_CLOSEEXCEPTION( SMETHOD, NID ) - #define LOG_INIT( NA, NID ) - #define LOG_CLOSE( NID ) -#endif - -//_________________________________________________________________________________________________________________ -// declarations -//_________________________________________________________________________________________________________________ - -sal_uInt16 getRandomValue() -{ - // Get new random value for thread-sleep! - // See run() for further informations. - // Always calculate a new random number. - sal_uInt16 nValue; - rtlRandomPool aPool = rtl_random_createPool(); - rtl_random_getBytes ( aPool, &nValue, 2 ); - rtl_random_destroyPool ( aPool ); - return nValue; -} - -/*-************************************************************************************************************//** - @descr This class is used from different threads at the same time. - We start working after calling init() first(!) ... - and finish it by calling close(). It exist two methods for reading/writing an - internal variable "A". Another function workA() do both things at the same time. - All public methods log information in a file if DO_LOG is defined. - - @attention Our public base class FaiRWLockBase is a struct with a RWLock as member. - This member can be used by guards to safe access at internal variables - in interface methods. - Another baseclass is the TransactionBase. They support rejection of wrong calls at wrong time. - e.g. calls after closing object! -*//*-*************************************************************************************************************/ - -class ThreadSafeClass : private ThreadHelpBase - , private TransactionBase - -{ - public: - - ThreadSafeClass (); - ~ThreadSafeClass(); - - // This methods are used from differnt threads - // to test this class. - void init ( sal_Int32 nA , - sal_Int32 nThreadID ); - void close ( sal_Int32 nThreadID ); - void setA ( sal_Int32 nA , - sal_Int32 nThreadID ); - sal_Int32 getA ( sal_Int32 nThreadID ); - sal_Int32 workA ( sal_Int32 nA , - sal_Int32 nThreadID ); - - #ifdef ENABLE_REQUESTCOUNT - // This methods are used for statistics only! - sal_Int32 getReadCount () { return m_nReadCount; } - sal_Int32 getWriteCount() { return m_nWriteCount; } - #endif - - private: - - sal_Int32 m_nA ; /// test member fro reading/writing - - #ifdef ENABLE_LOG - ::osl::Mutex m_aLogMutex ; /// mutex to serialize writing log file! - #endif - - #ifdef ENABLE_REQUESTCOUNT - oslInterlockedCount m_nReadCount ; /// statistic variables to count read/write requests - oslInterlockedCount m_nWriteCount ; - #endif -}; - -//_________________________________________________________________________________________________________________ -ThreadSafeClass::ThreadSafeClass() - : ThreadHelpBase ( ) - , TransactionBase ( ) - , m_nA ( 0 ) - #ifdef ENABLE_REQUESTCOUNT - , m_nReadCount ( 0 ) - , m_nWriteCount ( 0 ) - #endif -{ -} - -//_________________________________________________________________________________________________________________ -ThreadSafeClass::~ThreadSafeClass() -{ -} - -//_________________________________________________________________________________________________________________ -void ThreadSafeClass::init( sal_Int32 nA, sal_Int32 nThreadID ) -{ - // Look for multiple calls of this method first! - // Use E_SOFTEXCEPTIONS to disable automaticly throwing of exceptions for some working modes. - TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS ); - - // Set write lock for setting internal member AND - // protect changing of working mode! - WriteGuard aWriteLock( m_aLock ); - LOG_INIT( nA, nThreadID ) - - // OK, it must be the first call and we are synchronized with all other threads by using the write lock! - // Otherwise (e.g. if working mode == E_WORK) we get a exception and follow lines are never called. - - // We can set our member and change the working mode now. - m_nA = nA; - - aWriteLock.unlock(); - - m_aTransactionManager.setWorkingMode( E_WORK ); -} - -//_________________________________________________________________________________________________________________ -void ThreadSafeClass::close( sal_Int32 nThreadID ) -{ - // We must look for multiple calls of this method. - // Try to register this method as a transaction. - // In combination with E_HARDEXCEPTIONS only working mode E_WORK pass this barrier. - TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS ); - aTransaction.stop(); - - // Change working mode to BEFORECLOSE to enable rejection of normal interface calls - // and enable SOFTEXCEPTION mode for some impl- or helper methods! - // Attention: We must stop successful registered transaction first ... - // because setWorkingMode() blocks and wait for all current existing ones! - m_aTransactionManager.setWorkingMode( E_BEFORECLOSE ); - - // Make it threadsafe. - // It must be an exclusiv access! => WriteLock! - WriteGuard aWriteLock( m_aLock ); - - LOG_CLOSE( nThreadID ) - - // Now we are alone ... - // All further calls to this object are rejected ... - // (not all ... some special ones can work by using E_SOFTEXCEPTIONS!) - - // Deinitialize all member and set working mode to E_CLOSE. - m_nA = 0; - - aWriteLock.unlock(); - - m_aTransactionManager.setWorkingMode( E_CLOSE ); -} - -//_________________________________________________________________________________________________________________ -void ThreadSafeClass::setA( sal_Int32 nA, sal_Int32 nThreadID ) -{ - // Register this method as a transaction to prevent code against wrong calls - // after close() or before init()! - ERejectReason eReason; - TransactionGuard aTransaction( m_aTransactionManager, E_NOEXCEPTIONS, &eReason ); - if( eReason == E_NOREASON ) - { - // Make it threadsafe. - WriteGuard aWriteLock( m_aLock ); - - LOG_SETA_START( nA, nThreadID ) - - // This object is ready for working and we have full write access. - // We can work with our member. - m_nA = nA; - #ifdef ENABLE_REQUESTCOUNT - osl_incrementInterlockedCount( &m_nWriteCount ); - #endif - LOG_SETA_END( nA, eReason, nThreadID ) - } -} - -//_________________________________________________________________________________________________________________ -sal_Int32 ThreadSafeClass::getA( sal_Int32 nThreadID ) -{ - // Register this method as a transaction to prevent code against wrong calls - // after close() or before init()! - sal_Int32 nReturn = 0; - ERejectReason eReason; - TransactionGuard aTransaction( m_aTransactionManager, E_NOEXCEPTIONS, &eReason ); - if( eReason == E_NOREASON ) - { - // Make it threadsafe. - ReadGuard aReadLock( m_aLock ); - - LOG_GETA_START( nThreadID ) - - // This object is ready for working and we have a read access. - // We can work with our member. - nReturn = m_nA; - #ifdef ENABLE_REQUESTCOUNT - osl_incrementInterlockedCount( &m_nReadCount ); - #endif - LOG_GETA_END( nReturn, eReason, nThreadID ) - } - return nReturn; -} - -//_________________________________________________________________________________________________________________ -sal_Int32 ThreadSafeClass::workA( sal_Int32 nA , - sal_Int32 nThreadID ) -{ - // Register this method as a transaction to prevent code against wrong calls - // after close() or before init()! - sal_Int32 nReturn = 0; - ERejectReason eReason; - TransactionGuard aTransaction( m_aTransactionManager, E_NOEXCEPTIONS, &eReason ); - if( eReason == E_NOREASON ) - { - // This method test the downgrade-mechanism of used lock implementation! - // Make it threadsafe. - WriteGuard aWriteLock( m_aLock ); - - LOG_WORKA_START( nA, nThreadID ) - // We have write access to our member. - // Set new value. - m_nA = nA; - #ifdef ENABLE_REQUESTCOUNT - osl_incrementInterlockedCount( &m_nWriteCount ); - #endif - - // Downgrade write access to read access and read the set value again. - // This call can't be rejected - but it can fail! - aWriteLock.downgrade(); - nReturn = m_nA; - #ifdef ENABLE_REQUESTCOUNT - osl_incrementInterlockedCount( &m_nReadCount ); - #endif - - LOG_WORKA_END( nReturn, eReason, nThreadID ) - } - return nReturn; -} - -/*-****************************************************************************************************//** - @descr Every thread instance of these class lopp from 0 up to "nLoops". - He sleep for a random time and work with given test class "pClass" then. - We use random values for waiting for better results! - Otherwise all threads are sychron after first 2,3...5 calls - I think! -*//*-*****************************************************************************************************/ - -class TestThread : public OThread -{ - public: - - TestThread( ThreadSafeClass* pClass , - sal_Int32 nLoops , - Condition* pListener , - sal_Bool bOwner = sal_False ); - - private: - - virtual void SAL_CALL run (); - virtual void SAL_CALL onTerminated (); - - private: - - ThreadSafeClass* m_pClass ; - sal_Int32 m_nLoops ; - sal_Int32 m_nThreadID ; - Condition* m_pListener ; - sal_Bool m_bOwner ; -}; - -//_________________________________________________________________________________________________________________ -TestThread::TestThread( ThreadSafeClass* pClass , - sal_Int32 nLoops , - Condition* pListener , - sal_Bool bOwner ) - : m_pClass ( pClass ) - , m_nLoops ( nLoops ) - , m_pListener ( pListener ) - , m_bOwner ( bOwner ) -{ -} - -//_________________________________________________________________________________________________________________ -void SAL_CALL TestThread::run() -{ - // Get ID of this thread. - // Is used for logging information ... - m_nThreadID = getCurrentIdentifier(); - - // If we are the owner of given pClass - // we must initialize ... and close - // it. See at the end of this method too. - if( m_bOwner == sal_True ) - { - m_pClass->init( 0, m_nThreadID ); - } - - #ifdef ENABLE_THREADDELAY - TimeValue nDelay ; - #endif - - sal_Int32 nA ; - - for( sal_Int32 nCount=0; nCount<m_nLoops; ++nCount ) - { - // Work with class. - // Use random to select called method. - nA = (sal_Int32)getRandomValue(); - if( nA % 5 == 0 ) - { - //nA = m_pClass->workA( nA, m_nThreadID ); - } - else - if( nA % 3 == 0 ) - { - m_pClass->setA( nA, m_nThreadID ); - } - else - { - nA = m_pClass->getA( m_nThreadID ); - } - #ifdef ENABLE_THREADDELAY - // Sleep - use random value to do that too! - nDelay.Seconds = 0; - nDelay.Nanosec = getRandomValue(); - sleep( nDelay ); - #endif - } - - // Don't forget to "close" teset object if you are the owner! - if( m_bOwner == sal_True ) - { - m_pClass->close( m_nThreadID ); - } -} - -//_________________________________________________________________________________________________________________ -void SAL_CALL TestThread::onTerminated() -{ - // Destroy yourself if you finished. - // But don't forget to call listener before. - m_pListener->set(); - - m_pClass = NULL; - m_pListener = NULL; - - delete this; -} - -/*-****************************************************************************************************//** - @descr This is our test application. - We create one ThreadSafeClass object and a lot of threads - which use it at different times. -*//*-*****************************************************************************************************/ - -struct ThreadInfo -{ - Condition* pCondition ; - TestThread* pThread ; -}; - -class TestApplication : public Application -{ - public: - void Main ( ); - sal_Int32 measureTime ( sal_Int32 nThreadCount , - sal_Int32 nOwner , - sal_Int32 nLoops=0 ); -}; - -//_________________________________________________________________________________________________________________ -// definition -//_________________________________________________________________________________________________________________ - -TestApplication aApplication; - -//_________________________________________________________________________________________________________________ -// This function start "nThreadCount" threads to use same test class. -// You can specify the owner thread of this test class which start/stop it by using "nOwner". [1..nThreadcount]! -// If you specify "nLoops" different from 0 we use it as loop count for every started thread. -// Otherwise we work with random values. -sal_Int32 TestApplication::measureTime( sal_Int32 nThreadCount , - sal_Int32 nOwner , - sal_Int32 nLoops ) -{ - // This is the class which should be tested. - ThreadSafeClass aClass; - - // Create list of threads. - ThreadInfo* pThreads = new ThreadInfo[nThreadCount]; - sal_Int32 nLoopCount = nLoops ; - sal_Bool bOwner = sal_False ; - for( sal_Int32 nI=0; nI<nThreadCount; ++nI ) - { - // If nLoops==0 => we must use random value; otherwise we must use given count ... - if( nLoops == 0 ) - { - nLoopCount = getRandomValue(); - } - // Search owner of class. - bOwner = sal_False; - if( nOwner == nI ) - { - bOwner = sal_True; - } - // initialize condition. - pThreads[nI].pCondition = new Condition; - // Initialize thread. - pThreads[nI].pThread = new TestThread( &aClass, nLoopCount, pThreads[nI].pCondition, bOwner ); - } - - // Start clock to get information about used time. - sal_uInt32 nStartTime ; - sal_uInt32 nEndTime ; - - nStartTime = osl_getGlobalTimer(); - - // Start threads ... - for( nI=0; nI<nThreadCount; ++nI ) - { - pThreads[nI].pThread->create(); - } - - // Wait for threads ... - for( nI=0; nI<nThreadCount; ++nI ) - { - pThreads[nI].pCondition->wait(); - delete pThreads[nI].pCondition; - pThreads[nI].pCondition = NULL; - pThreads[nI].pThread = NULL; - } - - delete[] pThreads; - pThreads = NULL; - - nEndTime = osl_getGlobalTimer(); - - // Calc used time and return it. [ms] - return( nEndTime-nStartTime ); -} - -//_________________________________________________________________________________________________________________ -void TestApplication::Main() -{ - sal_Int32 nTestCount = 0; /// count of calling "measureTime()" - sal_Int32 nThreadCount = 0; /// count of used threads by "measure..." - sal_Int32 nLoops = 0; /// loop count for every thread - sal_Int32 nOwner = 0; /// number of owner thread - - // Parse command line. - // Attention: All parameter are required and must exist! - // syntax: "threadtest.exe <testcount> <threadcount> <loops> <owner>" - OStartupInfo aInfo ; - OUString sArgument ; - sal_Int32 nArgument ; - sal_Int32 nCount = aInfo.getCommandArgCount(); - - LOG_ASSERT2( nCount!=4 ,"TestApplication::Main()" , "Wrong argument line detected!") - - for( nArgument=0; nArgument<nCount; ++nArgument ) - { - aInfo.getCommandArg( nArgument, sArgument ); - if( nArgument== 0 ) nTestCount =sArgument.toInt32(); - if( nArgument== 1 ) nThreadCount=sArgument.toInt32(); - if( nArgument== 2 ) nLoops =sArgument.toInt32(); - if( nArgument== 3 ) nOwner =sArgument.toInt32(); - } - - LOG_ASSERT2( nTestCount==0||nThreadCount==0||nLoops==0||nOwner==0,"TestApplication::Main()", "Wrong argument value detected!" ) - - // Start test. - OStringBuffer sBuf(256); - sal_Int32 nTime=0; - sBuf.append( "Nr.\tTime\tThreadCount\tLoops\tOwner\n" ); - for( sal_Int32 nI=1; nI<=nTestCount; ++nI ) - { - nTime = measureTime( nThreadCount, nOwner, nLoops ); - sBuf.append( nI ); - sBuf.append( "\t" ); - sBuf.append( nTime ); - sBuf.append( "\t" ); - sBuf.append( nThreadCount ); - sBuf.append( "\t" ); - sBuf.append( nLoops ); - sBuf.append( "\t" ); - sBuf.append( nOwner ); - sBuf.append( "\n" ); - } - - WRITE_LOGFILE( STATISTICS_FILE, sBuf.makeStringAndClear() ); - LOG_ERROR( "TApplication::Main()", "Test finish successful!" ) -} |