jl165 merging heads
[LibreOffice.git] / testtools / source / performance / ubtest.cxx
blobaf174d8f306aca6d4f022b0f1bfe14ba1b81ab6d
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_testtools.hxx"
31 #include <stdio.h>
32 #include <math.h>
33 #include <string>
34 #include <hash_map>
35 #include <map>
37 #include <osl/diagnose.h>
38 #include <osl/mutex.hxx>
39 #include <osl/module.h>
40 #include <osl/process.h>
41 #include <osl/thread.h>
42 #include <osl/conditn.hxx>
43 #include <osl/time.h>
45 #ifdef SAL_W32
46 #include <windows.h>
47 #else
48 #include <sys/times.h>
49 #include <unistd.h>
50 #endif
52 #include <rtl/string.hxx>
53 #include <rtl/strbuf.hxx>
54 #include <rtl/ustrbuf.hxx>
56 #include <uno/environment.hxx>
57 #include <uno/mapping.hxx>
59 #include <cppuhelper/factory.hxx>
60 #include <cppuhelper/implbase2.hxx>
62 #include <com/sun/star/lang/XServiceInfo.hpp>
63 #include <com/sun/star/lang/XComponent.hpp>
64 #include <com/sun/star/lang/XMain.hpp>
65 #include <com/sun/star/lang/XInitialization.hpp>
66 #include <com/sun/star/loader/XImplementationLoader.hpp>
67 #include <com/sun/star/registry/XRegistryKey.hpp>
68 #include <com/sun/star/bridge/XUnoUrlResolver.hpp>
69 #include <com/sun/star/container/XSet.hpp>
70 #include <com/sun/star/test/performance/XPerformanceTest.hpp>
72 #define NLOOP 200000000
74 using namespace rtl;
75 using namespace osl;
76 using namespace cppu;
77 using namespace com::sun::star::uno;
78 using namespace com::sun::star::lang;
79 using namespace com::sun::star::loader;
80 using namespace com::sun::star::registry;
81 using namespace com::sun::star::bridge;
82 using namespace com::sun::star::container;
83 using namespace com::sun::star::test::performance;
85 #define SERVICENAME "com.sun.star.test.performance.PerformanceTest"
86 #define IMPLNAME "com.sun.star.comp.performance.PerformanceTest"
88 namespace benchmark_test
91 static inline sal_uInt32 getSystemTicks()
93 #ifdef SAL_W32
94 return (sal_uInt32)GetTickCount();
95 #else // only UNX supported for now
96 static sal_uInt32 nImplTicksPerSecond = 0;
97 static double dImplTicksPerSecond;
98 static double dImplTicksULONGMAX;
100 struct tms aTms;
101 sal_uInt32 nTicks = (sal_uInt32)times( &aTms );
103 if ( !nImplTicksPerSecond )
105 nImplTicksPerSecond = sysconf(_SC_CLK_TCK);
106 dImplTicksPerSecond = nImplTicksPerSecond;
107 dImplTicksULONGMAX = (double)(sal_uInt32)ULONG_MAX;
110 double fTicks = nTicks;
111 fTicks *= 1000;
112 fTicks /= dImplTicksPerSecond;
113 fTicks = fmod (fTicks, dImplTicksULONGMAX);
115 return (sal_uInt32)fTicks;
116 #endif
119 //--------------------------------------------------------------------------------------------------
120 static void out( const sal_Char * pText, FILE * stream = stderr,
121 sal_Int32 nStart = -1, sal_Char cFillchar = ' ' )
123 static sal_Int32 s_nPos = 0;
125 sal_Char ar[2] = { cFillchar, 0 };
126 while (s_nPos < nStart)
128 ::fprintf( stream, ar );
129 ++s_nPos;
132 ::fprintf( stream, pText );
134 for ( const sal_Char * p = pText; *p; ++p )
136 if (*p == '\n')
137 s_nPos = 0;
138 else
139 ++s_nPos;
142 //--------------------------------------------------------------------------------------------------
143 static inline void out( const OUString & rText, FILE * stream = stderr,
144 sal_Int32 nStart = -1, sal_Char cFillchar = ' ' )
146 OString aText( OUStringToOString( rText, RTL_TEXTENCODING_ASCII_US ) );
147 out( aText.getStr(), stream, nStart, cFillchar );
149 //--------------------------------------------------------------------------------------------------
150 static inline void out( double fVal, FILE * stream = stderr,
151 sal_Int32 nStart = -1, sal_Char cFillchar = ' ' )
153 sal_Char ar[128];
154 ::snprintf( ar, sizeof(ar), (fVal < 0.000001 ? "%g" : "%f"), fVal );
155 out( ar, stream, nStart, cFillchar );
157 //--------------------------------------------------------------------------------------------------
158 static inline void out( sal_Int64 nVal, FILE * stream = stderr,
159 sal_Int32 nStart = -1, sal_Char cFillchar = ' ' )
161 sal_Char ar[128];
162 ::snprintf( ar, sizeof(ar), "%ld", nVal );
163 out( ar, stream, nStart, cFillchar );
166 //==================================================================================================
167 Reference< XSingleServiceFactory > loadLibComponentFactory(
168 const OUString & rLibName, const OUString & rImplName,
169 const Reference< XMultiServiceFactory > & xSF, const Reference< XRegistryKey > & xKey )
171 Reference< XSingleServiceFactory > xRet;
173 OUStringBuffer aLibNameBuf( 32 );
174 #ifdef SAL_UNX
175 aLibNameBuf.appendAscii( RTL_CONSTASCII_STRINGPARAM("lib") );
176 aLibNameBuf.append( rLibName );
177 aLibNameBuf.appendAscii( RTL_CONSTASCII_STRINGPARAM(".so") );
178 #else
179 aLibNameBuf.append( rLibName );
180 aLibNameBuf.appendAscii( RTL_CONSTASCII_STRINGPARAM(".dll") );
181 #endif
182 OUString aLibName( aLibNameBuf.makeStringAndClear() );
183 oslModule lib = osl_loadModule( aLibName.pData, SAL_LOADMODULE_LAZY | SAL_LOADMODULE_GLOBAL );
185 if (lib)
187 void * pSym;
189 // ========================= LATEST VERSION =========================
190 OUString aGetEnvName( RTL_CONSTASCII_USTRINGPARAM(COMPONENT_GETENV) );
191 if (pSym = osl_getSymbol( lib, aGetEnvName.pData ))
193 uno_Environment * pCurrentEnv = 0;
194 uno_Environment * pEnv = 0;
195 const sal_Char * pEnvTypeName = 0;
196 (*((component_getImplementationEnvironmentFunc)pSym))( &pEnvTypeName, &pEnv );
198 sal_Bool bNeedsMapping =
199 (pEnv || 0 != rtl_str_compare( pEnvTypeName, CPPU_CURRENT_LANGUAGE_BINDING_NAME ));
201 OUString aEnvTypeName( OUString::createFromAscii( pEnvTypeName ) );
203 if (bNeedsMapping)
205 if (! pEnv)
206 uno_getEnvironment( &pEnv, aEnvTypeName.pData, 0 );
207 if (pEnv)
209 OUString aCppEnvTypeName( RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME) );
210 uno_getEnvironment( &pCurrentEnv, aCppEnvTypeName.pData, 0 );
211 if (pCurrentEnv)
212 bNeedsMapping = (pEnv != pCurrentEnv);
216 OUString aGetFactoryName( RTL_CONSTASCII_USTRINGPARAM(COMPONENT_GETFACTORY) );
217 if (pSym = osl_getSymbol( lib, aGetFactoryName.pData ))
219 OString aImplName( OUStringToOString( rImplName, RTL_TEXTENCODING_ASCII_US ) );
221 if (bNeedsMapping)
223 if (pEnv && pCurrentEnv)
225 Mapping aCurrent2Env( pCurrentEnv, pEnv );
226 Mapping aEnv2Current( pEnv, pCurrentEnv );
228 if (aCurrent2Env.is() && aEnv2Current.is())
230 void * pSMgr = aCurrent2Env.mapInterface(
231 xSF.get(), ::getCppuType( (const Reference< XMultiServiceFactory > *)0 ) );
232 void * pKey = aCurrent2Env.mapInterface(
233 xKey.get(), ::getCppuType( (const Reference< XRegistryKey > *)0 ) );
235 void * pSSF = (*((component_getFactoryFunc)pSym))(
236 aImplName.getStr(), pSMgr, pKey );
238 if (pKey)
239 (*pEnv->pExtEnv->releaseInterface)( pEnv->pExtEnv, pKey );
240 if (pSMgr)
241 (*pEnv->pExtEnv->releaseInterface)( pEnv->pExtEnv, pSMgr );
243 if (pSSF)
245 aEnv2Current.mapInterface(
246 reinterpret_cast< void ** >( &xRet ),
247 pSSF, ::getCppuType( (const Reference< XSingleServiceFactory > *)0 ) );
248 (*pEnv->pExtEnv->releaseInterface)( pEnv->pExtEnv, pSSF );
253 else
255 XSingleServiceFactory * pRet = (XSingleServiceFactory *)
256 (*((component_getFactoryFunc)pSym))(
257 aImplName.getStr(), xSF.get(), xKey.get() );
258 if (pRet)
260 xRet = pRet;
261 pRet->release();
266 if (pEnv)
267 (*pEnv->release)( pEnv );
268 if (pCurrentEnv)
269 (*pCurrentEnv->release)( pCurrentEnv );
272 // ========================= PREVIOUS VERSION =========================
273 else
275 OUString aGetFactoryName( RTL_CONSTASCII_USTRINGPARAM(CREATE_COMPONENT_FACTORY_FUNCTION) );
276 if (pSym = osl_getSymbol( lib, aGetFactoryName.pData ))
278 OUString aCppEnvTypeName( RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME) );
279 OUString aUnoEnvTypeName( RTL_CONSTASCII_USTRINGPARAM(UNO_LB_UNO) );
280 Mapping aUno2Cpp( aUnoEnvTypeName, aCppEnvTypeName );
281 Mapping aCpp2Uno( aCppEnvTypeName, aUnoEnvTypeName );
282 OSL_ENSURE( aUno2Cpp.is() && aCpp2Uno.is(), "### cannot get uno mappings!" );
284 if (aUno2Cpp.is() && aCpp2Uno.is())
286 uno_Interface * pUComponentFactory = 0;
288 uno_Interface * pUSFactory = (uno_Interface *)aCpp2Uno.mapInterface(
289 xSF.get(), ::getCppuType( (const Reference< XMultiServiceFactory > *)0 ) );
290 uno_Interface * pUKey = (uno_Interface *)aCpp2Uno.mapInterface(
291 xKey.get(), ::getCppuType( (const Reference< XRegistryKey > *)0 ) );
293 pUComponentFactory = (*((CreateComponentFactoryFunc)pSym))(
294 rImplName.getStr(), pUSFactory, pUKey );
296 if (pUKey)
297 (*pUKey->release)( pUKey );
298 if (pUSFactory)
299 (*pUSFactory->release)( pUSFactory );
301 if (pUComponentFactory)
303 XSingleServiceFactory * pXFactory =
304 (XSingleServiceFactory *)aUno2Cpp.mapInterface(
305 pUComponentFactory, ::getCppuType( (const Reference< XSingleServiceFactory > *)0 ) );
306 (*pUComponentFactory->release)( pUComponentFactory );
308 if (pXFactory)
310 xRet = pXFactory;
311 pXFactory->release();
318 if (! xRet.is())
319 osl_unloadModule( lib );
322 return xRet;
324 //--------------------------------------------------------------------------------------------------
325 template< class T >
326 static void createInstance( Reference< T > & rxOut,
327 const Reference< XMultiServiceFactory > & xMgr,
328 const OUString & rServiceName )
329 throw (RuntimeException)
331 Reference< XInterface > x( xMgr->createInstance( rServiceName ), UNO_QUERY );
333 if (! x.is())
335 static sal_Bool s_bSet = sal_False;
336 if (! s_bSet)
338 MutexGuard aGuard( Mutex::getGlobalMutex() );
339 if (! s_bSet)
341 Reference< XSet > xSet( xMgr, UNO_QUERY );
342 if (xSet.is())
344 // acceptor
345 xSet->insert( makeAny( loadLibComponentFactory(
346 OUString( RTL_CONSTASCII_USTRINGPARAM("acceptor") ),
347 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.stoc.Acceptor") ),
348 xMgr, Reference< XRegistryKey >() ) ) );
349 // connector
350 xSet->insert( makeAny( loadLibComponentFactory(
351 OUString( RTL_CONSTASCII_USTRINGPARAM("connectr") ),
352 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.stoc.Connector") ),
353 xMgr, Reference< XRegistryKey >() ) ) );
354 // iiop bridge
355 xSet->insert( makeAny( loadLibComponentFactory(
356 OUString( RTL_CONSTASCII_USTRINGPARAM("remotebridge") ),
357 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.bridge.Bridge.various") ),
358 xMgr, Reference< XRegistryKey >() ) ) );
359 // bridge factory
360 xSet->insert( makeAny( loadLibComponentFactory(
361 OUString( RTL_CONSTASCII_USTRINGPARAM("brdgfctr") ),
362 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.stoc.BridgeFactory") ),
363 xMgr, Reference< XRegistryKey >() ) ) );
364 // uno url resolver
365 xSet->insert( makeAny( loadLibComponentFactory(
366 OUString( RTL_CONSTASCII_USTRINGPARAM("uuresolver") ),
367 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.bridge.UnoUrlResolver") ),
368 xMgr, Reference< XRegistryKey >() ) ) );
369 // java loader
370 // xSet->insert( makeAny( loadLibComponentFactory(
371 // OUString( RTL_CONSTASCII_USTRINGPARAM("javaloader") ),
372 // OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.stoc.JavaComponentLoader") ),
373 // xMgr, Reference< XRegistryKey >() ) ) );
375 s_bSet = sal_True;
378 x = xMgr->createInstance( rServiceName );
381 if (! x.is())
383 OUStringBuffer buf( 64 );
384 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("cannot get service instance \"") );
385 buf.append( rServiceName );
386 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!") );
387 throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() );
390 rxOut = Reference< T >::query( x );
391 if (! rxOut.is())
393 OUStringBuffer buf( 64 );
394 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("service instance \"") );
395 buf.append( rServiceName );
396 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" does not support demanded interface \"") );
397 const Type & rType = ::getCppuType( (const Reference< T > *)0 );
398 buf.append( rType.getTypeName() );
399 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!") );
400 throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() );
404 //--------------------------------------------------------------------------------------------------
405 inline static Sequence< OUString > getSupportedServiceNames()
407 OUString aName( RTL_CONSTASCII_USTRINGPARAM(SERVICENAME) );
408 return Sequence< OUString >( &aName, 1 );
411 //==================================================================================================
412 class TestImpl : public WeakImplHelper2< XServiceInfo, XMain >
414 Reference< XMultiServiceFactory > _xSMgr;
416 Reference< XInterface > _xDirect;
417 Reference< XInterface > getDirect() throw (Exception);
418 Reference< XInterface > resolveObject( const OUString & rUnoUrl ) throw (Exception);
420 public:
421 TestImpl( const Reference< XMultiServiceFactory > & xSMgr );
422 virtual ~TestImpl();
424 // XServiceInfo
425 virtual OUString SAL_CALL getImplementationName() throw (RuntimeException);
426 virtual sal_Bool SAL_CALL supportsService( const OUString & rServiceName ) throw (RuntimeException);
427 virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw (RuntimeException);
429 // XMain
430 virtual sal_Int32 SAL_CALL run( const Sequence< OUString > & rArgs ) throw (RuntimeException);
433 //##################################################################################################
435 //__________________________________________________________________________________________________
436 TestImpl::TestImpl( const Reference< XMultiServiceFactory > & xSMgr )
437 : _xSMgr( xSMgr )
440 //__________________________________________________________________________________________________
441 TestImpl::~TestImpl()
445 //==================================================================================================
446 static Reference< XInterface > SAL_CALL TestImpl_create( const Reference< XMultiServiceFactory > & xSMgr )
448 return Reference< XInterface >( *new TestImpl( xSMgr ) );
451 // XServiceInfo
452 //__________________________________________________________________________________________________
453 OUString TestImpl::getImplementationName()
454 throw (RuntimeException)
456 return OUString( RTL_CONSTASCII_USTRINGPARAM(IMPLNAME) );
458 //__________________________________________________________________________________________________
459 sal_Bool TestImpl::supportsService( const OUString & rServiceName )
460 throw (RuntimeException)
462 const Sequence< OUString > & rSNL = getSupportedServiceNames();
463 const OUString * pArray = rSNL.getConstArray();
464 for ( sal_Int32 nPos = rSNL.getLength(); nPos--; )
466 if (pArray[nPos] == rServiceName)
467 return sal_True;
469 return sal_False;
471 //__________________________________________________________________________________________________
472 Sequence< OUString > TestImpl::getSupportedServiceNames()
473 throw (RuntimeException)
475 return benchmark_test::getSupportedServiceNames();
478 //__________________________________________________________________________________________________
479 Reference< XInterface > TestImpl::getDirect()
480 throw (Exception)
482 if (! _xDirect.is())
484 MutexGuard aGuard( Mutex::getGlobalMutex() );
485 if (! _xDirect.is())
487 Reference< XSingleServiceFactory > xFac( loadLibComponentFactory(
488 OUString( RTL_CONSTASCII_USTRINGPARAM("perfobj") ),
489 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.performance.PerformanceTestObject") ),
490 _xSMgr, Reference< XRegistryKey >() ) );
491 if (! xFac.is())
492 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("no test object available!") ), Reference< XInterface >() );
493 _xDirect = xFac->createInstance();
496 return _xDirect;
498 //--------------------------------------------------------------------------------------------------
499 Reference< XInterface > TestImpl::resolveObject( const OUString & rUnoUrl )
500 throw (Exception)
502 Reference< XUnoUrlResolver > xResolver;
503 createInstance(
504 xResolver, _xSMgr,
505 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.bridge.UnoUrlResolver") ) );
507 Reference< XInterface > xResolvedObject( xResolver->resolve( rUnoUrl ) );
509 if (! xResolvedObject.is())
511 OUStringBuffer buf( 32 );
512 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("cannot resolve object \"") );
513 buf.append( rUnoUrl );
514 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!") );
515 throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() );
518 return xResolvedObject;
521 //==================================================================================================
522 class TimeEntry
524 sal_Int64 nLoop;
525 sal_uInt32 nTicks;
527 public:
528 TimeEntry()
530 TimeEntry( sal_Int64 nLoop_, sal_uInt32 nTicks_ )
531 : nLoop( nLoop_ )
532 , nTicks( nTicks_ )
535 inline double secPerCall() const
536 { return (((double)nTicks) / (nLoop * 1000)); }
538 double ratio( const TimeEntry & rEntry ) const;
540 //__________________________________________________________________________________________________
541 double TimeEntry::ratio( const TimeEntry & rEntry ) const
543 double f = rEntry.nTicks * nLoop;
544 if (f == 0.0)
546 return 0.0;
548 else
550 return (((double)(nTicks * rEntry.nLoop)) / f);
554 //==================================================================================================
555 typedef std::map< std::string, TimeEntry > t_TimeEntryMap;
557 //==================================================================================================
558 struct TimingSheet
560 t_TimeEntryMap _entries;
561 void insert( const sal_Char * pText, sal_Int64 nLoop, sal_uInt32 nTicks );
563 //__________________________________________________________________________________________________
564 void TimingSheet::insert( const sal_Char * pText, sal_Int64 nLoop, sal_uInt32 nTicks )
566 _entries[ pText ] = TimeEntry( nLoop, nTicks );
569 //==================================================================================================
570 typedef std::hash_map< std::string, TimingSheet > t_TimingSheetMap;
572 //--------------------------------------------------------------------------------------------------
573 static void benchmark(
574 TimingSheet & rSheet, const Reference< XInterface > & xInstance, sal_Int64 nLoop )
575 throw (Exception)
577 Reference< XPerformanceTest > xBench( xInstance, UNO_QUERY );
578 if (! xBench.is())
579 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("illegal test object!") ), Reference< XInterface >() );
581 sal_Int64 i;
582 sal_uInt32 tStart, tEnd;
584 const Type & rKnownType = ::getCppuType( (const Reference< XPerformanceTest > *)0 );
585 const Type & rUnKnownType = ::getCppuType( (const Reference< XSet > *)0 );
587 ComplexTypes aDummyStruct;
589 //------------------------------------
590 // oneway calls
591 i = nLoop;
592 tStart = getSystemTicks();
593 while (i--)
594 xBench->async();
595 sal_uInt32 tEndSend = getSystemTicks();
596 xBench->sync();
597 tEnd = getSystemTicks();
598 rSheet.insert( "1a: sending simple oneway calls (no params, no return)", nLoop, tEndSend - tStart );
599 rSheet.insert( "1b: simple oneway calls (no params, no return)", nLoop, tEnd - tStart );
600 // synchron calls
601 i = nLoop;
602 tStart = getSystemTicks();
603 while (i--)
604 xBench->sync();
605 xBench->sync();
606 tEnd = getSystemTicks();
607 rSheet.insert( "1c: simple synchron calls (no params no return)", nLoop+1, tEnd - tStart );
609 // acquire
610 i = nLoop;
611 tStart = getSystemTicks();
612 while (i--)
613 xBench->acquire();
614 tEnd = getSystemTicks();
615 rSheet.insert( "2a: interface acquire() calls", nLoop, tEnd - tStart );
616 // release
617 i = nLoop;
618 tStart = getSystemTicks();
619 while (i--)
620 xBench->release();
621 tEnd = getSystemTicks();
622 rSheet.insert( "2b: interface release() calls", nLoop, tEnd - tStart );
624 // queryInterface() for known type
625 i = nLoop;
626 tStart = getSystemTicks();
627 while (i--)
628 xBench->queryInterface( rKnownType );
629 tEnd = getSystemTicks();
630 rSheet.insert( "2c: interface query for implemented type", nLoop, tEnd - tStart );
631 // queryInterface() for unknown type
632 i = nLoop;
633 tStart = getSystemTicks();
634 while (i--)
635 xBench->queryInterface( rUnKnownType );
636 tEnd = getSystemTicks();
637 rSheet.insert( "2d: interface query for unknown type", nLoop, tEnd - tStart );
639 // create and forget objects
640 Reference< XPerformanceTest > xBench2( xBench );
641 i = nLoop;
642 tStart = getSystemTicks();
643 while (i--)
644 xBench2 = xBench2->createObject();
645 tEnd = getSystemTicks();
646 rSheet.insert( "3a: create and release test objects", nLoop, tEnd - tStart );
648 // hold new objects
649 Sequence< Reference< XInterface > > aSeq( nLoop / 100 );
650 Reference< XInterface > * pSeq = aSeq.getArray();
651 xBench2 = xBench;
652 i = aSeq.getLength();
653 tStart = getSystemTicks();
654 while (i--)
655 pSeq[i] = xBench2 = xBench2->createObject();
656 tEnd = getSystemTicks();
657 rSheet.insert( "3b: create and hold test objects", nLoop, tEnd - tStart );
659 // structs
660 i = nLoop;
661 tStart = getSystemTicks();
662 while (i--)
663 xBench->complex_in( aDummyStruct );
664 tEnd = getSystemTicks();
665 rSheet.insert( "4a: complex_in() calls (in struct; return struct)", nLoop, tEnd - tStart );
666 i = nLoop;
667 tStart = getSystemTicks();
668 while (i--)
669 xBench->complex_inout( aDummyStruct );
670 tEnd = getSystemTicks();
671 rSheet.insert( "4b: complex_inout() calls (inout struct; return struct)", nLoop, tEnd - tStart );
673 i = nLoop;
674 tStart = getSystemTicks();
675 while (i--)
676 xBench->complex_oneway( aDummyStruct );
677 tEnd = getSystemTicks();
678 rSheet.insert( "4c: complex_oneway() oneway calls (in struct)", nLoop, tEnd - tStart );
679 i = nLoop;
680 tStart = getSystemTicks();
681 while (i--)
682 xBench->complex_noreturn( aDummyStruct );
683 tEnd = getSystemTicks();
684 rSheet.insert( "4d: complex_noreturn() calls (in struct)", nLoop, tEnd - tStart );
686 // attributes, get() methods
687 i = nLoop;
688 tStart = getSystemTicks();
689 while (i--)
690 xBench->getLong();
691 tEnd = getSystemTicks();
692 rSheet.insert( "5a: getLong() call", nLoop, tEnd - tStart );
693 i = nLoop;
694 tStart = getSystemTicks();
695 while (i--)
696 xBench->getLong_attr();
697 tEnd = getSystemTicks();
698 rSheet.insert( "5b: get long attribute", nLoop, tEnd - tStart );
700 i = nLoop;
701 tStart = getSystemTicks();
702 while (i--)
703 xBench->setLong( 0 );
704 tEnd = getSystemTicks();
705 rSheet.insert( "5c: setLong() call", nLoop, tEnd - tStart );
706 i = nLoop;
707 tStart = getSystemTicks();
708 while (i--)
709 xBench->setLong_attr( 0 );
710 tEnd = getSystemTicks();
711 rSheet.insert( "5d: set long attribute", nLoop, tEnd - tStart );
713 i = nLoop;
714 tStart = getSystemTicks();
715 while (i--)
716 xBench->getHyper();
717 tEnd = getSystemTicks();
718 rSheet.insert( "5e: getHyper() call", nLoop, tEnd - tStart );
719 i = nLoop;
720 tStart = getSystemTicks();
721 while (i--)
722 xBench->getHyper_attr();
723 tEnd = getSystemTicks();
724 rSheet.insert( "5f: get hyper attribute", nLoop, tEnd - tStart );
726 i = nLoop;
727 tStart = getSystemTicks();
728 while (i--)
729 xBench->setHyper( 0 );
730 tEnd = getSystemTicks();
731 rSheet.insert( "5g: setHyper() call", nLoop, tEnd - tStart );
732 i = nLoop;
733 tStart = getSystemTicks();
734 while (i--)
735 xBench->setHyper_attr( 0 );
736 tEnd = getSystemTicks();
737 rSheet.insert( "5h: set hyper attribute", nLoop, tEnd - tStart );
739 i = nLoop;
740 tStart = getSystemTicks();
741 while (i--)
742 xBench->getFloat();
743 tEnd = getSystemTicks();
744 rSheet.insert( "5i: getFloat() call", nLoop, tEnd - tStart );
745 i = nLoop;
746 tStart = getSystemTicks();
747 while (i--)
748 xBench->getFloat_attr();
749 tEnd = getSystemTicks();
750 rSheet.insert( "5j: get float attribute",nLoop, tEnd - tStart );
752 i = nLoop;
753 tStart = getSystemTicks();
754 while (i--)
755 xBench->setFloat( 0.0 );
756 tEnd = getSystemTicks();
757 rSheet.insert( "5k: setFloat() call", nLoop, tEnd - tStart );
758 i = nLoop;
759 tStart = getSystemTicks();
760 while (i--)
761 xBench->setFloat_attr( 0.0 );
762 tEnd = getSystemTicks();
763 rSheet.insert( "5l: set float attribute", nLoop, tEnd - tStart );
765 i = nLoop;
766 tStart = getSystemTicks();
767 while (i--)
768 xBench->getDouble();
769 tEnd = getSystemTicks();
770 rSheet.insert( "5m: getDouble() call", nLoop, tEnd - tStart );
771 i = nLoop;
772 tStart = getSystemTicks();
773 while (i--)
774 xBench->getDouble_attr();
775 tEnd = getSystemTicks();
776 rSheet.insert( "5n: get double attribute", nLoop, tEnd - tStart );
777 i = nLoop;
778 tStart = getSystemTicks();
779 while (i--)
780 xBench->setDouble( 0.0 );
781 tEnd = getSystemTicks();
782 rSheet.insert( "5o: setDouble() call", nLoop, tEnd - tStart );
783 i = nLoop;
784 tStart = getSystemTicks();
785 while (i--)
786 xBench->setDouble_attr( 0.0 );
787 tEnd = getSystemTicks();
788 rSheet.insert( "5p: set double attribute", nLoop, tEnd - tStart );
790 i = nLoop;
791 tStart = getSystemTicks();
792 while (i--)
793 xBench->getString();
794 tEnd = getSystemTicks();
795 rSheet.insert( "6a: getString() call (empty)", nLoop, tEnd - tStart );
796 i = nLoop;
797 tStart = getSystemTicks();
798 while (i--)
799 xBench->getString_attr();
800 tEnd = getSystemTicks();
801 rSheet.insert( "6b: get empty string attribute", nLoop, tEnd - tStart );
803 i = nLoop;
804 OUString aDummyString;
805 tStart = getSystemTicks();
806 while (i--)
807 xBench->setString( aDummyString );
808 tEnd = getSystemTicks();
809 rSheet.insert( "6c: setString() call (emtpy)", nLoop, tEnd - tStart );
810 i = nLoop;
811 tStart = getSystemTicks();
812 while (i--)
813 xBench->setString_attr( aDummyString );
814 tEnd = getSystemTicks();
815 rSheet.insert( "6d: set empty string attribute", nLoop, tEnd - tStart );
817 i = nLoop;
818 tStart = getSystemTicks();
819 while (i--)
820 xBench->getInterface();
821 tEnd = getSystemTicks();
822 rSheet.insert( "7a: getInterface() call (null)", nLoop, tEnd - tStart );
823 i = nLoop;
824 tStart = getSystemTicks();
825 while (i--)
826 xBench->getInterface_attr();
827 tEnd = getSystemTicks();
828 rSheet.insert( "7b: get interface attribute", nLoop, tEnd - tStart );
830 i = nLoop;
831 Reference< XInterface > aDummyInterface;
832 tStart = getSystemTicks();
833 while (i--)
834 xBench->setInterface( aDummyInterface );
835 tEnd = getSystemTicks();
836 rSheet.insert( "7c: setInterface() call (null)", nLoop, tEnd - tStart );
837 i = nLoop;
838 tStart = getSystemTicks();
839 while (i--)
840 xBench->setInterface_attr( Reference< XInterface >() );
841 tEnd = getSystemTicks();
842 rSheet.insert( "7d: set interface attribute", nLoop, tEnd - tStart );
844 i = nLoop;
845 tStart = getSystemTicks();
846 while (i--)
847 xBench->getAny();
848 tEnd = getSystemTicks();
849 rSheet.insert( "8a: getAny() call (empty)", nLoop, tEnd - tStart );
850 i = nLoop;
851 tStart = getSystemTicks();
852 while (i--)
853 xBench->getAny_attr();
854 tEnd = getSystemTicks();
855 rSheet.insert( "8b: get empty any attribute", nLoop, tEnd - tStart );
857 i = nLoop;
858 Any aDummyAny;
859 tStart = getSystemTicks();
860 while (i--)
861 xBench->setAny( aDummyAny );
862 tEnd = getSystemTicks();
863 rSheet.insert( "8c: setAny() call (empty)", nLoop, tEnd - tStart );
864 i = nLoop;
865 tStart = getSystemTicks();
866 while (i--)
867 xBench->setAny_attr( aDummyAny );
868 tEnd = getSystemTicks();
869 rSheet.insert( "8d: set empty any attribute", nLoop, tEnd - tStart );
871 i = nLoop;
872 tStart = getSystemTicks();
873 while (i--)
874 xBench->getSequence();
875 tEnd = getSystemTicks();
876 rSheet.insert( "9a: getSequence() call (empty)", nLoop, tEnd - tStart );
877 i = nLoop;
878 tStart = getSystemTicks();
879 while (i--)
880 xBench->getSequence_attr();
881 tEnd = getSystemTicks();
882 rSheet.insert( "9b: get empty sequence attribute", nLoop, tEnd - tStart );
883 i = nLoop;
884 Sequence< Reference< XInterface > > aDummySeq;
885 tStart = getSystemTicks();
886 while (i--)
887 xBench->setSequence( aDummySeq );
888 tEnd = getSystemTicks();
889 rSheet.insert( "9c: setSequence() call (empty)", nLoop, tEnd - tStart );
890 i = nLoop;
891 tStart = getSystemTicks();
892 while (i--)
893 xBench->setSequence_attr( aDummySeq );
894 tEnd = getSystemTicks();
895 rSheet.insert( "9d: set empty sequence attribute", nLoop, tEnd - tStart );
897 i = nLoop;
898 tStart = getSystemTicks();
899 while (i--)
900 xBench->getStruct();
901 tEnd = getSystemTicks();
902 rSheet.insert( "Aa: getStruct() call", nLoop, tEnd - tStart );
903 i = nLoop;
904 tStart = getSystemTicks();
905 while (i--)
906 xBench->getStruct_attr();
907 tEnd = getSystemTicks();
908 rSheet.insert( "Ab: get struct attribute", nLoop, tEnd - tStart );
910 i = nLoop;
911 tStart = getSystemTicks();
912 while (i--)
913 xBench->setStruct( aDummyStruct );
914 tEnd = getSystemTicks();
915 rSheet.insert( "Ac: setStruct() call", nLoop, tEnd - tStart );
916 i = nLoop;
917 tStart = getSystemTicks();
918 while (i--)
919 xBench->setStruct_attr( aDummyStruct );
920 tEnd = getSystemTicks();
921 rSheet.insert( "Ad: set struct attribute", nLoop, tEnd - tStart );
923 // load
924 // i = nLoop;
925 // tStart = getSystemTicks();
926 // while (i--)
927 // xBench->setSequence( aSeq );
928 // tEnd = getSystemTicks();
929 // rSheet.insert( "transfer of exisiting objects", nLoop, tEnd - tStart );
931 // exceptions
932 i = nLoop;
933 tStart = getSystemTicks();
934 while (i--)
938 xBench->raiseRuntimeException();
940 catch (RuntimeException &)
944 tEnd = getSystemTicks();
945 rSheet.insert( "Ba: raising RuntimeException", nLoop, tEnd - tStart );
947 //------------------------------------
950 //--------------------------------------------------------------------------------------------------
951 static OUString extractParam( const Sequence< OUString > & rArgs, const OUString & rParam )
953 const OUString * pArgs = rArgs.getConstArray();
954 for ( sal_Int32 nPos = rArgs.getLength(); nPos--; )
956 if (pArgs[nPos].indexOf( rParam ) == 0 &&
957 pArgs[nPos].getLength() > (rParam.getLength()+1))
959 return pArgs[nPos].copy( rParam.getLength() +1 ); // XXX=bla
962 return OUString();
965 const sal_Int32 nMagicNumberDirect = 34000;
967 //XMain
968 //__________________________________________________________________________________________________
969 sal_Int32 TestImpl::run( const Sequence< OUString > & rArgs )
970 throw (RuntimeException)
972 // defaults
973 FILE * stream = stderr;
974 sal_Int64 nLoop = NLOOP;
975 OUString aArg( RTL_CONSTASCII_USTRINGPARAM("dms") );
979 OUString aLoopStr( extractParam( rArgs, OUString( RTL_CONSTASCII_USTRINGPARAM("loop") ) ) );
980 if (aLoopStr.getLength())
982 sal_Int64 n = aLoopStr.toInt64();
983 if (n > 0)
984 nLoop = n;
987 OUString aDurationStr( extractParam( rArgs , OUString( RTL_CONSTASCII_USTRINGPARAM("duration" ) ) ) );
988 if( aDurationStr.getLength() )
990 sal_Int64 n = aDurationStr.toInt64();
991 if( n >0 )
992 nLoop = nMagicNumberDirect * n;
995 OUString aLogStr( extractParam( rArgs, OUString( RTL_CONSTASCII_USTRINGPARAM("log") ) ) );
996 if (aLogStr.getLength())
998 if (aLogStr.compareToAscii( "stderr" ) == 0)
1000 stream = stderr;
1002 else if (aLogStr.compareToAscii( "stdout" ) == 0)
1004 stream = stdout;
1006 else
1008 OString aFileName( OUStringToOString( aLogStr, RTL_TEXTENCODING_ASCII_US ) );
1009 stream = ::fopen( aFileName.getStr(), "w" );
1010 if (! stream)
1012 OUStringBuffer buf( 32 );
1013 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("cannot open file for writing: \"") );
1014 buf.append( aLogStr );
1015 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!") );
1016 throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() );
1021 OUString aArgStr( extractParam( rArgs, OUString( RTL_CONSTASCII_USTRINGPARAM("opt") ) ) );
1022 if (aArgStr.getLength())
1024 aArg = aArgStr;
1027 if (! rArgs.getLength())
1028 out( "\n> no options given, using defaults" );
1030 // params
1031 out( "\n> opt=" );
1032 out( aArg );
1033 out( " log=" );
1034 if (stream == stderr)
1035 out( "stderr" );
1036 else if (stream == stderr)
1037 out( "stdout loop=" );
1038 else
1039 out( aLogStr );
1040 out( " loop=" );
1041 out( nLoop );
1042 out( "\n" );
1043 t_TimingSheetMap aSheets;
1044 TimingSheet aDirect;
1046 //------------------------------------------------------------------------------------------
1048 if (aArg.indexOf( 'd' ) >= 0)
1050 // in process direct test
1051 sal_uInt32 nStart = getSystemTicks();
1052 benchmark( aDirect, getDirect(), nLoop );
1053 sal_uInt32 nEnd = getSystemTicks();
1054 fprintf( stderr, "Duration (direct in process): %g s\n", (nEnd - nStart)/1000. );
1057 //------------------------------------------------------------------------------------------
1059 if (aArg.indexOf( 'm' ) >= 0)
1061 // in process uno dispatch
1062 Environment aCppEnv, aAnoCppEnv;
1063 OUString aCurrentLanguageBindingName( RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME) );
1064 uno_getEnvironment( reinterpret_cast< uno_Environment ** >( &aCppEnv ),
1065 aCurrentLanguageBindingName.pData, 0 );
1066 // anonymous
1067 uno_createEnvironment( reinterpret_cast< uno_Environment ** >( &aAnoCppEnv ),
1068 aCurrentLanguageBindingName.pData, 0 );
1070 // pseudo mapping uno<->uno: does nothing!
1071 Mapping aMapping( aCppEnv.get(), aAnoCppEnv.get(), OUString( RTL_CONSTASCII_USTRINGPARAM("pseudo") ) );
1072 if (! aMapping.is())
1073 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("no pseudo mapping available!") ), Reference< XInterface >() );
1075 Reference< XInterface > xMapped;
1076 Reference< XInterface > xDirect( getDirect() );
1077 aMapping.mapInterface( reinterpret_cast< void ** >( &xMapped ), xDirect.get(),
1078 ::getCppuType( &xDirect ) );
1079 if (! xMapped.is())
1080 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("mapping object failed!") ), Reference< XInterface >() );
1082 sal_uInt32 nStart = getSystemTicks();
1083 benchmark( aSheets[ "mapped in process" ], xMapped, nLoop / 100 );
1084 sal_uInt32 nEnd = getSystemTicks();
1085 fprintf( stderr, "Duration (mapped in process): %g s\n", (nStart - nEnd)/1000. );
1088 //------------------------------------------------------------------------------------------
1090 if (aArg.indexOf( 's' ) >= 0)
1092 // start server process
1093 oslSecurity hSecurity = osl_getCurrentSecurity();
1094 if (! hSecurity)
1095 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("cannot get current security handle!") ), Reference< XInterface >() );
1097 OUString aArgs[] = {
1098 OUString( RTL_CONSTASCII_USTRINGPARAM("-c") ),
1099 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.performance.PerformanceTestObject") ),
1100 OUString( RTL_CONSTASCII_USTRINGPARAM("-l") ),
1101 #ifdef SAL_UNX
1102 OUString( RTL_CONSTASCII_USTRINGPARAM("libperfobj.so") ),
1103 #else
1104 OUString( RTL_CONSTASCII_USTRINGPARAM("perfobj.dll") ),
1105 #endif
1106 OUString( RTL_CONSTASCII_USTRINGPARAM("-r") ),
1107 OUString( RTL_CONSTASCII_USTRINGPARAM("applicat.rdb") ),
1108 OUString( RTL_CONSTASCII_USTRINGPARAM("-u") ),
1109 OUString( RTL_CONSTASCII_USTRINGPARAM("uno:socket,host=localhost,port=6000;iiop;TestRemoteObject") ),
1110 OUString( RTL_CONSTASCII_USTRINGPARAM("--singleaccept") )
1112 rtl_uString * pArgs[] = {
1113 aArgs[0].pData,
1114 aArgs[1].pData,
1115 aArgs[2].pData,
1116 aArgs[3].pData,
1117 aArgs[4].pData,
1118 aArgs[5].pData,
1119 aArgs[6].pData,
1120 aArgs[7].pData,
1121 aArgs[8].pData,
1122 aArgs[9].pData,
1125 out( "\n> executing: \"uno" );
1126 for ( sal_Int32 nPos = 0; nPos < (sizeof(aArgs) / sizeof(OUString)); ++nPos )
1128 out( " " );
1129 out( aArgs[nPos] );
1131 out( "\" ..." );
1133 oslProcess hProcess = 0;
1134 OUString aUnoExe( RTL_CONSTASCII_USTRINGPARAM("uno") );
1135 OUString aWorkingDir( RTL_CONSTASCII_USTRINGPARAM(".") );
1136 osl_executeProcess(
1137 aUnoExe.pData, pArgs, sizeof(aArgs) / sizeof(OUString),
1138 osl_Process_SEARCHPATH | osl_Process_DETACHED | osl_Process_NORMAL,
1139 hSecurity, aWorkingDir.pData, 0, 0, &hProcess );
1141 osl_freeSecurityHandle( hSecurity );
1142 if (! hProcess)
1143 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("cannot start server process!") ), Reference< XInterface >() );
1144 osl_freeProcessHandle( hProcess );
1146 // wait three seconds
1147 TimeValue threeSeconds;
1148 threeSeconds.Seconds = 3;
1149 osl_waitThread( &threeSeconds );
1151 // connect and resolve outer process object
1152 Reference< XInterface > xResolvedObject( resolveObject( OUString(
1153 RTL_CONSTASCII_USTRINGPARAM("uno:socket,host=localhost,port=6000;iiop;TestRemoteObject") ) ) );
1155 benchmark( aSheets[ "remote same host" ], xResolvedObject, nLoop / 300 );
1158 //------------------------------------------------------------------------------------------
1160 if (aArg.indexOf( 'r' ) >= 0)
1162 // remote
1163 OUString aUnoUrl( extractParam( rArgs, OUString( RTL_CONSTASCII_USTRINGPARAM("url") ) ) );
1164 if (! aUnoUrl.getLength())
1165 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("performance test r(emote) needs additional uno url!") ), Reference< XInterface >() );
1167 // connect and resolve outer process object
1168 Reference< XInterface > xResolvedObject( resolveObject( aUnoUrl ) );
1170 sal_Int32 t1 = getSystemTicks();
1171 OString o = OUStringToOString( aUnoUrl, RTL_TEXTENCODING_ASCII_US );
1172 benchmark( aSheets[ o.getStr() ], xResolvedObject, nLoop / 900 );
1173 sal_Int32 t2 = getSystemTicks();
1174 fprintf( stderr, "Duration (%s): %g s\n", o.getStr(),(t2 - t1)/1000. );
1177 //------------------------------------------------------------------------------------------
1179 if (aArg.indexOf( 'j' ) >= 0)
1181 // java
1182 benchmark( aSheets[ "java in process" ],
1183 _xSMgr->createInstance(OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.benchmark.JavaTestObject"))),
1184 nLoop / 1000 );
1187 //------------------------------------------------------------------------------------------
1188 // dump out tables
1190 out( "\nTimes( ratio to direct in process )", stream );
1191 #if OSL_DEBUG_LEVEL > 1
1192 out ("; compiled with OSL_DEBUG_LEVEL > 1", stream );
1193 #endif
1194 out( ":", stream );
1196 sal_Int32 nPos = 60;
1197 out( "[direct in process]", stream, nPos );
1198 t_TimingSheetMap::const_iterator iSheets( aSheets.begin() );
1199 for ( ; iSheets != aSheets.end(); ++iSheets )
1201 nPos += 40;
1202 out( "[", stream, nPos );
1203 out( (*iSheets).first.c_str(), stream );
1204 out( "]", stream );
1206 for ( t_TimeEntryMap::const_iterator iTopics( aDirect._entries.begin() );
1207 iTopics != aDirect._entries.end(); ++iTopics )
1209 const std::string & rTopic = (*iTopics).first;
1211 out( "\n", stream );
1212 out( rTopic.c_str(), stream );
1214 out( ":", stream, 58, '.' );
1216 sal_Int32 nPos = 60;
1218 double secs = (*iTopics).second.secPerCall();
1219 if (secs > 0.0)
1221 out( secs * 1000, stream, nPos );
1222 out( "ms", stream );
1224 else
1226 out( "NA", stream, nPos );
1229 iSheets = aSheets.begin();
1230 for ( ; iSheets != aSheets.end(); ++iSheets )
1232 const t_TimeEntryMap::const_iterator iFind( (*iSheets).second._entries.find( rTopic ) );
1233 OSL_ENSURE( iFind != (*iSheets).second._entries.end(), "####" );
1235 nPos += 40;
1237 double secs = (*iFind).second.secPerCall();
1238 if (secs != 0.0)
1240 out( secs * 1000, stream, nPos );
1241 out( "ms", stream );
1243 out( " (", stream );
1244 double ratio = (*iFind).second.ratio( (*iTopics).second );
1245 if (ratio != 0.0)
1247 out( ratio, stream );
1248 out( " x)", stream );
1250 else
1252 out( "NA)", stream );
1255 else
1257 out( "NA", stream, nPos );
1262 catch (Exception & rExc)
1264 if (stream != stderr && stream != stdout)
1265 ::fclose( stream );
1266 throw RuntimeException( rExc.Message, rExc.Context );
1269 if (stream != stderr && stream != stdout)
1270 ::fclose( stream );
1272 out( "\n> done.\n" );
1273 return 0;
1279 //##################################################################################################
1280 //##################################################################################################
1281 //##################################################################################################
1284 extern "C"
1286 //==================================================================================================
1287 void SAL_CALL component_getImplementationEnvironment(
1288 const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv )
1290 *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
1292 //==================================================================================================
1293 sal_Bool SAL_CALL component_writeInfo(
1294 void * pServiceManager, void * pRegistryKey )
1296 if (pRegistryKey)
1300 Reference< XRegistryKey > xNewKey(
1301 reinterpret_cast< XRegistryKey * >( pRegistryKey )->createKey(
1302 OUString( RTL_CONSTASCII_USTRINGPARAM("/" IMPLNAME "/UNO/SERVICES") ) ) );
1303 xNewKey->createKey( OUString( RTL_CONSTASCII_USTRINGPARAM(SERVICENAME) ) );
1305 return sal_True;
1307 catch (InvalidRegistryException &)
1309 OSL_ENSURE( sal_False, "### InvalidRegistryException!" );
1312 return sal_False;
1314 //==================================================================================================
1315 void * SAL_CALL component_getFactory(
1316 const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey )
1318 void * pRet = 0;
1320 if (pServiceManager && rtl_str_compare( pImplName, IMPLNAME ) == 0)
1322 Reference< XSingleServiceFactory > xFactory( createSingleFactory(
1323 reinterpret_cast< XMultiServiceFactory * >( pServiceManager ),
1324 OUString( RTL_CONSTASCII_USTRINGPARAM(IMPLNAME) ),
1325 benchmark_test::TestImpl_create,
1326 benchmark_test::getSupportedServiceNames() ) );
1328 if (xFactory.is())
1330 xFactory->acquire();
1331 pRet = xFactory.get();
1335 return pRet;