summaryrefslogtreecommitdiff
path: root/desktop/source/app/opencl.cxx
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@collabora.com>2019-04-22 21:23:44 +0200
committerLuboš Luňák <l.lunak@collabora.com>2019-04-29 10:40:12 +0200
commit101eea01c778ad255d3c8467e06643b23ff6bd76 (patch)
treef9defcf3be94e8d624d0ae098b68c4b508f66756 /desktop/source/app/opencl.cxx
parent7722ffd1f50ee431dfc501c4f0fecd40eb9046d3 (diff)
test in a separate helper process if OpenCL crashes (tdf#112252)
Some OpenCL implementations may be broken, e.g. pocl simply asserts and aborts if it can't find Clang. In order to protect against crashes caused by faulty OpenCL drivers, when testing OpenCL functionality on OpenCL setup change, first do a simple test in a separate helper. Change-Id: I1cf328e731c48f47745b27c7130e7521254209f5 Reviewed-on: https://gerrit.libreoffice.org/71080 Tested-by: Jenkins Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
Diffstat (limited to 'desktop/source/app/opencl.cxx')
-rw-r--r--desktop/source/app/opencl.cxx61
1 files changed, 60 insertions, 1 deletions
diff --git a/desktop/source/app/opencl.cxx b/desktop/source/app/opencl.cxx
index f62c93e32e1f..a728ba2b8b7d 100644
--- a/desktop/source/app/opencl.cxx
+++ b/desktop/source/app/opencl.cxx
@@ -38,6 +38,7 @@
#include <opencl/OpenCLZone.hxx>
#include <osl/file.hxx>
+#include <osl/process.h>
using namespace ::osl;
using namespace ::com::sun::star::uno;
@@ -47,6 +48,61 @@ namespace desktop {
#if HAVE_FEATURE_OPENCL
+static bool testOpenCLDriver()
+{
+ // A simple OpenCL test run in a separate process in order to test
+ // whether the driver crashes (asserts,etc.) when trying to use OpenCL.
+ SAL_INFO("opencl", "Starting CL driver test");
+
+ OUString testerURL("$BRAND_BASE_DIR/" LIBO_BIN_FOLDER "/opencltest");
+ rtl::Bootstrap::expandMacros(testerURL); //TODO: detect failure
+
+ OUString deviceName, platformName;
+ openclwrapper::getOpenCLDeviceName( deviceName, platformName );
+ rtl_uString* args[] = { deviceName.pData, platformName.pData };
+ sal_Int32 numArgs = 2;
+
+ oslProcess process;
+ oslSecurity security = osl_getCurrentSecurity();
+ oslProcessError error = osl_executeProcess(testerURL.pData, args, numArgs,
+ osl_Process_SEARCHPATH | osl_Process_HIDDEN, security,
+ nullptr, nullptr, 0, &process );
+ osl_freeSecurityHandle( security );
+ if( error != osl_Process_E_None )
+ {
+ SAL_WARN( "opencl", "failed to start CL driver test: " << error );
+ return false;
+ }
+ // If the driver takes more than 10 seconds, it's probably broken/useless.
+ TimeValue timeout( 10, 0 );
+ error = osl_joinProcessWithTimeout( process, &timeout );
+ if( error == osl_Process_E_None )
+ {
+ oslProcessInfo info;
+ info.Size = sizeof( info );
+ error = osl_getProcessInfo( process, osl_Process_EXITCODE, &info );
+ if( error == osl_Process_E_None )
+ {
+ if( info.Code == 0 )
+ {
+ SAL_INFO( "opencl", "CL driver test passed" );
+ osl_freeProcessHandle( process );
+ return true;
+ }
+ else
+ {
+ SAL_WARN( "opencl", "CL driver test failed - disabling: " << info.Code );
+ osl_freeProcessHandle( process );
+ return false;
+ }
+ }
+ }
+ SAL_WARN( "opencl", "CL driver test did not finish - disabling: " << error );
+ osl_terminateProcess( process );
+ osl_freeProcessHandle( process );
+ return false;
+}
+
static bool testOpenCLCompute(const Reference< XDesktop2 > &xDesktop, const OUString &rURL)
{
bool bSuccess = false;
@@ -178,7 +234,10 @@ void Desktop::CheckOpenCLCompute(const Reference< XDesktop2 > &xDesktop)
xBatch->commit();
}
- bool bSucceeded = testOpenCLCompute(xDesktop, aURL);
+ // Hopefully at least basic functionality always works and broken OpenCL implementations break
+ // only when they are used to compute something. If this assumptions turns out to be not true,
+ // the driver check needs to be moved sooner.
+ bool bSucceeded = testOpenCLDriver() && testOpenCLCompute(xDesktop, aURL);
{ // restore the minimum group size
std::shared_ptr<comphelper::ConfigurationChanges> xBatch(comphelper::ConfigurationChanges::create());