Multithreaded, Win32, Debug stack size
BlitzMax Forums/BlitzMax Programming/Multithreaded, Win32, Debug stack size
| ||
Running the code below causes a stack overflow only in MT-Debug builds;SuperStrict Type thing Field vals:Float[12] Function Create:thing() Local a:thing = New thing Return a End function End type Local biglist:TList = New TList For Local a:Int = 0 To 150000 - 1 Local t:thing = thing.Create() biglist.addlast( t ) If ( a Mod 1000 = 0 ) Print a Next Print "done!" but if I comment out the biglist.addlast() there's no problem. I've tried adjusting the dwStackSize parameter of the Windows CreateThread function calls to no avail (http://msdn.microsoft.com/en-gb/library/windows/desktop/ms682453(v=vs.85).aspx). It's currently zero. Is there a bug somewhere in BMax or am I being unreasonable here? |
| ||
Hiya, The garbage collector seems to throw up in multithreaded apps. One solution is to set it to be aggressive which is undocumented and probably unsupported due to being undocumented. You could also try setting it to manual but then you'll see lags and hiccups when you switch it back on and the collector does it thing. The aggressive collection collects pretty much immediately with practically zero slow down althougj there is an overhead obviously but with some good design it shouldnt really pose a problem. Use GCSetMode -1 for an aggressive collection. Worth a try. |
| ||
on linux there is no problem (i know you mentioned it is win32). But windows finishes without error while not finishing the loop I also removed the local variables without any change, so the GC has less to do, this changed nothing. What is way more remarkable: Same object: Local t:thing = New thing For Local a:Int = 0 To 150000 - 1 biglist.addlast( t ) If ( a Mod 1000 = 0 ) Print a Next ends at "95000" String: For Local a:Int = 0 To 150000 - 1 biglist.addlast( "t" ) If ( a Mod 1000 = 0 ) Print a Next ends at "95000" New objects: For Local a:Int = 0 To 150000 - 1 biglist.addlast( new thing ) If ( a Mod 1000 = 0 ) Print a Next ends at "124000" New objects returned from an extra function call: For Local a:Int = 0 To 150000 - 1 biglist.addlast( thing.Create() ) If ( a Mod 1000 = 0 ) Print a Next ends at "107000" This is hmm... while I understood extra function calls are not the best.... I do not understand why "new objects" are working "better" than the "same object" approach |
| ||
Another option would be to tell the linker to use a bigger stack for the main thread. Changing the stack size for CreateThread will work for when you spawn child threads not for the MainThread. To adjust the stack for the MainThread use Import "--stack 5242880" ' Tell the linker we want a 5Mb stack at the top of your main file. EDIT:- Looking through the standard bmk source, Mark sets the default stack size only on Win32 to 4194304 ( 4Mb ). This is more than likely the issue. |
| ||
Thanks for your input guys. But windows finishes without error while not finishing the loop not without error for me. It stops with a default beep. Applications don't normally stop this way, and very occasionally it did report a stack overflow. I really don't understand what it is specifically about a TList that uses up so much stack space. There are no temporary variables being created during insertion that need to be cleaned up. Which leads me to the GC.. Col, you certainly know some tricks! The aggressive GC mode didn't help. But, as above, I'm really not sure there is any GC'ing to be done in my example above. However, increasing the stack size with the Import "--stack " trick, has fixed it. I had to take it up to 24mb to get it to run my actual project code. I'm going to code my own list type that works with chunks of heap memory and see if I can get round it this way. I'll be sure to report back. Thanks again chaps. |