Multithreading Freezes Program

Started by aZen, May 01, 2013, 08:35:43 PM

Previous topic - Next topic

aZen

Hello EgonOlsen,

I'm having a strange problem: When I set useMultipleThreads = true I can run the application fine on my virtual machine (win 7, 32 bit). However when I start it on a non virtual os (win 7, 64 bit) the application simply freezes (tested on two different computers).

With useMultipleThreads = false there is no problem at all. Could this be a problem with 64 bit os? I'm using the latest jpct built (http://jpct.de/download/beta/jpct.jar).

Thanks you,
aZen

EgonOlsen

Most likely some of your own code blocks proper initialization of the render thread. This usually happens if you are polling Display, Mouse or Keyboard from anywhere outside the rendering thread, i.e. from outside an implementation of an IPaintListener. Apart from that, i'm not aware of any problems with multi-threading support. If nothing else helps, get a thread dump when it hangs and post it.

aZen

#2
That sounds like it's gonna take a while to find the problem.

Attached the thread dump(s). Not sure how useful they're gonna be.

Let me briefly explain how the application is laid out:
- There are four rendering container (JPanel) and each of them contains a FrameBuffer
- Interaction on one container (mouse) can change the content of the other container and trigger a repaint. The input events are caught by the JPanel
- Repainting is done from four worker threads by calling JPanel.repaint() (synchronizing the calls, or calling directly doesn't help with the freeze)
- The FrameBuffer are recreated when the the container are re-sized (since resize(x,y) doesn't work with the software renderer).
- when the container needs to be repainted the JPanel.repaint() method is called (from a worker thread) which then calls an overridden JPanel.paintComponent(Graphics g1) method. This then draws the FrameBuffer(s) and some overlay on the graphics argument.

Note: Sometimes the application initializes correctly and doesn't freeze for a bit. Mouse interaction then causes a freeze very quickly.

You said that the input might be a problem. Is it correct to capture it in the JPanels (they live in the main thread)? I'm out of ideas how to tackle this. Any idea what I should try to find the issue? Currently I'm using VisualVM, but still getting used to it.
Things would be a lot easier if I could reproduce the problem in my production environment, but unfortunately there it's running great (I can see big improvements through the multi-threading actually).

Thank you for your help.

Edit: Could this have something to do with the graphic card (that is available when it freezes)? Is MODE_OPENGL used when there is no graphic card or is there a fallback to MODE_LEGACY in that case?

[attachment deleted by admin]

EgonOlsen

If you are using the software renderer, my post about input and display doesn't apply. Looking at the dump, it looks like as if there's a lock in resource loading. I don't think that this is related to the engine itself. It doesn't do any threaded loading of resources. The engine threads all seem to idle in sleep waiting for the next repaint which never happens, because AWT is locked.

aZen

Thank you for the help! I finally managed to fix the problem by decoupling swing "repaint" and the repaint logic (and using a lot of synchronization)..

aZen

#5
Nvm, it still happens. I restructured the entire application (to be sure nothing "fishy" is going on). The exact same thing still happens (just that now the freeze doesn't happen right at the start).

What kind of code are you pushing to the AWT from the rendering threads?

Note: Input is now entirely decoupled from the rendering/data processing thread.

Edit: From what I can see this caused by your code. It probably has to do with the fact that I'm rapidly updating objects in the world. Do I need to synchronize these updates?

If I find the time I'll write a test case.

EgonOlsen

#6
Quote
What kind of code are you pushing to the AWT from the rendering threads?

I'm not doing anything related to AWT in the software renderer except for making some drawImage-calls once the image has been rendered. Everything else is just multithreaded writing and reading of int-values in int[]-arrays with no relation to AWT at all. If you set Config.useMultiThreadedBlitting=true, these drawImages will be done in multiple threads, but that's about it.
I've no idea what the problem should be here...a test case would be really helpful.

EgonOlsen

Quote from: aZen on May 03, 2013, 10:54:56 PM
Edit: From what I can see this caused by your code. It probably has to do with the fact that I'm rapidly updating objects in the world. Do I need to synchronize these updates?
No, you don't have to, because that part isn't multi-threaded (at least not by simply setting this switch to true). When using the software renderer, all that runs in multiple threads is:


  • rasterizing the scene
  • downsampling the image
  • applying fog
  • copying the image onto the screen (if Config.useMultiThreadedBlitting is also true)

Which part of the dump makes you think that the lock is inside jPCT? I can't find that. All i'm seeing is stuff about java.util.concurrent, which i'm not using and rmi, which i'm not using either... ???

aZen

#8
Sorry, I didn't mean to be speculative. It's just that I restructured and separated all parts of my code that "touch" the jpct and the symptoms are still the same.

Without a clean testcase I can't really say anything for sure though. Will do it when I find some chunk of free time! Thanks for the help.

aZen

I think I really fixed the issue finally. It turned out there was some twisted thread calling going on that ended up synchronize blocking. Multithreading messes with your head, that's for sure :o All is working great so far and it's so fast!

Sorry for the trouble. I'm very grateful for all your help!