Adam Miles

Hi,

I thought now might be as good a time as any to try and get a grip on Threading in .Net and specifically for the 360. I've been having a a look at the "How to: Use a ThreadPool" article that is linked to at the bottom of the "Thread Pools in the .Net Compact Framework for Xbox 360" article in the XNA Help. The only problem with the example code seems to be that WaitHandle.WaitAll(...) does not exist on the 360, but does under Windows.

WaitHandle on the 360 seems to serve no purpose at all as it's only methods are Equals and ReferenceEquals... so I'm at a loss really. If we kick off a load of threads in the constructor of our entry class what is the best way of waiting until all the threads in the ThreadPool have finished what they are doing

My only other problem was that I couldn't change ProcessorAffinity, but I just read in an old forum post that the thread has to change it's own Affinity rather than getting another thread to do it, so that should be ok (not tested it yet).

Thanks *again*,

Adam Miles



Re: XNA Framework Threading - WaitHandle

Malmer

Just so you know. XNA runs on a single core on the xbox 360 so using multiple threads won't give you access to more cores. So unless you really need to run things in parallel there is no gain in running multithreaded anyways.

Now it would be nice with a working thread in the background and the game happening in the foreground, or maybe giving you a minigame while loading.





Re: XNA Framework Threading - WaitHandle

Adam Miles

I don't think you're right somehow.

XNA Game Studio Express games should not use hardware threads 0 or 2, which are reserved for system use. The following table identifies Xbox 360 hardware thread usage.

Hardware Thread Available Associated Processes
0 No Reserved. System notifications, transports, and services.
1 Yes Main game thread, XNA Game Studio Express host, and the .NET Compact Framework for Xbox 360.
2 No Reserved. Xbox 360 content asynchronous operations.
3 Yes Some portions of the Xbox 360 Guide or Dashboard.
4 Yes Xbox Live Marketplace downloads.
5 Yes Some portions of the Xbox 360 Guide or Dashboard.





Re: XNA Framework Threading - WaitHandle

Gerix

I assume what you mean by that is the XNA API needs a single thread.

I'm planning to run several background worker threads which would not touch XNA and just use .NET.





Re: XNA Framework Threading - WaitHandle

BlueG

When I read your post, I decided to look at the threading namespace myself to see what was supported. First off, according to the documentation, the WaitHandle class does support WaitOne on the 360.

Although, for the problem you describe, since WaitAll isn't supported and the ThreadPool's GetAvailable method also isn't supported, I would think the next most efficient way would be a member variable serving as a counter. When you create the threads, you could set the variable to the number of threads (before starting the threads), then as each thread finishes it can decrement that variable. Of course, you have to synchronize access to that variable, but that wouldn't be too hard. That could be accomplished using lock semantics. It would probably be best to put this code (to decrement the variable) in its own method. Meanwhile, where you would have used the WaitAll method, you just create a simple loop that keeps checking the variable (you'll need to synchronize that access as well, but this is again easy using lock semantics) and calling Thread.Sleep until it reaches 0.

Incidentally, an altered version of this scheme if you didn't know the number of threads beforehand would be to have each thread increment that variable as it starts.






Re: XNA Framework Threading - WaitHandle

Aaron Leiby

There was a great talk at gamefest about multicore programming and more specifically memory coherence. At one point there was mention of the 'volatile' keyword being hijacked in VC++ 2005 for making int sized things atomic (it's a bit unclear from the slides). Looks like you still need memory barriers on 360 in C++, but I also seem to remember him saying that C# took care of that for you. Anyone have more info on that front Can we just mark a bool (or just ints ) as 'volatile' in C# and assume all operations on it are atomic (I've got to fix up my WaitAny code as well on 360.)

http://msdn.microsoft.com/directx/presentations/ (download the 'Gamefest 2006: Windows and Xbox 360 System Programming Track' and check out 'Multi-Core Memory Coherence: The Hidden Perils of Sharing Data').





Re: XNA Framework Threading - WaitHandle

Aaron Leiby

I see my question has been answered here already:

http://forums.microsoft.com/MSDN/ShowPost.aspx PostID=642116&SiteID=1

Rob Unoki - MSFT wrote:

For lockless programming, Thread.MemoryBarrier will be exposed to enforce full data sync across cores.

"lock" (System.Monitor) and volatile keywords will function correctly.

http://msdn2.microsoft.com/en-us/library/x13ttww7.aspx (volatile c# reference)





Re: XNA Framework Threading - WaitHandle

Malmer

Nice to be wrong. I was certain I heard them say it was single core on channel 9, but I probably got it confused with something else.



Re: XNA Framework Threading - WaitHandle

Adam Miles

Any word from an MSFT why WaitHandle is so lacking in functionality and what ways they wait for all threads to finish The counter was an interesting idea but not exactly ideal, more of a last resort.





Re: XNA Framework Threading - WaitHandle

Aaron Leiby

WaitOne works on 360, though, doesn't it Maybe something like...

private EventWaitHandle exitThreadEvent;

exitThreadEvent = new ManualResetEvent(false);

Then instead of using while (1) { ... Sleep(ms); }, in your worker threads...

while (!exitThreadEvent.WaitOne(ms, false)) { ... }

Then when you're ready to exit, call:

exitThreadEvent.Set();

And finally, loop through all your threads calling Join() on them.

If you don't care if they're in the middle of something, and just want to yank them out of it, you can always just call Abort(), right

If you've got a consumer thread, where it's already waiting on another EventWaitHandle, then what I've been doing (due to lack of WaitAny) is to set a volatile bool, then call Set() on its WaitHandle, and the first thing it does is check the bool and break out.

private volatile bool stopDispatch; // accessed by multiple threads
// WaitAny isn't implemented on 360, so set a bool instead,
// and signal the thread to wake up.
stopDispatch = true;
dispatchEvent.Set();
public void Dispatch()
{
#if XBOX360
// affinity may only be set after the thread has started,
// and may only be set by the thread itself.
pollingThread.SetProcessorAffinity(3);
#endif
while (dispatchEvent.WaitOne())
{
if (stopDispatch)
break;
DoDispatch();
}
}

All that said, I haven't ponied up the money for the Content Creator's club yet, so I haven't actually had a chance to test any of this yet on the 360.