summaryrefslogtreecommitdiffstats
path: root/testtools/source/performance
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 16:51:28 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 16:51:28 +0000
commit940b4d1848e8c70ab7642901a68594e8016caffc (patch)
treeeb72f344ee6c3d9b80a7ecc079ea79e9fba8676d /testtools/source/performance
parentInitial commit. (diff)
downloadlibreoffice-940b4d1848e8c70ab7642901a68594e8016caffc.tar.xz
libreoffice-940b4d1848e8c70ab7642901a68594e8016caffc.zip
Adding upstream version 1:7.0.4.upstream/1%7.0.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testtools/source/performance')
-rw-r--r--testtools/source/performance/cli_testobj_performance.cs109
-rw-r--r--testtools/source/performance/exports.dxp2
-rw-r--r--testtools/source/performance/makefile.mk89
-rw-r--r--testtools/source/performance/pseudo.cxx264
-rw-r--r--testtools/source/performance/pseudo_uno_uno.map25
-rw-r--r--testtools/source/performance/ubobject.cxx278
-rw-r--r--testtools/source/performance/ubtest.cxx1275
7 files changed, 2042 insertions, 0 deletions
diff --git a/testtools/source/performance/cli_testobj_performance.cs b/testtools/source/performance/cli_testobj_performance.cs
new file mode 100644
index 000000000..4affe89cd
--- /dev/null
+++ b/testtools/source/performance/cli_testobj_performance.cs
@@ -0,0 +1,109 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+using System;
+using System.Diagnostics;
+using uno;
+using uno.util;
+using unoidl.com.sun.star.uno;
+using unoidl.com.sun.star.lang;
+using unoidl.com.sun.star.test.performance;
+
+namespace testobj
+{
+
+[ServiceImplementation( "com.sun.star.test.performance.cli_uno.TestObject" )]
+public class PerformanceTestObject : ServiceBase, XPerformanceTest
+{
+ private XComponentContext m_xContext;
+
+ public PerformanceTestObject( XComponentContext xContext )
+ {
+ m_xContext = xContext;
+ }
+ public PerformanceTestObject()
+ {
+ }
+
+ private int _long;
+ private long _hyper;
+ private float _float;
+ private double _double;
+ private String _string = "";
+ private Object _xInterface;
+ private Any _any;
+ private Object[] _interface_sequence = new Object[0];
+ private ComplexTypes _complexTypes = new ComplexTypes();
+
+ // Attributes
+ public int getLong_attr() { return _long; }
+ public void setLong_attr( int _long_attr ) { _long = _long_attr; }
+ public long getHyper_attr() { return _hyper; }
+ public void setHyper_attr( long _hyper_attr ) { _hyper = _hyper_attr; }
+ public float getFloat_attr() { return _float; }
+ public void setFloat_attr( float _float_attr ) { _float = _float; }
+ public double getDouble_attr() { return _double; }
+ public void setDouble_attr( double _double_attr ) { _double = _double_attr; }
+ public String getString_attr() { return _string; }
+ public void setString_attr( String _string_attr ) { _string = _string_attr; }
+ public Object getInterface_attr() { return _xInterface; }
+ public void setInterface_attr( Object _interface_attr ) { _xInterface = _interface_attr; }
+ public Any getAny_attr() { return _any; }
+ public void setAny_attr( ref Any _any_attr ) { _any = _any_attr; }
+ public Object[] getSequence_attr() { return _interface_sequence; }
+ public void setSequence_attr(Object[] _sequence_attr ) { _interface_sequence = _sequence_attr; }
+ public ComplexTypes getStruct_attr() { return _complexTypes; }
+ public void setStruct_attr( ComplexTypes _struct_attr ) { _complexTypes = _struct_attr; }
+
+ // Methods
+ public void async() {}
+ public void sync( ) {}
+ public ComplexTypes complex_in( /*IN*/ComplexTypes aVal ) { return aVal; }
+ public ComplexTypes complex_inout( /*INOUT*/ref ComplexTypes aVal ) { return aVal; }
+ public void complex_oneway( /*IN*/ComplexTypes aVal ) {}
+ public void complex_noreturn( /*IN*/ComplexTypes aVal ) {}
+ public XPerformanceTest createObject( ) { return new PerformanceTestObject(); }
+ public int getLong() { return _long; }
+ public void setLong(/*IN*/int n) { _long = n; }
+ public long getHyper() { return _hyper; }
+ public void setHyper(/*IN*/long n) { _hyper = n; }
+ public float getFloat() { return _float; }
+ public void setFloat( /*IN*/float f ) { _float = f; }
+ public double getDouble( ) { return _double; }
+ public void setDouble( /*IN*/double f ) { _double = f; }
+ public String getString( ) { return _string; }
+ public void setString( /*IN*/String s ) { _string = s; }
+ public Object getInterface( ) { return _xInterface; }
+ public void setInterface( /*IN*/Object x ) { _xInterface = x; }
+ public Any getAny( ) { return _any; }
+ public void setAny( /*IN*/ref Any a ) { _any = a; }
+ public Object[] getSequence( ) { return _interface_sequence; }
+ public void setSequence( /*IN*/Object[] seq )
+ {
+#if DEBUG
+// Debug.WriteLine( "#### " + GetType().FullName + ".setSequence:" + seq );
+ Console.WriteLine( "#### " + GetType().FullName + ".setSequence:" + seq );
+#endif
+ _interface_sequence = seq;
+ }
+ public ComplexTypes getStruct( ) { return _complexTypes; }
+ public void setStruct( /*IN*/ComplexTypes c ) { _complexTypes = c; }
+ public void raiseRuntimeException( ) { throw new RuntimeException(); }
+}
+
+}
diff --git a/testtools/source/performance/exports.dxp b/testtools/source/performance/exports.dxp
new file mode 100644
index 000000000..51703a046
--- /dev/null
+++ b/testtools/source/performance/exports.dxp
@@ -0,0 +1,2 @@
+component_writeInfo
+component_getFactory
diff --git a/testtools/source/performance/makefile.mk b/testtools/source/performance/makefile.mk
new file mode 100644
index 000000000..be63e5349
--- /dev/null
+++ b/testtools/source/performance/makefile.mk
@@ -0,0 +1,89 @@
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+PRJ=..$/..
+
+PRJNAME=testtools
+TARGET=performancetest
+ENABLE_EXCEPTIONS=TRUE
+USE_DEFFILE=TRUE
+LIBTARGET=NO
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# ------------------------------------------------------------------
+
+LIB1TARGET=$(SLB)$/perftest.lib
+LIB1OBJFILES= \
+ $(SLO)$/ubtest.obj
+
+SHL1TARGET = $(ENFORCEDSHLPREFIX)$(ENFORCEDSHLPREFIX)perftest.uno
+
+SHL1VERSIONMAP = $(SOLARENV)$/src$/component.map
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(CPPUHELPERLIB) \
+ $(SALLIB)
+
+SHL1LIBS= $(LIB1TARGET)
+SHL1DEF= $(MISC)$/$(SHL1TARGET).def
+DEF1NAME= $(SHL1TARGET)
+
+# ---- test object ----
+
+LIB2TARGET=$(SLB)$/perfobj.lib
+LIB2OBJFILES= \
+ $(SLO)$/ubobject.obj
+
+SHL2TARGET = $(ENFORCEDSHLPREFIX)$(ENFORCEDSHLPREFIX)perfobj.uno
+
+SHL2VERSIONMAP = $(SOLARENV)$/src$/component.map
+
+SHL2STDLIBS= \
+ $(CPPULIB) \
+ $(CPPUHELPERLIB) \
+ $(SALLIB)
+
+SHL2LIBS= $(LIB2TARGET)
+SHL2DEF= $(MISC)$/$(SHL2TARGET).def
+DEF2NAME= $(SHL2TARGET)
+
+# ---- pseudo uno bridge ----
+
+LIB3TARGET=$(SLB)$/pseudo.lib
+LIB3OBJFILES= \
+ $(SLO)$/pseudo.obj
+
+SHL3TARGET=pseudo_uno_uno
+
+SHL3VERSIONMAP = pseudo_uno_uno.map
+
+SHL3STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB)
+
+SHL3LIBS= $(LIB3TARGET)
+SHL3DEF= $(MISC)$/$(SHL3TARGET).def
+DEF3NAME= $(SHL3TARGET)
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/testtools/source/performance/pseudo.cxx b/testtools/source/performance/pseudo.cxx
new file mode 100644
index 000000000..8417a0aa9
--- /dev/null
+++ b/testtools/source/performance/pseudo.cxx
@@ -0,0 +1,264 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <osl/diagnose.h>
+#include <osl/interlck.h>
+#include <rtl/ustring.hxx>
+#include <typelib/typedescription.h>
+#include <uno/dispatcher.h>
+#include <uno/environment.h>
+#include <uno/mapping.h>
+#include <uno/lbnames.h>
+
+
+namespace pseudo_uno
+{
+
+
+struct pseudo_Mapping : public uno_Mapping
+{
+ oslInterlockedCount nRef;
+
+ uno_ExtEnvironment * pFrom;
+ uno_ExtEnvironment * pTo;
+
+ pseudo_Mapping( uno_ExtEnvironment * pFrom_, uno_ExtEnvironment * pTo_ );
+ ~pseudo_Mapping();
+};
+
+//==== a UNO pseudo proxy =============================================================================
+struct pseudo_unoInterfaceProxy : public uno_Interface
+{
+ oslInterlockedCount nRef;
+ pseudo_Mapping * pPseudoMapping;
+
+ // mapping information
+ uno_Interface * pUnoI; // wrapped interface
+ typelib_InterfaceTypeDescription * pTypeDescr;
+ OUString oid;
+
+ // ctor
+ inline pseudo_unoInterfaceProxy( pseudo_Mapping * pPseudoMapping_,
+ uno_Interface * pUnoI_,
+ typelib_InterfaceTypeDescription * pTypeDescr_,
+ const OUString & rOId_ );
+};
+
+static void SAL_CALL pseudo_unoInterfaceProxy_dispatch(
+ uno_Interface * pUnoI,
+ const typelib_TypeDescription * pMemberType,
+ void * pReturn,
+ void * pArgs[],
+ uno_Any ** ppException )
+{
+ pseudo_unoInterfaceProxy * pThis = static_cast< pseudo_unoInterfaceProxy * >( pUnoI );
+ (*pThis->pUnoI->pDispatcher)( pThis->pUnoI, pMemberType, pReturn, pArgs, ppException );
+}
+
+
+static void SAL_CALL pseudo_unoInterfaceProxy_free( uno_ExtEnvironment * pEnv, void * pProxy )
+{
+ pseudo_unoInterfaceProxy * pThis =
+ static_cast< pseudo_unoInterfaceProxy * >(
+ reinterpret_cast< uno_Interface * >( pProxy ) );
+ OSL_ASSERT( pEnv == pThis->pPseudoMapping->pTo );
+
+ (*pThis->pPseudoMapping->pFrom->revokeInterface)( pThis->pPseudoMapping->pFrom, pThis->pUnoI );
+ (*pThis->pUnoI->release)( pThis->pUnoI );
+ typelib_typedescription_release( (typelib_TypeDescription *)pThis->pTypeDescr );
+ (*pThis->pPseudoMapping->release)( pThis->pPseudoMapping );
+
+#if OSL_DEBUG_LEVEL > 0
+ *(int *)pProxy = 0xdeadbabe;
+#endif
+ delete pThis;
+}
+
+static void SAL_CALL pseudo_unoInterfaceProxy_acquire( uno_Interface * pUnoI )
+{
+ if (1 == osl_atomic_increment( &static_cast< pseudo_unoInterfaceProxy * >( pUnoI )->nRef ))
+ {
+ // rebirth of proxy zombie
+ // register at uno env
+ void * pThis = static_cast< uno_Interface * >( pUnoI );
+ (*static_cast< pseudo_unoInterfaceProxy * >( pUnoI )->pPseudoMapping->pTo->registerProxyInterface)(
+ static_cast< pseudo_unoInterfaceProxy * >( pUnoI )->pPseudoMapping->pTo,
+ &pThis, pseudo_unoInterfaceProxy_free,
+ static_cast< pseudo_unoInterfaceProxy * >( pUnoI )->oid.pData,
+ static_cast< pseudo_unoInterfaceProxy * >( pUnoI )->pTypeDescr );
+ OSL_ASSERT( pThis == static_cast< uno_Interface * >( pUnoI ) );
+ }
+}
+
+static void SAL_CALL pseudo_unoInterfaceProxy_release( uno_Interface * pUnoI )
+{
+ if (! osl_atomic_decrement( & static_cast< pseudo_unoInterfaceProxy * >( pUnoI )->nRef ))
+ {
+ // revoke from uno env on last release
+ (*static_cast< pseudo_unoInterfaceProxy * >( pUnoI )->pPseudoMapping->pTo->revokeInterface)(
+ static_cast< pseudo_unoInterfaceProxy * >( pUnoI )->pPseudoMapping->pTo, pUnoI );
+ }
+}
+
+inline pseudo_unoInterfaceProxy::pseudo_unoInterfaceProxy(
+ pseudo_Mapping * pPseudoMapping_, uno_Interface * pUnoI_,
+ typelib_InterfaceTypeDescription * pTypeDescr_, const OUString & rOId_ )
+ : nRef( 1 )
+ , pPseudoMapping( pPseudoMapping_ )
+ , pUnoI( pUnoI_ )
+ , pTypeDescr( pTypeDescr_ )
+ , oid( rOId_ )
+{
+ (*pPseudoMapping->acquire)( pPseudoMapping );
+ typelib_typedescription_acquire( (typelib_TypeDescription *)pTypeDescr );
+ (*pPseudoMapping->pFrom->registerInterface)(
+ pPseudoMapping->pFrom, reinterpret_cast< void ** >( &pUnoI ), oid.pData, pTypeDescr );
+ (*pUnoI->acquire)( pUnoI );
+
+ // uno_Interface
+ uno_Interface::acquire = pseudo_unoInterfaceProxy_acquire;
+ uno_Interface::release = pseudo_unoInterfaceProxy_release;
+ uno_Interface::pDispatcher = pseudo_unoInterfaceProxy_dispatch;
+}
+
+
+static void SAL_CALL pseudo_Mapping_mapInterface(
+ uno_Mapping * pMapping, void ** ppOut,
+ void * pUnoI, typelib_InterfaceTypeDescription * pTypeDescr )
+{
+ OSL_ASSERT( ppOut && pTypeDescr );
+ if (*ppOut)
+ {
+ (*reinterpret_cast< uno_Interface * >( *ppOut )->release)(
+ reinterpret_cast< uno_Interface * >( *ppOut ) );
+ *ppOut = 0;
+ }
+ if (pUnoI && pTypeDescr)
+ {
+ // get object id of uno interface to be wrapped
+ rtl_uString * pOId = 0;
+ (*static_cast< pseudo_Mapping * >( pMapping )->pFrom->getObjectIdentifier)(
+ static_cast< pseudo_Mapping * >( pMapping )->pFrom, &pOId, pUnoI );
+ OSL_ASSERT( pOId );
+
+ if (pOId)
+ {
+ // try to get any known interface from target environment
+ (*static_cast< pseudo_Mapping * >( pMapping )->pTo->getRegisteredInterface)(
+ static_cast< pseudo_Mapping * >( pMapping )->pTo, ppOut, pOId, pTypeDescr );
+ if (! *ppOut) // no existing interface, register new proxy interface
+ {
+ // try to publish a new proxy (ref count initially 1)
+ void * pProxy = new pseudo_unoInterfaceProxy(
+ static_cast< pseudo_Mapping * >( pMapping ),
+ reinterpret_cast< uno_Interface * >( pUnoI ), pTypeDescr, pOId );
+
+ // proxy may be exchanged during registration
+ (*static_cast< pseudo_Mapping * >( pMapping )->pTo->registerProxyInterface)(
+ static_cast< pseudo_Mapping * >( pMapping )->pTo,
+ &pProxy, pseudo_unoInterfaceProxy_free, pOId, pTypeDescr );
+
+ *ppOut = pProxy;
+ }
+ rtl_uString_release( pOId );
+ }
+ }
+}
+
+static void SAL_CALL pseudo_Mapping_free( uno_Mapping * pMapping )
+{
+ delete static_cast< pseudo_Mapping * >( pMapping );
+}
+
+static void SAL_CALL pseudo_Mapping_acquire( uno_Mapping * pMapping )
+{
+ if (1 == osl_atomic_increment( & static_cast< pseudo_Mapping * >( pMapping )->nRef ))
+ {
+ OUString aMappingPurpose("pseudo");
+ uno_registerMapping( &pMapping,
+ pseudo_Mapping_free,
+ (uno_Environment *)((pseudo_Mapping *)pMapping)->pFrom,
+ (uno_Environment *)((pseudo_Mapping *)pMapping)->pTo,
+ aMappingPurpose.pData );
+ }
+}
+
+static void SAL_CALL pseudo_Mapping_release( uno_Mapping * pMapping )
+{
+ if (! osl_atomic_decrement( & static_cast< pseudo_Mapping * >( pMapping )->nRef ))
+ {
+ uno_revokeMapping( pMapping );
+ }
+}
+
+
+pseudo_Mapping::pseudo_Mapping( uno_ExtEnvironment * pFrom_, uno_ExtEnvironment * pTo_ )
+ : nRef( 1 )
+ , pFrom( pFrom_ )
+ , pTo( pTo_ )
+{
+ (*((uno_Environment *)pFrom)->acquire)( (uno_Environment *)pFrom );
+ (*((uno_Environment *)pTo)->acquire)( (uno_Environment *)pTo );
+
+ uno_Mapping::acquire = pseudo_Mapping_acquire;
+ uno_Mapping::release = pseudo_Mapping_release;
+ uno_Mapping::mapInterface = pseudo_Mapping_mapInterface;
+}
+
+pseudo_Mapping::~pseudo_Mapping()
+{
+ (*((uno_Environment *)pTo)->release)( (uno_Environment *)pTo );
+ (*((uno_Environment *)pFrom)->release)( (uno_Environment *)pFrom );
+}
+
+}
+
+
+extern "C" void SAL_CALL uno_initEnvironment( uno_Environment * pUnoEnv )
+{
+ OSL_FAIL( "### no impl: unexpected call!" );
+}
+
+extern "C" void SAL_CALL uno_ext_getMapping(
+ uno_Mapping ** ppMapping, uno_Environment * pFrom, uno_Environment * pTo )
+{
+ OSL_ASSERT( ppMapping && pFrom && pTo );
+ if (ppMapping && pFrom && pTo && pFrom->pExtEnv && pTo->pExtEnv)
+ {
+ uno_Mapping * pMapping = 0;
+
+ if (0 == rtl_ustr_ascii_compare( pFrom->pTypeName->buffer, UNO_LB_UNO ) &&
+ 0 == rtl_ustr_ascii_compare( pTo->pTypeName->buffer, UNO_LB_UNO ))
+ {
+ OUString aMappingPurpose("pseudo");
+ // ref count is initially 1
+ pMapping = new pseudo_uno::pseudo_Mapping( pFrom->pExtEnv, pTo->pExtEnv );
+ uno_registerMapping( &pMapping, pseudo_uno::pseudo_Mapping_free,
+ (uno_Environment *)pFrom->pExtEnv,
+ (uno_Environment *)pTo->pExtEnv,
+ aMappingPurpose.pData );
+ }
+
+ if (*ppMapping)
+ (*(*ppMapping)->release)( *ppMapping );
+ *ppMapping = pMapping;
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/testtools/source/performance/pseudo_uno_uno.map b/testtools/source/performance/pseudo_uno_uno.map
new file mode 100644
index 000000000..87862c4d1
--- /dev/null
+++ b/testtools/source/performance/pseudo_uno_uno.map
@@ -0,0 +1,25 @@
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+UDK_3_0_0 {
+ global:
+ uno_initEnvironment;
+ uno_ext_getMapping;
+ local:
+ *;
+};
diff --git a/testtools/source/performance/ubobject.cxx b/testtools/source/performance/ubobject.cxx
new file mode 100644
index 000000000..e437e9c9c
--- /dev/null
+++ b/testtools/source/performance/ubobject.cxx
@@ -0,0 +1,278 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+
+#include <osl/diagnose.h>
+#include <osl/interlck.h>
+
+#include <cppuhelper/factory.hxx>
+#include <cppuhelper/supportsservice.hxx>
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/registry/XRegistryKey.hpp>
+
+#include <com/sun/star/test/performance/XPerformanceTest.hpp>
+
+using namespace osl;
+using namespace cppu;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::registry;
+using namespace com::sun::star::test::performance;
+
+
+#define SERVICENAME "com.sun.star.test.performance.PerformanceTestObject"
+#define IMPLNAME "com.sun.star.comp.performance.PerformanceTestObject"
+
+namespace benchmark_object
+{
+
+
+inline static Sequence< OUString > getSupportedServiceNames()
+{
+ return { SERVICENAME };
+}
+
+
+class ServiceImpl
+ : public XServiceInfo
+ , public XPerformanceTest
+{
+ OUString _aDummyString;
+ Any _aDummyAny;
+ Sequence< Reference< XInterface > > _aDummySequence;
+ ComplexTypes _aDummyStruct;
+ RuntimeException _aDummyRE;
+
+ sal_Int32 _nRef;
+
+public:
+ ServiceImpl()
+ : _nRef( 0 )
+ {}
+ explicit ServiceImpl( const Reference< XMultiServiceFactory > & xMgr )
+ : _nRef( 0 )
+ {}
+
+ // XInterface
+ virtual css::uno::Any SAL_CALL queryInterface( const css::uno::Type& aType ) throw(css::uno::RuntimeException)
+ {
+ // execution time remains appr. constant any time
+ Any aRet;
+ if (aType == cppu::UnoType<XInterface>::get())
+ {
+ void * p = (XInterface *)(XPerformanceTest *)this;
+ aRet.setValue( &p, cppu::UnoType<XInterface>::get() );
+ }
+ if (aType == cppu::UnoType<XPerformanceTest>::get())
+ {
+ void * p = (XPerformanceTest *)this;
+ aRet.setValue( &p, cppu::UnoType<XPerformanceTest>::get() );
+ }
+ if (! aRet.hasValue())
+ {
+ void * p = (XPerformanceTest *)this;
+ Any aDummy( &p, cppu::UnoType<XPerformanceTest>::get() );
+ }
+ return aRet;
+ }
+ virtual void SAL_CALL acquire() throw()
+ { osl_atomic_increment( &_nRef ); }
+ virtual void SAL_CALL release() throw()
+ { if (! osl_atomic_decrement( &_nRef )) delete this; }
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() throw (RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const OUString & rServiceName ) throw (RuntimeException);
+ virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw (RuntimeException);
+
+ // Attributes
+ virtual sal_Int32 SAL_CALL getLong_attr() throw(css::uno::RuntimeException)
+ { return 0; }
+ virtual void SAL_CALL setLong_attr( sal_Int32 _attributelong ) throw(css::uno::RuntimeException)
+ {}
+ virtual sal_Int64 SAL_CALL getHyper_attr() throw(css::uno::RuntimeException)
+ { return 0; }
+ virtual void SAL_CALL setHyper_attr( sal_Int64 _attributehyper ) throw(css::uno::RuntimeException)
+ {}
+ virtual float SAL_CALL getFloat_attr() throw(css::uno::RuntimeException)
+ { return 0.0; }
+ virtual void SAL_CALL setFloat_attr( float _attributefloat ) throw(css::uno::RuntimeException)
+ {}
+ virtual double SAL_CALL getDouble_attr() throw(css::uno::RuntimeException)
+ { return 0.0; }
+ virtual void SAL_CALL setDouble_attr( double _attributedouble ) throw(css::uno::RuntimeException)
+ {}
+ virtual OUString SAL_CALL getString_attr() throw(css::uno::RuntimeException)
+ { return _aDummyString; }
+ virtual void SAL_CALL setString_attr( const OUString& _attributestring ) throw(css::uno::RuntimeException)
+ {}
+ virtual Reference< XInterface > SAL_CALL getInterface_attr() throw(css::uno::RuntimeException)
+ { return Reference< XInterface >(); }
+ virtual void SAL_CALL setInterface_attr( const Reference< XInterface >& _attributeinterface ) throw(css::uno::RuntimeException)
+ {}
+ virtual Any SAL_CALL getAny_attr() throw(css::uno::RuntimeException)
+ { return _aDummyAny; }
+ virtual void SAL_CALL setAny_attr( const Any& _attributeany ) throw(css::uno::RuntimeException)
+ {}
+ virtual Sequence< Reference< XInterface > > SAL_CALL getSequence_attr() throw(css::uno::RuntimeException)
+ { return _aDummySequence; }
+ virtual void SAL_CALL setSequence_attr( const Sequence< Reference< XInterface > >& _attributesequence ) throw(css::uno::RuntimeException)
+ {}
+ virtual ComplexTypes SAL_CALL getStruct_attr() throw(css::uno::RuntimeException)
+ { return _aDummyStruct; }
+ virtual void SAL_CALL setStruct_attr( const css::test::performance::ComplexTypes& _attributestruct ) throw(css::uno::RuntimeException)
+ {}
+
+ // Methods
+ virtual sal_Int32 SAL_CALL getLong() throw(css::uno::RuntimeException)
+ { return 0; }
+ virtual void SAL_CALL setLong( sal_Int32 _long ) throw(css::uno::RuntimeException)
+ {}
+ virtual sal_Int64 SAL_CALL getHyper() throw(css::uno::RuntimeException)
+ { return 0; }
+ virtual void SAL_CALL setHyper( sal_Int64 _hyper ) throw(css::uno::RuntimeException)
+ {}
+ virtual float SAL_CALL getFloat() throw(css::uno::RuntimeException)
+ { return 0; }
+ virtual void SAL_CALL setFloat( float _float ) throw(css::uno::RuntimeException)
+ {}
+ virtual double SAL_CALL getDouble() throw(css::uno::RuntimeException)
+ { return 0; }
+ virtual void SAL_CALL setDouble( double _double ) throw(css::uno::RuntimeException)
+ {}
+ virtual OUString SAL_CALL getString() throw(css::uno::RuntimeException)
+ { return _aDummyString; }
+ virtual void SAL_CALL setString( const OUString& _string ) throw(css::uno::RuntimeException)
+ {}
+ virtual Reference< XInterface > SAL_CALL getInterface() throw(css::uno::RuntimeException)
+ { return Reference< XInterface >(); }
+ virtual void SAL_CALL setInterface( const css::uno::Reference< css::uno::XInterface >& _interface ) throw(css::uno::RuntimeException)
+ {}
+ virtual Any SAL_CALL getAny() throw(css::uno::RuntimeException)
+ { return _aDummyAny; }
+ virtual void SAL_CALL setAny( const css::uno::Any& _any ) throw(css::uno::RuntimeException)
+ {}
+ virtual Sequence< Reference< XInterface > > SAL_CALL getSequence() throw(css::uno::RuntimeException)
+ { return _aDummySequence; }
+ virtual void SAL_CALL setSequence( const Sequence< Reference< XInterface > >& _sequence ) throw(css::uno::RuntimeException)
+ {}
+ virtual ComplexTypes SAL_CALL getStruct() throw(css::uno::RuntimeException)
+ { return _aDummyStruct; }
+ virtual void SAL_CALL setStruct( const css::test::performance::ComplexTypes& c ) throw(css::uno::RuntimeException)
+ {}
+
+ virtual void SAL_CALL async() throw(css::uno::RuntimeException)
+ {}
+ virtual void SAL_CALL sync() throw(css::uno::RuntimeException)
+ {}
+ virtual ComplexTypes SAL_CALL complex_in( const css::test::performance::ComplexTypes& aVal ) throw(css::uno::RuntimeException)
+ { return aVal; }
+ virtual ComplexTypes SAL_CALL complex_inout( css::test::performance::ComplexTypes& aVal ) throw(css::uno::RuntimeException)
+ { return aVal; }
+ virtual void SAL_CALL complex_oneway( const css::test::performance::ComplexTypes& aVal ) throw(css::uno::RuntimeException)
+ {}
+ virtual void SAL_CALL complex_noreturn( const css::test::performance::ComplexTypes& aVal ) throw(css::uno::RuntimeException)
+ {}
+ virtual Reference< XPerformanceTest > SAL_CALL createObject() throw(css::uno::RuntimeException)
+ { return new ServiceImpl(); }
+ virtual void SAL_CALL raiseRuntimeException( ) throw(css::uno::RuntimeException)
+ { throw _aDummyRE; }
+};
+
+
+// XServiceInfo
+
+OUString ServiceImpl::getImplementationName()
+ throw (RuntimeException)
+{
+ return OUString( IMPLNAME );
+}
+
+sal_Bool ServiceImpl::supportsService( const OUString & rServiceName )
+ throw (RuntimeException)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+Sequence< OUString > ServiceImpl::getSupportedServiceNames()
+ throw (RuntimeException)
+{
+ return benchmark_object::getSupportedServiceNames();
+}
+
+
+static Reference< XInterface > SAL_CALL ServiceImpl_create( const Reference< XMultiServiceFactory > & xSMgr )
+{
+ return Reference< XInterface >( (XPerformanceTest *)new ServiceImpl( xSMgr ) );
+}
+
+}
+
+
+extern "C"
+{
+sal_Bool SAL_CALL component_writeInfo(
+ void * pServiceManager, void * pRegistryKey )
+{
+ if (pRegistryKey)
+ {
+ try
+ {
+ Reference< XRegistryKey > xNewKey(
+ reinterpret_cast< XRegistryKey * >( pRegistryKey )->createKey(
+ OUString( ("/" IMPLNAME "/UNO/SERVICES") ) ) );
+ xNewKey->createKey( OUString( SERVICENAME ) );
+
+ return sal_True;
+ }
+ catch (InvalidRegistryException &)
+ {
+ OSL_FAIL( "### InvalidRegistryException!" );
+ }
+ }
+ return sal_False;
+}
+
+SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory(
+ const char * pImplName, void * pServiceManager, void * pRegistryKey )
+{
+ void * pRet = 0;
+
+ if (pServiceManager && rtl_str_compare( pImplName, IMPLNAME ) == 0)
+ {
+ Reference< XSingleServiceFactory > xFactory( createSingleFactory(
+ reinterpret_cast< XMultiServiceFactory * >( pServiceManager ),
+ OUString( IMPLNAME ),
+ benchmark_object::ServiceImpl_create,
+ benchmark_object::getSupportedServiceNames() ) );
+
+ if (xFactory.is())
+ {
+ xFactory->acquire();
+ pRet = xFactory.get();
+ }
+ }
+
+ return pRet;
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/testtools/source/performance/ubtest.cxx b/testtools/source/performance/ubtest.cxx
new file mode 100644
index 000000000..c30f31ba7
--- /dev/null
+++ b/testtools/source/performance/ubtest.cxx
@@ -0,0 +1,1275 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+
+#include <stdio.h>
+#include <math.h>
+#include <string>
+#include <map>
+#include <unordered_map>
+
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+#include <osl/module.h>
+#include <osl/process.h>
+#include <osl/thread.hxx>
+#include <osl/conditn.hxx>
+#include <osl/time.h>
+
+#ifdef _WIN32
+#if !defined WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+#else
+#include <sys/times.h>
+#include <unistd.h>
+#endif
+
+#include <rtl/string.hxx>
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+
+#include <uno/environment.hxx>
+#include <uno/lbnames.h>
+#include <uno/mapping.hxx>
+
+#include <cppuhelper/factory.hxx>
+#include <cppuhelper/implbase.hxx>
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/XMain.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/loader/XImplementationLoader.hpp>
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#include <com/sun/star/bridge/XUnoUrlResolver.hpp>
+#include <com/sun/star/container/XSet.hpp>
+#include <com/sun/star/test/performance/XPerformanceTest.hpp>
+
+#define NLOOP 200000000
+
+using namespace osl;
+using namespace cppu;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::loader;
+using namespace com::sun::star::registry;
+using namespace com::sun::star::bridge;
+using namespace com::sun::star::container;
+using namespace com::sun::star::test::performance;
+
+
+#define SERVICENAME "com.sun.star.test.performance.PerformanceTest"
+#define IMPLNAME "com.sun.star.comp.performance.PerformanceTest"
+
+namespace benchmark_test
+{
+
+static inline sal_uInt32 getSystemTicks()
+{
+#ifdef _WIN32
+ return (sal_uInt32)GetTickCount();
+#else // only UNX supported for now
+ static sal_uInt32 nImplTicksPerSecond = 0;
+ static double dImplTicksPerSecond;
+ static double dImplTicksULONGMAX;
+
+ struct tms aTms;
+ sal_uInt32 nTicks = (sal_uInt32)times( &aTms );
+
+ if ( !nImplTicksPerSecond )
+ {
+ nImplTicksPerSecond = sysconf(_SC_CLK_TCK);
+ dImplTicksPerSecond = nImplTicksPerSecond;
+ dImplTicksULONGMAX = (double)(sal_uInt32)ULONG_MAX;
+ }
+
+ double fTicks = nTicks;
+ fTicks *= 1000;
+ fTicks /= dImplTicksPerSecond;
+ fTicks = fmod (fTicks, dImplTicksULONGMAX);
+
+ return (sal_uInt32)fTicks;
+#endif
+}
+
+
+static void out( const char * pText, FILE * stream = stderr,
+ sal_Int32 nStart = -1, char cFillchar = ' ' )
+{
+ static sal_Int32 s_nPos = 0;
+
+ char ar[2] = { cFillchar, 0 };
+ while (s_nPos < nStart)
+ {
+ ::fprintf( stream, ar );
+ ++s_nPos;
+ }
+
+ ::fprintf( stream, pText );
+
+ for ( const char * p = pText; *p; ++p )
+ {
+ if (*p == '\n')
+ s_nPos = 0;
+ else
+ ++s_nPos;
+ }
+}
+
+static inline void out( const OUString & rText, FILE * stream = stderr,
+ sal_Int32 nStart = -1, char cFillchar = ' ' )
+{
+ OString aText( OUStringToOString( rText, RTL_TEXTENCODING_ASCII_US ) );
+ out( aText.getStr(), stream, nStart, cFillchar );
+}
+
+static inline void out( double fVal, FILE * stream = stderr,
+ sal_Int32 nStart = -1, char cFillchar = ' ' )
+{
+ char ar[128];
+ ::snprintf( ar, sizeof(ar), (fVal < 0.000001 ? "%g" : "%f"), fVal );
+ out( ar, stream, nStart, cFillchar );
+}
+
+static inline void out( sal_Int64 nVal, FILE * stream = stderr,
+ sal_Int32 nStart = -1, char cFillchar = ' ' )
+{
+ char ar[128];
+ ::snprintf( ar, sizeof(ar), "%ld", nVal );
+ out( ar, stream, nStart, cFillchar );
+}
+
+
+Reference< XSingleServiceFactory > loadLibComponentFactory(
+ const OUString & rLibName, const OUString & rImplName,
+ const Reference< XMultiServiceFactory > & xSF, const Reference< XRegistryKey > & xKey )
+{
+ Reference< XSingleServiceFactory > xRet;
+
+ OUStringBuffer aLibNameBuf( 32 );
+#ifdef SAL_UNX
+ aLibNameBuf.append( "lib" );
+ aLibNameBuf.append( rLibName );
+ aLibNameBuf.append( ".so" );
+#else
+ aLibNameBuf.append( rLibName );
+ aLibNameBuf.append( ".dll" );
+#endif
+ OUString aLibName( aLibNameBuf.makeStringAndClear() );
+ oslModule lib = osl_loadModule( aLibName.pData, SAL_LOADMODULE_LAZY | SAL_LOADMODULE_GLOBAL );
+
+ if (lib)
+ {
+ void * pSym;
+
+ // ========================= LATEST VERSION =========================
+ OUString aGetEnvName( COMPONENT_GETENV );
+ if (pSym = osl_getSymbol( lib, aGetEnvName.pData ))
+ {
+ uno_Environment * pCurrentEnv = 0;
+ uno_Environment * pEnv = 0;
+ const char * pEnvTypeName = 0;
+ (*((component_getImplementationEnvironmentFunc)pSym))( &pEnvTypeName, &pEnv );
+
+ sal_Bool bNeedsMapping =
+ (pEnv || 0 != rtl_str_compare( pEnvTypeName, CPPU_CURRENT_LANGUAGE_BINDING_NAME ));
+
+ OUString aEnvTypeName( OUString::createFromAscii( pEnvTypeName ) );
+
+ if (bNeedsMapping)
+ {
+ if (! pEnv)
+ uno_getEnvironment( &pEnv, aEnvTypeName.pData, 0 );
+ if (pEnv)
+ {
+ OUString aCppEnvTypeName( CPPU_CURRENT_LANGUAGE_BINDING_NAME );
+ uno_getEnvironment( &pCurrentEnv, aCppEnvTypeName.pData, 0 );
+ if (pCurrentEnv)
+ bNeedsMapping = (pEnv != pCurrentEnv);
+ }
+ }
+
+ OUString aGetFactoryName( COMPONENT_GETFACTORY );
+ if (pSym = osl_getSymbol( lib, aGetFactoryName.pData ))
+ {
+ OString aImplName( OUStringToOString( rImplName, RTL_TEXTENCODING_ASCII_US ) );
+
+ if (bNeedsMapping)
+ {
+ if (pEnv && pCurrentEnv)
+ {
+ Mapping aCurrent2Env( pCurrentEnv, pEnv );
+ Mapping aEnv2Current( pEnv, pCurrentEnv );
+
+ if (aCurrent2Env.is() && aEnv2Current.is())
+ {
+ void * pSMgr = aCurrent2Env.mapInterface(
+ xSF.get(), cppu::UnoType<XMultiServiceFactory>::get() );
+ void * pKey = aCurrent2Env.mapInterface(
+ xKey.get(), cppu::UnoType<XRegistryKey>::get() );
+
+ void * pSSF = (*((component_getFactoryFunc)pSym))(
+ aImplName.getStr(), pSMgr, pKey );
+
+ if (pKey)
+ (*pEnv->pExtEnv->releaseInterface)( pEnv->pExtEnv, pKey );
+ if (pSMgr)
+ (*pEnv->pExtEnv->releaseInterface)( pEnv->pExtEnv, pSMgr );
+
+ if (pSSF)
+ {
+ aEnv2Current.mapInterface(
+ reinterpret_cast< void ** >( &xRet ),
+ pSSF, cppu::UnoType<XSingleServiceFactory>::get() );
+ (*pEnv->pExtEnv->releaseInterface)( pEnv->pExtEnv, pSSF );
+ }
+ }
+ }
+ }
+ else
+ {
+ XSingleServiceFactory * pRet = (XSingleServiceFactory *)
+ (*((component_getFactoryFunc)pSym))(
+ aImplName.getStr(), xSF.get(), xKey.get() );
+ if (pRet)
+ {
+ xRet = pRet;
+ pRet->release();
+ }
+ }
+ }
+
+ if (pEnv)
+ (*pEnv->release)( pEnv );
+ if (pCurrentEnv)
+ (*pCurrentEnv->release)( pCurrentEnv );
+ }
+
+ // ========================= PREVIOUS VERSION =========================
+ else
+ {
+ OUString aGetFactoryName( CREATE_COMPONENT_FACTORY_FUNCTION );
+ if (pSym = osl_getSymbol( lib, aGetFactoryName.pData ))
+ {
+ OUString aCppEnvTypeName( CPPU_CURRENT_LANGUAGE_BINDING_NAME );
+ OUString aUnoEnvTypeName( UNO_LB_UNO );
+ Mapping aUno2Cpp( aUnoEnvTypeName, aCppEnvTypeName );
+ Mapping aCpp2Uno( aCppEnvTypeName, aUnoEnvTypeName );
+ OSL_ENSURE( aUno2Cpp.is() && aCpp2Uno.is(), "### cannot get uno mappings!" );
+
+ if (aUno2Cpp.is() && aCpp2Uno.is())
+ {
+ uno_Interface * pUComponentFactory = 0;
+
+ uno_Interface * pUSFactory = (uno_Interface *)aCpp2Uno.mapInterface(
+ xSF.get(), cppu::UnoType<XMultiServiceFactory>::get() );
+ uno_Interface * pUKey = (uno_Interface *)aCpp2Uno.mapInterface(
+ xKey.get(), cppu::UnoType<XRegistryKey>::get() );
+
+ pUComponentFactory = (*((CreateComponentFactoryFunc)pSym))(
+ rImplName.getStr(), pUSFactory, pUKey );
+
+ if (pUKey)
+ (*pUKey->release)( pUKey );
+ if (pUSFactory)
+ (*pUSFactory->release)( pUSFactory );
+
+ if (pUComponentFactory)
+ {
+ XSingleServiceFactory * pXFactory =
+ (XSingleServiceFactory *)aUno2Cpp.mapInterface(
+ pUComponentFactory, cppu::UnoType<XSingleServiceFactory>::get() );
+ (*pUComponentFactory->release)( pUComponentFactory );
+
+ if (pXFactory)
+ {
+ xRet = pXFactory;
+ pXFactory->release();
+ }
+ }
+ }
+ }
+ }
+
+ if (! xRet.is())
+ osl_unloadModule( lib );
+ }
+
+ return xRet;
+}
+
+template< class T >
+static void createInstance( Reference< T > & rxOut,
+ const Reference< XMultiServiceFactory > & xMgr,
+ const OUString & rServiceName )
+ throw (RuntimeException)
+{
+ Reference< XInterface > x( xMgr->createInstance( rServiceName ), UNO_QUERY );
+
+ if (! x.is())
+ {
+ static sal_Bool s_bSet = sal_False;
+ if (! s_bSet)
+ {
+ MutexGuard aGuard( Mutex::getGlobalMutex() );
+ if (! s_bSet)
+ {
+ Reference< XSet > xSet( xMgr, UNO_QUERY );
+ if (xSet.is())
+ {
+ // acceptor
+ xSet->insert( makeAny( loadLibComponentFactory(
+ OUString("acceptor"),
+ OUString("com.sun.star.comp.stoc.Acceptor"),
+ xMgr, Reference< XRegistryKey >() ) ) );
+ // connector
+ xSet->insert( makeAny( loadLibComponentFactory(
+ OUString("connector"),
+ OUString("com.sun.star.comp.stoc.Connector"),
+ xMgr, Reference< XRegistryKey >() ) ) );
+ // iiop bridge
+ xSet->insert( makeAny( loadLibComponentFactory(
+ OUString("remotebridge"),
+ OUString("com.sun.star.bridge.Bridge.various"),
+ xMgr, Reference< XRegistryKey >() ) ) );
+ // bridge factory
+ xSet->insert( makeAny( loadLibComponentFactory(
+ OUString("brdgfctr"),
+ OUString("com.sun.star.comp.stoc.BridgeFactory"),
+ xMgr, Reference< XRegistryKey >() ) ) );
+ // uno url resolver
+ xSet->insert( makeAny( loadLibComponentFactory(
+ OUString("uuresolver"),
+ OUString("com.sun.star.comp.bridge.UnoUrlResolver"),
+ xMgr, Reference< XRegistryKey >() ) ) );
+ // java loader
+// xSet->insert( makeAny( loadLibComponentFactory(
+// OUString("javaloader"),
+// OUString("com.sun.star.comp.stoc.JavaComponentLoader"),
+// xMgr, Reference< XRegistryKey >() ) ) );
+ }
+ s_bSet = sal_True;
+ }
+ }
+ x = xMgr->createInstance( rServiceName );
+ }
+
+ if (! x.is())
+ {
+ throw RuntimeException( "cannot get service instance \"" + rServiceName );
+ }
+
+ rxOut = Reference< T >::query( x );
+ if (! rxOut.is())
+ {
+ throw RuntimeException( "service instance \"" + rServiceName +
+ "\" does not support demanded interface \"" + cppu::UnoType<T>::get().getTypeName() );
+ }
+}
+
+
+inline static Sequence< OUString > getSupportedServiceNames()
+{
+ return { SERVICENAME };
+}
+
+
+class TestImpl : public WeakImplHelper< XServiceInfo, XMain >
+{
+ Reference< XMultiServiceFactory > _xSMgr;
+
+ Reference< XInterface > _xDirect;
+ Reference< XInterface > getDirect() throw (Exception);
+ Reference< XInterface > resolveObject( const OUString & rUnoUrl ) throw (Exception);
+
+public:
+ explicit TestImpl( const Reference< XMultiServiceFactory > & xSMgr );
+ virtual ~TestImpl();
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() throw (RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const OUString & rServiceName ) throw (RuntimeException);
+ virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw (RuntimeException);
+
+ // XMain
+ virtual sal_Int32 SAL_CALL run( const Sequence< OUString > & rArgs ) throw (RuntimeException);
+};
+
+
+TestImpl::TestImpl( const Reference< XMultiServiceFactory > & xSMgr )
+ : _xSMgr( xSMgr )
+{
+}
+
+TestImpl::~TestImpl()
+{
+}
+
+
+static Reference< XInterface > SAL_CALL TestImpl_create( const Reference< XMultiServiceFactory > & xSMgr )
+{
+ return Reference< XInterface >( *new TestImpl( xSMgr ) );
+}
+
+// XServiceInfo
+
+OUString TestImpl::getImplementationName()
+ throw (RuntimeException)
+{
+ return OUString( IMPLNAME );
+}
+
+sal_Bool TestImpl::supportsService( const OUString & rServiceName )
+ throw (RuntimeException)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+Sequence< OUString > TestImpl::getSupportedServiceNames()
+ throw (RuntimeException)
+{
+ return benchmark_test::getSupportedServiceNames();
+}
+
+
+Reference< XInterface > TestImpl::getDirect()
+ throw (Exception)
+{
+ if (! _xDirect.is())
+ {
+ MutexGuard aGuard( Mutex::getGlobalMutex() );
+ if (! _xDirect.is())
+ {
+ Reference< XSingleServiceFactory > xFac( loadLibComponentFactory(
+ OUString("perfobj"),
+ OUString("com.sun.star.comp.performance.PerformanceTestObject"),
+ _xSMgr, Reference< XRegistryKey >() ) );
+ if (! xFac.is())
+ throw RuntimeException("no test object available!" );
+ _xDirect = xFac->createInstance();
+ }
+ }
+ return _xDirect;
+}
+
+Reference< XInterface > TestImpl::resolveObject( const OUString & rUnoUrl )
+ throw (Exception)
+{
+ Reference< XUnoUrlResolver > xResolver;
+ createInstance(
+ xResolver, _xSMgr,
+ OUString("com.sun.star.bridge.UnoUrlResolver") );
+
+ Reference< XInterface > xResolvedObject( xResolver->resolve( rUnoUrl ) );
+
+ if (! xResolvedObject.is())
+ {
+ throw RuntimeException( "cannot resolve object \"" + rUnoUrl + "\"!" );
+ }
+
+ return xResolvedObject;
+}
+
+
+class TimeEntry
+{
+ sal_Int64 nLoop;
+ sal_uInt32 nTicks;
+
+public:
+ TimeEntry()
+ {}
+ TimeEntry( sal_Int64 nLoop_, sal_uInt32 nTicks_ )
+ : nLoop( nLoop_ )
+ , nTicks( nTicks_ )
+ {}
+
+ inline double secPerCall() const
+ { return (((double)nTicks) / (nLoop * 1000)); }
+
+ double ratio( const TimeEntry & rEntry ) const;
+};
+
+double TimeEntry::ratio( const TimeEntry & rEntry ) const
+{
+ double f = rEntry.nTicks * nLoop;
+ if (f == 0.0)
+ {
+ return 0.0;
+ }
+ else
+ {
+ return (((double)(nTicks * rEntry.nLoop)) / f);
+ }
+}
+
+
+typedef std::map< std::string, TimeEntry > t_TimeEntryMap;
+
+
+struct TimingSheet
+{
+ t_TimeEntryMap _entries;
+ void insert( const char * pText, sal_Int64 nLoop, sal_uInt32 nTicks );
+};
+
+void TimingSheet::insert( const char * pText, sal_Int64 nLoop, sal_uInt32 nTicks )
+{
+ _entries[ pText ] = TimeEntry( nLoop, nTicks );
+}
+
+typedef std::unordered_map< std::string, TimingSheet > t_TimingSheetMap;
+
+static void benchmark(
+ TimingSheet & rSheet, const Reference< XInterface > & xInstance, sal_Int64 nLoop )
+ throw (Exception)
+{
+ Reference< XPerformanceTest > xBench( xInstance, UNO_QUERY_THROW );
+
+ sal_Int64 i;
+ sal_uInt32 tStart, tEnd;
+
+ const Type & rKnownType = cppu::UnoType<XPerformanceTest>::get();
+ const Type & rUnKnownType = cppu::UnoType<XSet>::get();
+
+ ComplexTypes aDummyStruct;
+
+
+ // oneway calls
+ i = nLoop;
+ tStart = getSystemTicks();
+ while (i--)
+ xBench->async();
+ sal_uInt32 tEndSend = getSystemTicks();
+ xBench->sync();
+ tEnd = getSystemTicks();
+ rSheet.insert( "1a: sending simple oneway calls (no params, no return)", nLoop, tEndSend - tStart );
+ rSheet.insert( "1b: simple oneway calls (no params, no return)", nLoop, tEnd - tStart );
+ // synchron calls
+ i = nLoop;
+ tStart = getSystemTicks();
+ while (i--)
+ xBench->sync();
+ xBench->sync();
+ tEnd = getSystemTicks();
+ rSheet.insert( "1c: simple synchron calls (no params no return)", nLoop+1, tEnd - tStart );
+
+ // acquire
+ i = nLoop;
+ tStart = getSystemTicks();
+ while (i--)
+ xBench->acquire();
+ tEnd = getSystemTicks();
+ rSheet.insert( "2a: interface acquire() calls", nLoop, tEnd - tStart );
+ // release
+ i = nLoop;
+ tStart = getSystemTicks();
+ while (i--)
+ xBench->release();
+ tEnd = getSystemTicks();
+ rSheet.insert( "2b: interface release() calls", nLoop, tEnd - tStart );
+
+ // queryInterface() for known type
+ i = nLoop;
+ tStart = getSystemTicks();
+ while (i--)
+ xBench->queryInterface( rKnownType );
+ tEnd = getSystemTicks();
+ rSheet.insert( "2c: interface query for implemented type", nLoop, tEnd - tStart );
+ // queryInterface() for unknown type
+ i = nLoop;
+ tStart = getSystemTicks();
+ while (i--)
+ xBench->queryInterface( rUnKnownType );
+ tEnd = getSystemTicks();
+ rSheet.insert( "2d: interface query for unknown type", nLoop, tEnd - tStart );
+
+ // create and forget objects
+ Reference< XPerformanceTest > xBench2( xBench );
+ i = nLoop;
+ tStart = getSystemTicks();
+ while (i--)
+ xBench2 = xBench2->createObject();
+ tEnd = getSystemTicks();
+ rSheet.insert( "3a: create and release test objects", nLoop, tEnd - tStart );
+
+ // hold new objects
+ Sequence< Reference< XInterface > > aSeq( nLoop / 100 );
+ Reference< XInterface > * pSeq = aSeq.getArray();
+ xBench2 = xBench;
+ i = aSeq.getLength();
+ tStart = getSystemTicks();
+ while (i--)
+ pSeq[i] = xBench2 = xBench2->createObject();
+ tEnd = getSystemTicks();
+ rSheet.insert( "3b: create and hold test objects", nLoop, tEnd - tStart );
+
+ // structs
+ i = nLoop;
+ tStart = getSystemTicks();
+ while (i--)
+ xBench->complex_in( aDummyStruct );
+ tEnd = getSystemTicks();
+ rSheet.insert( "4a: complex_in() calls (in struct; return struct)", nLoop, tEnd - tStart );
+ i = nLoop;
+ tStart = getSystemTicks();
+ while (i--)
+ xBench->complex_inout( aDummyStruct );
+ tEnd = getSystemTicks();
+ rSheet.insert( "4b: complex_inout() calls (inout struct; return struct)", nLoop, tEnd - tStart );
+
+ i = nLoop;
+ tStart = getSystemTicks();
+ while (i--)
+ xBench->complex_oneway( aDummyStruct );
+ tEnd = getSystemTicks();
+ rSheet.insert( "4c: complex_oneway() oneway calls (in struct)", nLoop, tEnd - tStart );
+ i = nLoop;
+ tStart = getSystemTicks();
+ while (i--)
+ xBench->complex_noreturn( aDummyStruct );
+ tEnd = getSystemTicks();
+ rSheet.insert( "4d: complex_noreturn() calls (in struct)", nLoop, tEnd - tStart );
+
+ // attributes, get() methods
+ i = nLoop;
+ tStart = getSystemTicks();
+ while (i--)
+ xBench->getLong();
+ tEnd = getSystemTicks();
+ rSheet.insert( "5a: getLong() call", nLoop, tEnd - tStart );
+ i = nLoop;
+ tStart = getSystemTicks();
+ while (i--)
+ xBench->getLong_attr();
+ tEnd = getSystemTicks();
+ rSheet.insert( "5b: get long attribute", nLoop, tEnd - tStart );
+
+ i = nLoop;
+ tStart = getSystemTicks();
+ while (i--)
+ xBench->setLong( 0 );
+ tEnd = getSystemTicks();
+ rSheet.insert( "5c: setLong() call", nLoop, tEnd - tStart );
+ i = nLoop;
+ tStart = getSystemTicks();
+ while (i--)
+ xBench->setLong_attr( 0 );
+ tEnd = getSystemTicks();
+ rSheet.insert( "5d: set long attribute", nLoop, tEnd - tStart );
+
+ i = nLoop;
+ tStart = getSystemTicks();
+ while (i--)
+ xBench->getHyper();
+ tEnd = getSystemTicks();
+ rSheet.insert( "5e: getHyper() call", nLoop, tEnd - tStart );
+ i = nLoop;
+ tStart = getSystemTicks();
+ while (i--)
+ xBench->getHyper_attr();
+ tEnd = getSystemTicks();
+ rSheet.insert( "5f: get hyper attribute", nLoop, tEnd - tStart );
+
+ i = nLoop;
+ tStart = getSystemTicks();
+ while (i--)
+ xBench->setHyper( 0 );
+ tEnd = getSystemTicks();
+ rSheet.insert( "5g: setHyper() call", nLoop, tEnd - tStart );
+ i = nLoop;
+ tStart = getSystemTicks();
+ while (i--)
+ xBench->setHyper_attr( 0 );
+ tEnd = getSystemTicks();
+ rSheet.insert( "5h: set hyper attribute", nLoop, tEnd - tStart );
+
+ i = nLoop;
+ tStart = getSystemTicks();
+ while (i--)
+ xBench->getFloat();
+ tEnd = getSystemTicks();
+ rSheet.insert( "5i: getFloat() call", nLoop, tEnd - tStart );
+ i = nLoop;
+ tStart = getSystemTicks();
+ while (i--)
+ xBench->getFloat_attr();
+ tEnd = getSystemTicks();
+ rSheet.insert( "5j: get float attribute",nLoop, tEnd - tStart );
+
+ i = nLoop;
+ tStart = getSystemTicks();
+ while (i--)
+ xBench->setFloat( 0.0 );
+ tEnd = getSystemTicks();
+ rSheet.insert( "5k: setFloat() call", nLoop, tEnd - tStart );
+ i = nLoop;
+ tStart = getSystemTicks();
+ while (i--)
+ xBench->setFloat_attr( 0.0 );
+ tEnd = getSystemTicks();
+ rSheet.insert( "5l: set float attribute", nLoop, tEnd - tStart );
+
+ i = nLoop;
+ tStart = getSystemTicks();
+ while (i--)
+ xBench->getDouble();
+ tEnd = getSystemTicks();
+ rSheet.insert( "5m: getDouble() call", nLoop, tEnd - tStart );
+ i = nLoop;
+ tStart = getSystemTicks();
+ while (i--)
+ xBench->getDouble_attr();
+ tEnd = getSystemTicks();
+ rSheet.insert( "5n: get double attribute", nLoop, tEnd - tStart );
+ i = nLoop;
+ tStart = getSystemTicks();
+ while (i--)
+ xBench->setDouble( 0.0 );
+ tEnd = getSystemTicks();
+ rSheet.insert( "5o: setDouble() call", nLoop, tEnd - tStart );
+ i = nLoop;
+ tStart = getSystemTicks();
+ while (i--)
+ xBench->setDouble_attr( 0.0 );
+ tEnd = getSystemTicks();
+ rSheet.insert( "5p: set double attribute", nLoop, tEnd - tStart );
+
+ i = nLoop;
+ tStart = getSystemTicks();
+ while (i--)
+ xBench->getString();
+ tEnd = getSystemTicks();
+ rSheet.insert( "6a: getString() call (empty)", nLoop, tEnd - tStart );
+ i = nLoop;
+ tStart = getSystemTicks();
+ while (i--)
+ xBench->getString_attr();
+ tEnd = getSystemTicks();
+ rSheet.insert( "6b: get empty string attribute", nLoop, tEnd - tStart );
+
+ i = nLoop;
+ OUString aDummyString;
+ tStart = getSystemTicks();
+ while (i--)
+ xBench->setString( aDummyString );
+ tEnd = getSystemTicks();
+ rSheet.insert( "6c: setString() call (empty)", nLoop, tEnd - tStart );
+ i = nLoop;
+ tStart = getSystemTicks();
+ while (i--)
+ xBench->setString_attr( aDummyString );
+ tEnd = getSystemTicks();
+ rSheet.insert( "6d: set empty string attribute", nLoop, tEnd - tStart );
+
+ i = nLoop;
+ tStart = getSystemTicks();
+ while (i--)
+ xBench->getInterface();
+ tEnd = getSystemTicks();
+ rSheet.insert( "7a: getInterface() call (null)", nLoop, tEnd - tStart );
+ i = nLoop;
+ tStart = getSystemTicks();
+ while (i--)
+ xBench->getInterface_attr();
+ tEnd = getSystemTicks();
+ rSheet.insert( "7b: get interface attribute", nLoop, tEnd - tStart );
+
+ i = nLoop;
+ Reference< XInterface > aDummyInterface;
+ tStart = getSystemTicks();
+ while (i--)
+ xBench->setInterface( aDummyInterface );
+ tEnd = getSystemTicks();
+ rSheet.insert( "7c: setInterface() call (null)", nLoop, tEnd - tStart );
+ i = nLoop;
+ tStart = getSystemTicks();
+ while (i--)
+ xBench->setInterface_attr( Reference< XInterface >() );
+ tEnd = getSystemTicks();
+ rSheet.insert( "7d: set interface attribute", nLoop, tEnd - tStart );
+
+ i = nLoop;
+ tStart = getSystemTicks();
+ while (i--)
+ xBench->getAny();
+ tEnd = getSystemTicks();
+ rSheet.insert( "8a: getAny() call (empty)", nLoop, tEnd - tStart );
+ i = nLoop;
+ tStart = getSystemTicks();
+ while (i--)
+ xBench->getAny_attr();
+ tEnd = getSystemTicks();
+ rSheet.insert( "8b: get empty any attribute", nLoop, tEnd - tStart );
+
+ i = nLoop;
+ Any aDummyAny;
+ tStart = getSystemTicks();
+ while (i--)
+ xBench->setAny( aDummyAny );
+ tEnd = getSystemTicks();
+ rSheet.insert( "8c: setAny() call (empty)", nLoop, tEnd - tStart );
+ i = nLoop;
+ tStart = getSystemTicks();
+ while (i--)
+ xBench->setAny_attr( aDummyAny );
+ tEnd = getSystemTicks();
+ rSheet.insert( "8d: set empty any attribute", nLoop, tEnd - tStart );
+
+ i = nLoop;
+ tStart = getSystemTicks();
+ while (i--)
+ xBench->getSequence();
+ tEnd = getSystemTicks();
+ rSheet.insert( "9a: getSequence() call (empty)", nLoop, tEnd - tStart );
+ i = nLoop;
+ tStart = getSystemTicks();
+ while (i--)
+ xBench->getSequence_attr();
+ tEnd = getSystemTicks();
+ rSheet.insert( "9b: get empty sequence attribute", nLoop, tEnd - tStart );
+ i = nLoop;
+ Sequence< Reference< XInterface > > aDummySeq;
+ tStart = getSystemTicks();
+ while (i--)
+ xBench->setSequence( aDummySeq );
+ tEnd = getSystemTicks();
+ rSheet.insert( "9c: setSequence() call (empty)", nLoop, tEnd - tStart );
+ i = nLoop;
+ tStart = getSystemTicks();
+ while (i--)
+ xBench->setSequence_attr( aDummySeq );
+ tEnd = getSystemTicks();
+ rSheet.insert( "9d: set empty sequence attribute", nLoop, tEnd - tStart );
+
+ i = nLoop;
+ tStart = getSystemTicks();
+ while (i--)
+ xBench->getStruct();
+ tEnd = getSystemTicks();
+ rSheet.insert( "Aa: getStruct() call", nLoop, tEnd - tStart );
+ i = nLoop;
+ tStart = getSystemTicks();
+ while (i--)
+ xBench->getStruct_attr();
+ tEnd = getSystemTicks();
+ rSheet.insert( "Ab: get struct attribute", nLoop, tEnd - tStart );
+
+ i = nLoop;
+ tStart = getSystemTicks();
+ while (i--)
+ xBench->setStruct( aDummyStruct );
+ tEnd = getSystemTicks();
+ rSheet.insert( "Ac: setStruct() call", nLoop, tEnd - tStart );
+ i = nLoop;
+ tStart = getSystemTicks();
+ while (i--)
+ xBench->setStruct_attr( aDummyStruct );
+ tEnd = getSystemTicks();
+ rSheet.insert( "Ad: set struct attribute", nLoop, tEnd - tStart );
+
+ // load
+// i = nLoop;
+// tStart = getSystemTicks();
+// while (i--)
+// xBench->setSequence( aSeq );
+// tEnd = getSystemTicks();
+// rSheet.insert( "transfer of existing objects", nLoop, tEnd - tStart );
+
+ // exceptions
+ i = nLoop;
+ tStart = getSystemTicks();
+ while (i--)
+ {
+ try
+ {
+ xBench->raiseRuntimeException();
+ }
+ catch (RuntimeException &)
+ {
+ }
+ }
+ tEnd = getSystemTicks();
+ rSheet.insert( "Ba: raising RuntimeException", nLoop, tEnd - tStart );
+
+
+}
+
+
+static OUString extractParam( const Sequence< OUString > & rArgs, const OUString & rParam )
+{
+ const OUString * pArgs = rArgs.getConstArray();
+ for ( sal_Int32 nPos = rArgs.getLength(); nPos--; )
+ {
+ if (pArgs[nPos].startsWith( rParam ) &&
+ pArgs[nPos].getLength() > (rParam.getLength()+1))
+ {
+ return pArgs[nPos].copy( rParam.getLength() +1 ); // XXX=bla
+ }
+ }
+ return OUString();
+}
+
+const sal_Int32 nMagicNumberDirect = 34000;
+
+//XMain
+
+sal_Int32 TestImpl::run( const Sequence< OUString > & rArgs )
+ throw (RuntimeException)
+{
+ // defaults
+ FILE * stream = stderr;
+ sal_Int64 nLoop = NLOOP;
+ OUString aArg("dms");
+
+ try
+ {
+ OUString aLoopStr( extractParam( rArgs, OUString("loop") ) );
+ if (aLoopStr.getLength())
+ {
+ sal_Int64 n = aLoopStr.toInt64();
+ if (n > 0)
+ nLoop = n;
+ }
+
+ OUString aDurationStr( extractParam( rArgs , OUString("duration" ) ) );
+ if( aDurationStr.getLength() )
+ {
+ sal_Int64 n = aDurationStr.toInt64();
+ if( n >0 )
+ nLoop = nMagicNumberDirect * n;
+ }
+
+ OUString aLogStr( extractParam( rArgs, OUString("log") ) );
+ if (aLogStr.getLength())
+ {
+ if (aLogStr.equalsAscii( "stderr" ) )
+ {
+ stream = stderr;
+ }
+ else if (aLogStr.equalsAscii( "stdout" ) )
+ {
+ stream = stdout;
+ }
+ else
+ {
+ OString aFileName( OUStringToOString( aLogStr, RTL_TEXTENCODING_ASCII_US ) );
+ stream = ::fopen( aFileName.getStr(), "w" );
+ if (! stream)
+ {
+ throw RuntimeException( "cannot open file for writing: \"" + aLogStr + "\"!" );
+ }
+ }
+ }
+
+ OUString aArgStr( extractParam( rArgs, OUString("opt") ) );
+ if (aArgStr.getLength())
+ {
+ aArg = aArgStr;
+ }
+
+ if (! rArgs.getLength())
+ out( "\n> no options given, using defaults" );
+
+ // params
+ out( "\n> opt=" );
+ out( aArg );
+ out( " log=" );
+ if (stream == stderr)
+ out( "stderr" );
+ else if (stream == stdout)
+ out( "stdout loop=" );
+ else
+ out( aLogStr );
+ out( " loop=" );
+ out( nLoop );
+ out( "\n" );
+ t_TimingSheetMap aSheets;
+ TimingSheet aDirect;
+
+
+ if (aArg.indexOf( 'd' ) >= 0)
+ {
+ // in process direct test
+ sal_uInt32 nStart = getSystemTicks();
+ benchmark( aDirect, getDirect(), nLoop );
+ sal_uInt32 nEnd = getSystemTicks();
+ fprintf( stderr, "Duration (direct in process): %g s\n", (nEnd - nStart)/1000. );
+ }
+
+
+ if (aArg.indexOf( 'm' ) >= 0)
+ {
+ // in process uno dispatch
+ Environment aCppEnv, aAnoCppEnv;
+ OUString aCurrentLanguageBindingName( CPPU_CURRENT_LANGUAGE_BINDING_NAME );
+ uno_getEnvironment( reinterpret_cast< uno_Environment ** >( &aCppEnv ),
+ aCurrentLanguageBindingName.pData, 0 );
+ // anonymous
+ uno_createEnvironment( reinterpret_cast< uno_Environment ** >( &aAnoCppEnv ),
+ aCurrentLanguageBindingName.pData, 0 );
+
+ // pseudo mapping uno<->uno: does nothing!
+ Mapping aMapping( aCppEnv.get(), aAnoCppEnv.get(), OUString("pseudo") );
+ if (! aMapping.is())
+ throw RuntimeException("no pseudo mapping available!" );
+
+ Reference< XInterface > xMapped;
+ Reference< XInterface > xDirect( getDirect() );
+ aMapping.mapInterface( reinterpret_cast< void ** >( &xMapped ), xDirect.get(),
+ cppu::UnoType<decltype(xDirect)>::get() );
+ if (! xMapped.is())
+ throw RuntimeException("mapping object failed!" );
+
+ sal_uInt32 nStart = getSystemTicks();
+ benchmark( aSheets[ "mapped in process" ], xMapped, nLoop / 100 );
+ sal_uInt32 nEnd = getSystemTicks();
+ fprintf( stderr, "Duration (mapped in process): %g s\n", (nStart - nEnd)/1000. );
+ }
+
+
+ if (aArg.indexOf( 's' ) >= 0)
+ {
+ // start server process
+ oslSecurity hSecurity = osl_getCurrentSecurity();
+ if (! hSecurity)
+ throw RuntimeException("cannot get current security handle!" );
+
+ OUString aArgs[] = {
+ OUString("-c"),
+ OUString("com.sun.star.comp.performance.PerformanceTestObject"),
+ OUString("-l"),
+#ifdef SAL_UNX
+ OUString("libperfobj.so"),
+#else
+ OUString("perfobj.dll"),
+#endif
+ OUString("-r"),
+ OUString("applicat.rdb"),
+ OUString("-u"),
+ OUString("uno:socket,host=localhost,port=6000;iiop;TestRemoteObject"),
+ OUString("--singleaccept")
+ };
+ rtl_uString * pArgs[] = {
+ aArgs[0].pData,
+ aArgs[1].pData,
+ aArgs[2].pData,
+ aArgs[3].pData,
+ aArgs[4].pData,
+ aArgs[5].pData,
+ aArgs[6].pData,
+ aArgs[7].pData,
+ aArgs[8].pData,
+ };
+
+ out( "\n> executing: \"uno" );
+ for ( sal_Int32 nPos = 0; nPos < (sizeof(aArgs) / sizeof(OUString)); ++nPos )
+ {
+ out( " " );
+ out( aArgs[nPos] );
+ }
+ out( "\" ..." );
+
+ oslProcess hProcess = 0;
+ OUString aUnoExe("uno");
+ OUString aWorkingDir(".");
+ osl_executeProcess(
+ aUnoExe.pData, pArgs, sizeof(aArgs) / sizeof(OUString),
+ osl_Process_SEARCHPATH | osl_Process_DETACHED | osl_Process_NORMAL,
+ hSecurity, aWorkingDir.pData, 0, 0, &hProcess );
+
+ osl_freeSecurityHandle( hSecurity );
+ if (! hProcess)
+ throw RuntimeException("cannot start server process!" );
+ osl_freeProcessHandle( hProcess );
+
+ // wait three seconds
+ osl::Thread::wait(std::chrono::seconds(3));
+
+ // connect and resolve outer process object
+ Reference< XInterface > xResolvedObject( resolveObject( OUString("uno:socket,host=localhost,port=6000;iiop;TestRemoteObject") ) );
+
+ benchmark( aSheets[ "remote same host" ], xResolvedObject, nLoop / 300 );
+ }
+
+
+ if (aArg.indexOf( 'r' ) >= 0)
+ {
+ // remote
+ OUString aUnoUrl( extractParam( rArgs, OUString("url") ) );
+ if (! aUnoUrl.getLength())
+ throw RuntimeException( "performance test r(emote) needs additional uno url!" );
+
+ // connect and resolve outer process object
+ Reference< XInterface > xResolvedObject( resolveObject( aUnoUrl ) );
+
+ sal_Int32 t1 = getSystemTicks();
+ OString o = OUStringToOString( aUnoUrl, RTL_TEXTENCODING_ASCII_US );
+ benchmark( aSheets[ o.getStr() ], xResolvedObject, nLoop / 900 );
+ sal_Int32 t2 = getSystemTicks();
+ fprintf( stderr, "Duration (%s): %g s\n", o.getStr(),(t2 - t1)/1000. );
+ }
+
+
+ if (aArg.indexOf( 'j' ) >= 0)
+ {
+ // java
+ benchmark( aSheets[ "java in process" ],
+ _xSMgr->createInstance("com.sun.star.comp.benchmark.JavaTestObject"),
+ nLoop / 1000 );
+ }
+
+
+ // dump out tables
+
+ out( "\nTimes( ratio to direct in process )", stream );
+ out( ":", stream );
+
+ sal_Int32 nPos = 60;
+ out( "[direct in process]", stream, nPos );
+ for ( const auto& rSheet : aSheets )
+ {
+ nPos += 40;
+ out( "[", stream, nPos );
+ out( rSheet.first.c_str(), stream );
+ out( "]", stream );
+ }
+ for ( const auto& rTopics : aDirect._entries )
+ {
+ const std::string & rTopic = rTopics.first;
+
+ out( "\n", stream );
+ out( rTopic.c_str(), stream );
+
+ out( ":", stream, 58, '.' );
+
+ sal_Int32 nPos = 60;
+
+ double secs = rTopics.second.secPerCall();
+ if (secs > 0.0)
+ {
+ out( secs * 1000, stream, nPos );
+ out( "ms", stream );
+ }
+ else
+ {
+ out( "NA", stream, nPos );
+ }
+
+ for ( const auto& rSheet : aSheets )
+ {
+ const t_TimeEntryMap::const_iterator iFind( rSheet.second._entries.find( rTopic ) );
+ OSL_ENSURE( iFind != rSheet.second._entries.end(), "####" );
+
+ nPos += 40;
+
+ double secs = (*iFind).second.secPerCall();
+ if (secs != 0.0)
+ {
+ out( secs * 1000, stream, nPos );
+ out( "ms", stream );
+
+ out( " (", stream );
+ double ratio = (*iFind).second.ratio( rTopics.second );
+ if (ratio != 0.0)
+ {
+ out( ratio, stream );
+ out( " x)", stream );
+ }
+ else
+ {
+ out( "NA)", stream );
+ }
+ }
+ else
+ {
+ out( "NA", stream, nPos );
+ }
+ }
+ }
+ }
+ catch (Exception & rExc)
+ {
+ if (stream != stderr && stream != stdout)
+ ::fclose( stream );
+ throw RuntimeException( rExc.Message, rExc.Context );
+ }
+
+ if (stream != stderr && stream != stdout)
+ ::fclose( stream );
+
+ out( "\n> done.\n" );
+ return 0;
+}
+
+}
+
+
+extern "C"
+{
+
+sal_Bool SAL_CALL component_writeInfo(
+ void * pServiceManager, void * pRegistryKey )
+{
+ if (pRegistryKey)
+ {
+ try
+ {
+ Reference< XRegistryKey > xNewKey(
+ reinterpret_cast< XRegistryKey * >( pRegistryKey )->createKey(
+ OUString( "/" IMPLNAME "/UNO/SERVICES" ) ) );
+ xNewKey->createKey( OUString( SERVICENAME ) );
+
+ return sal_True;
+ }
+ catch (InvalidRegistryException &)
+ {
+ OSL_FAIL( "### InvalidRegistryException!" );
+ }
+ }
+ return sal_False;
+}
+
+SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory(
+ const char * pImplName, void * pServiceManager, void * pRegistryKey )
+{
+ void * pRet = 0;
+
+ if (pServiceManager && rtl_str_compare( pImplName, IMPLNAME ) == 0)
+ {
+ Reference< XSingleServiceFactory > xFactory( createSingleFactory(
+ reinterpret_cast< XMultiServiceFactory * >( pServiceManager ),
+ OUString( IMPLNAME ),
+ benchmark_test::TestImpl_create,
+ benchmark_test::getSupportedServiceNames() ) );
+
+ if (xFactory.is())
+ {
+ xFactory->acquire();
+ pRet = xFactory.get();
+ }
+ }
+
+ return pRet;
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */