BlitzThreads (Windows only)

Community Forums/Showcase/BlitzThreads (Windows only)

AntonyWells(Posted 2005) [#1]
Blitzthreads lets you spawn windows-driven threads(Including dynamic priority per thread) within bmax.
This version is freeware.

With this you can run functions side by side your main app.
You can run upto 2024 threads at once(Although I wouldn't suggest it...:) )

www.excess.eclipse.co.uk/dreamspace.mod.zip

It's object driven, although there are function wrappers for those used to that.

Classes are(There's no docs)

TThread.

Global functions(Contained within TThread. I.e TThread.

Create() )
Create( BlitzFunction ) Create a thread and return a TThread object.
RunAll() 'Runs all threads
PauseAll() 'Pauses all threads
StopAll() 'Stops all threads

Local functions specific to each thread instance,

Run() 'Runs the function provided when creating the thread, in another thread.

Priority( Value:Int) 'Set the threads priority, value ranges from 1 to 7. (default = 3, pre-set)

Pause() 'Pause the thread

Resume() 'Resume the thread,
-
Global functions within TThread to allow async data access,
All return a TResource object/integer handle.

ProtectInt( x variable )
ProtectFloat( x variable )
ProtectBank( Bank:TBank )
ProtectStream( Stream:TStream )
-

With the tResource object returned, you can lock access rights to it within your thread,

Wrapper functions are,

ThreadHandle =CreateThread( Function )
PauseThread( ThreadHandle )
ThreadPriority( ThreadHandle,Priority )
PauseThread(Threadhandle)
ResumeThread(ThreadHandle)
StopThread(ThreadHandle)
RunThread(ThreadHandle)

There's also a manual locking system, in addition to protected storage.

Lock = CreateLock()

RequestLock(Lock)
ReleaseLock(lock)

which allows you to restrict threads of the same locking patterns to one run at a time.(Prevent deadlocks..if you're lucky :) )

TestApp

Simple mode
Update = CreateThread( UpdateVal )
NetWork = CreateThread( PrintVal )
RunThread(Update)
RunThread(NetWork)


Global ourVal

Function updateVal:Int(bb_func:Byte Ptr)

	repeat
		ourVal:+1
	forever
	
End function

Function printVal:Int (bb_func:Byte Ptr)

	repeat
		Print "Val:"+OurVal
		Delay 1000
	forever

End Function 

Print "Thread Handle>"+Res

repeat
	Delay 5000
	Print "Master thread!"
Forever


Advanced Mode

Update:TThread = TThread.Create( UpdateVal )
NetWork:TThread = TThread.Create( PrintVal )
Update.Run()
Network.Run()


Global ourVal

Function updateVal:Int(bb_func:Byte Ptr)

	repeat
		ourVal:+1
	forever
	
End function

Function printVal:Int (bb_func:Byte Ptr)

	repeat
		Print "Val:"+OurVal
		Delay 1000
	forever

End Function 

Print "Thread Handle>"+Res

repeat
	Delay 5000
	Print "Master thread!"
Forever


To install, copy dreamspace.mod folder into your bmax mod folder(Windows only atm) and you're done.


LarsG(Posted 2005) [#2]
First tests work great here.. Nice work, Antony.. :)


Kanati(Posted 2005) [#3]
very nice addition to bmax.


Paul "Taiphoz"(Posted 2005) [#4]
am I awake ? ..

ok I have a few questions if you dont mind ant.

1. Can I start a thread that will play an AVI aka game into and then continue to load my game media ?

2. Can more than one thread drop stuff to the back buffer ?
for example a game I did in Java, I had a "Insert Coin" that flashed on the screen, but the flash was controlled by a thread so it didnt have anything in the main loop telling it to flash. So can this be done ?

Is it stable enough to put something like AI into a thread and let it mince away on some complex AI choice tree while the rest of the game runs alone as normal, think chess ?


AntonyWells(Posted 2005) [#5]
Thanks lars, Kanati.

1. Can I start a thread that will play an AVI aka game into and then continue to load my game media ?


If you can do it in your main game, you can put it in a thread. I think the only thing on windows that doesn't like being threaded is dx stuff. Gl should be fine.



2. Can more than one thread drop stuff to the back buffer ?
for example a game I did in Java, I had a "Insert Coin" that flashed on the screen, but the flash was controlled by a thread so it didnt have anything in the main loop telling it to flash. So can this be done ?



Yep. Just create an endless loop in the thread. they don't have to return, whenever you call a thread it returns immediately.


Is it stable enough to put something like AI into a thread and let it mince away on some complex AI choice tree while the rest of the game runs alone as normal, think chess ?



Yep.

In the 'next' version, you can specify which processer the thread is executed on, in theory allowing true multi-cpu possibilities.


AdrianT(Posted 2005) [#6]
Nice one Ant ;)


Dreamora(Posted 2005) [#7]
Great thing :)

Now I can start to dream of stuff that I was not capable to create without bad headaches in the past :)


Bot Builder(Posted 2005) [#8]
Wow. It'd be really awesome if some linux and mac people could implement the same functions sets for those platforms, so you can use these on all platforms.


Paul "Taiphoz"(Posted 2005) [#9]
WELL all I got left to say is BLOODY well done m8 and where the heck is the download link for it(j/k)

Hay Any chance you could possibly knock up an example of it in use ?


Paul "Taiphoz"(Posted 2005) [#10]
I got a request if thats ok.

IsThreadActive:Boolean()

My thoughts are like this.

initgame()
thread -> loadmedia()
repeat
until IsThreadActive()=false
Playegame()

if thats not clear, we need a way to check if a thread thats loading media for the game is done yet, so we know if its safe to actually start drawing or playing sounds..

would be a nightmare if on some machines the thread dosent get all the needed media loaded befre the main program gets to a draw command.


Jeroen(Posted 2005) [#11]
awesome. it is win32 only?


Tibit(Posted 2005) [#12]
Nice and Impressive Antony!

Is it planned to make this work crossplatform;MacOs,Linux?

I haven't programmed with threads before but I can imagine what will be possible =)


Hotcakes(Posted 2005) [#13]
Awesome work Antony. Frikkin brilliant. I second Bot Builders request! If it's too messy to merge into one module, each platform could have a seperate thread module, so long as eventually somebody makes a fourth 'helper' module that handles all the messiness behind the scenes...


Dreamora(Posted 2005) [#14]
Yavin ...
your way of using it makes it useless if you wait until loading is done anyway ... you could just use the normal functionality then ;)


Paul "Taiphoz"(Posted 2005) [#15]
Dreamora : Wrong.
the example I gave was for playing an AVI Game Intro while loading the game media in the background, when the Intro AVI ends you want the game menu to start but there could be a situation where the thread loading all your media behind the avi is not yet finished, so a please wait msg could be displayed intil it is done.

So like I said Ant the thread god could we get a isitrunning function.

ta :)


Dreamora(Posted 2005) [#16]
thread are really good, thats out of question
but can't see your "runs an avi" thing ... you have an init and a thread that is loading and after loading is finished you play the game ... where is there actually the "AVI" part? thats why I meant there is not much use of this construct, sorry.


xlsior(Posted 2005) [#17]
but can't see your "runs an avi" thing ... you have an init and a thread that is loading and after loading is finished you play the game ... where is there actually the "AVI" part? thats why I meant there is not much use of this construct, sorry.

Eh?

I think he's just talking about the ability to play an animation *while* the necesary sprites, background, music, etc. of your game is being loaded in the background. Which would be quite useful, since it means you don't have to stare at a static screen during the loading period.


FlameDuck(Posted 2005) [#18]
Thanks Antony. Like Bot Builder, I'd also like to see versions for Linux and Mac.

I think he's just talking about the ability to play an animation *while* the necesary sprites, background, music, etc. of your game is being loaded in the background.
Yeah. Games could learn alot from that. Having 9 or 10 long animations running before the game starts, that you can't even skip past, and then once you've done that, it's "Please wait some more ... Loading".


AntonyWells(Posted 2005) [#19]

I got a request if thats ok.

IsThreadActive:Boolean()

My thoughts are like this.

initgame()
thread -> loadmedia()
repeat
until IsThreadActive()=false
Playegame()



The 'next' version will spawn threads within a carrier function to allow this. Sadly winAPI doesn't(or at least msdn doesn't document it) have any functions to just check if a thread is running.

In the mean time, remember threads have the SAME scope as the function would if you called it normally.

So for now,

global MediaLoading = true
function LoadMedia:Int(bb_func:Byte ptr )
  'load media
  MediaLoading = false
end function

CreateThreaad( LoadMedia)

while MediaLoading
wend 'wait for media to finish loading.

---

it is win32 only?



Is it planned to make this work crossplatform;MacOs,Linux?



Win32 for now, mac/Linux versions to come. It will be totally abstracted, so anycode you write in the windows version will eventually work without alteration on other platforms, basically..
---
Btw, never mentioned it before, but if you guys find any bugs, please report them.

Ant.

And on the next version of Arrested Threads, Jobe smuggles himself out of prison and into solitary. "I've made a huge mistake"


maximo(Posted 2005) [#20]
So now BlitzMax has threads, why do you ask Mark to add it if you can do it this easy ;)


AntonyWells(Posted 2005) [#21]
I thought it would be harder :)


flying willy(Posted 2005) [#22]
This is his finest hour, he stands among giants. The wind blasts through his heroic mane, and his steely jaw glints and reflects lensflares from the burning sun!

His threading has caused the mob to hush in awe... Rome is the mob and Antony is the Queen. I mean, erm.


Well done, it's great stuff - how will you do mac and linux?


skn3(Posted 2005) [#23]
Nice stuff :) I was gonna look into this, but it looks like you have beat me!

Lets hope BRL see the light. People want power!


Paul "Taiphoz"(Posted 2005) [#24]
Ah cool Ant, I never thought of that, that will solve any problems with the thread taking longer than expected to finish.


LOL and Flameduck, I think its a hell of a lot better to sit and watch some nice wee game intro than to sit looking at a static loading screen..

I mean if its a simple choice between looking at "Loading please wait ......" or some nice looking logo thing or game intro I know what one Id pick.

OF course though all loading should be kept to a min to make sure the player gets into the game nice and quick.


Mark Tiffany(Posted 2005) [#25]
Flameduck, I think its a hell of a lot better to sit and watch some nice wee game intro than to sit looking at a static loading screen..

I think you misunderstand Flameduck. He's not advocating static screens over animated screens. He's advocating that loading should occur DURING the intro animation(s), not AFTER on a static loading screen. This happens far too often in commercial games and to me smacks of laziness.

Oh, and well done Antony, looks good!


Paul "Taiphoz"(Posted 2005) [#26]
Yeah your right Mark.

I guess I missread that the first time. Soz flameduck and I agree with you 100%.

I could name a few games as well that hit you with a loading animation and then when its done they load the game media.

Well thanks to Antony and his thready goodness we wont have to bother waiting around anymore.

I guess the only question is now, Whos good at making avi intros lol.


teamonkey(Posted 2005) [#27]
I think the only thing on windows that doesn't like being threaded is dx stuff. Gl should be fine.


OpenGL is not thread safe. Everything should be done in the same thread that created the graphics context, unfortunately. It might work on some systems, but not with others. YMMV.

As a rule of thumb, I'd keep all the graphics commands in the original thread.


Warren(Posted 2005) [#28]
I imagine there's more stuff that isn't thread safe than you would imagine. I'd be very careful with this stuff, folks. If BlitzMax doesn't have threads natively, odds are that it wasn't coded in a thread safe, re-entrant manner.

Be wary. There may be weird and spooky bugs ahead. :)


Paul "Taiphoz"(Posted 2005) [#29]
I can think of two areas where this is going to really help, the first is as I said above, getting all your media loaded while playing some movie intro at the same time to keep the gamer intrested.

Then you have AI to think of, AI in games is and has always beena big bottle neck, the more complex the AI the more cpu time it takes away from your game logic/rendering time. just think how good its going to be when in your main loop, at the start of it you can just fire your AI function off in a thread and then while thats working out its next move your code can then get on with updating vars, or drawing the game to screen.

The last thing I can think of and probably the first thing I will try is going to be networking. Just think for example if you want to ping a list of servers, to find out if the gameserver is still running or to find out what the ttl is. you will be able to fire off say 20 pings at once in threads at a single time instead of running through each one , one at a time.

the amount of time this is going to save is .... well a lot.


Warren(Posted 2005) [#30]
Just to be a slightly soggy blanket here ... threading isn't magic. It isn't like you're getting another processor installed in your machine or something. You're still using the same amount of processor each frame, except now you're spreading it over a wider array of tasks. Things are still going to take the same amount of time to complete (possibly more, in fact), but the main advantage is that they can move forward at the same time rather than in sequence.


maximo(Posted 2005) [#31]
>the main advantage is that they can move forward at the same time rather than in sequence

exactly, nothing will be faster, things will be proccessed in sequence and instead of thing A finishing before thing Z, now both things will finish at the same time.


AntonyWells(Posted 2005) [#32]
You can off-load threads onto any cpu, so if you do have a multi-cpu set up, it is like getting another processor, as according to a flameduck(I think) post blitzMax only uses one, no matter how many there are.
That may be niche now..but it won't be in two years.(Not at the high end..multi-core will be the new p4. or whatever.)
-
But saying that, the beauty of threads to me has never been a magical means to speed up existing routines, it's been to open new doors. I just finished adding streaming support to trinity.(Load wise) so can load an entity in about 0.3 secs(On a p2-350 atm..<insert appropriate swear word>) without pausing the app.
And in a real time context, reducing a 0.3 second pause per frame to no pause is a quantum leap in performace.
-

Skunk, lay off the..yourself. :)


OpenGL is not thread safe. Everything should be done in the same thread that created the graphics context, unfortunately. It might work on some systems, but not with others. YMMV.

As a rule of thumb, I'd keep all the graphics commands in the original thread.



Are you sure? I've seen numerous sites specifically citing speeding up real time apps by threading the 3d engine(I.e the rendering aspect). Though it's not vital anyway, as the cpu intensive stuff is what you want to thread.


dmoc(Posted 2005) [#33]
It's responsiveness not speed that's improved - many people mistakenly mix the two. Re opengl, same thing basically and I would guess mainly offloading non rendering stuff while keeping rendering in same thread. Seperate threads for seperate context's seems a good idea?


teamonkey(Posted 2005) [#34]
Are you sure?

Pretty sure. OpenGL is state-based. Mess with anything out of sequence and you're screwed. Not only that, but it's been my experience that just calling an OpenGL function can cause the app to segfault. I don't know why.

Do you have any links to those sites?


AntonyWells(Posted 2005) [#35]
Not 'on me', it was when I was reading up on threads..So could be any link on google from a "thread tutorial/ C++ Threads" search, was in the sections mentioning the benefits of threads.
-

About being state based, my own solution would be to objectize(ahem) state access throug a wrapper class, and precede every function with a mutex lock request on it's own personal mutex.
So if two threads do attempt to change a state at once they'll be denied access.(they'll just queue up in order of request)
Plus you can implement a lock/unlock method when you want to prevent any other threads from making changes.
The nice thing about a mutex request is it actually stalls the thread on the request until it has the lock, so it prevents multiple threads from accessing any proceding code.

I believe recent drivers also added support for child Contexts, or shared contexts, which may be a solution to any crashes caused by that.(Not tested.)


Dreamora(Posted 2005) [#36]
There is stuff you can do in threads on OpenGL like buffer modifications or display list modifications but I think threading anything out of the "pipe" would totally screw the thing ...


Hotcakes(Posted 2005) [#37]
So now BlitzMax has threads, why do you ask Mark to add it if you can do it this easy ;)

I think the better question is why hasn't Mark done this since it's so damn easy ;] There may be a very good reason... but it's -so- -much- more FUN to find out the hard way, innit? ;]

Whos good at making avi intros lol.

It's not too difficult to get your hands on some 'home movie' sorta software for a reasonable price. Movie Maker if you're -really- desperate (altho then you'd need another proggy to convert the wmv to avi)


Paul "Taiphoz"(Posted 2005) [#38]
It's not too difficult to get your hands on some 'home movie' sorta software for a reasonable price. Movie Maker if you're -really- desperate (altho then you'd need another proggy to convert the wmv to avi)


I use Prem 8 on the PC and some times I edit my TV or cinema trailer stuff on Mac, just recently had to submit two trailers for the movie robocop.

The Hardware and software aint a problem, I was more thinking along the lines of creating the 3D intro like mby EA's or Capcoms.. something like that.


alligator(Posted 2005) [#39]
well done, but beware..

http://home.pacbell.net/ouster/threads.pdf

an older article but still relavant.


Warren(Posted 2005) [#40]
That's a really good article. Lays it all out in plain English.


ImaginaryHuman(Posted 2005) [#41]
This seems like a groovy addition, but I can't myself consider it an `addition to blitzmax` or that `blitzmax now has threads` until it is supported on all the platforms that blitzmax ports to *being purist*. But great job on the `progress` though.

I also am expecting there must be some areas where, having two parts of a BlitzMax app running simultaneously is likely to not take into account some internal variables which may have no protection from being changed at the wrong time or not being locked, etc... I guess it'll almost be hit and miss as to which parts work together and which dont?

Still, it's pretty cool and looking forward to seeing it on all platforms.


AntonyWells(Posted 2005) [#42]
Urban legends aside, I've got too much going on project wise to try and implement any sort of multi-platform.
So here's the bmax/C++ source used, public domain so hopefully someone else can finish it off for us.(this won't be a commercial product from me. ever.)

anyway, enough rambling, here's the juice. (This is the latest version btw, I'd nab it if you're using the above.
You can now pass a pointer to a thread. (Edit-fixed a bug.)


'TheadLayer.c


Freel free to upload any improvements to this thread..or your own.


ashmantle(Posted 2005) [#43]
Antony, you're a great asset to this community! Thanks alot!


marksibly(Posted 2005) [#44]
Umm,

Sorry to be a party pooper, but this is pretty much guaranteed to fail sooner or later.

The likely result of using threads like this is that things will work fine 99% of the time, and every now and then something will mysteriously screw up.

The problem is that certain runtime operations need 'locks' around them to work properly concurrently, and there is nothing like that in place.

By all means, use at your own risk - but you've been warned! Threading is something I eventually want to look at, but it's not as simple as it sounds.


AntonyWells(Posted 2005) [#45]
Ash, thanks, I usually hear that in reverse :)

Mark, locking is in place, so any modules of yours can be manually locked.
Custom modules, like mine of course CAN be wrote thread safe from the start, so it's only really true of your modules anyway.
Unless your compiler is generating asm which relies on any global areas that other threads could 'mess up' regardless of the modules being used?
I don't see any such code in the asm produced though, though I never looked too hard.

Would be helpful if you made it clearer to us what to avoid, if I've missed something. -[Edit - Or the usual stonewall of silence..whatever...