xref: /AOO41X/main/testtools/source/performance/ubtest.cxx (revision d48fe8487b35dbcb65150b3b6c4d21d39e83cf4c)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_testtools.hxx"
26 
27 #include <stdio.h>
28 #include <math.h>
29 #include <string>
30 #include <hash_map>
31 #include <map>
32 
33 #include <osl/diagnose.h>
34 #include <osl/mutex.hxx>
35 #include <osl/module.h>
36 #include <osl/process.h>
37 #include <osl/thread.h>
38 #include <osl/conditn.hxx>
39 #include <osl/time.h>
40 
41 #ifdef SAL_W32
42 #include <windows.h>
43 #else
44 #include <sys/times.h>
45 #include <unistd.h>
46 #endif
47 
48 #include <rtl/string.hxx>
49 #include <rtl/strbuf.hxx>
50 #include <rtl/ustrbuf.hxx>
51 
52 #include <uno/environment.hxx>
53 #include <uno/mapping.hxx>
54 
55 #include <cppuhelper/factory.hxx>
56 #include <cppuhelper/implbase2.hxx>
57 
58 #include <com/sun/star/lang/XServiceInfo.hpp>
59 #include <com/sun/star/lang/XComponent.hpp>
60 #include <com/sun/star/lang/XMain.hpp>
61 #include <com/sun/star/lang/XInitialization.hpp>
62 #include <com/sun/star/loader/XImplementationLoader.hpp>
63 #include <com/sun/star/registry/XRegistryKey.hpp>
64 #include <com/sun/star/bridge/XUnoUrlResolver.hpp>
65 #include <com/sun/star/container/XSet.hpp>
66 #include <com/sun/star/test/performance/XPerformanceTest.hpp>
67 
68 #define NLOOP 200000000
69 
70 using namespace rtl;
71 using namespace osl;
72 using namespace cppu;
73 using namespace com::sun::star::uno;
74 using namespace com::sun::star::lang;
75 using namespace com::sun::star::loader;
76 using namespace com::sun::star::registry;
77 using namespace com::sun::star::bridge;
78 using namespace com::sun::star::container;
79 using namespace com::sun::star::test::performance;
80 
81 #define SERVICENAME     "com.sun.star.test.performance.PerformanceTest"
82 #define IMPLNAME        "com.sun.star.comp.performance.PerformanceTest"
83 
84 namespace benchmark_test
85 {
86 
getSystemTicks()87 static inline sal_uInt32 getSystemTicks()
88 {
89 #ifdef SAL_W32
90     return (sal_uInt32)GetTickCount();
91 #else // only UNX supported for now
92     static sal_uInt32   nImplTicksPerSecond = 0;
93     static double       dImplTicksPerSecond;
94     static double       dImplTicksULONGMAX;
95 
96     struct tms          aTms;
97     sal_uInt32 nTicks = (sal_uInt32)times( &aTms );
98 
99     if ( !nImplTicksPerSecond )
100     {
101         nImplTicksPerSecond = sysconf(_SC_CLK_TCK);
102         dImplTicksPerSecond = nImplTicksPerSecond;
103         dImplTicksULONGMAX  = (double)(sal_uInt32)ULONG_MAX;
104     }
105 
106     double fTicks = nTicks;
107     fTicks *= 1000;
108     fTicks /= dImplTicksPerSecond;
109     fTicks = fmod (fTicks, dImplTicksULONGMAX);
110 
111     return (sal_uInt32)fTicks;
112 #endif
113 }
114 
115 //--------------------------------------------------------------------------------------------------
out(const sal_Char * pText,FILE * stream=stderr,sal_Int32 nStart=-1,sal_Char cFillchar=' ')116 static void out( const sal_Char * pText, FILE * stream = stderr,
117                  sal_Int32 nStart = -1, sal_Char cFillchar = ' ' )
118 {
119     static sal_Int32 s_nPos = 0;
120 
121     sal_Char ar[2] = { cFillchar, 0 };
122     while (s_nPos < nStart)
123     {
124         ::fprintf( stream, ar );
125         ++s_nPos;
126     }
127 
128     ::fprintf( stream, pText );
129 
130     for ( const sal_Char * p = pText; *p; ++p )
131     {
132         if (*p == '\n')
133             s_nPos = 0;
134         else
135             ++s_nPos;
136     }
137 }
138 //--------------------------------------------------------------------------------------------------
out(const OUString & rText,FILE * stream=stderr,sal_Int32 nStart=-1,sal_Char cFillchar=' ')139 static inline void out( const OUString & rText, FILE * stream = stderr,
140                         sal_Int32 nStart = -1, sal_Char cFillchar = ' ' )
141 {
142     OString aText( OUStringToOString( rText, RTL_TEXTENCODING_ASCII_US ) );
143     out( aText.getStr(), stream, nStart, cFillchar );
144 }
145 //--------------------------------------------------------------------------------------------------
out(double fVal,FILE * stream=stderr,sal_Int32 nStart=-1,sal_Char cFillchar=' ')146 static inline void out( double fVal, FILE * stream = stderr,
147                         sal_Int32 nStart = -1, sal_Char cFillchar = ' ' )
148 {
149     sal_Char ar[128];
150     ::snprintf( ar, sizeof(ar), (fVal < 0.000001 ? "%g" : "%f"), fVal );
151     out( ar, stream, nStart, cFillchar );
152 }
153 //--------------------------------------------------------------------------------------------------
out(sal_Int64 nVal,FILE * stream=stderr,sal_Int32 nStart=-1,sal_Char cFillchar=' ')154 static inline void out( sal_Int64 nVal, FILE * stream = stderr,
155                         sal_Int32 nStart = -1, sal_Char cFillchar = ' ' )
156 {
157     sal_Char ar[128];
158     ::snprintf( ar, sizeof(ar), "%ld", nVal );
159     out( ar, stream, nStart, cFillchar );
160 }
161 
162 //==================================================================================================
loadLibComponentFactory(const OUString & rLibName,const OUString & rImplName,const Reference<XMultiServiceFactory> & xSF,const Reference<XRegistryKey> & xKey)163 Reference< XSingleServiceFactory > loadLibComponentFactory(
164     const OUString & rLibName, const OUString & rImplName,
165     const Reference< XMultiServiceFactory > & xSF, const Reference< XRegistryKey > & xKey )
166 {
167     Reference< XSingleServiceFactory > xRet;
168 
169     OUStringBuffer aLibNameBuf( 32 );
170 #ifdef SAL_UNX
171     aLibNameBuf.appendAscii( RTL_CONSTASCII_STRINGPARAM("lib") );
172     aLibNameBuf.append( rLibName );
173     aLibNameBuf.appendAscii( RTL_CONSTASCII_STRINGPARAM(".so") );
174 #else
175     aLibNameBuf.append( rLibName );
176     aLibNameBuf.appendAscii( RTL_CONSTASCII_STRINGPARAM(".dll") );
177 #endif
178     OUString aLibName( aLibNameBuf.makeStringAndClear() );
179     oslModule lib = osl_loadModule( aLibName.pData, SAL_LOADMODULE_LAZY | SAL_LOADMODULE_GLOBAL );
180 
181     if (lib)
182     {
183         void * pSym;
184 
185         // ========================= LATEST VERSION =========================
186         OUString aGetEnvName( RTL_CONSTASCII_USTRINGPARAM(COMPONENT_GETENV) );
187         if (pSym = osl_getSymbol( lib, aGetEnvName.pData ))
188         {
189             uno_Environment * pCurrentEnv = 0;
190             uno_Environment * pEnv = 0;
191             const sal_Char * pEnvTypeName = 0;
192             (*((component_getImplementationEnvironmentFunc)pSym))( &pEnvTypeName, &pEnv );
193 
194             sal_Bool bNeedsMapping =
195                 (pEnv || 0 != rtl_str_compare( pEnvTypeName, CPPU_CURRENT_LANGUAGE_BINDING_NAME ));
196 
197             OUString aEnvTypeName( OUString::createFromAscii( pEnvTypeName ) );
198 
199             if (bNeedsMapping)
200             {
201                 if (! pEnv)
202                     uno_getEnvironment( &pEnv, aEnvTypeName.pData, 0 );
203                 if (pEnv)
204                 {
205                     OUString aCppEnvTypeName( RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME) );
206                     uno_getEnvironment( &pCurrentEnv, aCppEnvTypeName.pData, 0 );
207                     if (pCurrentEnv)
208                         bNeedsMapping = (pEnv != pCurrentEnv);
209                 }
210             }
211 
212             OUString aGetFactoryName( RTL_CONSTASCII_USTRINGPARAM(COMPONENT_GETFACTORY) );
213             if (pSym = osl_getSymbol( lib, aGetFactoryName.pData ))
214             {
215                 OString aImplName( OUStringToOString( rImplName, RTL_TEXTENCODING_ASCII_US ) );
216 
217                 if (bNeedsMapping)
218                 {
219                     if (pEnv && pCurrentEnv)
220                     {
221                         Mapping aCurrent2Env( pCurrentEnv, pEnv );
222                         Mapping aEnv2Current( pEnv, pCurrentEnv );
223 
224                         if (aCurrent2Env.is() && aEnv2Current.is())
225                         {
226                             void * pSMgr = aCurrent2Env.mapInterface(
227                                 xSF.get(), ::getCppuType( (const Reference< XMultiServiceFactory > *)0 ) );
228                             void * pKey = aCurrent2Env.mapInterface(
229                                 xKey.get(), ::getCppuType( (const Reference< XRegistryKey > *)0 ) );
230 
231                             void * pSSF = (*((component_getFactoryFunc)pSym))(
232                                 aImplName.getStr(), pSMgr, pKey );
233 
234                             if (pKey)
235                                 (*pEnv->pExtEnv->releaseInterface)( pEnv->pExtEnv, pKey );
236                             if (pSMgr)
237                                 (*pEnv->pExtEnv->releaseInterface)( pEnv->pExtEnv, pSMgr );
238 
239                             if (pSSF)
240                             {
241                                 aEnv2Current.mapInterface(
242                                     reinterpret_cast< void ** >( &xRet ),
243                                     pSSF, ::getCppuType( (const Reference< XSingleServiceFactory > *)0 ) );
244                                 (*pEnv->pExtEnv->releaseInterface)( pEnv->pExtEnv, pSSF );
245                             }
246                         }
247                     }
248                 }
249                 else
250                 {
251                     XSingleServiceFactory * pRet = (XSingleServiceFactory *)
252                         (*((component_getFactoryFunc)pSym))(
253                             aImplName.getStr(), xSF.get(), xKey.get() );
254                     if (pRet)
255                     {
256                         xRet = pRet;
257                         pRet->release();
258                     }
259                 }
260             }
261 
262             if (pEnv)
263                 (*pEnv->release)( pEnv );
264             if (pCurrentEnv)
265                 (*pCurrentEnv->release)( pCurrentEnv );
266         }
267 
268         // ========================= PREVIOUS VERSION =========================
269         else
270         {
271             OUString aGetFactoryName( RTL_CONSTASCII_USTRINGPARAM(CREATE_COMPONENT_FACTORY_FUNCTION) );
272             if (pSym = osl_getSymbol( lib, aGetFactoryName.pData ))
273             {
274                 OUString aCppEnvTypeName( RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME) );
275                 OUString aUnoEnvTypeName( RTL_CONSTASCII_USTRINGPARAM(UNO_LB_UNO) );
276                 Mapping aUno2Cpp( aUnoEnvTypeName, aCppEnvTypeName );
277                 Mapping aCpp2Uno( aCppEnvTypeName, aUnoEnvTypeName );
278                 OSL_ENSURE( aUno2Cpp.is() && aCpp2Uno.is(), "### cannot get uno mappings!" );
279 
280                 if (aUno2Cpp.is() && aCpp2Uno.is())
281                 {
282                     uno_Interface * pUComponentFactory = 0;
283 
284                     uno_Interface * pUSFactory = (uno_Interface *)aCpp2Uno.mapInterface(
285                         xSF.get(), ::getCppuType( (const Reference< XMultiServiceFactory > *)0 ) );
286                     uno_Interface * pUKey = (uno_Interface *)aCpp2Uno.mapInterface(
287                         xKey.get(), ::getCppuType( (const Reference< XRegistryKey > *)0 ) );
288 
289                     pUComponentFactory = (*((CreateComponentFactoryFunc)pSym))(
290                         rImplName.getStr(), pUSFactory, pUKey );
291 
292                     if (pUKey)
293                         (*pUKey->release)( pUKey );
294                     if (pUSFactory)
295                         (*pUSFactory->release)( pUSFactory );
296 
297                     if (pUComponentFactory)
298                     {
299                         XSingleServiceFactory * pXFactory =
300                             (XSingleServiceFactory *)aUno2Cpp.mapInterface(
301                                 pUComponentFactory, ::getCppuType( (const Reference< XSingleServiceFactory > *)0 ) );
302                         (*pUComponentFactory->release)( pUComponentFactory );
303 
304                         if (pXFactory)
305                         {
306                             xRet = pXFactory;
307                             pXFactory->release();
308                         }
309                     }
310                 }
311             }
312         }
313 
314         if (! xRet.is())
315             osl_unloadModule( lib );
316     }
317 
318     return xRet;
319 }
320 //--------------------------------------------------------------------------------------------------
321 template< class T >
createInstance(Reference<T> & rxOut,const Reference<XMultiServiceFactory> & xMgr,const OUString & rServiceName)322 static void createInstance( Reference< T > & rxOut,
323                             const Reference< XMultiServiceFactory > & xMgr,
324                             const OUString & rServiceName )
325     throw (RuntimeException)
326 {
327     Reference< XInterface > x( xMgr->createInstance( rServiceName ), UNO_QUERY );
328 
329     if (! x.is())
330     {
331         static sal_Bool s_bSet = sal_False;
332         if (! s_bSet)
333         {
334             MutexGuard aGuard( Mutex::getGlobalMutex() );
335             if (! s_bSet)
336             {
337                 Reference< XSet > xSet( xMgr, UNO_QUERY );
338                 if (xSet.is())
339                 {
340                     // acceptor
341                     xSet->insert( makeAny( loadLibComponentFactory(
342                         OUString( RTL_CONSTASCII_USTRINGPARAM("acceptor") ),
343                         OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.stoc.Acceptor") ),
344                         xMgr, Reference< XRegistryKey >() ) ) );
345                     // connector
346                     xSet->insert( makeAny( loadLibComponentFactory(
347                         OUString( RTL_CONSTASCII_USTRINGPARAM("connectr") ),
348                         OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.stoc.Connector") ),
349                         xMgr, Reference< XRegistryKey >() ) ) );
350                     // iiop bridge
351                     xSet->insert( makeAny( loadLibComponentFactory(
352                         OUString( RTL_CONSTASCII_USTRINGPARAM("remotebridge") ),
353                         OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.bridge.Bridge.various") ),
354                         xMgr, Reference< XRegistryKey >() ) ) );
355                     // bridge factory
356                     xSet->insert( makeAny( loadLibComponentFactory(
357                         OUString( RTL_CONSTASCII_USTRINGPARAM("brdgfctr") ),
358                         OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.stoc.BridgeFactory") ),
359                         xMgr, Reference< XRegistryKey >() ) ) );
360                     // uno url resolver
361                     xSet->insert( makeAny( loadLibComponentFactory(
362                         OUString( RTL_CONSTASCII_USTRINGPARAM("uuresolver") ),
363                         OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.bridge.UnoUrlResolver") ),
364                         xMgr, Reference< XRegistryKey >() ) ) );
365                     // java loader
366 //                      xSet->insert( makeAny( loadLibComponentFactory(
367 //                          OUString( RTL_CONSTASCII_USTRINGPARAM("javaloader") ),
368 //                          OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.stoc.JavaComponentLoader") ),
369 //                          xMgr, Reference< XRegistryKey >() ) ) );
370                 }
371                 s_bSet = sal_True;
372             }
373         }
374         x = xMgr->createInstance( rServiceName );
375     }
376 
377     if (! x.is())
378     {
379         OUStringBuffer buf( 64 );
380         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("cannot get service instance \"") );
381         buf.append( rServiceName );
382         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!") );
383         throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() );
384     }
385 
386     rxOut = Reference< T >::query( x );
387     if (! rxOut.is())
388     {
389         OUStringBuffer buf( 64 );
390         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("service instance \"") );
391         buf.append( rServiceName );
392         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" does not support demanded interface \"") );
393         const Type & rType = ::getCppuType( (const Reference< T > *)0 );
394         buf.append( rType.getTypeName() );
395         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!") );
396         throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() );
397     }
398 }
399 
400 //--------------------------------------------------------------------------------------------------
getSupportedServiceNames()401 inline static Sequence< OUString > getSupportedServiceNames()
402 {
403     OUString aName( RTL_CONSTASCII_USTRINGPARAM(SERVICENAME) );
404     return Sequence< OUString >( &aName, 1 );
405 }
406 
407 //==================================================================================================
408 class TestImpl : public WeakImplHelper2< XServiceInfo, XMain >
409 {
410     Reference< XMultiServiceFactory > _xSMgr;
411 
412     Reference< XInterface > _xDirect;
413     Reference< XInterface > getDirect() throw (Exception);
414     Reference< XInterface > resolveObject( const OUString & rUnoUrl ) throw (Exception);
415 
416 public:
417     TestImpl( const Reference< XMultiServiceFactory > & xSMgr );
418     virtual ~TestImpl();
419 
420     // XServiceInfo
421     virtual OUString SAL_CALL getImplementationName() throw (RuntimeException);
422     virtual sal_Bool SAL_CALL supportsService( const OUString & rServiceName ) throw (RuntimeException);
423     virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw (RuntimeException);
424 
425     // XMain
426     virtual sal_Int32 SAL_CALL run( const Sequence< OUString > & rArgs ) throw (RuntimeException);
427 };
428 
429 //##################################################################################################
430 
431 //__________________________________________________________________________________________________
TestImpl(const Reference<XMultiServiceFactory> & xSMgr)432 TestImpl::TestImpl( const Reference< XMultiServiceFactory > & xSMgr )
433     : _xSMgr( xSMgr )
434 {
435 }
436 //__________________________________________________________________________________________________
~TestImpl()437 TestImpl::~TestImpl()
438 {
439 }
440 
441 //==================================================================================================
TestImpl_create(const Reference<XMultiServiceFactory> & xSMgr)442 static Reference< XInterface > SAL_CALL TestImpl_create( const Reference< XMultiServiceFactory > & xSMgr )
443 {
444     return Reference< XInterface >( *new TestImpl( xSMgr ) );
445 }
446 
447 // XServiceInfo
448 //__________________________________________________________________________________________________
getImplementationName()449 OUString TestImpl::getImplementationName()
450     throw (RuntimeException)
451 {
452     return OUString( RTL_CONSTASCII_USTRINGPARAM(IMPLNAME) );
453 }
454 //__________________________________________________________________________________________________
supportsService(const OUString & rServiceName)455 sal_Bool TestImpl::supportsService( const OUString & rServiceName )
456     throw (RuntimeException)
457 {
458     const Sequence< OUString > & rSNL = getSupportedServiceNames();
459     const OUString * pArray = rSNL.getConstArray();
460     for ( sal_Int32 nPos = rSNL.getLength(); nPos--; )
461     {
462         if (pArray[nPos] == rServiceName)
463             return sal_True;
464     }
465     return sal_False;
466 }
467 //__________________________________________________________________________________________________
getSupportedServiceNames()468 Sequence< OUString > TestImpl::getSupportedServiceNames()
469     throw (RuntimeException)
470 {
471     return benchmark_test::getSupportedServiceNames();
472 }
473 
474 //__________________________________________________________________________________________________
getDirect()475 Reference< XInterface > TestImpl::getDirect()
476     throw (Exception)
477 {
478     if (! _xDirect.is())
479     {
480         MutexGuard aGuard( Mutex::getGlobalMutex() );
481         if (! _xDirect.is())
482         {
483             Reference< XSingleServiceFactory > xFac( loadLibComponentFactory(
484                 OUString( RTL_CONSTASCII_USTRINGPARAM("perfobj") ),
485                 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.performance.PerformanceTestObject") ),
486                 _xSMgr, Reference< XRegistryKey >() ) );
487             if (! xFac.is())
488                 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("no test object available!") ), Reference< XInterface >() );
489             _xDirect = xFac->createInstance();
490         }
491     }
492     return _xDirect;
493 }
494 //--------------------------------------------------------------------------------------------------
resolveObject(const OUString & rUnoUrl)495 Reference< XInterface > TestImpl::resolveObject( const OUString & rUnoUrl )
496     throw (Exception)
497 {
498     Reference< XUnoUrlResolver > xResolver;
499     createInstance(
500         xResolver, _xSMgr,
501         OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.bridge.UnoUrlResolver") ) );
502 
503     Reference< XInterface > xResolvedObject( xResolver->resolve( rUnoUrl ) );
504 
505     if (! xResolvedObject.is())
506     {
507         OUStringBuffer buf( 32 );
508         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("cannot resolve object \"") );
509         buf.append( rUnoUrl );
510         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!") );
511         throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() );
512     }
513 
514     return xResolvedObject;
515 }
516 
517 //==================================================================================================
518 class TimeEntry
519 {
520     sal_Int64           nLoop;
521     sal_uInt32          nTicks;
522 
523 public:
TimeEntry()524     TimeEntry()
525         {}
TimeEntry(sal_Int64 nLoop_,sal_uInt32 nTicks_)526     TimeEntry( sal_Int64 nLoop_, sal_uInt32 nTicks_ )
527         : nLoop( nLoop_ )
528         , nTicks( nTicks_ )
529         {}
530 
secPerCall() const531     inline double secPerCall() const
532         { return (((double)nTicks) / (nLoop * 1000)); }
533 
534     double ratio( const TimeEntry & rEntry ) const;
535 };
536 //__________________________________________________________________________________________________
ratio(const TimeEntry & rEntry) const537 double TimeEntry::ratio( const TimeEntry & rEntry ) const
538 {
539     double f = rEntry.nTicks * nLoop;
540     if (f == 0.0)
541     {
542         return 0.0;
543     }
544     else
545     {
546         return (((double)(nTicks * rEntry.nLoop)) / f);
547     }
548 }
549 
550 //==================================================================================================
551 typedef std::map< std::string, TimeEntry > t_TimeEntryMap;
552 
553 //==================================================================================================
554 struct TimingSheet
555 {
556     t_TimeEntryMap      _entries;
557     void insert( const sal_Char * pText, sal_Int64 nLoop, sal_uInt32 nTicks );
558 };
559 //__________________________________________________________________________________________________
insert(const sal_Char * pText,sal_Int64 nLoop,sal_uInt32 nTicks)560 void TimingSheet::insert( const sal_Char * pText, sal_Int64 nLoop, sal_uInt32 nTicks )
561 {
562     _entries[ pText ] = TimeEntry( nLoop, nTicks );
563 }
564 
565 //==================================================================================================
566 typedef std::hash_map< std::string, TimingSheet > t_TimingSheetMap;
567 
568 //--------------------------------------------------------------------------------------------------
benchmark(TimingSheet & rSheet,const Reference<XInterface> & xInstance,sal_Int64 nLoop)569 static void benchmark(
570     TimingSheet & rSheet, const Reference< XInterface > & xInstance, sal_Int64 nLoop )
571     throw (Exception)
572 {
573     Reference< XPerformanceTest > xBench( xInstance, UNO_QUERY );
574     if (! xBench.is())
575         throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("illegal test object!") ), Reference< XInterface >() );
576 
577     sal_Int64 i;
578     sal_uInt32 tStart, tEnd;
579 
580     const Type & rKnownType = ::getCppuType( (const Reference< XPerformanceTest > *)0 );
581     const Type & rUnKnownType = ::getCppuType( (const Reference< XSet > *)0 );
582 
583     ComplexTypes aDummyStruct;
584 
585     //------------------------------------
586     // oneway calls
587     i = nLoop;
588     tStart = getSystemTicks();
589     while (i--)
590         xBench->async();
591     sal_uInt32 tEndSend = getSystemTicks();
592     xBench->sync();
593     tEnd = getSystemTicks();
594     rSheet.insert( "1a: sending simple oneway calls (no params, no return)", nLoop, tEndSend - tStart );
595     rSheet.insert( "1b: simple oneway calls (no params, no return)", nLoop, tEnd - tStart );
596     // synchron calls
597     i = nLoop;
598     tStart = getSystemTicks();
599     while (i--)
600         xBench->sync();
601     xBench->sync();
602     tEnd = getSystemTicks();
603     rSheet.insert( "1c: simple synchron calls (no params no return)", nLoop+1, tEnd - tStart );
604 
605     // acquire
606     i = nLoop;
607     tStart = getSystemTicks();
608     while (i--)
609         xBench->acquire();
610     tEnd = getSystemTicks();
611     rSheet.insert( "2a: interface acquire() calls", nLoop, tEnd - tStart );
612     // release
613     i = nLoop;
614     tStart = getSystemTicks();
615     while (i--)
616         xBench->release();
617     tEnd = getSystemTicks();
618     rSheet.insert( "2b: interface release() calls", nLoop, tEnd - tStart );
619 
620     // queryInterface() for known type
621     i = nLoop;
622     tStart = getSystemTicks();
623     while (i--)
624         xBench->queryInterface( rKnownType );
625     tEnd = getSystemTicks();
626     rSheet.insert( "2c: interface query for implemented type", nLoop, tEnd - tStart );
627     // queryInterface() for unknown type
628     i = nLoop;
629     tStart = getSystemTicks();
630     while (i--)
631         xBench->queryInterface( rUnKnownType );
632     tEnd = getSystemTicks();
633     rSheet.insert( "2d: interface query for unknown type", nLoop, tEnd - tStart );
634 
635     // create and forget objects
636     Reference< XPerformanceTest > xBench2( xBench );
637     i = nLoop;
638     tStart = getSystemTicks();
639     while (i--)
640         xBench2 = xBench2->createObject();
641     tEnd = getSystemTicks();
642     rSheet.insert( "3a: create and release test objects", nLoop, tEnd - tStart );
643 
644     // hold new objects
645     Sequence< Reference< XInterface > > aSeq( nLoop / 100 );
646     Reference< XInterface > * pSeq = aSeq.getArray();
647     xBench2 = xBench;
648     i = aSeq.getLength();
649     tStart = getSystemTicks();
650     while (i--)
651         pSeq[i] = xBench2 = xBench2->createObject();
652     tEnd = getSystemTicks();
653     rSheet.insert( "3b: create and hold test objects", nLoop, tEnd - tStart );
654 
655     // structs
656     i = nLoop;
657     tStart = getSystemTicks();
658     while (i--)
659         xBench->complex_in( aDummyStruct );
660     tEnd = getSystemTicks();
661     rSheet.insert( "4a: complex_in() calls (in struct; return struct)", nLoop, tEnd - tStart );
662     i = nLoop;
663     tStart = getSystemTicks();
664     while (i--)
665         xBench->complex_inout( aDummyStruct );
666     tEnd = getSystemTicks();
667     rSheet.insert( "4b: complex_inout() calls (inout struct; return struct)", nLoop, tEnd - tStart );
668 
669     i = nLoop;
670     tStart = getSystemTicks();
671     while (i--)
672         xBench->complex_oneway( aDummyStruct );
673     tEnd = getSystemTicks();
674     rSheet.insert( "4c: complex_oneway() oneway calls (in struct)", nLoop, tEnd - tStart );
675     i = nLoop;
676     tStart = getSystemTicks();
677     while (i--)
678         xBench->complex_noreturn( aDummyStruct );
679     tEnd = getSystemTicks();
680     rSheet.insert( "4d: complex_noreturn() calls (in struct)", nLoop, tEnd - tStart );
681 
682     // attributes, get() methods
683     i = nLoop;
684     tStart = getSystemTicks();
685     while (i--)
686         xBench->getLong();
687     tEnd = getSystemTicks();
688     rSheet.insert( "5a: getLong() call", nLoop, tEnd - tStart );
689     i = nLoop;
690     tStart = getSystemTicks();
691     while (i--)
692         xBench->getLong_attr();
693     tEnd = getSystemTicks();
694     rSheet.insert( "5b: get long attribute", nLoop, tEnd - tStart );
695 
696     i = nLoop;
697     tStart = getSystemTicks();
698     while (i--)
699         xBench->setLong( 0 );
700     tEnd = getSystemTicks();
701     rSheet.insert( "5c: setLong() call", nLoop, tEnd - tStart );
702     i = nLoop;
703     tStart = getSystemTicks();
704     while (i--)
705         xBench->setLong_attr( 0 );
706     tEnd = getSystemTicks();
707     rSheet.insert( "5d: set long attribute", nLoop, tEnd - tStart );
708 
709     i = nLoop;
710     tStart = getSystemTicks();
711     while (i--)
712         xBench->getHyper();
713     tEnd = getSystemTicks();
714     rSheet.insert( "5e: getHyper() call", nLoop, tEnd - tStart );
715     i = nLoop;
716     tStart = getSystemTicks();
717     while (i--)
718         xBench->getHyper_attr();
719     tEnd = getSystemTicks();
720     rSheet.insert( "5f: get hyper attribute", nLoop, tEnd - tStart );
721 
722     i = nLoop;
723     tStart = getSystemTicks();
724     while (i--)
725         xBench->setHyper( 0 );
726     tEnd = getSystemTicks();
727     rSheet.insert( "5g: setHyper() call", nLoop, tEnd - tStart );
728     i = nLoop;
729     tStart = getSystemTicks();
730     while (i--)
731         xBench->setHyper_attr( 0 );
732     tEnd = getSystemTicks();
733     rSheet.insert( "5h: set hyper attribute", nLoop, tEnd - tStart );
734 
735     i = nLoop;
736     tStart = getSystemTicks();
737     while (i--)
738         xBench->getFloat();
739     tEnd = getSystemTicks();
740     rSheet.insert( "5i: getFloat() call", nLoop, tEnd - tStart );
741     i = nLoop;
742     tStart = getSystemTicks();
743     while (i--)
744         xBench->getFloat_attr();
745     tEnd = getSystemTicks();
746     rSheet.insert( "5j: get float attribute",nLoop,  tEnd - tStart );
747 
748     i = nLoop;
749     tStart = getSystemTicks();
750     while (i--)
751         xBench->setFloat( 0.0 );
752     tEnd = getSystemTicks();
753     rSheet.insert( "5k: setFloat() call", nLoop, tEnd - tStart );
754     i = nLoop;
755     tStart = getSystemTicks();
756     while (i--)
757         xBench->setFloat_attr( 0.0 );
758     tEnd = getSystemTicks();
759     rSheet.insert( "5l: set float attribute", nLoop, tEnd - tStart );
760 
761     i = nLoop;
762     tStart = getSystemTicks();
763     while (i--)
764         xBench->getDouble();
765     tEnd = getSystemTicks();
766     rSheet.insert( "5m: getDouble() call", nLoop, tEnd - tStart );
767     i = nLoop;
768     tStart = getSystemTicks();
769     while (i--)
770         xBench->getDouble_attr();
771     tEnd = getSystemTicks();
772     rSheet.insert( "5n: get double attribute", nLoop, tEnd - tStart );
773     i = nLoop;
774     tStart = getSystemTicks();
775     while (i--)
776         xBench->setDouble( 0.0 );
777     tEnd = getSystemTicks();
778     rSheet.insert( "5o: setDouble() call", nLoop, tEnd - tStart );
779     i = nLoop;
780     tStart = getSystemTicks();
781     while (i--)
782         xBench->setDouble_attr( 0.0 );
783     tEnd = getSystemTicks();
784     rSheet.insert( "5p: set double attribute", nLoop, tEnd - tStart );
785 
786     i = nLoop;
787     tStart = getSystemTicks();
788     while (i--)
789         xBench->getString();
790     tEnd = getSystemTicks();
791     rSheet.insert( "6a: getString() call (empty)", nLoop, tEnd - tStart );
792     i = nLoop;
793     tStart = getSystemTicks();
794     while (i--)
795         xBench->getString_attr();
796     tEnd = getSystemTicks();
797     rSheet.insert( "6b: get empty string attribute", nLoop, tEnd - tStart );
798 
799     i = nLoop;
800     OUString aDummyString;
801     tStart = getSystemTicks();
802     while (i--)
803         xBench->setString( aDummyString );
804     tEnd = getSystemTicks();
805     rSheet.insert( "6c: setString() call (emtpy)", nLoop, tEnd - tStart );
806     i = nLoop;
807     tStart = getSystemTicks();
808     while (i--)
809         xBench->setString_attr( aDummyString );
810     tEnd = getSystemTicks();
811     rSheet.insert( "6d: set empty string attribute", nLoop, tEnd - tStart );
812 
813     i = nLoop;
814     tStart = getSystemTicks();
815     while (i--)
816         xBench->getInterface();
817     tEnd = getSystemTicks();
818     rSheet.insert( "7a: getInterface() call (null)", nLoop, tEnd - tStart );
819     i = nLoop;
820     tStart = getSystemTicks();
821     while (i--)
822         xBench->getInterface_attr();
823     tEnd = getSystemTicks();
824     rSheet.insert( "7b: get interface attribute", nLoop, tEnd - tStart );
825 
826     i = nLoop;
827     Reference< XInterface > aDummyInterface;
828     tStart = getSystemTicks();
829     while (i--)
830         xBench->setInterface( aDummyInterface );
831     tEnd = getSystemTicks();
832     rSheet.insert( "7c: setInterface() call (null)", nLoop, tEnd - tStart );
833     i = nLoop;
834     tStart = getSystemTicks();
835     while (i--)
836         xBench->setInterface_attr( Reference< XInterface >() );
837     tEnd = getSystemTicks();
838     rSheet.insert( "7d: set interface attribute", nLoop, tEnd - tStart );
839 
840     i = nLoop;
841     tStart = getSystemTicks();
842     while (i--)
843         xBench->getAny();
844     tEnd = getSystemTicks();
845     rSheet.insert( "8a: getAny() call (empty)", nLoop, tEnd - tStart );
846     i = nLoop;
847     tStart = getSystemTicks();
848     while (i--)
849         xBench->getAny_attr();
850     tEnd = getSystemTicks();
851     rSheet.insert( "8b: get empty any attribute", nLoop, tEnd - tStart );
852 
853     i = nLoop;
854     Any aDummyAny;
855     tStart = getSystemTicks();
856     while (i--)
857         xBench->setAny( aDummyAny );
858     tEnd = getSystemTicks();
859     rSheet.insert( "8c: setAny() call (empty)", nLoop, tEnd - tStart );
860     i = nLoop;
861     tStart = getSystemTicks();
862     while (i--)
863         xBench->setAny_attr( aDummyAny );
864     tEnd = getSystemTicks();
865     rSheet.insert( "8d: set empty any attribute", nLoop, tEnd - tStart );
866 
867     i = nLoop;
868     tStart = getSystemTicks();
869     while (i--)
870         xBench->getSequence();
871     tEnd = getSystemTicks();
872     rSheet.insert( "9a: getSequence() call (empty)", nLoop, tEnd - tStart );
873     i = nLoop;
874     tStart = getSystemTicks();
875     while (i--)
876         xBench->getSequence_attr();
877     tEnd = getSystemTicks();
878     rSheet.insert( "9b: get empty sequence attribute", nLoop, tEnd - tStart );
879     i = nLoop;
880     Sequence< Reference< XInterface > > aDummySeq;
881     tStart = getSystemTicks();
882     while (i--)
883         xBench->setSequence( aDummySeq );
884     tEnd = getSystemTicks();
885     rSheet.insert( "9c: setSequence() call (empty)", nLoop, tEnd - tStart );
886     i = nLoop;
887     tStart = getSystemTicks();
888     while (i--)
889         xBench->setSequence_attr( aDummySeq );
890     tEnd = getSystemTicks();
891     rSheet.insert( "9d: set empty sequence attribute", nLoop, tEnd - tStart );
892 
893     i = nLoop;
894     tStart = getSystemTicks();
895     while (i--)
896         xBench->getStruct();
897     tEnd = getSystemTicks();
898     rSheet.insert( "Aa: getStruct() call", nLoop, tEnd - tStart );
899     i = nLoop;
900     tStart = getSystemTicks();
901     while (i--)
902         xBench->getStruct_attr();
903     tEnd = getSystemTicks();
904     rSheet.insert( "Ab: get struct attribute", nLoop, tEnd - tStart );
905 
906     i = nLoop;
907     tStart = getSystemTicks();
908     while (i--)
909         xBench->setStruct( aDummyStruct );
910     tEnd = getSystemTicks();
911     rSheet.insert( "Ac: setStruct() call", nLoop, tEnd - tStart );
912     i = nLoop;
913     tStart = getSystemTicks();
914     while (i--)
915         xBench->setStruct_attr( aDummyStruct );
916     tEnd = getSystemTicks();
917     rSheet.insert( "Ad: set struct attribute", nLoop, tEnd - tStart );
918 
919     // load
920 //      i = nLoop;
921 //      tStart = getSystemTicks();
922 //      while (i--)
923 //          xBench->setSequence( aSeq );
924 //      tEnd = getSystemTicks();
925 //      rSheet.insert( "transfer of exisiting objects", nLoop, tEnd - tStart );
926 
927     // exceptions
928     i = nLoop;
929     tStart = getSystemTicks();
930     while (i--)
931     {
932         try
933         {
934             xBench->raiseRuntimeException();
935         }
936         catch (RuntimeException &)
937         {
938         }
939     }
940     tEnd = getSystemTicks();
941     rSheet.insert( "Ba: raising RuntimeException", nLoop, tEnd - tStart );
942 
943     //------------------------------------
944 }
945 
946 //--------------------------------------------------------------------------------------------------
extractParam(const Sequence<OUString> & rArgs,const OUString & rParam)947 static OUString extractParam( const Sequence< OUString > & rArgs, const OUString & rParam )
948 {
949     const OUString * pArgs = rArgs.getConstArray();
950     for ( sal_Int32 nPos = rArgs.getLength(); nPos--; )
951     {
952         if (pArgs[nPos].indexOf( rParam ) == 0 &&
953             pArgs[nPos].getLength() > (rParam.getLength()+1))
954         {
955             return pArgs[nPos].copy( rParam.getLength() +1 ); // XXX=bla
956         }
957     }
958     return OUString();
959 }
960 
961 const sal_Int32 nMagicNumberDirect = 34000;
962 
963 //XMain
964 //__________________________________________________________________________________________________
run(const Sequence<OUString> & rArgs)965 sal_Int32 TestImpl::run( const Sequence< OUString > & rArgs )
966     throw (RuntimeException)
967 {
968     // defaults
969     FILE * stream = stderr;
970     sal_Int64 nLoop = NLOOP;
971     OUString aArg( RTL_CONSTASCII_USTRINGPARAM("dms") );
972 
973     try
974     {
975         OUString aLoopStr( extractParam( rArgs, OUString( RTL_CONSTASCII_USTRINGPARAM("loop") ) ) );
976         if (aLoopStr.getLength())
977         {
978             sal_Int64 n = aLoopStr.toInt64();
979             if (n > 0)
980                 nLoop = n;
981         }
982 
983         OUString aDurationStr( extractParam( rArgs , OUString( RTL_CONSTASCII_USTRINGPARAM("duration" ) ) ) );
984         if( aDurationStr.getLength() )
985         {
986             sal_Int64 n = aDurationStr.toInt64();
987             if( n >0 )
988                 nLoop = nMagicNumberDirect * n;
989         }
990 
991         OUString aLogStr( extractParam( rArgs, OUString( RTL_CONSTASCII_USTRINGPARAM("log") ) ) );
992         if (aLogStr.getLength())
993         {
994             if (aLogStr.compareToAscii( "stderr" ) == 0)
995             {
996                 stream = stderr;
997             }
998             else if (aLogStr.compareToAscii( "stdout" ) == 0)
999             {
1000                 stream = stdout;
1001             }
1002             else
1003             {
1004                 OString aFileName( OUStringToOString( aLogStr, RTL_TEXTENCODING_ASCII_US ) );
1005                 stream = ::fopen( aFileName.getStr(), "w" );
1006                 if (! stream)
1007                 {
1008                     OUStringBuffer buf( 32 );
1009                     buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("cannot open file for writing: \"") );
1010                     buf.append( aLogStr );
1011                     buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!") );
1012                     throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() );
1013                 }
1014             }
1015         }
1016 
1017         OUString aArgStr( extractParam( rArgs, OUString( RTL_CONSTASCII_USTRINGPARAM("opt") ) ) );
1018         if (aArgStr.getLength())
1019         {
1020             aArg = aArgStr;
1021         }
1022 
1023         if (! rArgs.getLength())
1024             out( "\n> no options given, using defaults" );
1025 
1026         // params
1027         out( "\n> opt=" );
1028         out( aArg );
1029         out( " log=" );
1030         if (stream == stderr)
1031             out( "stderr" );
1032         else if (stream == stderr)
1033             out( "stdout loop=" );
1034         else
1035             out( aLogStr );
1036         out( " loop=" );
1037         out( nLoop );
1038         out( "\n" );
1039         t_TimingSheetMap aSheets;
1040         TimingSheet aDirect;
1041 
1042         //------------------------------------------------------------------------------------------
1043 
1044         if (aArg.indexOf( 'd' ) >= 0)
1045         {
1046             // in process direct test
1047             sal_uInt32 nStart = getSystemTicks();
1048             benchmark( aDirect, getDirect(), nLoop );
1049             sal_uInt32 nEnd = getSystemTicks();
1050             fprintf( stderr, "Duration (direct in process): %g s\n", (nEnd - nStart)/1000.  );
1051         }
1052 
1053         //------------------------------------------------------------------------------------------
1054 
1055         if (aArg.indexOf( 'm' ) >= 0)
1056         {
1057             // in process uno dispatch
1058             Environment aCppEnv, aAnoCppEnv;
1059             OUString aCurrentLanguageBindingName( RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME) );
1060             uno_getEnvironment( reinterpret_cast< uno_Environment ** >( &aCppEnv ),
1061                                 aCurrentLanguageBindingName.pData, 0 );
1062             // anonymous
1063             uno_createEnvironment( reinterpret_cast< uno_Environment ** >( &aAnoCppEnv ),
1064                                    aCurrentLanguageBindingName.pData, 0 );
1065 
1066             // pseudo mapping uno<->uno: does nothing!
1067             Mapping aMapping( aCppEnv.get(), aAnoCppEnv.get(), OUString( RTL_CONSTASCII_USTRINGPARAM("pseudo") ) );
1068             if (! aMapping.is())
1069                 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("no pseudo mapping available!") ), Reference< XInterface >() );
1070 
1071             Reference< XInterface > xMapped;
1072             Reference< XInterface > xDirect( getDirect() );
1073             aMapping.mapInterface( reinterpret_cast< void ** >( &xMapped ), xDirect.get(),
1074                                    ::getCppuType( &xDirect ) );
1075             if (! xMapped.is())
1076                 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("mapping object failed!") ), Reference< XInterface >() );
1077 
1078             sal_uInt32 nStart = getSystemTicks();
1079             benchmark( aSheets[ "mapped in process" ], xMapped, nLoop / 100 );
1080             sal_uInt32 nEnd = getSystemTicks();
1081             fprintf( stderr, "Duration (mapped in process): %g s\n", (nStart - nEnd)/1000. );
1082         }
1083 
1084         //------------------------------------------------------------------------------------------
1085 
1086         if (aArg.indexOf( 's' ) >= 0)
1087         {
1088             // start server process
1089             oslSecurity hSecurity = osl_getCurrentSecurity();
1090             if (! hSecurity)
1091                 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("cannot get current security handle!") ), Reference< XInterface >() );
1092 
1093             OUString aArgs[] = {
1094                 OUString( RTL_CONSTASCII_USTRINGPARAM("-c") ),
1095                 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.performance.PerformanceTestObject") ),
1096                 OUString( RTL_CONSTASCII_USTRINGPARAM("-l") ),
1097 #ifdef SAL_UNX
1098                 OUString( RTL_CONSTASCII_USTRINGPARAM("libperfobj.so") ),
1099 #else
1100                 OUString( RTL_CONSTASCII_USTRINGPARAM("perfobj.dll") ),
1101 #endif
1102                 OUString( RTL_CONSTASCII_USTRINGPARAM("-r") ),
1103                 OUString( RTL_CONSTASCII_USTRINGPARAM("applicat.rdb") ),
1104                 OUString( RTL_CONSTASCII_USTRINGPARAM("-u") ),
1105                 OUString( RTL_CONSTASCII_USTRINGPARAM("uno:socket,host=localhost,port=6000;iiop;TestRemoteObject") ),
1106                 OUString( RTL_CONSTASCII_USTRINGPARAM("--singleaccept") )
1107             };
1108             rtl_uString * pArgs[] = {
1109                 aArgs[0].pData,
1110                 aArgs[1].pData,
1111                 aArgs[2].pData,
1112                 aArgs[3].pData,
1113                 aArgs[4].pData,
1114                 aArgs[5].pData,
1115                 aArgs[6].pData,
1116                 aArgs[7].pData,
1117                 aArgs[8].pData,
1118                 aArgs[9].pData,
1119             };
1120 
1121             out( "\n> executing: \"uno" );
1122             for ( sal_Int32 nPos = 0; nPos < (sizeof(aArgs) / sizeof(OUString)); ++nPos )
1123             {
1124                 out( " " );
1125                 out( aArgs[nPos] );
1126             }
1127             out( "\" ..." );
1128 
1129             oslProcess hProcess = 0;
1130             OUString aUnoExe( RTL_CONSTASCII_USTRINGPARAM("uno") );
1131             OUString aWorkingDir( RTL_CONSTASCII_USTRINGPARAM(".") );
1132             osl_executeProcess(
1133                 aUnoExe.pData, pArgs, sizeof(aArgs) / sizeof(OUString),
1134                 osl_Process_SEARCHPATH | osl_Process_DETACHED | osl_Process_NORMAL,
1135                 hSecurity, aWorkingDir.pData, 0, 0, &hProcess );
1136 
1137             osl_freeSecurityHandle( hSecurity );
1138             if (! hProcess)
1139                 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("cannot start server process!") ), Reference< XInterface >() );
1140             osl_freeProcessHandle( hProcess );
1141 
1142             // wait three seconds
1143             TimeValue threeSeconds;
1144             threeSeconds.Seconds = 3;
1145             osl_waitThread( &threeSeconds );
1146 
1147             // connect and resolve outer process object
1148             Reference< XInterface > xResolvedObject( resolveObject( OUString(
1149                 RTL_CONSTASCII_USTRINGPARAM("uno:socket,host=localhost,port=6000;iiop;TestRemoteObject") ) ) );
1150 
1151             benchmark( aSheets[ "remote same host" ], xResolvedObject, nLoop / 300 );
1152         }
1153 
1154         //------------------------------------------------------------------------------------------
1155 
1156         if (aArg.indexOf( 'r' ) >= 0)
1157         {
1158             // remote
1159             OUString aUnoUrl( extractParam( rArgs, OUString( RTL_CONSTASCII_USTRINGPARAM("url") ) ) );
1160             if (! aUnoUrl.getLength())
1161                 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("performance test r(emote) needs additional uno url!") ), Reference< XInterface >() );
1162 
1163             // connect and resolve outer process object
1164             Reference< XInterface > xResolvedObject( resolveObject( aUnoUrl ) );
1165 
1166             sal_Int32 t1 = getSystemTicks();
1167             OString o = OUStringToOString( aUnoUrl, RTL_TEXTENCODING_ASCII_US );
1168             benchmark( aSheets[ o.getStr() ], xResolvedObject, nLoop / 900 );
1169             sal_Int32 t2 = getSystemTicks();
1170             fprintf( stderr, "Duration (%s): %g s\n", o.getStr(),(t2 - t1)/1000. );
1171         }
1172 
1173         //------------------------------------------------------------------------------------------
1174 
1175         if (aArg.indexOf( 'j' ) >= 0)
1176         {
1177             // java
1178             benchmark( aSheets[ "java in process" ],
1179                        _xSMgr->createInstance(OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.benchmark.JavaTestObject"))),
1180                        nLoop / 1000 );
1181         }
1182 
1183         //------------------------------------------------------------------------------------------
1184         // dump out tables
1185 
1186         out( "\nTimes( ratio to direct in process )", stream );
1187 #if OSL_DEBUG_LEVEL > 1
1188         out ("; compiled with OSL_DEBUG_LEVEL > 1", stream );
1189 #endif
1190         out( ":", stream );
1191 
1192         sal_Int32 nPos = 60;
1193         out( "[direct in process]", stream, nPos );
1194         t_TimingSheetMap::const_iterator iSheets( aSheets.begin() );
1195         for ( ; iSheets != aSheets.end(); ++iSheets )
1196         {
1197             nPos += 40;
1198             out( "[", stream, nPos );
1199             out( (*iSheets).first.c_str(), stream );
1200             out( "]", stream );
1201         }
1202         for ( t_TimeEntryMap::const_iterator iTopics( aDirect._entries.begin() );
1203               iTopics != aDirect._entries.end(); ++iTopics )
1204         {
1205             const std::string & rTopic = (*iTopics).first;
1206 
1207             out( "\n", stream );
1208             out( rTopic.c_str(), stream );
1209 
1210             out( ":", stream, 58, '.' );
1211 
1212             sal_Int32 nPos = 60;
1213 
1214             double secs = (*iTopics).second.secPerCall();
1215             if (secs > 0.0)
1216             {
1217                 out( secs * 1000, stream, nPos );
1218                 out( "ms", stream );
1219             }
1220             else
1221             {
1222                 out( "NA", stream, nPos );
1223             }
1224 
1225             iSheets = aSheets.begin();
1226             for ( ; iSheets != aSheets.end(); ++iSheets )
1227             {
1228                 const t_TimeEntryMap::const_iterator iFind( (*iSheets).second._entries.find( rTopic ) );
1229                 OSL_ENSURE( iFind != (*iSheets).second._entries.end(), "####" );
1230 
1231                 nPos += 40;
1232 
1233                 double secs = (*iFind).second.secPerCall();
1234                 if (secs != 0.0)
1235                 {
1236                     out( secs * 1000, stream, nPos );
1237                     out( "ms", stream );
1238 
1239                     out( " (", stream );
1240                     double ratio = (*iFind).second.ratio( (*iTopics).second );
1241                     if (ratio != 0.0)
1242                     {
1243                         out( ratio, stream );
1244                         out( " x)", stream );
1245                     }
1246                     else
1247                     {
1248                         out( "NA)", stream );
1249                     }
1250                 }
1251                 else
1252                 {
1253                     out( "NA", stream, nPos );
1254                 }
1255             }
1256         }
1257     }
1258     catch (Exception & rExc)
1259     {
1260         if (stream != stderr && stream != stdout)
1261             ::fclose( stream );
1262         throw RuntimeException( rExc.Message, rExc.Context );
1263     }
1264 
1265     if (stream != stderr && stream != stdout)
1266         ::fclose( stream );
1267 
1268     out( "\n> done.\n" );
1269     return 0;
1270 }
1271 
1272 }
1273 
1274 
1275 //##################################################################################################
1276 //##################################################################################################
1277 //##################################################################################################
1278 
1279 
1280 extern "C"
1281 {
1282 //==================================================================================================
component_getImplementationEnvironment(const sal_Char ** ppEnvTypeName,uno_Environment ** ppEnv)1283 void SAL_CALL component_getImplementationEnvironment(
1284     const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv )
1285 {
1286     *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
1287 }
1288 //==================================================================================================
component_writeInfo(void * pServiceManager,void * pRegistryKey)1289 sal_Bool SAL_CALL component_writeInfo(
1290     void * pServiceManager, void * pRegistryKey )
1291 {
1292     if (pRegistryKey)
1293     {
1294         try
1295         {
1296             Reference< XRegistryKey > xNewKey(
1297                 reinterpret_cast< XRegistryKey * >( pRegistryKey )->createKey(
1298                     OUString( RTL_CONSTASCII_USTRINGPARAM("/" IMPLNAME "/UNO/SERVICES") ) ) );
1299             xNewKey->createKey( OUString( RTL_CONSTASCII_USTRINGPARAM(SERVICENAME) ) );
1300 
1301             return sal_True;
1302         }
1303         catch (InvalidRegistryException &)
1304         {
1305             OSL_ENSURE( sal_False, "### InvalidRegistryException!" );
1306         }
1307     }
1308     return sal_False;
1309 }
1310 //==================================================================================================
component_getFactory(const sal_Char * pImplName,void * pServiceManager,void * pRegistryKey)1311 void * SAL_CALL component_getFactory(
1312     const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey )
1313 {
1314     void * pRet = 0;
1315 
1316     if (pServiceManager && rtl_str_compare( pImplName, IMPLNAME ) == 0)
1317     {
1318         Reference< XSingleServiceFactory > xFactory( createSingleFactory(
1319             reinterpret_cast< XMultiServiceFactory * >( pServiceManager ),
1320             OUString( RTL_CONSTASCII_USTRINGPARAM(IMPLNAME) ),
1321             benchmark_test::TestImpl_create,
1322             benchmark_test::getSupportedServiceNames() ) );
1323 
1324         if (xFactory.is())
1325         {
1326             xFactory->acquire();
1327             pRet = xFactory.get();
1328         }
1329     }
1330 
1331     return pRet;
1332 }
1333 }
1334