Update ooo320-m1
[ooovba.git] / testtools / source / performance / ubtest.cxx
blobea6895d7ba52c9fdbffcd8e102db74d6d0abd381
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ubtest.cxx,v $
10 * $Revision: 1.8 $
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"
34 #include <stdio.h>
35 #include <math.h>
36 #include <string>
37 #include <hash_map>
38 #include <map>
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>
46 #include <osl/time.h>
48 #ifdef SAL_W32
49 #include <windows.h>
50 #else
51 #include <sys/times.h>
52 #include <unistd.h>
53 #endif
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
77 using namespace rtl;
78 using namespace osl;
79 using namespace cppu;
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()
96 #ifdef SAL_W32
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;
103 struct tms aTms;
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;
114 fTicks *= 1000;
115 fTicks /= dImplTicksPerSecond;
116 fTicks = fmod (fTicks, dImplTicksULONGMAX);
118 return (sal_uInt32)fTicks;
119 #endif
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 );
132 ++s_nPos;
135 ::fprintf( stream, pText );
137 for ( const sal_Char * p = pText; *p; ++p )
139 if (*p == '\n')
140 s_nPos = 0;
141 else
142 ++s_nPos;
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 = ' ' )
156 sal_Char ar[128];
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 = ' ' )
164 sal_Char ar[128];
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 );
177 #ifdef SAL_UNX
178 aLibNameBuf.appendAscii( RTL_CONSTASCII_STRINGPARAM("lib") );
179 aLibNameBuf.append( rLibName );
180 aLibNameBuf.appendAscii( RTL_CONSTASCII_STRINGPARAM(".so") );
181 #else
182 aLibNameBuf.append( rLibName );
183 aLibNameBuf.appendAscii( RTL_CONSTASCII_STRINGPARAM(".dll") );
184 #endif
185 OUString aLibName( aLibNameBuf.makeStringAndClear() );
186 oslModule lib = osl_loadModule( aLibName.pData, SAL_LOADMODULE_LAZY | SAL_LOADMODULE_GLOBAL );
188 if (lib)
190 void * pSym;
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 ) );
206 if (bNeedsMapping)
208 if (! pEnv)
209 uno_getEnvironment( &pEnv, aEnvTypeName.pData, 0 );
210 if (pEnv)
212 OUString aCppEnvTypeName( RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME) );
213 uno_getEnvironment( &pCurrentEnv, aCppEnvTypeName.pData, 0 );
214 if (pCurrentEnv)
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 ) );
224 if (bNeedsMapping)
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 );
241 if (pKey)
242 (*pEnv->pExtEnv->releaseInterface)( pEnv->pExtEnv, pKey );
243 if (pSMgr)
244 (*pEnv->pExtEnv->releaseInterface)( pEnv->pExtEnv, pSMgr );
246 if (pSSF)
248 aEnv2Current.mapInterface(
249 reinterpret_cast< void ** >( &xRet ),
250 pSSF, ::getCppuType( (const Reference< XSingleServiceFactory > *)0 ) );
251 (*pEnv->pExtEnv->releaseInterface)( pEnv->pExtEnv, pSSF );
256 else
258 XSingleServiceFactory * pRet = (XSingleServiceFactory *)
259 (*((component_getFactoryFunc)pSym))(
260 aImplName.getStr(), xSF.get(), xKey.get() );
261 if (pRet)
263 xRet = pRet;
264 pRet->release();
269 if (pEnv)
270 (*pEnv->release)( pEnv );
271 if (pCurrentEnv)
272 (*pCurrentEnv->release)( pCurrentEnv );
275 // ========================= PREVIOUS VERSION =========================
276 else
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 );
299 if (pUKey)
300 (*pUKey->release)( pUKey );
301 if (pUSFactory)
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 );
311 if (pXFactory)
313 xRet = pXFactory;
314 pXFactory->release();
321 if (! xRet.is())
322 osl_unloadModule( lib );
325 return xRet;
327 //--------------------------------------------------------------------------------------------------
328 template< class T >
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 );
336 if (! x.is())
338 static sal_Bool s_bSet = sal_False;
339 if (! s_bSet)
341 MutexGuard aGuard( Mutex::getGlobalMutex() );
342 if (! s_bSet)
344 Reference< XSet > xSet( xMgr, UNO_QUERY );
345 if (xSet.is())
347 // acceptor
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 >() ) ) );
352 // connector
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 >() ) ) );
357 // iiop bridge
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 >() ) ) );
362 // bridge factory
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 >() ) ) );
367 // uno url resolver
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 >() ) ) );
372 // java loader
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 >() ) ) );
378 s_bSet = sal_True;
381 x = xMgr->createInstance( rServiceName );
384 if (! x.is())
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 );
394 if (! rxOut.is())
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);
423 public:
424 TestImpl( const Reference< XMultiServiceFactory > & xSMgr );
425 virtual ~TestImpl();
427 // XServiceInfo
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);
432 // XMain
433 virtual sal_Int32 SAL_CALL run( const Sequence< OUString > & rArgs ) throw (RuntimeException);
436 //##################################################################################################
438 //__________________________________________________________________________________________________
439 TestImpl::TestImpl( const Reference< XMultiServiceFactory > & xSMgr )
440 : _xSMgr( 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 ) );
454 // XServiceInfo
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)
470 return sal_True;
472 return sal_False;
474 //__________________________________________________________________________________________________
475 Sequence< OUString > TestImpl::getSupportedServiceNames()
476 throw (RuntimeException)
478 return benchmark_test::getSupportedServiceNames();
481 //__________________________________________________________________________________________________
482 Reference< XInterface > TestImpl::getDirect()
483 throw (Exception)
485 if (! _xDirect.is())
487 MutexGuard aGuard( Mutex::getGlobalMutex() );
488 if (! _xDirect.is())
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 >() ) );
494 if (! xFac.is())
495 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("no test object available!") ), Reference< XInterface >() );
496 _xDirect = xFac->createInstance();
499 return _xDirect;
501 //--------------------------------------------------------------------------------------------------
502 Reference< XInterface > TestImpl::resolveObject( const OUString & rUnoUrl )
503 throw (Exception)
505 Reference< XUnoUrlResolver > xResolver;
506 createInstance(
507 xResolver, _xSMgr,
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 //==================================================================================================
525 class TimeEntry
527 sal_Int64 nLoop;
528 sal_uInt32 nTicks;
530 public:
531 TimeEntry()
533 TimeEntry( sal_Int64 nLoop_, sal_uInt32 nTicks_ )
534 : nLoop( nLoop_ )
535 , nTicks( 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;
547 if (f == 0.0)
549 return 0.0;
551 else
553 return (((double)(nTicks * rEntry.nLoop)) / f);
557 //==================================================================================================
558 typedef std::map< std::string, TimeEntry > t_TimeEntryMap;
560 //==================================================================================================
561 struct TimingSheet
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 )
578 throw (Exception)
580 Reference< XPerformanceTest > xBench( xInstance, UNO_QUERY );
581 if (! xBench.is())
582 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("illegal test object!") ), Reference< XInterface >() );
584 sal_Int64 i;
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 //------------------------------------
593 // oneway calls
594 i = nLoop;
595 tStart = getSystemTicks();
596 while (i--)
597 xBench->async();
598 sal_uInt32 tEndSend = getSystemTicks();
599 xBench->sync();
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 );
603 // synchron calls
604 i = nLoop;
605 tStart = getSystemTicks();
606 while (i--)
607 xBench->sync();
608 xBench->sync();
609 tEnd = getSystemTicks();
610 rSheet.insert( "1c: simple synchron calls (no params no return)", nLoop+1, tEnd - tStart );
612 // acquire
613 i = nLoop;
614 tStart = getSystemTicks();
615 while (i--)
616 xBench->acquire();
617 tEnd = getSystemTicks();
618 rSheet.insert( "2a: interface acquire() calls", nLoop, tEnd - tStart );
619 // release
620 i = nLoop;
621 tStart = getSystemTicks();
622 while (i--)
623 xBench->release();
624 tEnd = getSystemTicks();
625 rSheet.insert( "2b: interface release() calls", nLoop, tEnd - tStart );
627 // queryInterface() for known type
628 i = nLoop;
629 tStart = getSystemTicks();
630 while (i--)
631 xBench->queryInterface( rKnownType );
632 tEnd = getSystemTicks();
633 rSheet.insert( "2c: interface query for implemented type", nLoop, tEnd - tStart );
634 // queryInterface() for unknown type
635 i = nLoop;
636 tStart = getSystemTicks();
637 while (i--)
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 );
644 i = nLoop;
645 tStart = getSystemTicks();
646 while (i--)
647 xBench2 = xBench2->createObject();
648 tEnd = getSystemTicks();
649 rSheet.insert( "3a: create and release test objects", nLoop, tEnd - tStart );
651 // hold new objects
652 Sequence< Reference< XInterface > > aSeq( nLoop / 100 );
653 Reference< XInterface > * pSeq = aSeq.getArray();
654 xBench2 = xBench;
655 i = aSeq.getLength();
656 tStart = getSystemTicks();
657 while (i--)
658 pSeq[i] = xBench2 = xBench2->createObject();
659 tEnd = getSystemTicks();
660 rSheet.insert( "3b: create and hold test objects", nLoop, tEnd - tStart );
662 // structs
663 i = nLoop;
664 tStart = getSystemTicks();
665 while (i--)
666 xBench->complex_in( aDummyStruct );
667 tEnd = getSystemTicks();
668 rSheet.insert( "4a: complex_in() calls (in struct; return struct)", nLoop, tEnd - tStart );
669 i = nLoop;
670 tStart = getSystemTicks();
671 while (i--)
672 xBench->complex_inout( aDummyStruct );
673 tEnd = getSystemTicks();
674 rSheet.insert( "4b: complex_inout() calls (inout struct; return struct)", nLoop, tEnd - tStart );
676 i = nLoop;
677 tStart = getSystemTicks();
678 while (i--)
679 xBench->complex_oneway( aDummyStruct );
680 tEnd = getSystemTicks();
681 rSheet.insert( "4c: complex_oneway() oneway calls (in struct)", nLoop, tEnd - tStart );
682 i = nLoop;
683 tStart = getSystemTicks();
684 while (i--)
685 xBench->complex_noreturn( aDummyStruct );
686 tEnd = getSystemTicks();
687 rSheet.insert( "4d: complex_noreturn() calls (in struct)", nLoop, tEnd - tStart );
689 // attributes, get() methods
690 i = nLoop;
691 tStart = getSystemTicks();
692 while (i--)
693 xBench->getLong();
694 tEnd = getSystemTicks();
695 rSheet.insert( "5a: getLong() call", nLoop, tEnd - tStart );
696 i = nLoop;
697 tStart = getSystemTicks();
698 while (i--)
699 xBench->getLong_attr();
700 tEnd = getSystemTicks();
701 rSheet.insert( "5b: get long attribute", nLoop, tEnd - tStart );
703 i = nLoop;
704 tStart = getSystemTicks();
705 while (i--)
706 xBench->setLong( 0 );
707 tEnd = getSystemTicks();
708 rSheet.insert( "5c: setLong() call", nLoop, tEnd - tStart );
709 i = nLoop;
710 tStart = getSystemTicks();
711 while (i--)
712 xBench->setLong_attr( 0 );
713 tEnd = getSystemTicks();
714 rSheet.insert( "5d: set long attribute", nLoop, tEnd - tStart );
716 i = nLoop;
717 tStart = getSystemTicks();
718 while (i--)
719 xBench->getHyper();
720 tEnd = getSystemTicks();
721 rSheet.insert( "5e: getHyper() call", nLoop, tEnd - tStart );
722 i = nLoop;
723 tStart = getSystemTicks();
724 while (i--)
725 xBench->getHyper_attr();
726 tEnd = getSystemTicks();
727 rSheet.insert( "5f: get hyper attribute", nLoop, tEnd - tStart );
729 i = nLoop;
730 tStart = getSystemTicks();
731 while (i--)
732 xBench->setHyper( 0 );
733 tEnd = getSystemTicks();
734 rSheet.insert( "5g: setHyper() call", nLoop, tEnd - tStart );
735 i = nLoop;
736 tStart = getSystemTicks();
737 while (i--)
738 xBench->setHyper_attr( 0 );
739 tEnd = getSystemTicks();
740 rSheet.insert( "5h: set hyper attribute", nLoop, tEnd - tStart );
742 i = nLoop;
743 tStart = getSystemTicks();
744 while (i--)
745 xBench->getFloat();
746 tEnd = getSystemTicks();
747 rSheet.insert( "5i: getFloat() call", nLoop, tEnd - tStart );
748 i = nLoop;
749 tStart = getSystemTicks();
750 while (i--)
751 xBench->getFloat_attr();
752 tEnd = getSystemTicks();
753 rSheet.insert( "5j: get float attribute",nLoop, tEnd - tStart );
755 i = nLoop;
756 tStart = getSystemTicks();
757 while (i--)
758 xBench->setFloat( 0.0 );
759 tEnd = getSystemTicks();
760 rSheet.insert( "5k: setFloat() call", nLoop, tEnd - tStart );
761 i = nLoop;
762 tStart = getSystemTicks();
763 while (i--)
764 xBench->setFloat_attr( 0.0 );
765 tEnd = getSystemTicks();
766 rSheet.insert( "5l: set float attribute", nLoop, tEnd - tStart );
768 i = nLoop;
769 tStart = getSystemTicks();
770 while (i--)
771 xBench->getDouble();
772 tEnd = getSystemTicks();
773 rSheet.insert( "5m: getDouble() call", nLoop, tEnd - tStart );
774 i = nLoop;
775 tStart = getSystemTicks();
776 while (i--)
777 xBench->getDouble_attr();
778 tEnd = getSystemTicks();
779 rSheet.insert( "5n: get double attribute", nLoop, tEnd - tStart );
780 i = nLoop;
781 tStart = getSystemTicks();
782 while (i--)
783 xBench->setDouble( 0.0 );
784 tEnd = getSystemTicks();
785 rSheet.insert( "5o: setDouble() call", nLoop, tEnd - tStart );
786 i = nLoop;
787 tStart = getSystemTicks();
788 while (i--)
789 xBench->setDouble_attr( 0.0 );
790 tEnd = getSystemTicks();
791 rSheet.insert( "5p: set double attribute", nLoop, tEnd - tStart );
793 i = nLoop;
794 tStart = getSystemTicks();
795 while (i--)
796 xBench->getString();
797 tEnd = getSystemTicks();
798 rSheet.insert( "6a: getString() call (empty)", nLoop, tEnd - tStart );
799 i = nLoop;
800 tStart = getSystemTicks();
801 while (i--)
802 xBench->getString_attr();
803 tEnd = getSystemTicks();
804 rSheet.insert( "6b: get empty string attribute", nLoop, tEnd - tStart );
806 i = nLoop;
807 OUString aDummyString;
808 tStart = getSystemTicks();
809 while (i--)
810 xBench->setString( aDummyString );
811 tEnd = getSystemTicks();
812 rSheet.insert( "6c: setString() call (emtpy)", nLoop, tEnd - tStart );
813 i = nLoop;
814 tStart = getSystemTicks();
815 while (i--)
816 xBench->setString_attr( aDummyString );
817 tEnd = getSystemTicks();
818 rSheet.insert( "6d: set empty string attribute", nLoop, tEnd - tStart );
820 i = nLoop;
821 tStart = getSystemTicks();
822 while (i--)
823 xBench->getInterface();
824 tEnd = getSystemTicks();
825 rSheet.insert( "7a: getInterface() call (null)", nLoop, tEnd - tStart );
826 i = nLoop;
827 tStart = getSystemTicks();
828 while (i--)
829 xBench->getInterface_attr();
830 tEnd = getSystemTicks();
831 rSheet.insert( "7b: get interface attribute", nLoop, tEnd - tStart );
833 i = nLoop;
834 Reference< XInterface > aDummyInterface;
835 tStart = getSystemTicks();
836 while (i--)
837 xBench->setInterface( aDummyInterface );
838 tEnd = getSystemTicks();
839 rSheet.insert( "7c: setInterface() call (null)", nLoop, tEnd - tStart );
840 i = nLoop;
841 tStart = getSystemTicks();
842 while (i--)
843 xBench->setInterface_attr( Reference< XInterface >() );
844 tEnd = getSystemTicks();
845 rSheet.insert( "7d: set interface attribute", nLoop, tEnd - tStart );
847 i = nLoop;
848 tStart = getSystemTicks();
849 while (i--)
850 xBench->getAny();
851 tEnd = getSystemTicks();
852 rSheet.insert( "8a: getAny() call (empty)", nLoop, tEnd - tStart );
853 i = nLoop;
854 tStart = getSystemTicks();
855 while (i--)
856 xBench->getAny_attr();
857 tEnd = getSystemTicks();
858 rSheet.insert( "8b: get empty any attribute", nLoop, tEnd - tStart );
860 i = nLoop;
861 Any aDummyAny;
862 tStart = getSystemTicks();
863 while (i--)
864 xBench->setAny( aDummyAny );
865 tEnd = getSystemTicks();
866 rSheet.insert( "8c: setAny() call (empty)", nLoop, tEnd - tStart );
867 i = nLoop;
868 tStart = getSystemTicks();
869 while (i--)
870 xBench->setAny_attr( aDummyAny );
871 tEnd = getSystemTicks();
872 rSheet.insert( "8d: set empty any attribute", nLoop, tEnd - tStart );
874 i = nLoop;
875 tStart = getSystemTicks();
876 while (i--)
877 xBench->getSequence();
878 tEnd = getSystemTicks();
879 rSheet.insert( "9a: getSequence() call (empty)", nLoop, tEnd - tStart );
880 i = nLoop;
881 tStart = getSystemTicks();
882 while (i--)
883 xBench->getSequence_attr();
884 tEnd = getSystemTicks();
885 rSheet.insert( "9b: get empty sequence attribute", nLoop, tEnd - tStart );
886 i = nLoop;
887 Sequence< Reference< XInterface > > aDummySeq;
888 tStart = getSystemTicks();
889 while (i--)
890 xBench->setSequence( aDummySeq );
891 tEnd = getSystemTicks();
892 rSheet.insert( "9c: setSequence() call (empty)", nLoop, tEnd - tStart );
893 i = nLoop;
894 tStart = getSystemTicks();
895 while (i--)
896 xBench->setSequence_attr( aDummySeq );
897 tEnd = getSystemTicks();
898 rSheet.insert( "9d: set empty sequence attribute", nLoop, tEnd - tStart );
900 i = nLoop;
901 tStart = getSystemTicks();
902 while (i--)
903 xBench->getStruct();
904 tEnd = getSystemTicks();
905 rSheet.insert( "Aa: getStruct() call", nLoop, tEnd - tStart );
906 i = nLoop;
907 tStart = getSystemTicks();
908 while (i--)
909 xBench->getStruct_attr();
910 tEnd = getSystemTicks();
911 rSheet.insert( "Ab: get struct attribute", nLoop, tEnd - tStart );
913 i = nLoop;
914 tStart = getSystemTicks();
915 while (i--)
916 xBench->setStruct( aDummyStruct );
917 tEnd = getSystemTicks();
918 rSheet.insert( "Ac: setStruct() call", nLoop, tEnd - tStart );
919 i = nLoop;
920 tStart = getSystemTicks();
921 while (i--)
922 xBench->setStruct_attr( aDummyStruct );
923 tEnd = getSystemTicks();
924 rSheet.insert( "Ad: set struct attribute", nLoop, tEnd - tStart );
926 // load
927 // i = nLoop;
928 // tStart = getSystemTicks();
929 // while (i--)
930 // xBench->setSequence( aSeq );
931 // tEnd = getSystemTicks();
932 // rSheet.insert( "transfer of exisiting objects", nLoop, tEnd - tStart );
934 // exceptions
935 i = nLoop;
936 tStart = getSystemTicks();
937 while (i--)
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
965 return OUString();
968 const sal_Int32 nMagicNumberDirect = 34000;
970 //XMain
971 //__________________________________________________________________________________________________
972 sal_Int32 TestImpl::run( const Sequence< OUString > & rArgs )
973 throw (RuntimeException)
975 // defaults
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();
986 if (n > 0)
987 nLoop = n;
990 OUString aDurationStr( extractParam( rArgs , OUString( RTL_CONSTASCII_USTRINGPARAM("duration" ) ) ) );
991 if( aDurationStr.getLength() )
993 sal_Int64 n = aDurationStr.toInt64();
994 if( n >0 )
995 nLoop = nMagicNumberDirect * n;
998 OUString aLogStr( extractParam( rArgs, OUString( RTL_CONSTASCII_USTRINGPARAM("log") ) ) );
999 if (aLogStr.getLength())
1001 if (aLogStr.compareToAscii( "stderr" ) == 0)
1003 stream = stderr;
1005 else if (aLogStr.compareToAscii( "stdout" ) == 0)
1007 stream = stdout;
1009 else
1011 OString aFileName( OUStringToOString( aLogStr, RTL_TEXTENCODING_ASCII_US ) );
1012 stream = ::fopen( aFileName.getStr(), "w" );
1013 if (! stream)
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())
1027 aArg = aArgStr;
1030 if (! rArgs.getLength())
1031 out( "\n> no options given, using defaults" );
1033 // params
1034 out( "\n> opt=" );
1035 out( aArg );
1036 out( " log=" );
1037 if (stream == stderr)
1038 out( "stderr" );
1039 else if (stream == stderr)
1040 out( "stdout loop=" );
1041 else
1042 out( aLogStr );
1043 out( " loop=" );
1044 out( nLoop );
1045 out( "\n" );
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 );
1069 // anonymous
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 ) );
1082 if (! xMapped.is())
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();
1097 if (! hSecurity)
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") ),
1104 #ifdef SAL_UNX
1105 OUString( RTL_CONSTASCII_USTRINGPARAM("libperfobj.so") ),
1106 #else
1107 OUString( RTL_CONSTASCII_USTRINGPARAM("perfobj.dll") ),
1108 #endif
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[] = {
1116 aArgs[0].pData,
1117 aArgs[1].pData,
1118 aArgs[2].pData,
1119 aArgs[3].pData,
1120 aArgs[4].pData,
1121 aArgs[5].pData,
1122 aArgs[6].pData,
1123 aArgs[7].pData,
1124 aArgs[8].pData,
1125 aArgs[9].pData,
1128 out( "\n> executing: \"uno" );
1129 for ( sal_Int32 nPos = 0; nPos < (sizeof(aArgs) / sizeof(OUString)); ++nPos )
1131 out( " " );
1132 out( aArgs[nPos] );
1134 out( "\" ..." );
1136 oslProcess hProcess = 0;
1137 OUString aUnoExe( RTL_CONSTASCII_USTRINGPARAM("uno") );
1138 OUString aWorkingDir( RTL_CONSTASCII_USTRINGPARAM(".") );
1139 osl_executeProcess(
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 );
1145 if (! hProcess)
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)
1165 // remote
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)
1184 // java
1185 benchmark( aSheets[ "java in process" ],
1186 _xSMgr->createInstance(OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.benchmark.JavaTestObject"))),
1187 nLoop / 1000 );
1190 //------------------------------------------------------------------------------------------
1191 // dump out tables
1193 out( "\nTimes( ratio to direct in process )", stream );
1194 #if OSL_DEBUG_LEVEL > 1
1195 out ("; compiled with OSL_DEBUG_LEVEL > 1", stream );
1196 #endif
1197 out( ":", 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 )
1204 nPos += 40;
1205 out( "[", stream, nPos );
1206 out( (*iSheets).first.c_str(), stream );
1207 out( "]", 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();
1222 if (secs > 0.0)
1224 out( secs * 1000, stream, nPos );
1225 out( "ms", stream );
1227 else
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(), "####" );
1238 nPos += 40;
1240 double secs = (*iFind).second.secPerCall();
1241 if (secs != 0.0)
1243 out( secs * 1000, stream, nPos );
1244 out( "ms", stream );
1246 out( " (", stream );
1247 double ratio = (*iFind).second.ratio( (*iTopics).second );
1248 if (ratio != 0.0)
1250 out( ratio, stream );
1251 out( " x)", stream );
1253 else
1255 out( "NA)", stream );
1258 else
1260 out( "NA", stream, nPos );
1265 catch (Exception & rExc)
1267 if (stream != stderr && stream != stdout)
1268 ::fclose( stream );
1269 throw RuntimeException( rExc.Message, rExc.Context );
1272 if (stream != stderr && stream != stdout)
1273 ::fclose( stream );
1275 out( "\n> done.\n" );
1276 return 0;
1282 //##################################################################################################
1283 //##################################################################################################
1284 //##################################################################################################
1287 extern "C"
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 )
1299 if (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) ) );
1308 return sal_True;
1310 catch (InvalidRegistryException &)
1312 OSL_ENSURE( sal_False, "### InvalidRegistryException!" );
1315 return sal_False;
1317 //==================================================================================================
1318 void * SAL_CALL component_getFactory(
1319 const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey )
1321 void * pRet = 0;
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() ) );
1331 if (xFactory.is())
1333 xFactory->acquire();
1334 pRet = xFactory.get();
1338 return pRet;