Bug fixesI found an issue with the callsite of certain constructors and Matthias solved it immediately by letting the instrumentation code emit an exception. Matthias is looking into a permanent solution, but for now it's good to have the instrumentator notify you of the edge case where it cannot produce valid continuations... yet. More info on this later, until then, download the latest version and pay attention to any warnings printed on the console.

I am currently using the Matthias continuations library and have found that it has greatly simplified my AI and network code. Perhaps i am a bit slow, but what have you added from that original lib? Is it just a green threads implementation?

Can't you already run many many native threads in linux for example anyway (aka the old thread per socket web server or a Selector).

I have no special talents. I am only passionately curious.--Albert Einstein

You can run many threads on any OS; the problem is that you are then dealing with synchronization and non-deterministic behaviour. And on ARM you even have significant memory barrier overhead as the ARM architecture doesn't enforce memory consistency between cores.

I am currently using the Matthias continuations library and have found that it has greatly simplified my AI and network code. Perhaps i am a bit slow, but what have you added from that original lib? Is it just a green threads implementation?

It's 'just' that, yes. If you browse through the code you'll see that 'just' is relative

I wrote this highlevel library on top of the continuations library, so that the concepts (processor, thread, sleep, lock, etc) are familiar for anybody having minimal experience with threading. Writing a proper scheduler (the VirtualProcessor) is not quite trivial, and it took me a few iterations to get it to where it is now. I think it's good to share the code, so others don't have to reinvent the wheel, lowering the bar for usage of Matthias Mann's ingenious library.

Most scalable servers use a model that isn't thread-per-client, but they tend to use nio, which is probably not what you meant. JRockit uses a hybrid green/native model, and that runs some pretty heavy duty servers.

For everybody wondering what this library can be used for apart from AI, I just wrote a simple (http) server that was load-tested with a utility called load_http. My server reads the request, sends the response and closes the connection. There is no logic or file I/O involved.

The code is based on NIO, but without Selectors. It will forcefully perform I/O, until the SocketChannel tells the http server that it cannot read/write anything, and cause the VirtualThread to sleep for a bit and try again. Imagine the process like this:

I can imagine most of you guys will yawn, but on a quad-core, with 4 native threads each running a VirtualProcessor, I managed 12,000 16,000 requests & responses per second (each with its own tcp connection), within a VirtualBox VM running Debian 2.6.32 on a Win7 host.

That IS cool as hell! Still, I find it a bit hard to justify its use in games though. I guess the win lies in how you can design things like AI more than performance. So, when will JGO be hosted with that? ^^

Why is it hard to justify in games? Especially in AI the possibilities are endless. AI with intelligent (!) and complex behaviour is very hard to achieve without flow-control. I agree that for simple AI, this library is indeed over the top.

Hi, appreciate more people! Σ ♥ = ¾Learn how to award medals... and work your way up the social rankings!

Nothing of the sort. Why would they be more overkill than, say, a loop? Okay, yes, I'll grant that a continuations library with its kinky bytecode manipulation to get around a language not having native support might not be the first thing to reach for when a native approach would work equally well. But continuations aren't mysterious exotic things -- in fact their main problem is that they're too low-level for most circumstances, a sort of "functional GOTO" you can build any other control flow construct you want from.

Let's demystify continuations. This library is a great first step toward that. Interestingly it seems to be following the path of Stackless Python, which started with first-class continuations, then increasingly focused on microthreads until ultimately abandoning callcc-style mechanisms altogether. But I'm also a sucker for CSP primitives too, so this library is awesome any way you slice it.

Let's demystify continuations. This library is a great first step toward that. Interestingly it seems to be following the path of Stackless Python, which started with first-class continuations, then increasingly focused on microthreads ---

In my opinion coroutines and continuations are too lowlevel for just about all developers. The idea that you can store a capture of a method in memory and then execute it multiple times will scare the hell out of just about everybody dealing with C-like languages, although I think it comes reasonably close to an out-of-bounds POSIX fork.

I think this incredibly powerful and awesome functionality, provided by Matthias Mann's library, is best hidden away from average Joe and put behind a simple abstraction layer that exposes it as a concept that the developer is already familiar with: threads.

The only thing people have got to get used to is co-operative scheduling, which (obviously) isn't a requirement in a native thread.

Hi, appreciate more people! Σ ♥ = ¾Learn how to award medals... and work your way up the social rankings!

I dunno. For someone that knows nothing about either (coop & pre-emptive) I'd think that learning coop is easier...but I suppose it's all about the API/language integration. As an aside one of the uni's very active in HotSpot (and other Sun/Oracle JVMs) has implemented coroutines in the JVM (along with a fair number of other nice features like real mixins) (http://ssw.jku.at/Research/Projects/JVM/).

I haven't (yet) looked at Riven's source. Serialization? Have you thought about a watchdog thread with time-out as an option?

I'm using this for an export dialog, simply to display progress without needing a state machine for my huge export method that has to run in the GL thread. It isn't really a big deal to use the agent and put some processing in the build. Just now upgrading to the latest, if you break all my stuff Riven, I kill you! Edit: seems to still work.

As an aside one of the uni's very active in HotSpot (and other Sun/Oracle JVMs) has implemented coroutines in the JVM (along with a fair number of other nice features like real mixins) (http://ssw.jku.at/Research/Projects/JVM/).

I wrote a simple Java bytecode interpreter in Java *gasp* and implementing continuations in that was trivial. After all, you basically just save and change the instruction-pointer (and stack - which contains the execution frames) and restore the stack some time later by simply setting a pointer. The amount of trickely involved to support this with bytecode instrumentation is mind boggling.

I haven't (yet) looked at Riven's source. Serialization? Have you thought about a watchdog thread with time-out as an option?

Serialization is already supported. The downside of using a watchdog thread is that when you want to kill a VirtualThread you really have to kill the native thread, which... doesn't exactly equate to pre-emptive scheduling as it will kill your entire single-threaded application.

Hi, appreciate more people! Σ ♥ = ¾Learn how to award medals... and work your way up the social rankings!

I was thinking more along the lines of (as an example): you have a single real thread running just AIs and one of the fibers goes into an infinite loop (or is simply taking too long)...watchdog kills, the system starts a new thread to continue running (after perhaps calling a "you've been a bad boy" method on the offender)..etc.

Again, the problem is that you can only kill a VirtualThread by killing the native thread, and thereby killing all VirtualThreads that run on the VirtualProcessor.

You cannot simply restart the game logic with spawning a new AI thread, as all stacks and execution frames of all VirtualThreads are lost.

It's like... calling java.lang.Thread.stop() (as that's actually what happens), you leave the application in undefined state. Finally blocks won't get executed, referenced objects can be left in corrupt state (only N out of M fields are updated) - in short, you're pretty likely to leave your application in a state that you don't even want it to recover from.

Hi, appreciate more people! Σ ♥ = ¾Learn how to award medals... and work your way up the social rankings!

I really like this, and i intend to use it too. I remember some years ago i was working on AI bots, and i had to write my own scheduler for them. It would have been much better if i could write code which doesn't have to go trough the complete bot logic at each iteration.

What about using this for handling players too? Put a certain number of players onto a single native thread and make a VirtualThread for each of the players. I'm evaluating Netty.IO for networking right now, and seems to me that it handles incoming UDP differently than TCP. TCP connection can be delegated out to threads, so each native thread can handle certain number of connections. But UDP packets sent to a single listening port just get delivered to a single thread/channel/pipeline, no matter from where they came. So its the UDP handlers task to sort them out. What if players first got to connect to a specific UDP port, and after authentication they were redirected to resume their traffic with another port? So the server would listen on certain UDP ports, and the players would be distributed over those. At each UDP port there would be a native thread with a handler, and the packets would be delivered to VirtualThreads. I really want to avoid having a single thread for forwarding data to players, since that would mean that all the traffic would have to pass trough one specific queue. (I know this belongs to networking. I was just thinking about how this could be combined with that.)

java-gaming.org is not responsible for the content posted by its members, including references to external websites,
and other references that may or may not have a relation with our primarily
gaming and game production oriented community.
inquiries and complaints can be sent via email to the info‑account of the
company managing the website of java‑gaming.org