1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ubtest.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_testtools.hxx"
40 #include <osl/diagnose.h>
41 #include <osl/mutex.hxx>
42 #include <osl/module.h>
43 #include <osl/process.h>
44 #include <osl/thread.h>
45 #include <osl/conditn.hxx>
51 #include <sys/times.h>
55 #include <rtl/string.hxx>
56 #include <rtl/strbuf.hxx>
57 #include <rtl/ustrbuf.hxx>
59 #include <uno/environment.hxx>
60 #include <uno/mapping.hxx>
62 #include <cppuhelper/factory.hxx>
63 #include <cppuhelper/implbase2.hxx>
65 #include <com/sun/star/lang/XServiceInfo.hpp>
66 #include <com/sun/star/lang/XComponent.hpp>
67 #include <com/sun/star/lang/XMain.hpp>
68 #include <com/sun/star/lang/XInitialization.hpp>
69 #include <com/sun/star/loader/XImplementationLoader.hpp>
70 #include <com/sun/star/registry/XRegistryKey.hpp>
71 #include <com/sun/star/bridge/XUnoUrlResolver.hpp>
72 #include <com/sun/star/container/XSet.hpp>
73 #include <com/sun/star/test/performance/XPerformanceTest.hpp>
75 #define NLOOP 200000000
80 using namespace com::sun::star::uno
;
81 using namespace com::sun::star::lang
;
82 using namespace com::sun::star::loader
;
83 using namespace com::sun::star::registry
;
84 using namespace com::sun::star::bridge
;
85 using namespace com::sun::star::container
;
86 using namespace com::sun::star::test::performance
;
88 #define SERVICENAME "com.sun.star.test.performance.PerformanceTest"
89 #define IMPLNAME "com.sun.star.comp.performance.PerformanceTest"
91 namespace benchmark_test
94 static inline sal_uInt32
getSystemTicks()
97 return (sal_uInt32
)GetTickCount();
98 #else // only UNX supported for now
99 static sal_uInt32 nImplTicksPerSecond
= 0;
100 static double dImplTicksPerSecond
;
101 static double dImplTicksULONGMAX
;
104 sal_uInt32 nTicks
= (sal_uInt32
)times( &aTms
);
106 if ( !nImplTicksPerSecond
)
108 nImplTicksPerSecond
= sysconf(_SC_CLK_TCK
);
109 dImplTicksPerSecond
= nImplTicksPerSecond
;
110 dImplTicksULONGMAX
= (double)(sal_uInt32
)ULONG_MAX
;
113 double fTicks
= nTicks
;
115 fTicks
/= dImplTicksPerSecond
;
116 fTicks
= fmod (fTicks
, dImplTicksULONGMAX
);
118 return (sal_uInt32
)fTicks
;
122 //--------------------------------------------------------------------------------------------------
123 static void out( const sal_Char
* pText
, FILE * stream
= stderr
,
124 sal_Int32 nStart
= -1, sal_Char cFillchar
= ' ' )
126 static sal_Int32 s_nPos
= 0;
128 sal_Char ar
[2] = { cFillchar
, 0 };
129 while (s_nPos
< nStart
)
131 ::fprintf( stream
, ar
);
135 ::fprintf( stream
, pText
);
137 for ( const sal_Char
* p
= pText
; *p
; ++p
)
145 //--------------------------------------------------------------------------------------------------
146 static inline void out( const OUString
& rText
, FILE * stream
= stderr
,
147 sal_Int32 nStart
= -1, sal_Char cFillchar
= ' ' )
149 OString
aText( OUStringToOString( rText
, RTL_TEXTENCODING_ASCII_US
) );
150 out( aText
.getStr(), stream
, nStart
, cFillchar
);
152 //--------------------------------------------------------------------------------------------------
153 static inline void out( double fVal
, FILE * stream
= stderr
,
154 sal_Int32 nStart
= -1, sal_Char cFillchar
= ' ' )
157 ::snprintf( ar
, sizeof(ar
), (fVal
< 0.000001 ? "%g" : "%f"), fVal
);
158 out( ar
, stream
, nStart
, cFillchar
);
160 //--------------------------------------------------------------------------------------------------
161 static inline void out( sal_Int64 nVal
, FILE * stream
= stderr
,
162 sal_Int32 nStart
= -1, sal_Char cFillchar
= ' ' )
165 ::snprintf( ar
, sizeof(ar
), "%ld", nVal
);
166 out( ar
, stream
, nStart
, cFillchar
);
169 //==================================================================================================
170 Reference
< XSingleServiceFactory
> loadLibComponentFactory(
171 const OUString
& rLibName
, const OUString
& rImplName
,
172 const Reference
< XMultiServiceFactory
> & xSF
, const Reference
< XRegistryKey
> & xKey
)
174 Reference
< XSingleServiceFactory
> xRet
;
176 OUStringBuffer
aLibNameBuf( 32 );
178 aLibNameBuf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("lib") );
179 aLibNameBuf
.append( rLibName
);
180 aLibNameBuf
.appendAscii( RTL_CONSTASCII_STRINGPARAM(".so") );
182 aLibNameBuf
.append( rLibName
);
183 aLibNameBuf
.appendAscii( RTL_CONSTASCII_STRINGPARAM(".dll") );
185 OUString
aLibName( aLibNameBuf
.makeStringAndClear() );
186 oslModule lib
= osl_loadModule( aLibName
.pData
, SAL_LOADMODULE_LAZY
| SAL_LOADMODULE_GLOBAL
);
192 // ========================= LATEST VERSION =========================
193 OUString
aGetEnvName( RTL_CONSTASCII_USTRINGPARAM(COMPONENT_GETENV
) );
194 if (pSym
= osl_getSymbol( lib
, aGetEnvName
.pData
))
196 uno_Environment
* pCurrentEnv
= 0;
197 uno_Environment
* pEnv
= 0;
198 const sal_Char
* pEnvTypeName
= 0;
199 (*((component_getImplementationEnvironmentFunc
)pSym
))( &pEnvTypeName
, &pEnv
);
201 sal_Bool bNeedsMapping
=
202 (pEnv
|| 0 != rtl_str_compare( pEnvTypeName
, CPPU_CURRENT_LANGUAGE_BINDING_NAME
));
204 OUString
aEnvTypeName( OUString::createFromAscii( pEnvTypeName
) );
209 uno_getEnvironment( &pEnv
, aEnvTypeName
.pData
, 0 );
212 OUString
aCppEnvTypeName( RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME
) );
213 uno_getEnvironment( &pCurrentEnv
, aCppEnvTypeName
.pData
, 0 );
215 bNeedsMapping
= (pEnv
!= pCurrentEnv
);
219 OUString
aGetFactoryName( RTL_CONSTASCII_USTRINGPARAM(COMPONENT_GETFACTORY
) );
220 if (pSym
= osl_getSymbol( lib
, aGetFactoryName
.pData
))
222 OString
aImplName( OUStringToOString( rImplName
, RTL_TEXTENCODING_ASCII_US
) );
226 if (pEnv
&& pCurrentEnv
)
228 Mapping
aCurrent2Env( pCurrentEnv
, pEnv
);
229 Mapping
aEnv2Current( pEnv
, pCurrentEnv
);
231 if (aCurrent2Env
.is() && aEnv2Current
.is())
233 void * pSMgr
= aCurrent2Env
.mapInterface(
234 xSF
.get(), ::getCppuType( (const Reference
< XMultiServiceFactory
> *)0 ) );
235 void * pKey
= aCurrent2Env
.mapInterface(
236 xKey
.get(), ::getCppuType( (const Reference
< XRegistryKey
> *)0 ) );
238 void * pSSF
= (*((component_getFactoryFunc
)pSym
))(
239 aImplName
.getStr(), pSMgr
, pKey
);
242 (*pEnv
->pExtEnv
->releaseInterface
)( pEnv
->pExtEnv
, pKey
);
244 (*pEnv
->pExtEnv
->releaseInterface
)( pEnv
->pExtEnv
, pSMgr
);
248 aEnv2Current
.mapInterface(
249 reinterpret_cast< void ** >( &xRet
),
250 pSSF
, ::getCppuType( (const Reference
< XSingleServiceFactory
> *)0 ) );
251 (*pEnv
->pExtEnv
->releaseInterface
)( pEnv
->pExtEnv
, pSSF
);
258 XSingleServiceFactory
* pRet
= (XSingleServiceFactory
*)
259 (*((component_getFactoryFunc
)pSym
))(
260 aImplName
.getStr(), xSF
.get(), xKey
.get() );
270 (*pEnv
->release
)( pEnv
);
272 (*pCurrentEnv
->release
)( pCurrentEnv
);
275 // ========================= PREVIOUS VERSION =========================
278 OUString
aGetFactoryName( RTL_CONSTASCII_USTRINGPARAM(CREATE_COMPONENT_FACTORY_FUNCTION
) );
279 if (pSym
= osl_getSymbol( lib
, aGetFactoryName
.pData
))
281 OUString
aCppEnvTypeName( RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME
) );
282 OUString
aUnoEnvTypeName( RTL_CONSTASCII_USTRINGPARAM(UNO_LB_UNO
) );
283 Mapping
aUno2Cpp( aUnoEnvTypeName
, aCppEnvTypeName
);
284 Mapping
aCpp2Uno( aCppEnvTypeName
, aUnoEnvTypeName
);
285 OSL_ENSURE( aUno2Cpp
.is() && aCpp2Uno
.is(), "### cannot get uno mappings!" );
287 if (aUno2Cpp
.is() && aCpp2Uno
.is())
289 uno_Interface
* pUComponentFactory
= 0;
291 uno_Interface
* pUSFactory
= (uno_Interface
*)aCpp2Uno
.mapInterface(
292 xSF
.get(), ::getCppuType( (const Reference
< XMultiServiceFactory
> *)0 ) );
293 uno_Interface
* pUKey
= (uno_Interface
*)aCpp2Uno
.mapInterface(
294 xKey
.get(), ::getCppuType( (const Reference
< XRegistryKey
> *)0 ) );
296 pUComponentFactory
= (*((CreateComponentFactoryFunc
)pSym
))(
297 rImplName
.getStr(), pUSFactory
, pUKey
);
300 (*pUKey
->release
)( pUKey
);
302 (*pUSFactory
->release
)( pUSFactory
);
304 if (pUComponentFactory
)
306 XSingleServiceFactory
* pXFactory
=
307 (XSingleServiceFactory
*)aUno2Cpp
.mapInterface(
308 pUComponentFactory
, ::getCppuType( (const Reference
< XSingleServiceFactory
> *)0 ) );
309 (*pUComponentFactory
->release
)( pUComponentFactory
);
314 pXFactory
->release();
322 osl_unloadModule( lib
);
327 //--------------------------------------------------------------------------------------------------
329 static void createInstance( Reference
< T
> & rxOut
,
330 const Reference
< XMultiServiceFactory
> & xMgr
,
331 const OUString
& rServiceName
)
332 throw (RuntimeException
)
334 Reference
< XInterface
> x( xMgr
->createInstance( rServiceName
), UNO_QUERY
);
338 static sal_Bool s_bSet
= sal_False
;
341 MutexGuard
aGuard( Mutex::getGlobalMutex() );
344 Reference
< XSet
> xSet( xMgr
, UNO_QUERY
);
348 xSet
->insert( makeAny( loadLibComponentFactory(
349 OUString( RTL_CONSTASCII_USTRINGPARAM("acceptor") ),
350 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.stoc.Acceptor") ),
351 xMgr
, Reference
< XRegistryKey
>() ) ) );
353 xSet
->insert( makeAny( loadLibComponentFactory(
354 OUString( RTL_CONSTASCII_USTRINGPARAM("connectr") ),
355 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.stoc.Connector") ),
356 xMgr
, Reference
< XRegistryKey
>() ) ) );
358 xSet
->insert( makeAny( loadLibComponentFactory(
359 OUString( RTL_CONSTASCII_USTRINGPARAM("remotebridge") ),
360 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.bridge.Bridge.various") ),
361 xMgr
, Reference
< XRegistryKey
>() ) ) );
363 xSet
->insert( makeAny( loadLibComponentFactory(
364 OUString( RTL_CONSTASCII_USTRINGPARAM("brdgfctr") ),
365 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.stoc.BridgeFactory") ),
366 xMgr
, Reference
< XRegistryKey
>() ) ) );
368 xSet
->insert( makeAny( loadLibComponentFactory(
369 OUString( RTL_CONSTASCII_USTRINGPARAM("uuresolver") ),
370 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.bridge.UnoUrlResolver") ),
371 xMgr
, Reference
< XRegistryKey
>() ) ) );
373 // xSet->insert( makeAny( loadLibComponentFactory(
374 // OUString( RTL_CONSTASCII_USTRINGPARAM("javaloader") ),
375 // OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.stoc.JavaComponentLoader") ),
376 // xMgr, Reference< XRegistryKey >() ) ) );
381 x
= xMgr
->createInstance( rServiceName
);
386 OUStringBuffer
buf( 64 );
387 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("cannot get service instance \"") );
388 buf
.append( rServiceName
);
389 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!") );
390 throw RuntimeException( buf
.makeStringAndClear(), Reference
< XInterface
>() );
393 rxOut
= Reference
< T
>::query( x
);
396 OUStringBuffer
buf( 64 );
397 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("service instance \"") );
398 buf
.append( rServiceName
);
399 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" does not support demanded interface \"") );
400 const Type
& rType
= ::getCppuType( (const Reference
< T
> *)0 );
401 buf
.append( rType
.getTypeName() );
402 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!") );
403 throw RuntimeException( buf
.makeStringAndClear(), Reference
< XInterface
>() );
407 //--------------------------------------------------------------------------------------------------
408 inline static Sequence
< OUString
> getSupportedServiceNames()
410 OUString
aName( RTL_CONSTASCII_USTRINGPARAM(SERVICENAME
) );
411 return Sequence
< OUString
>( &aName
, 1 );
414 //==================================================================================================
415 class TestImpl
: public WeakImplHelper2
< XServiceInfo
, XMain
>
417 Reference
< XMultiServiceFactory
> _xSMgr
;
419 Reference
< XInterface
> _xDirect
;
420 Reference
< XInterface
> getDirect() throw (Exception
);
421 Reference
< XInterface
> resolveObject( const OUString
& rUnoUrl
) throw (Exception
);
424 TestImpl( const Reference
< XMultiServiceFactory
> & xSMgr
);
428 virtual OUString SAL_CALL
getImplementationName() throw (RuntimeException
);
429 virtual sal_Bool SAL_CALL
supportsService( const OUString
& rServiceName
) throw (RuntimeException
);
430 virtual Sequence
< OUString
> SAL_CALL
getSupportedServiceNames() throw (RuntimeException
);
433 virtual sal_Int32 SAL_CALL
run( const Sequence
< OUString
> & rArgs
) throw (RuntimeException
);
436 //##################################################################################################
438 //__________________________________________________________________________________________________
439 TestImpl::TestImpl( const Reference
< XMultiServiceFactory
> & xSMgr
)
443 //__________________________________________________________________________________________________
444 TestImpl::~TestImpl()
448 //==================================================================================================
449 static Reference
< XInterface
> SAL_CALL
TestImpl_create( const Reference
< XMultiServiceFactory
> & xSMgr
)
451 return Reference
< XInterface
>( *new TestImpl( xSMgr
) );
455 //__________________________________________________________________________________________________
456 OUString
TestImpl::getImplementationName()
457 throw (RuntimeException
)
459 return OUString( RTL_CONSTASCII_USTRINGPARAM(IMPLNAME
) );
461 //__________________________________________________________________________________________________
462 sal_Bool
TestImpl::supportsService( const OUString
& rServiceName
)
463 throw (RuntimeException
)
465 const Sequence
< OUString
> & rSNL
= getSupportedServiceNames();
466 const OUString
* pArray
= rSNL
.getConstArray();
467 for ( sal_Int32 nPos
= rSNL
.getLength(); nPos
--; )
469 if (pArray
[nPos
] == rServiceName
)
474 //__________________________________________________________________________________________________
475 Sequence
< OUString
> TestImpl::getSupportedServiceNames()
476 throw (RuntimeException
)
478 return benchmark_test::getSupportedServiceNames();
481 //__________________________________________________________________________________________________
482 Reference
< XInterface
> TestImpl::getDirect()
487 MutexGuard
aGuard( Mutex::getGlobalMutex() );
490 Reference
< XSingleServiceFactory
> xFac( loadLibComponentFactory(
491 OUString( RTL_CONSTASCII_USTRINGPARAM("perfobj") ),
492 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.performance.PerformanceTestObject") ),
493 _xSMgr
, Reference
< XRegistryKey
>() ) );
495 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("no test object available!") ), Reference
< XInterface
>() );
496 _xDirect
= xFac
->createInstance();
501 //--------------------------------------------------------------------------------------------------
502 Reference
< XInterface
> TestImpl::resolveObject( const OUString
& rUnoUrl
)
505 Reference
< XUnoUrlResolver
> xResolver
;
508 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.bridge.UnoUrlResolver") ) );
510 Reference
< XInterface
> xResolvedObject( xResolver
->resolve( rUnoUrl
) );
512 if (! xResolvedObject
.is())
514 OUStringBuffer
buf( 32 );
515 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("cannot resolve object \"") );
516 buf
.append( rUnoUrl
);
517 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!") );
518 throw RuntimeException( buf
.makeStringAndClear(), Reference
< XInterface
>() );
521 return xResolvedObject
;
524 //==================================================================================================
533 TimeEntry( sal_Int64 nLoop_
, sal_uInt32 nTicks_
)
538 inline double secPerCall() const
539 { return (((double)nTicks
) / (nLoop
* 1000)); }
541 double ratio( const TimeEntry
& rEntry
) const;
543 //__________________________________________________________________________________________________
544 double TimeEntry::ratio( const TimeEntry
& rEntry
) const
546 double f
= rEntry
.nTicks
* nLoop
;
553 return (((double)(nTicks
* rEntry
.nLoop
)) / f
);
557 //==================================================================================================
558 typedef std::map
< std::string
, TimeEntry
> t_TimeEntryMap
;
560 //==================================================================================================
563 t_TimeEntryMap _entries
;
564 void insert( const sal_Char
* pText
, sal_Int64 nLoop
, sal_uInt32 nTicks
);
566 //__________________________________________________________________________________________________
567 void TimingSheet::insert( const sal_Char
* pText
, sal_Int64 nLoop
, sal_uInt32 nTicks
)
569 _entries
[ pText
] = TimeEntry( nLoop
, nTicks
);
572 //==================================================================================================
573 typedef std::hash_map
< std::string
, TimingSheet
> t_TimingSheetMap
;
575 //--------------------------------------------------------------------------------------------------
576 static void benchmark(
577 TimingSheet
& rSheet
, const Reference
< XInterface
> & xInstance
, sal_Int64 nLoop
)
580 Reference
< XPerformanceTest
> xBench( xInstance
, UNO_QUERY
);
582 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("illegal test object!") ), Reference
< XInterface
>() );
585 sal_uInt32 tStart
, tEnd
;
587 const Type
& rKnownType
= ::getCppuType( (const Reference
< XPerformanceTest
> *)0 );
588 const Type
& rUnKnownType
= ::getCppuType( (const Reference
< XSet
> *)0 );
590 ComplexTypes aDummyStruct
;
592 //------------------------------------
595 tStart
= getSystemTicks();
598 sal_uInt32 tEndSend
= getSystemTicks();
600 tEnd
= getSystemTicks();
601 rSheet
.insert( "1a: sending simple oneway calls (no params, no return)", nLoop
, tEndSend
- tStart
);
602 rSheet
.insert( "1b: simple oneway calls (no params, no return)", nLoop
, tEnd
- tStart
);
605 tStart
= getSystemTicks();
609 tEnd
= getSystemTicks();
610 rSheet
.insert( "1c: simple synchron calls (no params no return)", nLoop
+1, tEnd
- tStart
);
614 tStart
= getSystemTicks();
617 tEnd
= getSystemTicks();
618 rSheet
.insert( "2a: interface acquire() calls", nLoop
, tEnd
- tStart
);
621 tStart
= getSystemTicks();
624 tEnd
= getSystemTicks();
625 rSheet
.insert( "2b: interface release() calls", nLoop
, tEnd
- tStart
);
627 // queryInterface() for known type
629 tStart
= getSystemTicks();
631 xBench
->queryInterface( rKnownType
);
632 tEnd
= getSystemTicks();
633 rSheet
.insert( "2c: interface query for implemented type", nLoop
, tEnd
- tStart
);
634 // queryInterface() for unknown type
636 tStart
= getSystemTicks();
638 xBench
->queryInterface( rUnKnownType
);
639 tEnd
= getSystemTicks();
640 rSheet
.insert( "2d: interface query for unknown type", nLoop
, tEnd
- tStart
);
642 // create and forget objects
643 Reference
< XPerformanceTest
> xBench2( xBench
);
645 tStart
= getSystemTicks();
647 xBench2
= xBench2
->createObject();
648 tEnd
= getSystemTicks();
649 rSheet
.insert( "3a: create and release test objects", nLoop
, tEnd
- tStart
);
652 Sequence
< Reference
< XInterface
> > aSeq( nLoop
/ 100 );
653 Reference
< XInterface
> * pSeq
= aSeq
.getArray();
655 i
= aSeq
.getLength();
656 tStart
= getSystemTicks();
658 pSeq
[i
] = xBench2
= xBench2
->createObject();
659 tEnd
= getSystemTicks();
660 rSheet
.insert( "3b: create and hold test objects", nLoop
, tEnd
- tStart
);
664 tStart
= getSystemTicks();
666 xBench
->complex_in( aDummyStruct
);
667 tEnd
= getSystemTicks();
668 rSheet
.insert( "4a: complex_in() calls (in struct; return struct)", nLoop
, tEnd
- tStart
);
670 tStart
= getSystemTicks();
672 xBench
->complex_inout( aDummyStruct
);
673 tEnd
= getSystemTicks();
674 rSheet
.insert( "4b: complex_inout() calls (inout struct; return struct)", nLoop
, tEnd
- tStart
);
677 tStart
= getSystemTicks();
679 xBench
->complex_oneway( aDummyStruct
);
680 tEnd
= getSystemTicks();
681 rSheet
.insert( "4c: complex_oneway() oneway calls (in struct)", nLoop
, tEnd
- tStart
);
683 tStart
= getSystemTicks();
685 xBench
->complex_noreturn( aDummyStruct
);
686 tEnd
= getSystemTicks();
687 rSheet
.insert( "4d: complex_noreturn() calls (in struct)", nLoop
, tEnd
- tStart
);
689 // attributes, get() methods
691 tStart
= getSystemTicks();
694 tEnd
= getSystemTicks();
695 rSheet
.insert( "5a: getLong() call", nLoop
, tEnd
- tStart
);
697 tStart
= getSystemTicks();
699 xBench
->getLong_attr();
700 tEnd
= getSystemTicks();
701 rSheet
.insert( "5b: get long attribute", nLoop
, tEnd
- tStart
);
704 tStart
= getSystemTicks();
706 xBench
->setLong( 0 );
707 tEnd
= getSystemTicks();
708 rSheet
.insert( "5c: setLong() call", nLoop
, tEnd
- tStart
);
710 tStart
= getSystemTicks();
712 xBench
->setLong_attr( 0 );
713 tEnd
= getSystemTicks();
714 rSheet
.insert( "5d: set long attribute", nLoop
, tEnd
- tStart
);
717 tStart
= getSystemTicks();
720 tEnd
= getSystemTicks();
721 rSheet
.insert( "5e: getHyper() call", nLoop
, tEnd
- tStart
);
723 tStart
= getSystemTicks();
725 xBench
->getHyper_attr();
726 tEnd
= getSystemTicks();
727 rSheet
.insert( "5f: get hyper attribute", nLoop
, tEnd
- tStart
);
730 tStart
= getSystemTicks();
732 xBench
->setHyper( 0 );
733 tEnd
= getSystemTicks();
734 rSheet
.insert( "5g: setHyper() call", nLoop
, tEnd
- tStart
);
736 tStart
= getSystemTicks();
738 xBench
->setHyper_attr( 0 );
739 tEnd
= getSystemTicks();
740 rSheet
.insert( "5h: set hyper attribute", nLoop
, tEnd
- tStart
);
743 tStart
= getSystemTicks();
746 tEnd
= getSystemTicks();
747 rSheet
.insert( "5i: getFloat() call", nLoop
, tEnd
- tStart
);
749 tStart
= getSystemTicks();
751 xBench
->getFloat_attr();
752 tEnd
= getSystemTicks();
753 rSheet
.insert( "5j: get float attribute",nLoop
, tEnd
- tStart
);
756 tStart
= getSystemTicks();
758 xBench
->setFloat( 0.0 );
759 tEnd
= getSystemTicks();
760 rSheet
.insert( "5k: setFloat() call", nLoop
, tEnd
- tStart
);
762 tStart
= getSystemTicks();
764 xBench
->setFloat_attr( 0.0 );
765 tEnd
= getSystemTicks();
766 rSheet
.insert( "5l: set float attribute", nLoop
, tEnd
- tStart
);
769 tStart
= getSystemTicks();
772 tEnd
= getSystemTicks();
773 rSheet
.insert( "5m: getDouble() call", nLoop
, tEnd
- tStart
);
775 tStart
= getSystemTicks();
777 xBench
->getDouble_attr();
778 tEnd
= getSystemTicks();
779 rSheet
.insert( "5n: get double attribute", nLoop
, tEnd
- tStart
);
781 tStart
= getSystemTicks();
783 xBench
->setDouble( 0.0 );
784 tEnd
= getSystemTicks();
785 rSheet
.insert( "5o: setDouble() call", nLoop
, tEnd
- tStart
);
787 tStart
= getSystemTicks();
789 xBench
->setDouble_attr( 0.0 );
790 tEnd
= getSystemTicks();
791 rSheet
.insert( "5p: set double attribute", nLoop
, tEnd
- tStart
);
794 tStart
= getSystemTicks();
797 tEnd
= getSystemTicks();
798 rSheet
.insert( "6a: getString() call (empty)", nLoop
, tEnd
- tStart
);
800 tStart
= getSystemTicks();
802 xBench
->getString_attr();
803 tEnd
= getSystemTicks();
804 rSheet
.insert( "6b: get empty string attribute", nLoop
, tEnd
- tStart
);
807 OUString aDummyString
;
808 tStart
= getSystemTicks();
810 xBench
->setString( aDummyString
);
811 tEnd
= getSystemTicks();
812 rSheet
.insert( "6c: setString() call (emtpy)", nLoop
, tEnd
- tStart
);
814 tStart
= getSystemTicks();
816 xBench
->setString_attr( aDummyString
);
817 tEnd
= getSystemTicks();
818 rSheet
.insert( "6d: set empty string attribute", nLoop
, tEnd
- tStart
);
821 tStart
= getSystemTicks();
823 xBench
->getInterface();
824 tEnd
= getSystemTicks();
825 rSheet
.insert( "7a: getInterface() call (null)", nLoop
, tEnd
- tStart
);
827 tStart
= getSystemTicks();
829 xBench
->getInterface_attr();
830 tEnd
= getSystemTicks();
831 rSheet
.insert( "7b: get interface attribute", nLoop
, tEnd
- tStart
);
834 Reference
< XInterface
> aDummyInterface
;
835 tStart
= getSystemTicks();
837 xBench
->setInterface( aDummyInterface
);
838 tEnd
= getSystemTicks();
839 rSheet
.insert( "7c: setInterface() call (null)", nLoop
, tEnd
- tStart
);
841 tStart
= getSystemTicks();
843 xBench
->setInterface_attr( Reference
< XInterface
>() );
844 tEnd
= getSystemTicks();
845 rSheet
.insert( "7d: set interface attribute", nLoop
, tEnd
- tStart
);
848 tStart
= getSystemTicks();
851 tEnd
= getSystemTicks();
852 rSheet
.insert( "8a: getAny() call (empty)", nLoop
, tEnd
- tStart
);
854 tStart
= getSystemTicks();
856 xBench
->getAny_attr();
857 tEnd
= getSystemTicks();
858 rSheet
.insert( "8b: get empty any attribute", nLoop
, tEnd
- tStart
);
862 tStart
= getSystemTicks();
864 xBench
->setAny( aDummyAny
);
865 tEnd
= getSystemTicks();
866 rSheet
.insert( "8c: setAny() call (empty)", nLoop
, tEnd
- tStart
);
868 tStart
= getSystemTicks();
870 xBench
->setAny_attr( aDummyAny
);
871 tEnd
= getSystemTicks();
872 rSheet
.insert( "8d: set empty any attribute", nLoop
, tEnd
- tStart
);
875 tStart
= getSystemTicks();
877 xBench
->getSequence();
878 tEnd
= getSystemTicks();
879 rSheet
.insert( "9a: getSequence() call (empty)", nLoop
, tEnd
- tStart
);
881 tStart
= getSystemTicks();
883 xBench
->getSequence_attr();
884 tEnd
= getSystemTicks();
885 rSheet
.insert( "9b: get empty sequence attribute", nLoop
, tEnd
- tStart
);
887 Sequence
< Reference
< XInterface
> > aDummySeq
;
888 tStart
= getSystemTicks();
890 xBench
->setSequence( aDummySeq
);
891 tEnd
= getSystemTicks();
892 rSheet
.insert( "9c: setSequence() call (empty)", nLoop
, tEnd
- tStart
);
894 tStart
= getSystemTicks();
896 xBench
->setSequence_attr( aDummySeq
);
897 tEnd
= getSystemTicks();
898 rSheet
.insert( "9d: set empty sequence attribute", nLoop
, tEnd
- tStart
);
901 tStart
= getSystemTicks();
904 tEnd
= getSystemTicks();
905 rSheet
.insert( "Aa: getStruct() call", nLoop
, tEnd
- tStart
);
907 tStart
= getSystemTicks();
909 xBench
->getStruct_attr();
910 tEnd
= getSystemTicks();
911 rSheet
.insert( "Ab: get struct attribute", nLoop
, tEnd
- tStart
);
914 tStart
= getSystemTicks();
916 xBench
->setStruct( aDummyStruct
);
917 tEnd
= getSystemTicks();
918 rSheet
.insert( "Ac: setStruct() call", nLoop
, tEnd
- tStart
);
920 tStart
= getSystemTicks();
922 xBench
->setStruct_attr( aDummyStruct
);
923 tEnd
= getSystemTicks();
924 rSheet
.insert( "Ad: set struct attribute", nLoop
, tEnd
- tStart
);
928 // tStart = getSystemTicks();
930 // xBench->setSequence( aSeq );
931 // tEnd = getSystemTicks();
932 // rSheet.insert( "transfer of exisiting objects", nLoop, tEnd - tStart );
936 tStart
= getSystemTicks();
941 xBench
->raiseRuntimeException();
943 catch (RuntimeException
&)
947 tEnd
= getSystemTicks();
948 rSheet
.insert( "Ba: raising RuntimeException", nLoop
, tEnd
- tStart
);
950 //------------------------------------
953 //--------------------------------------------------------------------------------------------------
954 static OUString
extractParam( const Sequence
< OUString
> & rArgs
, const OUString
& rParam
)
956 const OUString
* pArgs
= rArgs
.getConstArray();
957 for ( sal_Int32 nPos
= rArgs
.getLength(); nPos
--; )
959 if (pArgs
[nPos
].indexOf( rParam
) == 0 &&
960 pArgs
[nPos
].getLength() > (rParam
.getLength()+1))
962 return pArgs
[nPos
].copy( rParam
.getLength() +1 ); // XXX=bla
968 const sal_Int32 nMagicNumberDirect
= 34000;
971 //__________________________________________________________________________________________________
972 sal_Int32
TestImpl::run( const Sequence
< OUString
> & rArgs
)
973 throw (RuntimeException
)
976 FILE * stream
= stderr
;
977 sal_Int64 nLoop
= NLOOP
;
978 OUString
aArg( RTL_CONSTASCII_USTRINGPARAM("dms") );
982 OUString
aLoopStr( extractParam( rArgs
, OUString( RTL_CONSTASCII_USTRINGPARAM("loop") ) ) );
983 if (aLoopStr
.getLength())
985 sal_Int64 n
= aLoopStr
.toInt64();
990 OUString
aDurationStr( extractParam( rArgs
, OUString( RTL_CONSTASCII_USTRINGPARAM("duration" ) ) ) );
991 if( aDurationStr
.getLength() )
993 sal_Int64 n
= aDurationStr
.toInt64();
995 nLoop
= nMagicNumberDirect
* n
;
998 OUString
aLogStr( extractParam( rArgs
, OUString( RTL_CONSTASCII_USTRINGPARAM("log") ) ) );
999 if (aLogStr
.getLength())
1001 if (aLogStr
.compareToAscii( "stderr" ) == 0)
1005 else if (aLogStr
.compareToAscii( "stdout" ) == 0)
1011 OString
aFileName( OUStringToOString( aLogStr
, RTL_TEXTENCODING_ASCII_US
) );
1012 stream
= ::fopen( aFileName
.getStr(), "w" );
1015 OUStringBuffer
buf( 32 );
1016 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("cannot open file for writing: \"") );
1017 buf
.append( aLogStr
);
1018 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!") );
1019 throw RuntimeException( buf
.makeStringAndClear(), Reference
< XInterface
>() );
1024 OUString
aArgStr( extractParam( rArgs
, OUString( RTL_CONSTASCII_USTRINGPARAM("opt") ) ) );
1025 if (aArgStr
.getLength())
1030 if (! rArgs
.getLength())
1031 out( "\n> no options given, using defaults" );
1037 if (stream
== stderr
)
1039 else if (stream
== stderr
)
1040 out( "stdout loop=" );
1046 t_TimingSheetMap aSheets
;
1047 TimingSheet aDirect
;
1049 //------------------------------------------------------------------------------------------
1051 if (aArg
.indexOf( 'd' ) >= 0)
1053 // in process direct test
1054 sal_uInt32 nStart
= getSystemTicks();
1055 benchmark( aDirect
, getDirect(), nLoop
);
1056 sal_uInt32 nEnd
= getSystemTicks();
1057 fprintf( stderr
, "Duration (direct in process): %g s\n", (nEnd
- nStart
)/1000. );
1060 //------------------------------------------------------------------------------------------
1062 if (aArg
.indexOf( 'm' ) >= 0)
1064 // in process uno dispatch
1065 Environment aCppEnv
, aAnoCppEnv
;
1066 OUString
aCurrentLanguageBindingName( RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME
) );
1067 uno_getEnvironment( reinterpret_cast< uno_Environment
** >( &aCppEnv
),
1068 aCurrentLanguageBindingName
.pData
, 0 );
1070 uno_createEnvironment( reinterpret_cast< uno_Environment
** >( &aAnoCppEnv
),
1071 aCurrentLanguageBindingName
.pData
, 0 );
1073 // pseudo mapping uno<->uno: does nothing!
1074 Mapping
aMapping( aCppEnv
.get(), aAnoCppEnv
.get(), OUString( RTL_CONSTASCII_USTRINGPARAM("pseudo") ) );
1075 if (! aMapping
.is())
1076 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("no pseudo mapping available!") ), Reference
< XInterface
>() );
1078 Reference
< XInterface
> xMapped
;
1079 Reference
< XInterface
> xDirect( getDirect() );
1080 aMapping
.mapInterface( reinterpret_cast< void ** >( &xMapped
), xDirect
.get(),
1081 ::getCppuType( &xDirect
) );
1083 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("mapping object failed!") ), Reference
< XInterface
>() );
1085 sal_uInt32 nStart
= getSystemTicks();
1086 benchmark( aSheets
[ "mapped in process" ], xMapped
, nLoop
/ 100 );
1087 sal_uInt32 nEnd
= getSystemTicks();
1088 fprintf( stderr
, "Duration (mapped in process): %g s\n", (nStart
- nEnd
)/1000. );
1091 //------------------------------------------------------------------------------------------
1093 if (aArg
.indexOf( 's' ) >= 0)
1095 // start server process
1096 oslSecurity hSecurity
= osl_getCurrentSecurity();
1098 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("cannot get current security handle!") ), Reference
< XInterface
>() );
1100 OUString aArgs
[] = {
1101 OUString( RTL_CONSTASCII_USTRINGPARAM("-c") ),
1102 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.performance.PerformanceTestObject") ),
1103 OUString( RTL_CONSTASCII_USTRINGPARAM("-l") ),
1105 OUString( RTL_CONSTASCII_USTRINGPARAM("libperfobj.so") ),
1107 OUString( RTL_CONSTASCII_USTRINGPARAM("perfobj.dll") ),
1109 OUString( RTL_CONSTASCII_USTRINGPARAM("-r") ),
1110 OUString( RTL_CONSTASCII_USTRINGPARAM("applicat.rdb") ),
1111 OUString( RTL_CONSTASCII_USTRINGPARAM("-u") ),
1112 OUString( RTL_CONSTASCII_USTRINGPARAM("uno:socket,host=localhost,port=6000;iiop;TestRemoteObject") ),
1113 OUString( RTL_CONSTASCII_USTRINGPARAM("--singleaccept") )
1115 rtl_uString
* pArgs
[] = {
1128 out( "\n> executing: \"uno" );
1129 for ( sal_Int32 nPos
= 0; nPos
< (sizeof(aArgs
) / sizeof(OUString
)); ++nPos
)
1136 oslProcess hProcess
= 0;
1137 OUString
aUnoExe( RTL_CONSTASCII_USTRINGPARAM("uno") );
1138 OUString
aWorkingDir( RTL_CONSTASCII_USTRINGPARAM(".") );
1140 aUnoExe
.pData
, pArgs
, sizeof(aArgs
) / sizeof(OUString
),
1141 osl_Process_SEARCHPATH
| osl_Process_DETACHED
| osl_Process_NORMAL
,
1142 hSecurity
, aWorkingDir
.pData
, 0, 0, &hProcess
);
1144 osl_freeSecurityHandle( hSecurity
);
1146 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("cannot start server process!") ), Reference
< XInterface
>() );
1147 osl_freeProcessHandle( hProcess
);
1149 // wait three seconds
1150 TimeValue threeSeconds
;
1151 threeSeconds
.Seconds
= 3;
1152 osl_waitThread( &threeSeconds
);
1154 // connect and resolve outer process object
1155 Reference
< XInterface
> xResolvedObject( resolveObject( OUString(
1156 RTL_CONSTASCII_USTRINGPARAM("uno:socket,host=localhost,port=6000;iiop;TestRemoteObject") ) ) );
1158 benchmark( aSheets
[ "remote same host" ], xResolvedObject
, nLoop
/ 300 );
1161 //------------------------------------------------------------------------------------------
1163 if (aArg
.indexOf( 'r' ) >= 0)
1166 OUString
aUnoUrl( extractParam( rArgs
, OUString( RTL_CONSTASCII_USTRINGPARAM("url") ) ) );
1167 if (! aUnoUrl
.getLength())
1168 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("performance test r(emote) needs additional uno url!") ), Reference
< XInterface
>() );
1170 // connect and resolve outer process object
1171 Reference
< XInterface
> xResolvedObject( resolveObject( aUnoUrl
) );
1173 sal_Int32 t1
= getSystemTicks();
1174 OString o
= OUStringToOString( aUnoUrl
, RTL_TEXTENCODING_ASCII_US
);
1175 benchmark( aSheets
[ o
.getStr() ], xResolvedObject
, nLoop
/ 900 );
1176 sal_Int32 t2
= getSystemTicks();
1177 fprintf( stderr
, "Duration (%s): %g s\n", o
.getStr(),(t2
- t1
)/1000. );
1180 //------------------------------------------------------------------------------------------
1182 if (aArg
.indexOf( 'j' ) >= 0)
1185 benchmark( aSheets
[ "java in process" ],
1186 _xSMgr
->createInstance(OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.benchmark.JavaTestObject"))),
1190 //------------------------------------------------------------------------------------------
1193 out( "\nTimes( ratio to direct in process )", stream
);
1194 #if OSL_DEBUG_LEVEL > 1
1195 out ("; compiled with OSL_DEBUG_LEVEL > 1", stream
);
1199 sal_Int32 nPos
= 60;
1200 out( "[direct in process]", stream
, nPos
);
1201 t_TimingSheetMap::const_iterator
iSheets( aSheets
.begin() );
1202 for ( ; iSheets
!= aSheets
.end(); ++iSheets
)
1205 out( "[", stream
, nPos
);
1206 out( (*iSheets
).first
.c_str(), stream
);
1209 for ( t_TimeEntryMap::const_iterator
iTopics( aDirect
._entries
.begin() );
1210 iTopics
!= aDirect
._entries
.end(); ++iTopics
)
1212 const std::string
& rTopic
= (*iTopics
).first
;
1214 out( "\n", stream
);
1215 out( rTopic
.c_str(), stream
);
1217 out( ":", stream
, 58, '.' );
1219 sal_Int32 nPos
= 60;
1221 double secs
= (*iTopics
).second
.secPerCall();
1224 out( secs
* 1000, stream
, nPos
);
1225 out( "ms", stream
);
1229 out( "NA", stream
, nPos
);
1232 iSheets
= aSheets
.begin();
1233 for ( ; iSheets
!= aSheets
.end(); ++iSheets
)
1235 const t_TimeEntryMap::const_iterator
iFind( (*iSheets
).second
._entries
.find( rTopic
) );
1236 OSL_ENSURE( iFind
!= (*iSheets
).second
._entries
.end(), "####" );
1240 double secs
= (*iFind
).second
.secPerCall();
1243 out( secs
* 1000, stream
, nPos
);
1244 out( "ms", stream
);
1246 out( " (", stream
);
1247 double ratio
= (*iFind
).second
.ratio( (*iTopics
).second
);
1250 out( ratio
, stream
);
1251 out( " x)", stream
);
1255 out( "NA)", stream
);
1260 out( "NA", stream
, nPos
);
1265 catch (Exception
& rExc
)
1267 if (stream
!= stderr
&& stream
!= stdout
)
1269 throw RuntimeException( rExc
.Message
, rExc
.Context
);
1272 if (stream
!= stderr
&& stream
!= stdout
)
1275 out( "\n> done.\n" );
1282 //##################################################################################################
1283 //##################################################################################################
1284 //##################################################################################################
1289 //==================================================================================================
1290 void SAL_CALL
component_getImplementationEnvironment(
1291 const sal_Char
** ppEnvTypeName
, uno_Environment
** ppEnv
)
1293 *ppEnvTypeName
= CPPU_CURRENT_LANGUAGE_BINDING_NAME
;
1295 //==================================================================================================
1296 sal_Bool SAL_CALL
component_writeInfo(
1297 void * pServiceManager
, void * pRegistryKey
)
1303 Reference
< XRegistryKey
> xNewKey(
1304 reinterpret_cast< XRegistryKey
* >( pRegistryKey
)->createKey(
1305 OUString( RTL_CONSTASCII_USTRINGPARAM("/" IMPLNAME
"/UNO/SERVICES") ) ) );
1306 xNewKey
->createKey( OUString( RTL_CONSTASCII_USTRINGPARAM(SERVICENAME
) ) );
1310 catch (InvalidRegistryException
&)
1312 OSL_ENSURE( sal_False
, "### InvalidRegistryException!" );
1317 //==================================================================================================
1318 void * SAL_CALL
component_getFactory(
1319 const sal_Char
* pImplName
, void * pServiceManager
, void * pRegistryKey
)
1323 if (pServiceManager
&& rtl_str_compare( pImplName
, IMPLNAME
) == 0)
1325 Reference
< XSingleServiceFactory
> xFactory( createSingleFactory(
1326 reinterpret_cast< XMultiServiceFactory
* >( pServiceManager
),
1327 OUString( RTL_CONSTASCII_USTRINGPARAM(IMPLNAME
) ),
1328 benchmark_test::TestImpl_create
,
1329 benchmark_test::getSupportedServiceNames() ) );
1333 xFactory
->acquire();
1334 pRet
= xFactory
.get();