diff options
author | Luboš Luňák <l.lunak@collabora.com> | 2019-04-22 21:23:44 +0200 |
---|---|---|
committer | Luboš Luňák <l.lunak@collabora.com> | 2019-04-29 10:40:12 +0200 |
commit | 101eea01c778ad255d3c8467e06643b23ff6bd76 (patch) | |
tree | f9defcf3be94e8d624d0ae098b68c4b508f66756 /desktop | |
parent | 7722ffd1f50ee431dfc501c4f0fecd40eb9046d3 (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')
-rw-r--r-- | desktop/source/app/opencl.cxx | 61 |
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()); |