Building Multi-threaded Panda from source

hello,

After reading this blog post
http://www.panda3d.org/manual/index.php/Multithreaded_Render_Pipeline

I thought I give it a try.

I am a bit confused as to where I have to set the
HAVE_THREADS define ?

also in what relation stands the “–threads N” in the compile options ? So If I specify N as 3 I’ll get 3 threads, will those be “App/Cull/Draw” ? so If I want to have a fourth thread for lets say background operations I need to define 4 right ?
Is there somewhere some C++ examples/documentation that explains how to work those threads in panda ?

and in the manual it says :

but if you read what the string “above” actually says

it doesn’t mention “app” ? is that implicit ?

Chrys [/b]

If you download the latest source from cvs (not the 1.7.2 version, but more recent than that), then you don’t have to change HAVE_THREADS, because it’s already set correctly for you. (If you’re using the 1.7.2 version, this won’t work anyway, so you should get the more recent version.)

The --threads option for compiling only refers to the number of threads that are used while compiling. It has nothing to do with the number of threads that the resulting program can use.

App is always the main thread, it is implicit.

David

I download my source directly from the panda repository…so it should be the latest version.

Is there some c++ example floating around where it is explained how to use the threads ?

What more do you need other than “threading-model Cull/Draw”? There’s no code change required.

David

I’d like to create my own background thread to execute code on (other thatn the main thread running my app).

If you want to create low-level threads yourself, go ahead and do it using your favorite low-level threading constructs. Panda won’t get in your way.

If you want to use Panda’s threading constructs (which are a thin wrapper around the OS’s threading constructs), see the Thread class in the API reference. This assumes you already have some experience with writing threaded code.

You can also use the Task Chain interface to create threads, but in C++ this isn’t any easier than using low-level threading constructs yourself, so I’d recommend just creating threads yourself.

David

I’ve now enabled in my config.prc

threading-model Cull/Draw

but my code now appears to hang here

	WindowProperties prop; 
	gTheFramework.get_default_window_props(prop);
	prop.set_parent_window((size_t)pandaFrame->winId()); 
	prop.set_title("Panda Viewer");
	prop.set_size(pandaFrame->width(), pandaFrame->height());
	prop.set_origin(0,0);
	
	gTheWindow = gTheFramework.open_window(prop,0); 

to be precise here

gTheWindow = gTheFramework.open_window(prop,0);

I’ve read in the blog that this could be the cause

if that is the cause of my hang - how do I fix this in c++ ?

Passing a WindowProperties to PandaFramework::open_window() is the correct thing to do. I don’t see anything wrong in the code you paste, so I don’t know why, offhand, it is hanging. I presume you are not creating a child thread at this point and you are not running this open_window() call from another thread than the main thread?

If you can provide a simple program that reproduces the hanging problem, I should be able to investigate it. Otherwise, you will have to break into it with a debugger and see what, specifically, it is hanging on yourself.

David

Oh, wait. You are passing a parent window, which has been known to cause problems with threading (the problem is that the parent window has to get window update messages while the child window is being created).

What parent window are you using? What kind of window is it, where was it created? Who is processing the window update loop for the parent window?

David

ok I’ve done some debugging and the problems seems on of the threads down in this code

void GraphicsEngine::
open_windows() {
  Thread *current_thread = Thread::get_current_thread();

  MutexHolder holder(_lock, current_thread);

  if (!_windows_sorted) {
    do_resort_windows();
  }

  // We do it twice, to allow both cull and draw to process the
  // window.
  for (int i = 0; i < 2; ++i) {
    _app.do_windows(this, current_thread);
    _app.do_pending(this, current_thread);

    PStatTimer timer(_wait_pcollector, current_thread);
    Threads::const_iterator ti;
    for (ti = _threads.begin(); ti != _threads.end(); ++ti) {
      RenderThread *thread = (*ti).second;
 HERE -->     thread->_cv_mutex.acquire();
      
      while (thread->_thread_state != TS_wait) {
        thread->_cv_done.wait();
      }
      
      thread->_thread_state = TS_do_windows;
      thread->_cv_start.notify();
      thread->_cv_mutex.release();
    }
  }

the thread->_cv_mutex.acquire(); seems to get stuck on

////////////////////////////////////////////////////////////////////
//     Function: MutexWin32Impl::acquire
//       Access: Public
//  Description: 
////////////////////////////////////////////////////////////////////
INLINE void MutexWin32Impl::
acquire() {
  EnterCriticalSection(&_lock);
}

I can’t step into that function.

It executes thread->_cv_mutex.acquire(); 3 times before it gets stuck.

I use “Qt” for building my windows app and pass in a frame winId handle as parent window

int main(int argc, char *argv[])
{
	ConfigPage* pConfig = load_prc_file("../Data/AWEditor/Configs/Config.prc");

	QApplication application(argc, argv);
	AWEditor awe;
	gAWEditor = &awe;

	awe.showMaximized();

	gTheFramework.open_framework(argc, argv); 
	

	QWidget* pandaFrame = awe.PandaFrame();

	WindowProperties prop; 
	gTheFramework.get_default_window_props(prop);
	prop.set_parent_window((size_t)pandaFrame->winId()); 
	prop.set_title("Viewer");
	prop.set_size(pandaFrame->width(), pandaFrame->height());
	prop.set_origin(0,0);
	

	gTheWindow = gTheFramework.open_window(prop,0); 
	gTheWindow->set_background_type(WindowFramework::BT_gray);

...........
......
....
	

}

Ah, as I look back in my logs, I see that I haven’t found a solution to this problem yet.

So, for now, you cannot use threading-model in conjunction with a window attached to another parent window. Sorry. You must remain single-threaded.

David

okay I’ll put panda’s multi-threading on the backburner for now then.

I still need to look into implementing a secondary thread for some background works I need to perform.

Looking forward to see a fix for this though :slight_smile:
I am probably not the only one who runs his panda app with a parent window.

Are there any news about this issue ?

No, not yet.