During the version 9 run it became apparent that a central lock on the "big list of textures" was going to be increasingly problematic - the lock was already showing up in performance profiles under only moderate strain. Clearly a central lock was not going to be an option.
The scheme we use now is based on a central lock that is only needed for resource allocation/destruction - not access. It goes something like this:
Resources are always referenced by a pointer, not an index. This means that client code that simply needs to utilize the resource can do so without access to the "central list". Thus resource usage can be lock free.
(This is the most important case. We only create and destroy a texture once but we might use thousands of textures per frame.)
The reference count on an object is atomic, so we don't need to lock the object to add or delete references. From a performance standpoint this is nice but not critical.
Resource deletion is explicit. This is the most surprising part: we don't actually release a resource until we explicitly make a "garbage collect" call. This has two effects:
- We avoid thrash because we can start re-using a zero-reference object before it is thrown out.
- It limits the locking of the big list of objects to one explicit function call.