February 2011 Archives

The CIOPool class's constructor takes a ThreadIdentifier value which is used to allow the threads in the pool to know that they're in the pool. The value is stored in thread local storage for each thread in the pool and can then be examined to determine if a thread belongs to the I/O pool. The value can also be queried and other threads can 'be treated as I/O pool threads' by setting the appropriate TLS slot to this value.

This is all used to allow us to skip the marshalling of I/O requests into the I/O pool if the request is being issued by a thread that's already in the pool. This allows the code to run slightly faster on pre-Vista machines in some circumstances.

Unfortunately the value passed in is never checked for zero and so incorrect configuration could lead to a thread pool which has zero passed in for its thread identifier. This is highly unlikely as most pools are never specifically configured for the thread identifier and simply use the default. If a thread identifier is set to zero then all threads will appear to be part of the I/O pool - an uninitialised TLS slot contains zero. This will mean that NO I/O requests are marshalled even on platforms where not doing so could cause problems.

In 6.4 I've removed the thread identifier from the constructor, it's now automatically generated and guaranteed to be non-zero. I've also changed the interface for how a thread acts as part of the I/O pool. This removes the design bugs and prevents incorrect configuration causing I/O operations to potentially be aborted if the thread that issued them exits before they complete (on pre-Vista systems).

Performance, allocators, pooling and 6.4

I've been doing a lot of performance related work over the past few months. Much of it has originally stemmed from work that I have been doing for our Online Game Company client. They want the asynchronous ENet-based server that we've built for them to be the fastest it can be and so I've been looking at all aspects of performance within the framework. The testing hasn't brought anything too embarrassing to light; the I/O recursion limiter that was introduced in 6.3 affected performance more than I would have liked, but that's now fixed and they weren't using it anyway.