xref: /trunk/main/testtools/source/performance/ubtest.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
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.
14  *
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).
20  *
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.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_testtools.hxx"
30 
31 #include <stdio.h>
32 #include <math.h>
33 #include <string>
34 #include <hash_map>
35 #include <map>
36 
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>
44 
45 #ifdef SAL_W32
46 #include <windows.h>
47 #else
48 #include <sys/times.h>
49 #include <unistd.h>
50 #endif
51 
52 #include <rtl/string.hxx>
53 #include <rtl/strbuf.hxx>
54 #include <rtl/ustrbuf.hxx>
55 
56 #include <uno/environment.hxx>
57 #include <uno/mapping.hxx>
58 
59 #include <cppuhelper/factory.hxx>
60 #include <cppuhelper/implbase2.hxx>
61 
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>
71 
72 #define NLOOP 200000000
73 
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;
84 
85 #define SERVICENAME     "com.sun.star.test.performance.PerformanceTest"
86 #define IMPLNAME        "com.sun.star.comp.performance.PerformanceTest"
87 
88 namespace benchmark_test
89 {
90 
91 static inline sal_uInt32 getSystemTicks()
92 {
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;
99 
100     struct tms          aTms;
101     sal_uInt32 nTicks = (sal_uInt32)times( &aTms );
102 
103     if ( !nImplTicksPerSecond )
104     {
105         nImplTicksPerSecond = sysconf(_SC_CLK_TCK);
106         dImplTicksPerSecond = nImplTicksPerSecond;
107         dImplTicksULONGMAX  = (double)(sal_uInt32)ULONG_MAX;
108     }
109 
110     double fTicks = nTicks;
111     fTicks *= 1000;
112     fTicks /= dImplTicksPerSecond;
113     fTicks = fmod (fTicks, dImplTicksULONGMAX);
114 
115     return (sal_uInt32)fTicks;
116 #endif
117 }
118 
119 //--------------------------------------------------------------------------------------------------
120 static void out( const sal_Char * pText, FILE * stream = stderr,
121                  sal_Int32 nStart = -1, sal_Char cFillchar = ' ' )
122 {
123     static sal_Int32 s_nPos = 0;
124 
125     sal_Char ar[2] = { cFillchar, 0 };
126     while (s_nPos < nStart)
127     {
128         ::fprintf( stream, ar );
129         ++s_nPos;
130     }
131 
132     ::fprintf( stream, pText );
133 
134     for ( const sal_Char * p = pText; *p; ++p )
135     {
136         if (*p == '\n')
137             s_nPos = 0;
138         else
139             ++s_nPos;
140     }
141 }
142 //--------------------------------------------------------------------------------------------------
143 static inline void out( const OUString & rText, FILE * stream = stderr,
144                         sal_Int32 nStart = -1, sal_Char cFillchar = ' ' )
145 {
146     OString aText( OUStringToOString( rText, RTL_TEXTENCODING_ASCII_US ) );
147     out( aText.getStr(), stream, nStart, cFillchar );
148 }
149 //--------------------------------------------------------------------------------------------------
150 static inline void out( double fVal, FILE * stream = stderr,
151                         sal_Int32 nStart = -1, sal_Char cFillchar = ' ' )
152 {
153     sal_Char ar[128];
154     ::snprintf( ar, sizeof(ar), (fVal < 0.000001 ? "%g" : "%f"), fVal );
155     out( ar, stream, nStart, cFillchar );
156 }
157 //--------------------------------------------------------------------------------------------------
158 static inline void out( sal_Int64 nVal, FILE * stream = stderr,
159                         sal_Int32 nStart = -1, sal_Char cFillchar = ' ' )
160 {
161     sal_Char ar[128];
162     ::snprintf( ar, sizeof(ar), "%ld", nVal );
163     out( ar, stream, nStart, cFillchar );
164 }
165 
166 //==================================================================================================
167 Reference< XSingleServiceFactory > loadLibComponentFactory(
168     const OUString & rLibName, const OUString & rImplName,
169     const Reference< XMultiServiceFactory > & xSF, const Reference< XRegistryKey > & xKey )
170 {
171     Reference< XSingleServiceFactory > xRet;
172 
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 );
184 
185     if (lib)
186     {
187         void * pSym;
188 
189         // ========================= LATEST VERSION =========================
190         OUString aGetEnvName( RTL_CONSTASCII_USTRINGPARAM(COMPONENT_GETENV) );
191         if (pSym = osl_getSymbol( lib, aGetEnvName.pData ))
192         {
193             uno_Environment * pCurrentEnv = 0;
194             uno_Environment * pEnv = 0;
195             const sal_Char * pEnvTypeName = 0;
196             (*((component_getImplementationEnvironmentFunc)pSym))( &pEnvTypeName, &pEnv );
197 
198             sal_Bool bNeedsMapping =
199                 (pEnv || 0 != rtl_str_compare( pEnvTypeName, CPPU_CURRENT_LANGUAGE_BINDING_NAME ));
200 
201             OUString aEnvTypeName( OUString::createFromAscii( pEnvTypeName ) );
202 
203             if (bNeedsMapping)
204             {
205                 if (! pEnv)
206                     uno_getEnvironment( &pEnv, aEnvTypeName.pData, 0 );
207                 if (pEnv)
208                 {
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);
213                 }
214             }
215 
216             OUString aGetFactoryName( RTL_CONSTASCII_USTRINGPARAM(COMPONENT_GETFACTORY) );
217             if (pSym = osl_getSymbol( lib, aGetFactoryName.pData ))
218             {
219                 OString aImplName( OUStringToOString( rImplName, RTL_TEXTENCODING_ASCII_US ) );
220 
221                 if (bNeedsMapping)
222                 {
223                     if (pEnv && pCurrentEnv)
224                     {
225                         Mapping aCurrent2Env( pCurrentEnv, pEnv );
226                         Mapping aEnv2Current( pEnv, pCurrentEnv );
227 
228                         if (aCurrent2Env.is() && aEnv2Current.is())
229                         {
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 ) );
234 
235                             void * pSSF = (*((component_getFactoryFunc)pSym))(
236                                 aImplName.getStr(), pSMgr, pKey );
237 
238                             if (pKey)
239                                 (*pEnv->pExtEnv->releaseInterface)( pEnv->pExtEnv, pKey );
240                             if (pSMgr)
241                                 (*pEnv->pExtEnv->releaseInterface)( pEnv->pExtEnv, pSMgr );
242 
243                             if (pSSF)
244                             {
245                                 aEnv2Current.mapInterface(
246                                     reinterpret_cast< void ** >( &xRet ),
247                                     pSSF, ::getCppuType( (const Reference< XSingleServiceFactory > *)0 ) );
248                                 (*pEnv->pExtEnv->releaseInterface)( pEnv->pExtEnv, pSSF );
249                             }
250                         }
251                     }
252                 }
253                 else
254                 {
255                     XSingleServiceFactory * pRet = (XSingleServiceFactory *)
256                         (*((component_getFactoryFunc)pSym))(
257                             aImplName.getStr(), xSF.get(), xKey.get() );
258                     if (pRet)
259                     {
260                         xRet = pRet;
261                         pRet->release();
262                     }
263                 }
264             }
265 
266             if (pEnv)
267                 (*pEnv->release)( pEnv );
268             if (pCurrentEnv)
269                 (*pCurrentEnv->release)( pCurrentEnv );
270         }
271 
272         // ========================= PREVIOUS VERSION =========================
273         else
274         {
275             OUString aGetFactoryName( RTL_CONSTASCII_USTRINGPARAM(CREATE_COMPONENT_FACTORY_FUNCTION) );
276             if (pSym = osl_getSymbol( lib, aGetFactoryName.pData ))
277             {
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!" );
283 
284                 if (aUno2Cpp.is() && aCpp2Uno.is())
285                 {
286                     uno_Interface * pUComponentFactory = 0;
287 
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 ) );
292 
293                     pUComponentFactory = (*((CreateComponentFactoryFunc)pSym))(
294                         rImplName.getStr(), pUSFactory, pUKey );
295 
296                     if (pUKey)
297                         (*pUKey->release)( pUKey );
298                     if (pUSFactory)
299                         (*pUSFactory->release)( pUSFactory );
300 
301                     if (pUComponentFactory)
302                     {
303                         XSingleServiceFactory * pXFactory =
304                             (XSingleServiceFactory *)aUno2Cpp.mapInterface(
305                                 pUComponentFactory, ::getCppuType( (const Reference< XSingleServiceFactory > *)0 ) );
306                         (*pUComponentFactory->release)( pUComponentFactory );
307 
308                         if (pXFactory)
309                         {
310                             xRet = pXFactory;
311                             pXFactory->release();
312                         }
313                     }
314                 }
315             }
316         }
317 
318         if (! xRet.is())
319             osl_unloadModule( lib );
320     }
321 
322     return xRet;
323 }
324 //--------------------------------------------------------------------------------------------------
325 template< class T >
326 static void createInstance( Reference< T > & rxOut,
327                             const Reference< XMultiServiceFactory > & xMgr,
328                             const OUString & rServiceName )
329     throw (RuntimeException)
330 {
331     Reference< XInterface > x( xMgr->createInstance( rServiceName ), UNO_QUERY );
332 
333     if (! x.is())
334     {
335         static sal_Bool s_bSet = sal_False;
336         if (! s_bSet)
337         {
338             MutexGuard aGuard( Mutex::getGlobalMutex() );
339             if (! s_bSet)
340             {
341                 Reference< XSet > xSet( xMgr, UNO_QUERY );
342                 if (xSet.is())
343                 {
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 >() ) ) );
374                 }
375                 s_bSet = sal_True;
376             }
377         }
378         x = xMgr->createInstance( rServiceName );
379     }
380 
381     if (! x.is())
382     {
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 >() );
388     }
389 
390     rxOut = Reference< T >::query( x );
391     if (! rxOut.is())
392     {
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 >() );
401     }
402 }
403 
404 //--------------------------------------------------------------------------------------------------
405 inline static Sequence< OUString > getSupportedServiceNames()
406 {
407     OUString aName( RTL_CONSTASCII_USTRINGPARAM(SERVICENAME) );
408     return Sequence< OUString >( &aName, 1 );
409 }
410 
411 //==================================================================================================
412 class TestImpl : public WeakImplHelper2< XServiceInfo, XMain >
413 {
414     Reference< XMultiServiceFactory > _xSMgr;
415 
416     Reference< XInterface > _xDirect;
417     Reference< XInterface > getDirect() throw (Exception);
418     Reference< XInterface > resolveObject( const OUString & rUnoUrl ) throw (Exception);
419 
420 public:
421     TestImpl( const Reference< XMultiServiceFactory > & xSMgr );
422     virtual ~TestImpl();
423 
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);
428 
429     // XMain
430     virtual sal_Int32 SAL_CALL run( const Sequence< OUString > & rArgs ) throw (RuntimeException);
431 };
432 
433 //##################################################################################################
434 
435 //__________________________________________________________________________________________________
436 TestImpl::TestImpl( const Reference< XMultiServiceFactory > & xSMgr )
437     : _xSMgr( xSMgr )
438 {
439 }
440 //__________________________________________________________________________________________________
441 TestImpl::~TestImpl()
442 {
443 }
444 
445 //==================================================================================================
446 static Reference< XInterface > SAL_CALL TestImpl_create( const Reference< XMultiServiceFactory > & xSMgr )
447 {
448     return Reference< XInterface >( *new TestImpl( xSMgr ) );
449 }
450 
451 // XServiceInfo
452 //__________________________________________________________________________________________________
453 OUString TestImpl::getImplementationName()
454     throw (RuntimeException)
455 {
456     return OUString( RTL_CONSTASCII_USTRINGPARAM(IMPLNAME) );
457 }
458 //__________________________________________________________________________________________________
459 sal_Bool TestImpl::supportsService( const OUString & rServiceName )
460     throw (RuntimeException)
461 {
462     const Sequence< OUString > & rSNL = getSupportedServiceNames();
463     const OUString * pArray = rSNL.getConstArray();
464     for ( sal_Int32 nPos = rSNL.getLength(); nPos--; )
465     {
466         if (pArray[nPos] == rServiceName)
467             return sal_True;
468     }
469     return sal_False;
470 }
471 //__________________________________________________________________________________________________
472 Sequence< OUString > TestImpl::getSupportedServiceNames()
473     throw (RuntimeException)
474 {
475     return benchmark_test::getSupportedServiceNames();
476 }
477 
478 //__________________________________________________________________________________________________
479 Reference< XInterface > TestImpl::getDirect()
480     throw (Exception)
481 {
482     if (! _xDirect.is())
483     {
484         MutexGuard aGuard( Mutex::getGlobalMutex() );
485         if (! _xDirect.is())
486         {
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();
494         }
495     }
496     return _xDirect;
497 }
498 //--------------------------------------------------------------------------------------------------
499 Reference< XInterface > TestImpl::resolveObject( const OUString & rUnoUrl )
500     throw (Exception)
501 {
502     Reference< XUnoUrlResolver > xResolver;
503     createInstance(
504         xResolver, _xSMgr,
505         OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.bridge.UnoUrlResolver") ) );
506 
507     Reference< XInterface > xResolvedObject( xResolver->resolve( rUnoUrl ) );
508 
509     if (! xResolvedObject.is())
510     {
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 >() );
516     }
517 
518     return xResolvedObject;
519 }
520 
521 //==================================================================================================
522 class TimeEntry
523 {
524     sal_Int64           nLoop;
525     sal_uInt32          nTicks;
526 
527 public:
528     TimeEntry()
529         {}
530     TimeEntry( sal_Int64 nLoop_, sal_uInt32 nTicks_ )
531         : nLoop( nLoop_ )
532         , nTicks( nTicks_ )
533         {}
534 
535     inline double secPerCall() const
536         { return (((double)nTicks) / (nLoop * 1000)); }
537 
538     double ratio( const TimeEntry & rEntry ) const;
539 };
540 //__________________________________________________________________________________________________
541 double TimeEntry::ratio( const TimeEntry & rEntry ) const
542 {
543     double f = rEntry.nTicks * nLoop;
544     if (f == 0.0)
545     {
546         return 0.0;
547     }
548     else
549     {
550         return (((double)(nTicks * rEntry.nLoop)) / f);
551     }
552 }
553 
554 //==================================================================================================
555 typedef std::map< std::string, TimeEntry > t_TimeEntryMap;
556 
557 //==================================================================================================
558 struct TimingSheet
559 {
560     t_TimeEntryMap      _entries;
561     void insert( const sal_Char * pText, sal_Int64 nLoop, sal_uInt32 nTicks );
562 };
563 //__________________________________________________________________________________________________
564 void TimingSheet::insert( const sal_Char * pText, sal_Int64 nLoop, sal_uInt32 nTicks )
565 {
566     _entries[ pText ] = TimeEntry( nLoop, nTicks );
567 }
568 
569 //==================================================================================================
570 typedef std::hash_map< std::string, TimingSheet > t_TimingSheetMap;
571 
572 //--------------------------------------------------------------------------------------------------
573 static void benchmark(
574     TimingSheet & rSheet, const Reference< XInterface > & xInstance, sal_Int64 nLoop )
575     throw (Exception)
576 {
577     Reference< XPerformanceTest > xBench( xInstance, UNO_QUERY );
578     if (! xBench.is())
579         throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("illegal test object!") ), Reference< XInterface >() );
580 
581     sal_Int64 i;
582     sal_uInt32 tStart, tEnd;
583 
584     const Type & rKnownType = ::getCppuType( (const Reference< XPerformanceTest > *)0 );
585     const Type & rUnKnownType = ::getCppuType( (const Reference< XSet > *)0 );
586 
587     ComplexTypes aDummyStruct;
588 
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 );
608 
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 );
623 
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 );
638 
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 );
647 
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 );
658 
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 );
672 
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 );
685 
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 );
699 
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 );
712 
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 );
725 
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 );
738 
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 );
751 
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 );
764 
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 );
789 
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 );
802 
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 );
816 
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 );
829 
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 );
843 
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 );
856 
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 );
870 
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 );
896 
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 );
909 
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 );
922 
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 );
930 
931     // exceptions
932     i = nLoop;
933     tStart = getSystemTicks();
934     while (i--)
935     {
936         try
937         {
938             xBench->raiseRuntimeException();
939         }
940         catch (RuntimeException &)
941         {
942         }
943     }
944     tEnd = getSystemTicks();
945     rSheet.insert( "Ba: raising RuntimeException", nLoop, tEnd - tStart );
946 
947     //------------------------------------
948 }
949 
950 //--------------------------------------------------------------------------------------------------
951 static OUString extractParam( const Sequence< OUString > & rArgs, const OUString & rParam )
952 {
953     const OUString * pArgs = rArgs.getConstArray();
954     for ( sal_Int32 nPos = rArgs.getLength(); nPos--; )
955     {
956         if (pArgs[nPos].indexOf( rParam ) == 0 &&
957             pArgs[nPos].getLength() > (rParam.getLength()+1))
958         {
959             return pArgs[nPos].copy( rParam.getLength() +1 ); // XXX=bla
960         }
961     }
962     return OUString();
963 }
964 
965 const sal_Int32 nMagicNumberDirect = 34000;
966 
967 //XMain
968 //__________________________________________________________________________________________________
969 sal_Int32 TestImpl::run( const Sequence< OUString > & rArgs )
970     throw (RuntimeException)
971 {
972     // defaults
973     FILE * stream = stderr;
974     sal_Int64 nLoop = NLOOP;
975     OUString aArg( RTL_CONSTASCII_USTRINGPARAM("dms") );
976 
977     try
978     {
979         OUString aLoopStr( extractParam( rArgs, OUString( RTL_CONSTASCII_USTRINGPARAM("loop") ) ) );
980         if (aLoopStr.getLength())
981         {
982             sal_Int64 n = aLoopStr.toInt64();
983             if (n > 0)
984                 nLoop = n;
985         }
986 
987         OUString aDurationStr( extractParam( rArgs , OUString( RTL_CONSTASCII_USTRINGPARAM("duration" ) ) ) );
988         if( aDurationStr.getLength() )
989         {
990             sal_Int64 n = aDurationStr.toInt64();
991             if( n >0 )
992                 nLoop = nMagicNumberDirect * n;
993         }
994 
995         OUString aLogStr( extractParam( rArgs, OUString( RTL_CONSTASCII_USTRINGPARAM("log") ) ) );
996         if (aLogStr.getLength())
997         {
998             if (aLogStr.compareToAscii( "stderr" ) == 0)
999             {
1000                 stream = stderr;
1001             }
1002             else if (aLogStr.compareToAscii( "stdout" ) == 0)
1003             {
1004                 stream = stdout;
1005             }
1006             else
1007             {
1008                 OString aFileName( OUStringToOString( aLogStr, RTL_TEXTENCODING_ASCII_US ) );
1009                 stream = ::fopen( aFileName.getStr(), "w" );
1010                 if (! stream)
1011                 {
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 >() );
1017                 }
1018             }
1019         }
1020 
1021         OUString aArgStr( extractParam( rArgs, OUString( RTL_CONSTASCII_USTRINGPARAM("opt") ) ) );
1022         if (aArgStr.getLength())
1023         {
1024             aArg = aArgStr;
1025         }
1026 
1027         if (! rArgs.getLength())
1028             out( "\n> no options given, using defaults" );
1029 
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;
1045 
1046         //------------------------------------------------------------------------------------------
1047 
1048         if (aArg.indexOf( 'd' ) >= 0)
1049         {
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.  );
1055         }
1056 
1057         //------------------------------------------------------------------------------------------
1058 
1059         if (aArg.indexOf( 'm' ) >= 0)
1060         {
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 );
1069 
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 >() );
1074 
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 >() );
1081 
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. );
1086         }
1087 
1088         //------------------------------------------------------------------------------------------
1089 
1090         if (aArg.indexOf( 's' ) >= 0)
1091         {
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 >() );
1096 
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") )
1111             };
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,
1123             };
1124 
1125             out( "\n> executing: \"uno" );
1126             for ( sal_Int32 nPos = 0; nPos < (sizeof(aArgs) / sizeof(OUString)); ++nPos )
1127             {
1128                 out( " " );
1129                 out( aArgs[nPos] );
1130             }
1131             out( "\" ..." );
1132 
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 );
1140 
1141             osl_freeSecurityHandle( hSecurity );
1142             if (! hProcess)
1143                 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("cannot start server process!") ), Reference< XInterface >() );
1144             osl_freeProcessHandle( hProcess );
1145 
1146             // wait three seconds
1147             TimeValue threeSeconds;
1148             threeSeconds.Seconds = 3;
1149             osl_waitThread( &threeSeconds );
1150 
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") ) ) );
1154 
1155             benchmark( aSheets[ "remote same host" ], xResolvedObject, nLoop / 300 );
1156         }
1157 
1158         //------------------------------------------------------------------------------------------
1159 
1160         if (aArg.indexOf( 'r' ) >= 0)
1161         {
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 >() );
1166 
1167             // connect and resolve outer process object
1168             Reference< XInterface > xResolvedObject( resolveObject( aUnoUrl ) );
1169 
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. );
1175         }
1176 
1177         //------------------------------------------------------------------------------------------
1178 
1179         if (aArg.indexOf( 'j' ) >= 0)
1180         {
1181             // java
1182             benchmark( aSheets[ "java in process" ],
1183                        _xSMgr->createInstance(OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.benchmark.JavaTestObject"))),
1184                        nLoop / 1000 );
1185         }
1186 
1187         //------------------------------------------------------------------------------------------
1188         // dump out tables
1189 
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 );
1195 
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 )
1200         {
1201             nPos += 40;
1202             out( "[", stream, nPos );
1203             out( (*iSheets).first.c_str(), stream );
1204             out( "]", stream );
1205         }
1206         for ( t_TimeEntryMap::const_iterator iTopics( aDirect._entries.begin() );
1207               iTopics != aDirect._entries.end(); ++iTopics )
1208         {
1209             const std::string & rTopic = (*iTopics).first;
1210 
1211             out( "\n", stream );
1212             out( rTopic.c_str(), stream );
1213 
1214             out( ":", stream, 58, '.' );
1215 
1216             sal_Int32 nPos = 60;
1217 
1218             double secs = (*iTopics).second.secPerCall();
1219             if (secs > 0.0)
1220             {
1221                 out( secs * 1000, stream, nPos );
1222                 out( "ms", stream );
1223             }
1224             else
1225             {
1226                 out( "NA", stream, nPos );
1227             }
1228 
1229             iSheets = aSheets.begin();
1230             for ( ; iSheets != aSheets.end(); ++iSheets )
1231             {
1232                 const t_TimeEntryMap::const_iterator iFind( (*iSheets).second._entries.find( rTopic ) );
1233                 OSL_ENSURE( iFind != (*iSheets).second._entries.end(), "####" );
1234 
1235                 nPos += 40;
1236 
1237                 double secs = (*iFind).second.secPerCall();
1238                 if (secs != 0.0)
1239                 {
1240                     out( secs * 1000, stream, nPos );
1241                     out( "ms", stream );
1242 
1243                     out( " (", stream );
1244                     double ratio = (*iFind).second.ratio( (*iTopics).second );
1245                     if (ratio != 0.0)
1246                     {
1247                         out( ratio, stream );
1248                         out( " x)", stream );
1249                     }
1250                     else
1251                     {
1252                         out( "NA)", stream );
1253                     }
1254                 }
1255                 else
1256                 {
1257                     out( "NA", stream, nPos );
1258                 }
1259             }
1260         }
1261     }
1262     catch (Exception & rExc)
1263     {
1264         if (stream != stderr && stream != stdout)
1265             ::fclose( stream );
1266         throw RuntimeException( rExc.Message, rExc.Context );
1267     }
1268 
1269     if (stream != stderr && stream != stdout)
1270         ::fclose( stream );
1271 
1272     out( "\n> done.\n" );
1273     return 0;
1274 }
1275 
1276 }
1277 
1278 
1279 //##################################################################################################
1280 //##################################################################################################
1281 //##################################################################################################
1282 
1283 
1284 extern "C"
1285 {
1286 //==================================================================================================
1287 void SAL_CALL component_getImplementationEnvironment(
1288     const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv )
1289 {
1290     *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
1291 }
1292 //==================================================================================================
1293 sal_Bool SAL_CALL component_writeInfo(
1294     void * pServiceManager, void * pRegistryKey )
1295 {
1296     if (pRegistryKey)
1297     {
1298         try
1299         {
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) ) );
1304 
1305             return sal_True;
1306         }
1307         catch (InvalidRegistryException &)
1308         {
1309             OSL_ENSURE( sal_False, "### InvalidRegistryException!" );
1310         }
1311     }
1312     return sal_False;
1313 }
1314 //==================================================================================================
1315 void * SAL_CALL component_getFactory(
1316     const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey )
1317 {
1318     void * pRet = 0;
1319 
1320     if (pServiceManager && rtl_str_compare( pImplName, IMPLNAME ) == 0)
1321     {
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() ) );
1327 
1328         if (xFactory.is())
1329         {
1330             xFactory->acquire();
1331             pRet = xFactory.get();
1332         }
1333     }
1334 
1335     return pRet;
1336 }
1337 }
1338