VisionWorks Toolkit Reference

April 8, 2016 | 1.4 Release

 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
Thread Safety

The most of NVXIO API is not considered to be thread safe.

The following needs explicit syncronization points:

The following NVXIO classes are thread safe:

One of the most dangerous classes, in terms of thread safety, is FrameSrouce as well as Render and Render3D. Internally, the instances of FrameSource use thread unsafe CUDA EGL Interoperability API, NvMedia API, hold CUDA device memory and so on. Both Render and Render3D use CUDA OpenGL interop and hold some CUDA resources, which can be unsafe in multi GPU environment.

Valid Concurrent Calls

The following examples describe the variants of FrameSource and Render usage, that are treated as thread safe:

Valid FrameSource Example

// from any thread
std::unique_ptr<nvxio::FrameSource> source(nvxio::createDefaultFrameSource(context, uri));
NVXIO_ASSERT(source->open());
source->fetch(image);

Valid FrameSource Usage in Multi GPU Environment

// from main thread with CUDA device ID 1
std::unique_ptr<nvxio::FrameSource> frameSource = nvxio::createDefaultFrameSource(context, uri);
NVXIO_ASSERT(nullptr != frameSource);
// get CUDA device ID
int cudaDeviceID = -1;
// must return 1
NVXIO_ASSERT(cudaSuccess == cudaGetDevice(&cudaDeviceID));
// from another thread
// set current CUDA device, which will be used in `fetch` below
// to initialize CUDA context
NVXIO_ASSERT(cudaSuccess == cudaSetDevice(cudaDeviceID));
// initializes CUDA context internally
frameSource->fetch(image);

Valid Render Example

// from any thread
std::unique_ptr<nvxio::Render> render(nvxio::createDefaultRender(
context, "Valid Render usage", 640, 480));
render->putImage(image);
render->flush();

Invalid Concurrent Calls

The examples of usage, that is not guaranteed to be thread safe:

Invalid FrameSource Usage in Multi GPU Environment

// from main thread with CUDA device ID 1
std::unique_ptr<nvxio::FrameSource> source2(nvxio::createDefaultFrameSource(context, uri));
NVXIO_ASSERT(source->open());
// from another thread
// CUDA device ID is not explicitly set, so it's 0 by default.
// The code is unsafe because current thread may use internal
// framesource buffers, that belong to main thread and GPU 0
source2->fetch(image);

Invalid Render Usage in Multi GPU Environment

// from main thread with CUDA device 1
std::unique_ptr<nvxio::Render> render2(nvxio::createDefaultRender(
context, "Invalid Render usage from Multi GPU env", 640, 480));
// from another thread
// 1. OpenGL context is thread-local and cannot be used in 2 threads simultaneously.
// 2. CUDA device ID is not explicitly set, so it's 0 by default.
// The code is unsafe because current thread may use internal
// render CUDA resources, that belong to main thread with active GPU 0
render->putImage(image);