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

Using tbb in a plugin (for maya)

vanswaaij
Beginner
186 Views
Maya is an animation package that supports user written extensions using plugins.
Plugins are compiled as dynamic shared libraries and loaded, beyond our control, into the package.
Any advice on how to load the tbb library, which itself is dynamically shared?

Thanks.
0 Kudos
4 Replies
pvonkaenel
New Contributor III
186 Views
Quoting - vanswaaij
Maya is an animation package that supports user written extensions using plugins.
Plugins are compiled as dynamic shared libraries and loaded, beyond our control, into the package.
Any advice on how to load the tbb library, which itself is dynamically shared?

Thanks.

I'm going to guess that your DLL is run-time dynamic linked from Maya using LoadLibrary(). You can using standard load-time dynamic linking in your DLL to the TBB DLL - I've done this in a plug-in for another package. You can then create the scheduler like in the following:

[cpp]tbb::task_scheduler_init g_tbbinit(tbb::task_scheduler_init::deferred);


BOOL APIENTRY DllMain( HMODULE /*hModule*/,
                       DWORD  ul_reason_for_call,
                       LPVOID /*lpReserved*/ )
{
    switch (ul_reason_for_call) {
        case DLL_PROCESS_ATTACH:
            ippStaticInit();
            g_tbbinit.initialize();
            break;
        case DLL_THREAD_ATTACH:
        case DLL_THREAD_DETACH:
            break;
        case DLL_PROCESS_DETACH:
            g_tbbinit.terminate();
            break;
    }
    return TRUE;
}
[/cpp]


Note, however, that I've experienced deadlock in the terminate() call if the application calls FreeLibrary() on your DLL. If you bump into this, let me know and I'll upload my potentially risky solution to this problem.

Then add a tbb::task_scheduler_init instance to each routine that uses TBB (since you don't know what thread from Maya has called it), and use TBB normally.

Peter
vanswaaij
Beginner
186 Views
Thanks for your reply. I'm not familiar with the calls you describe, is that linux or windows?
pvonkaenel
New Contributor III
186 Views
Quoting - vanswaaij
Thanks for your reply. I'm not familiar with the calls you describe, is that linux or windows?

Windows. Not sure what you need to do for Linux. Is there a DllMain() equivalent in Linux where TBB can be initialized?
Roman_D_Intel
Employee
186 Views
Quoting - pvonkaenel

Windows. Not sure what you need to do for Linux. Is there a DllMain() equivalent in Linux where TBB can be initialized?


Hi,

an equivalent in Linux would be library constructor/destructor functions. If you use gcc/g++ you can mark your library initialization function as "__attribute__ ((constructor))" and the cleanup function as "__attribute__ ((destructor))".

[cpp]void my_init() __attribute__ ((constructor))
{
   // init tbb here
}

void my_fini() __attribute__ ((destructor))
{
  // call tbb clean up functions
}[/cpp]


A more platform-independent way of doing init/cleanup would be using a static C++ object that calls tbb initialization in its constructor and cleans up tbb in the destructor:

[cpp]struct TBBInitFini
{
     TBBInitFini()
     {
         // init tbb here
     }
     ~TBBInitFini()
     {
         // clean up tbb here
     }
};

static TBBInitFini tbbInitFini;
[/cpp]


When your library will be loaded the static objectconstructor will be called and on library unload the destructor.

Hope thiscan help,

Roman

Reply