[Libreoffice-commits] core.git: 2 commits - comphelper/Library_comphelper.mk comphelper/source desktop/scripts desktop/source include/comphelper include/opencl include/sal opencl/source vcl/inc vcl/Library_vcl.mk vcl/README.vars vcl/source
LuboÅ¡ LuÅák (via logerrit)
logerrit at kemper.freedesktop.org
Fri Feb 7 08:12:06 UTC 2020
comphelper/Library_comphelper.mk | 1
comphelper/source/misc/debuggerinfo.cxx | 58 +++++++++++
comphelper/source/misc/threadpool.cxx | 31 ------
desktop/scripts/soffice.sh | 2
desktop/source/app/opencl.cxx | 2
include/comphelper/crashzone.hxx | 72 ++++++++++++++
include/comphelper/debuggerinfo.hxx | 38 +++++++
include/opencl/OpenCLZone.hxx | 42 +-------
include/sal/log-areas.dox | 1
opencl/source/OpenCLZone.cxx | 10 --
vcl/Library_vcl.mk | 1
vcl/README.vars | 2
vcl/inc/opengl/watchdog.hxx | 67 -------------
vcl/inc/opengl/zone.hxx | 39 +------
vcl/inc/watchdog.hxx | 32 ++++++
vcl/source/app/svmain.cxx | 8 -
vcl/source/app/watchdog.cxx | 144 ++++++++++++++++++++++++++++
vcl/source/opengl/OpenGLHelper.cxx | 160 +++++++++-----------------------
18 files changed, 416 insertions(+), 294 deletions(-)
New commits:
commit ac9083f64fc064e4bad3dc522a90ca214b3f1c2f
Author: Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Wed Feb 5 11:09:02 2020 +0100
Commit: Luboš Luňák <l.lunak at collabora.com>
CommitDate: Fri Feb 7 09:11:45 2020 +0100
make isDebuggerAttached() public comphelper API
So that it can be used also from other places.
Change-Id: Iab90350fd02872ffde180ce74f01f7ff5e4448b4
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/88009
Tested-by: Jenkins
Reviewed-by: Luboš Luňák <l.lunak at collabora.com>
diff --git a/comphelper/Library_comphelper.mk b/comphelper/Library_comphelper.mk
index 6e9a6fc77f79..7a8d5bd6f3a6 100644
--- a/comphelper/Library_comphelper.mk
+++ b/comphelper/Library_comphelper.mk
@@ -102,6 +102,7 @@ $(eval $(call gb_Library_add_exception_objects,comphelper,\
comphelper/source/misc/componentmodule \
comphelper/source/misc/configuration \
comphelper/source/misc/configurationhelper \
+ comphelper/source/misc/debuggerinfo \
comphelper/source/misc/DirectoryHelper \
comphelper/source/misc/dispatchcommand \
comphelper/source/misc/docpasswordhelper \
diff --git a/comphelper/source/misc/debuggerinfo.cxx b/comphelper/source/misc/debuggerinfo.cxx
new file mode 100644
index 000000000000..9d452f174ab5
--- /dev/null
+++ b/comphelper/source/misc/debuggerinfo.cxx
@@ -0,0 +1,58 @@
+/* -*- 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/.
+ */
+
+#include <comphelper/debuggerinfo.hxx>
+
+#include <cassert>
+#include <cstring>
+#include <ctype.h>
+
+#if defined(_WIN32)
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#elif defined UNX
+#include <unistd.h>
+#include <fcntl.h>
+#endif
+
+namespace comphelper
+{
+#if defined DBG_UTIL && !defined NDEBUG
+bool isDebuggerAttached()
+{
+#if defined(_WIN32)
+ return IsDebuggerPresent();
+#elif defined LINUX
+ char buf[4096];
+ int fd = open("/proc/self/status", O_RDONLY);
+ if (fd < 0)
+ return false;
+ int size = read(fd, buf, sizeof(buf) - 1);
+ close(fd);
+ if (size < 0)
+ return false;
+ assert(size < int(sizeof(buf)) - 1);
+ buf[sizeof(buf) - 1] = '\0';
+ // "TracerPid: <pid>" for pid != 0 means something is attached
+ const char* pos = strstr(buf, "TracerPid:");
+ if (pos == nullptr)
+ return false;
+ pos += strlen("TracerPid:");
+ while (*pos != '\n' && isspace(*pos))
+ ++pos;
+ return *pos != '\n' && *pos != '0';
+#else
+ return false; // feel free to add your platform
+#endif
+}
+#endif
+
+} // namespace comphelper
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/comphelper/source/misc/threadpool.cxx b/comphelper/source/misc/threadpool.cxx
index 9b1991b7f3a1..9dfbff0e2900 100644
--- a/comphelper/source/misc/threadpool.cxx
+++ b/comphelper/source/misc/threadpool.cxx
@@ -19,6 +19,7 @@
#include <memory>
#include <thread>
#include <chrono>
+#include <comphelper/debuggerinfo.hxx>
#if defined HAVE_VALGRIND_HEADERS
#include <valgrind/memcheck.h>
@@ -320,36 +321,6 @@ bool ThreadTaskTag::isDone()
return mnTasksWorking == 0;
}
-#if defined DBG_UTIL && !defined NDEBUG
-static bool isDebuggerAttached()
-{
-#if defined(_WIN32)
- return IsDebuggerPresent();
-#elif defined LINUX
- char buf[ 4096 ];
- int fd = open( "/proc/self/status", O_RDONLY );
- if( fd < 0 )
- return false;
- int size = read( fd, buf, sizeof( buf ) - 1 );
- close( fd );
- if( size < 0 )
- return false;
- assert( size < int( sizeof( buf )) - 1 );
- buf[ sizeof( buf ) - 1 ] = '\0';
- // "TracerPid: <pid>" for pid != 0 means something is attached
- const char* pos = strstr( buf, "TracerPid:" );
- if( pos == nullptr )
- return false;
- pos += strlen( "TracerPid:" );
- while( *pos != '\n' && isspace( *pos ))
- ++pos;
- return *pos != '\n' && *pos != '0';
-#else
- return false; // feel free to add your platform
-#endif
-}
-#endif
-
void ThreadTaskTag::waitUntilDone()
{
std::unique_lock< std::mutex > aGuard( maMutex );
diff --git a/include/comphelper/debuggerinfo.hxx b/include/comphelper/debuggerinfo.hxx
new file mode 100644
index 000000000000..8c4c0a4cb2c6
--- /dev/null
+++ b/include/comphelper/debuggerinfo.hxx
@@ -0,0 +1,38 @@
+/* -*- 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/.
+ */
+
+#ifndef INCLUDED_COMPHELPER_DEBUGINFO_HXX
+#define INCLUDED_COMPHELPER_DEBUGINFO_HXX
+
+#include <comphelper/comphelperdllapi.h>
+
+namespace comphelper
+{
+#if defined DBG_UTIL
+/// Returns true if the process is running with a debugger attached.
+///
+/// This is useful to disable watchdogs or increase timeouts if they trigger
+/// too soon while using a debugger.
+COMPHELPER_DLLPUBLIC bool isDebuggerAttached();
+#endif
+
+// For detecting whether Valgrind is used, add valgrind to gb_Library_use_externals
+// and then in code use:
+// #if defined HAVE_VALGRIND_HEADERS
+// #include <valgrind/memcheck.h>
+// #endif
+// ...
+// #if defined HAVE_VALGRIND_HEADERS
+// if( RUNNING_ON_VALGRIND )
+
+} // namespace comphelper
+
+#endif // INCLUDED_COMPHELPER_DEBUGINFO_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 397ad713cf9bc951b4882ca4b6baeb57541e318c
Author: Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Tue Feb 4 17:28:10 2020 +0100
Commit: Luboš Luňák <l.lunak at collabora.com>
CommitDate: Fri Feb 7 09:11:32 2020 +0100
merge OpenGLZone and OpenCLZone into one generic code
To be used also by Skia code to detect problems with Vulkan drivers.
The watchdog does not handle OpenCL because neither did the original
code, but also because OpenCLZone::hardDisable() called from it
would deadlock on SolarMutex for some reason.
Change-Id: I483d8cb0b11a4e1e65c564f4e4c29ab68843ff71
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/88008
Tested-by: Jenkins
Reviewed-by: Luboš Luňák <l.lunak at collabora.com>
diff --git a/desktop/scripts/soffice.sh b/desktop/scripts/soffice.sh
index 415ea047361d..5538c968ee18 100755
--- a/desktop/scripts/soffice.sh
+++ b/desktop/scripts/soffice.sh
@@ -130,7 +130,7 @@ for arg in "$@" $EXTRAOPT ; do
unset MALLOC_CHECK_ MALLOC_PERTURB_ G_SLICE
export SAL_DISABLE_FLOATGRAB=1
export OOO_DISABLE_RECOVERY=1
- export SAL_DISABLE_GL_WATCHDOG=1
+ export SAL_DISABLE_WATCHDOG=1
export LD_BIND_NOW=1
;;
esac
diff --git a/desktop/source/app/opencl.cxx b/desktop/source/app/opencl.cxx
index 4cbea032a15c..a1fe3c0f6aea 100644
--- a/desktop/source/app/opencl.cxx
+++ b/desktop/source/app/opencl.cxx
@@ -193,7 +193,7 @@ void Desktop::CheckOpenCLCompute(const Reference< XDesktop2 > &xDesktop)
SAL_INFO("opencl", "Initiating test of OpenCL device");
OpenCLZone aZone;
- OpenCLZone::enterInitialTest();
+ OpenCLInitialZone aInitialZone;
OUString aDevice = officecfg::Office::Calc::Formula::Calculation::OpenCLDevice::get();
OUString aSelectedCLDeviceVersionID;
diff --git a/include/comphelper/crashzone.hxx b/include/comphelper/crashzone.hxx
new file mode 100644
index 000000000000..6cbbe718f8a4
--- /dev/null
+++ b/include/comphelper/crashzone.hxx
@@ -0,0 +1,72 @@
+/* -*- 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/.
+ */
+
+#ifndef INCLUDED_COMPHELPER_CRASHZONE_H
+#define INCLUDED_COMPHELPER_CRASHZONE_H
+
+#include <sal/config.h>
+#include <sal/types.h>
+#include <comphelper/comphelperdllapi.h>
+
+#include <atomic>
+#include <csignal>
+#include <type_traits>
+
+struct CrashWatchdogTimingsValues
+{
+ /// delays to take various actions in 1/4 of a second increments.
+ int mnDisableEntries;
+ int const mnAbortAfter;
+};
+
+/**
+ * A generic class for detecting if a given crash or a lock-up came from a specific
+ * area of code (such as OpenGL).
+ * Use this helper to track that.
+ * The class is a template so that there can be multiple instances of static variables.
+ */
+template <typename Dummy> class CrashZone
+{
+// gnEnterCount and gnLeaveCount are accessed both from multiple threads (cf.
+// WatchdogThread::execute; so need to be of atomic type) and from signal handlers (cf.
+// VCLExceptionSignal_impl; so need to be of lock-free atomic type). sig_atomic_t is chosen as
+// the underlying type under the assumption that it is most likely to lead to an atomic type
+// that is actually lock-free. However, gnEnterCount and gnLeaveCount are both monotonically
+// increasing, so will eventually overflow, so the underlying type better be unsigned, which
+// sig_atomic_t is not guaranteed to be:
+#if !defined ARM32 || (defined ARM32 && defined __ARM_PCS_VFP)
+ using AtomicCounter = std::atomic<std::make_unsigned_t<std::sig_atomic_t>>;
+ static_assert(AtomicCounter::is_always_lock_free);
+#else
+ using AtomicCounter = volatile std::make_unsigned_t<std::sig_atomic_t>;
+#endif
+
+ /// how many times have we entered a zone
+ static inline AtomicCounter gnEnterCount = 0;
+ /// how many times have we left a new zone
+ static inline AtomicCounter gnLeaveCount = 0;
+
+public:
+ CrashZone() { enter(); }
+ ~CrashZone() { leave(); }
+ static bool isInZone() { return gnEnterCount != gnLeaveCount; }
+ static const AtomicCounter& enterCount() { return gnEnterCount; }
+ // prefer creating instances to manually calling enter()/leave()
+ static void enter() { gnEnterCount++; }
+ static void leave() { gnLeaveCount++; }
+ // these should be implemented for each specific zone if needed
+ // static void hardDisable();
+ // static const CrashWatchdogTimingsValues& getCrashWatchdogTimingsValues();
+ // static void checkDebug(int nUnchanged, const CrashWatchdogTimingsValues& aTimingValues);
+ // static const char* name();
+};
+
+#endif // INCLUDED_COMPHELPER_CRASHZONE_H
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/opencl/OpenCLZone.hxx b/include/opencl/OpenCLZone.hxx
index 50d0f81c3191..1bbf3a46161c 100644
--- a/include/opencl/OpenCLZone.hxx
+++ b/include/opencl/OpenCLZone.hxx
@@ -12,45 +12,19 @@
#include <sal/config.h>
-#include <cassert>
-#include <csignal>
-
#include <opencl/opencldllapi.h>
-// FIXME: post back-port, templatize me and share with OpenGLZone.
-class OPENCL_DLLPUBLIC OpenCLZone
-{
- /// how many times have we entered a CL zone and not yet left it
- static volatile std::sig_atomic_t gnEnterCount;
- static volatile bool gbInInitialTest;
+#include <comphelper/crashzone.hxx>
+class OPENCL_DLLPUBLIC OpenCLZone : public CrashZone< OpenCLZone >
+{
public:
- OpenCLZone()
- {
- gnEnterCount = gnEnterCount + 1; //TODO: overflow
- }
-
- ~OpenCLZone()
- {
- // coverity[assert_side_effect]
- assert(gnEnterCount > 0);
- gnEnterCount = gnEnterCount - 1;
- if (!isInZone())
- gbInInitialTest = false;
- }
-
- static bool isInZone()
- {
- return gnEnterCount > 0;
- }
-
- static bool isInInitialTest()
- {
- return gbInInitialTest;
- }
-
static void hardDisable();
- static void enterInitialTest();
+};
+
+// Used during initial testing of OpenCL.
+class OPENCL_DLLPUBLIC OpenCLInitialZone : public CrashZone< OpenCLInitialZone >
+{
};
#endif // INCLUDED_OPENCL_INC_OPENCL_ZONE_HXX
diff --git a/include/sal/log-areas.dox b/include/sal/log-areas.dox
index ce0fa239b292..3ebe47afd2b4 100644
--- a/include/sal/log-areas.dox
+++ b/include/sal/log-areas.dox
@@ -504,6 +504,7 @@ certain functionality.
@li @c vcl.unx.dtrans
@li @c vcl.unx.print
@li @c vcl.virdev
+ at li @c vcl.watchdog
@li @c vcl.window
@li @c vcl.wmf
diff --git a/opencl/source/OpenCLZone.cxx b/opencl/source/OpenCLZone.cxx
index f7c8e961364d..43ac31899c4d 100644
--- a/opencl/source/OpenCLZone.cxx
+++ b/opencl/source/OpenCLZone.cxx
@@ -17,11 +17,6 @@
#include <com/sun/star/util/XFlushable.hpp>
#include <com/sun/star/configuration/theDefaultProvider.hpp>
-// FIXME: templatize me vs. OpenGLZone.
-
-std::sig_atomic_t volatile OpenCLZone::gnEnterCount = 0;
-bool volatile OpenCLZone::gbInInitialTest = false;
-
/**
* Called from a signal handler if we get
* a crash or hang in some CL code.
@@ -47,9 +42,4 @@ void OpenCLZone::hardDisable()
}
}
-void OpenCLZone::enterInitialTest()
-{
- gbInInitialTest = true;
-}
-
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index 3a7122f15b11..16be92968a92 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -399,6 +399,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
vcl/source/app/unohelp2 \
vcl/source/app/unohelp \
vcl/source/app/vclevent \
+ vcl/source/app/watchdog \
vcl/source/app/weldutils \
vcl/source/app/winscheduler \
vcl/source/components/dtranscomp \
diff --git a/vcl/README.vars b/vcl/README.vars
index 538c6975f26d..495c9679e401 100644
--- a/vcl/README.vars
+++ b/vcl/README.vars
@@ -36,7 +36,7 @@ OpenGL
SAL_FORCEGL - force enable OpenGL
SAL_GL_NO_SWAP - disable buffer swapping if set (should show nothing)
SAL_GL_SLEEP_ON_SWAP - sleep for half a second on each swap-buffers.
-SAL_DISABLE_GL_WATCHDOG - don't start the thread that watches for broken GL drivers
+SAL_DISABLE_WATCHDOG - don't start the thread that watches for broken GL/Vulkan/OpenCL drivers
Skia
----
diff --git a/vcl/inc/opengl/watchdog.hxx b/vcl/inc/opengl/watchdog.hxx
deleted file mode 100644
index a675894c4ff3..000000000000
--- a/vcl/inc/opengl/watchdog.hxx
+++ /dev/null
@@ -1,67 +0,0 @@
-/* -*- 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/.
- */
-
-#ifndef INCLUDED_VCL_INC_OPENGL_WATCHDOG_H
-#define INCLUDED_VCL_INC_OPENGL_WATCHDOG_H
-
-#include <sal/config.h>
-#include <salhelper/thread.hxx>
-#include <atomic>
-#include <vector>
-
-struct WatchdogTimingsValues
-{
- /// delays to take various actions in 1/4 of a second increments.
- int mnDisableEntries;
- int const mnAbortAfter;
-};
-
-enum class WatchdogTimingMode
-{
- NORMAL,
- SHADER_COMPILE
-};
-
-class WatchdogTimings
-{
-private:
- std::vector<WatchdogTimingsValues> maTimingValues;
- std::atomic<bool> mbRelaxed;
-
-public:
- WatchdogTimings();
-
- void setRelax(bool bRelaxed)
- {
- mbRelaxed = bRelaxed;
- }
-
- WatchdogTimingsValues const & getWatchdogTimingsValues(WatchdogTimingMode eMode)
- {
- size_t index = (eMode == WatchdogTimingMode::SHADER_COMPILE) ? 1 : 0;
- index = mbRelaxed ? index + 2 : index;
-
- return maTimingValues[index];
- }
-};
-
-class OpenGLWatchdogThread : private salhelper::Thread
-{
- OpenGLWatchdogThread();
- virtual void execute() override;
-public:
- using salhelper::Thread::acquire;
- using salhelper::Thread::release;
- static void start();
- static void stop();
-};
-
-#endif // INCLUDED_VCL_INC_OPENGL_WATCHDOG_H
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/opengl/zone.hxx b/vcl/inc/opengl/zone.hxx
index 90b7f48fd5a8..621ee4289b27 100644
--- a/vcl/inc/opengl/zone.hxx
+++ b/vcl/inc/opengl/zone.hxx
@@ -13,48 +13,19 @@
#include <sal/config.h>
#include <sal/types.h>
#include <vcl/dllapi.h>
-
-#include <atomic>
-#include <csignal>
-#include <type_traits>
-
-class OpenGLWatchdogThread;
+#include <comphelper/crashzone.hxx>
/**
* We want to be able to detect if a given crash came
* from the OpenGL code, so use this helper to track that.
*/
-class VCL_DLLPUBLIC OpenGLZone {
- friend class OpenGLWatchdogThread;
- friend class OpenGLSalGraphicsImpl;
-
- // gnEnterCount and gnLeaveCount are accessed both from multiple threads (cf.
- // OpenGLWatchdogThread::execute; so need to be of atomic type) and from signal handlers (cf.
- // VCLExceptionSignal_impl; so need to be of lock-free atomic type). sig_atomic_t is chosen as
- // the underlying type under the assumption that it is most likely to lead to an atomic type
- // that is actually lock-free. However, gnEnterCount and gnLeaveCount are both monotonically
- // increasing, so will eventually overflow, so the underlying type better be unsigned, which
- // sig_atomic_t is not guaranteed to be:
-#if !defined ARM32 || (defined ARM32 && defined __ARM_PCS_VFP)
- using AtomicCounter = std::atomic<std::make_unsigned_t<std::sig_atomic_t>>;
- static_assert(AtomicCounter::is_always_lock_free);
-#else
- using AtomicCounter = volatile std::make_unsigned_t<std::sig_atomic_t>;
-#endif
-
- /// how many times have we entered a GL zone
- static AtomicCounter gnEnterCount;
- /// how many times have we left a new GL zone
- static AtomicCounter gnLeaveCount;
-
- static void enter() { gnEnterCount++; }
- static void leave() { gnLeaveCount++; }
+class VCL_DLLPUBLIC OpenGLZone : public CrashZone< OpenGLZone > {
public:
- OpenGLZone() { enter(); }
- ~OpenGLZone() { leave(); }
- static bool isInZone() { return gnEnterCount != gnLeaveCount; }
static void hardDisable();
static void relaxWatchdogTimings();
+ static const CrashWatchdogTimingsValues& getCrashWatchdogTimingsValues();
+ static void checkDebug( int nUnchanged, const CrashWatchdogTimingsValues& aTimingValues );
+ static const char* name() { return "OpenGL"; }
};
/// Create this to not only enter the zone, but set VCL context.
diff --git a/vcl/inc/watchdog.hxx b/vcl/inc/watchdog.hxx
new file mode 100644
index 000000000000..ee357fb2dc89
--- /dev/null
+++ b/vcl/inc/watchdog.hxx
@@ -0,0 +1,32 @@
+/* -*- 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/.
+ */
+
+#ifndef INCLUDED_VCL_INC_WATCHDOG_H
+#define INCLUDED_VCL_INC_WATCHDOG_H
+
+#include <sal/config.h>
+#include <salhelper/thread.hxx>
+#include <atomic>
+#include <vector>
+
+class WatchdogThread : private salhelper::Thread
+{
+ WatchdogThread();
+ virtual void execute() override;
+
+public:
+ using salhelper::Thread::acquire;
+ using salhelper::Thread::release;
+ static void start();
+ static void stop();
+};
+
+#endif // INCLUDED_VCL_INC_WATCHDOG_H
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/app/svmain.cxx b/vcl/source/app/svmain.cxx
index b8c97d08d9c8..207a6ff4eaad 100644
--- a/vcl/source/app/svmain.cxx
+++ b/vcl/source/app/svmain.cxx
@@ -88,7 +88,7 @@
#include <opencl/OpenCLZone.hxx>
#include <opengl/zone.hxx>
-#include <opengl/watchdog.hxx>
+#include <watchdog.hxx>
#include <basegfx/utils/systemdependentdata.hxx>
#include <tools/diagnose_ex.h>
@@ -128,7 +128,7 @@ static oslSignalAction VCLExceptionSignal_impl( void* /*pData*/, oslSignalInfo*
{
OpenCLZone::hardDisable();
#ifdef _WIN32
- if (OpenCLZone::isInInitialTest())
+ if (OpenCLInitialZone::isInZone())
TerminateProcess(GetCurrentProcess(), EXITHELPER_NORMAL_RESTART);
#endif
}
@@ -212,9 +212,7 @@ int ImplSVMain()
pSVData->mxAccessBridge.clear();
}
-#if HAVE_FEATURE_OPENGL
- OpenGLWatchdogThread::stop();
-#endif
+ WatchdogThread::stop();
DeInitVCL();
return nReturn;
diff --git a/vcl/source/app/watchdog.cxx b/vcl/source/app/watchdog.cxx
new file mode 100644
index 000000000000..c6c43e7e013b
--- /dev/null
+++ b/vcl/source/app/watchdog.cxx
@@ -0,0 +1,144 @@
+/* -*- 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/.
+ */
+
+#include <watchdog.hxx>
+
+#include <config_features.h>
+
+#include <osl/conditn.hxx>
+#include <rtl/ref.hxx>
+#include <rtl/string.hxx>
+#include <sal/log.hxx>
+#include <opengl/zone.hxx>
+
+#include <stdlib.h>
+
+namespace
+{
+static volatile bool gbWatchdogFiring = false;
+static osl::Condition* gpWatchdogExit = nullptr;
+static rtl::Reference<WatchdogThread> gxWatchdog;
+
+template <typename Zone> struct WatchdogHelper
+{
+ static inline sal_uInt64 nLastEnters = 0;
+ static inline int nUnchanged = 0; // how many unchanged nEnters
+ static inline bool bFired = false;
+ static inline bool bAbortFired = false;
+ static void setLastEnters() { nLastEnters = Zone::enterCount(); }
+ static void check()
+ {
+ if (Zone::isInZone())
+ {
+ const CrashWatchdogTimingsValues& aTimingValues = Zone::getCrashWatchdogTimingsValues();
+
+ if (nLastEnters == Zone::enterCount())
+ nUnchanged++;
+ else
+ nUnchanged = 0;
+ Zone::checkDebug(nUnchanged, aTimingValues);
+
+ // Not making progress
+ if (nUnchanged >= aTimingValues.mnDisableEntries)
+ {
+ if (!bFired)
+ {
+ gbWatchdogFiring = true;
+ SAL_WARN("vcl.watchdog",
+ OStringLiteral("Watchdog triggered: hard disable ") + Zone::name());
+ Zone::hardDisable();
+ gbWatchdogFiring = false;
+ }
+ bFired = true;
+
+ // we can hang using VCL in the abort handling -> be impatient
+ if (bAbortFired)
+ {
+ SAL_WARN("vcl.watchdog",
+ OStringLiteral("Watchdog gave up: hard exiting ") + Zone::name());
+ _Exit(1);
+ }
+ }
+
+ // Not making even more progress
+ if (nUnchanged >= aTimingValues.mnAbortAfter)
+ {
+ if (!bAbortFired)
+ {
+ SAL_WARN("vcl.watchdog",
+ OStringLiteral("Watchdog gave up: aborting ") + Zone::name());
+ gbWatchdogFiring = true;
+ std::abort();
+ }
+ // coverity[dead_error_line] - we might have caught SIGABRT and failed to exit yet
+ bAbortFired = true;
+ }
+ }
+ else
+ {
+ nUnchanged = 0;
+ }
+ }
+};
+
+} // namespace
+
+WatchdogThread::WatchdogThread()
+ : salhelper::Thread("Crash Watchdog")
+{
+}
+
+void WatchdogThread::execute()
+{
+ TimeValue aQuarterSecond(0, 1000 * 1000 * 1000 * 0.25);
+ do
+ {
+#if HAVE_FEATURE_OPENGL
+ WatchdogHelper<OpenGLZone>::setLastEnters();
+#endif
+
+ gpWatchdogExit->wait(&aQuarterSecond);
+
+#if HAVE_FEATURE_OPENGL
+ WatchdogHelper<OpenGLZone>::check();
+#endif
+
+ } while (!gpWatchdogExit->check());
+}
+
+void WatchdogThread::start()
+{
+ if (gxWatchdog != nullptr)
+ return; // already running
+ if (getenv("SAL_DISABLE_WATCHDOG"))
+ return;
+ gpWatchdogExit = new osl::Condition();
+ gxWatchdog.set(new WatchdogThread());
+ gxWatchdog->launch();
+}
+
+void WatchdogThread::stop()
+{
+ if (gbWatchdogFiring)
+ return; // in watchdog thread
+
+ if (gpWatchdogExit)
+ gpWatchdogExit->set();
+
+ if (gxWatchdog.is())
+ {
+ gxWatchdog->join();
+ gxWatchdog.clear();
+ }
+
+ delete gpWatchdogExit;
+ gpWatchdogExit = nullptr;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/opengl/OpenGLHelper.cxx b/vcl/source/opengl/OpenGLHelper.cxx
index 1c9fa66436c8..081bf240cc8b 100644
--- a/vcl/source/opengl/OpenGLHelper.cxx
+++ b/vcl/source/opengl/OpenGLHelper.cxx
@@ -29,12 +29,11 @@
#include <unordered_map>
#include <opengl/zone.hxx>
-#include <opengl/watchdog.hxx>
-#include <osl/conditn.hxx>
#include <vcl/opengl/OpenGLWrapper.hxx>
#include <vcl/opengl/OpenGLContext.hxx>
#include <desktop/crashreport.hxx>
#include <bitmapwriteaccess.hxx>
+#include <watchdog.hxx>
#if defined UNX && !defined MACOSX && !defined IOS && !defined ANDROID && !defined HAIKU
#include <opengl/x11/X11DeviceInfo.hxx>
@@ -45,8 +44,6 @@
#include "GLMHelper.hxx"
static bool volatile gbInShaderCompile = false;
-OpenGLZone::AtomicCounter OpenGLZone::gnEnterCount = 0;
-OpenGLZone::AtomicCounter OpenGLZone::gnLeaveCount = 0;
namespace {
@@ -793,121 +790,50 @@ bool OpenGLHelper::supportsVCLOpenGL()
return !bDisableGL && !bBlacklisted;
}
-namespace {
- static volatile bool gbWatchdogFiring = false;
- static osl::Condition* gpWatchdogExit = nullptr;
- static WatchdogTimings gWatchdogTimings;
- static rtl::Reference<OpenGLWatchdogThread> gxWatchdog;
-}
-
-WatchdogTimings::WatchdogTimings()
- : maTimingValues{
- {{6, 20} /* 1.5s, 5s */, {20, 120} /* 5s, 30s */,
- {60, 240} /* 15s, 60s */, {60, 240} /* 15s, 60s */}
- }
- , mbRelaxed(false)
+namespace
{
-}
-OpenGLWatchdogThread::OpenGLWatchdogThread()
- : salhelper::Thread("OpenGL Watchdog")
+enum class CrashWatchdogTimingMode
{
-}
+ NORMAL,
+ SHADER_COMPILE
+};
-void OpenGLWatchdogThread::execute()
+class CrashWatchdogTimings
{
- int nUnchanged = 0; // how many unchanged nEnters
- TimeValue aQuarterSecond(0, 1000*1000*1000*0.25);
- bool bAbortFired = false;
+private:
+ std::vector<CrashWatchdogTimingsValues> maTimingValues;
+ std::atomic<bool> mbRelaxed;
- do {
- sal_uInt64 nLastEnters = OpenGLZone::gnEnterCount;
+public:
+ CrashWatchdogTimings();
- gpWatchdogExit->wait(&aQuarterSecond);
+ void setRelax(bool bRelaxed)
+ {
+ mbRelaxed = bRelaxed;
+ }
- if (OpenGLZone::isInZone())
- {
- // The shader compiler can take a long time, first time.
- WatchdogTimingMode eMode = gbInShaderCompile ? WatchdogTimingMode::SHADER_COMPILE : WatchdogTimingMode::NORMAL;
- WatchdogTimingsValues aTimingValues = gWatchdogTimings.getWatchdogTimingsValues(eMode);
+ CrashWatchdogTimingsValues const & getWatchdogTimingsValues(CrashWatchdogTimingMode eMode)
+ {
+ size_t index = (eMode == CrashWatchdogTimingMode::SHADER_COMPILE) ? 1 : 0;
+ index = mbRelaxed ? index + 2 : index;
- if (nLastEnters == OpenGLZone::gnEnterCount)
- nUnchanged++;
- else
- nUnchanged = 0;
- SAL_INFO("vcl.opengl", "GL watchdog - unchanged " <<
- nUnchanged << " enter count " <<
- OpenGLZone::gnEnterCount << " type " <<
- (eMode == WatchdogTimingMode::SHADER_COMPILE ? "in shader" : "normal gl") <<
- "breakpoints mid: " << aTimingValues.mnDisableEntries <<
- " max " << aTimingValues.mnAbortAfter);
-
- // Not making progress
- if (nUnchanged >= aTimingValues.mnDisableEntries)
- {
- static bool bFired = false;
- if (!bFired)
- {
- gbWatchdogFiring = true;
- SAL_WARN("vcl.opengl", "Watchdog triggered: hard disable GL");
- OpenGLZone::hardDisable();
- gbWatchdogFiring = false;
- }
- bFired = true;
-
- // we can hang using VCL in the abort handling -> be impatient
- if (bAbortFired)
- {
- SAL_WARN("vcl.opengl", "Watchdog gave up: hard exiting");
- _exit(1);
- }
- }
+ return maTimingValues[index];
+ }
+};
- // Not making even more progress
- if (nUnchanged >= aTimingValues.mnAbortAfter)
- {
- if (!bAbortFired)
- {
- SAL_WARN("vcl.opengl", "Watchdog gave up: aborting");
- gbWatchdogFiring = true;
- std::abort();
- }
- // coverity[dead_error_line] - we might have caught SIGABRT and failed to exit yet
- bAbortFired = true;
- }
- }
- else
- {
- nUnchanged = 0;
- }
- } while (!gpWatchdogExit->check());
-}
+static CrashWatchdogTimings gWatchdogTimings;
-void OpenGLWatchdogThread::start()
+CrashWatchdogTimings::CrashWatchdogTimings()
+ : maTimingValues{
+ {{6, 20} /* 1.5s, 5s */, {20, 120} /* 5s, 30s */,
+ {60, 240} /* 15s, 60s */, {60, 240} /* 15s, 60s */}
+ }
+ , mbRelaxed(false)
{
- assert (gxWatchdog == nullptr);
- gpWatchdogExit = new osl::Condition();
- gxWatchdog.set(new OpenGLWatchdogThread());
- gxWatchdog->launch();
}
-void OpenGLWatchdogThread::stop()
-{
- if (gbWatchdogFiring)
- return; // in watchdog thread
-
- if (gpWatchdogExit)
- gpWatchdogExit->set();
-
- if (gxWatchdog.is())
- {
- gxWatchdog->join();
- gxWatchdog.clear();
- }
-
- delete gpWatchdogExit;
- gpWatchdogExit = nullptr;
-}
+} // namespace
/**
* Called from a signal handler or watchdog thread if we get
@@ -932,8 +858,6 @@ void OpenGLZone::hardDisable()
css::configuration::theDefaultProvider::get(
comphelper::getProcessComponentContext()),
css::uno::UNO_QUERY_THROW)->flush();
-
- OpenGLWatchdogThread::stop();
}
}
@@ -942,6 +866,22 @@ void OpenGLZone::relaxWatchdogTimings()
gWatchdogTimings.setRelax(true);
}
+void OpenGLZone::checkDebug( int nUnchanged, const CrashWatchdogTimingsValues& aTimingValues )
+{
+ SAL_INFO("vcl.watchdog", "GL watchdog - unchanged "
+ << nUnchanged << " enter count " << enterCount() << " type "
+ << (gbInShaderCompile ? "in shader" : "normal gl")
+ << " breakpoints mid: " << aTimingValues.mnDisableEntries
+ << " max " << aTimingValues.mnAbortAfter);
+}
+
+const CrashWatchdogTimingsValues& OpenGLZone::getCrashWatchdogTimingsValues()
+{
+ // The shader compiler can take a long time, first time.
+ CrashWatchdogTimingMode eMode = gbInShaderCompile ? CrashWatchdogTimingMode::SHADER_COMPILE : CrashWatchdogTimingMode::NORMAL;
+ return gWatchdogTimings.getWatchdogTimingsValues(eMode);
+}
+
OpenGLVCLContextZone::OpenGLVCLContextZone()
{
OpenGLContext::makeVCLCurrent();
@@ -1019,10 +959,8 @@ bool OpenGLHelper::isVCLOpenGLEnabled()
}
if (bRet)
- {
- if (!getenv("SAL_DISABLE_GL_WATCHDOG"))
- OpenGLWatchdogThread::start();
- }
+ WatchdogThread::start();
+
CrashReporter::addKeyValue("UseOpenGL", OUString::boolean(bRet), CrashReporter::Write);
return bRet;
More information about the Libreoffice-commits
mailing list