Intel® oneAPI Threading Building Blocks
Ask questions and share information about adding parallelism to your applications when using this threading library.

Forcing a specific task to a specific thread.

klaim
Beginner
557 Views
Hi,
I have a tbb::task that needs to do some work that involve manipulating OpenGL API.
However, OpenGL contexts cannot be called from different threads.
So each time my tbb::task implementation is executed by a different thread than the one where I created the OpenGL context, I get errors from the drivers implementations.
I tried to set affinity but as it is not guaranteed by TBB to stick to a specific thread, I still get some problems.
So, is there any way to make sure a task will be executed by the same thread?
I know it goes against the design of TBB but I want to be sure.
0 Kudos
4 Replies
Anton_M_Intel
Employee
557 Views
No, it is not possible with tbb::task. Please try thread_bound_filter in parallel_pipeline
instead. It requires a separete thread servicing the filter which is different from the thread which executes the pipeline.
0 Kudos
jimdempseyatthecove
Honored Contributor III
557 Views
If you were to program this in QuickThread, you would use:

    parallel_task(IsThreadNumber$ + OpenGLthreadNumber, aFun, arg1, arg2); // with or without args

Where OpenGLthreadNumber is the thread number you desire.

    intptr_t OpenGLthreadNumber = -1; // global scope
    ...
    // after thread pool init, as main thread
    OpenGLthreadNumber = qt_get_thread_num();

Some versions of OpenGL requires the process main thread to open the handle to GL, other versions do not.
You will have to decide as to if you want to use or not use the main thread for OpenGL.

Jim Dempsey
   
0 Kudos
SergeyKostrov
Valued Contributor II
557 Views
Quoting klaim
...So each time my tbb::task implementation is executed by a different thread than the one where I created
the OpenGL context, I get errors from the drivers implementations...


I think some kind of binding based on indexing could be used ( below is a pseudo-code / sorry, I didn't try it to execute ):

...
class CMyTask : public tbb::task
{
public :
     CMyTask( void ) { ... };

     CMyTask( int iNumber )
     {
          m_iNumber = iNumber;
     };

     ~CMyTask( void ){ ...  };

     tbb::task * execute()
     {
          if( m_iNumber == 1 )
          {
               ...do task 1...
          }
          else
          if( m_iNumber == 2 )
          {
               ...do task 2...
          }
          ...
          return ( tbb::task * )NULL;
     };

private:
     int m_iNumber;
};

I agree that it doesn't look good but if it works and allows to do what you want why not?

By the way, I use a similar trick with OpenMP when I need to "bind" some processing to some OpenMP thread.

Best regards,
Sergey

0 Kudos
klaim
Beginner
557 Views
Sergey, I'm sorry I don't understand what your example do exactly. Does it do something depending on which thread runs the task?
0 Kudos
Reply