Skip to content

Commit 5172def

Browse files
committed
Work around buggy OpenCL ICD loader
ocl-icd under 2.2.3 calls dlopen() in its library constructor and accesses a thread local variable in the process. This causes all subsequent access to any other thread local variables to deadlock. The bug is fixed in ocl-icd 2.2.4, which is not in stable releases in Ubuntu or Debian. Thus this provides a workaround given buggy ocl-icd. To avoid access to thread local variable, errno, std::ostream with unitbuf, and exception handling in libstdc++ cannot be used. This commit checks ocl-icd version, and refactor the OpenCL processor to not use exceptions. Then disable unitbuf on std::cerr and disable all exceptions with -fno-exceptions (when available). This commit and the ocl-icd bug do not affect Mac OS X or Windows.
1 parent 0dbff0a commit 5172def

File tree

4 files changed

+185
-146
lines changed

4 files changed

+185
-146
lines changed

examples/protonect/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,13 @@ IF(ENABLE_OPENCL)
166166
LIST(APPEND RESOURCES
167167
src/opencl_depth_packet_processor.cl
168168
)
169+
170+
# Major Linux distro stable releases have buggy OpenCL ICD loader.
171+
# The workaround of disabling exceptions can only be set up during compile time.
172+
# Diabling it for all should be harmless. The flag is the same for GCC/Clang/ICC.
173+
IF(UNIX AND NOT APPLE)
174+
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions")
175+
ENDIF()
169176
ENDIF(OPENCL_FOUND)
170177
ENDIF(ENABLE_OPENCL)
171178

examples/protonect/src/logging.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,12 @@ class ConsoleLogger : public Logger
9797
ConsoleLogger(Level level)
9898
{
9999
level_ = level;
100+
//std::ios_base::unitbuf causes automatic flushing which access
101+
//thread local variable via std::uncaught_exception().
102+
//This causes deadlock with ocl-icd until its recent update.
103+
//Accessing TLS has a slight performance penalty.
104+
//log() always flush the ostream so unitbuf is unnecessary anyway.
105+
std::nounitbuf(std::cerr);
100106
}
101107
virtual ~ConsoleLogger() {}
102108
virtual void log(Level level, const std::string &message)

0 commit comments

Comments
 (0)