New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account


paroj opened this Issue Jul 20, 2017 · 0 comments


None yet
1 participant

paroj commented Jul 20, 2017


OGRE_THREAD_SUPPORT==1 where resource management is fully threaded, was hopelessly naive. It required too many locks, and also that the rendersystem was multi-threaded. OGRE_THREAD_SUPPORT==2 improved that by not requiring that the rendersystem was threaded, and just doing disk I/O in the background, but still, the whole process is still driven within the Resource class, which means the locks are still in place on Resource and by association SharedPtr and a bunch of other classes too.

  1. Add a new OGRE_THREAD_SUPPORT option, 3
  2. This results in OGRE_MUTEX, OGRE_LOCK_MUTEX etc all becoming no-ops just like in OGRE_THREAD_SUPPORT=0 - so SharedPtr, Resource etc are all not thread safe
  3. WorkQueue changed to use different macros, e.g. OGRE_WQ_MUTEX, which are the only ones enabled when OGRE_THREAD_SUPPORT=3
  4. Resource prepare() when OGRE_THREAD_SUPPORT=3 is 'deferred' rather than 'threaded'. That is, we make all changes to Resource in the main render thread, and simply push a request on to WorkQueue to read / optionally pre-process the data in a thread. This thread cannot access any of Ogre in a threadsafe manner, it can only use software structures.
  5. All data exchanged between the threads must be totally encapsulated in the Request and Response, so that it is self-contained and ownership can be passed cleanly between threads.
  6. The main challenge here is the resource path & archive system - we need to make these lock-free (locking them will start to bleed into other areas and we'll end up with too much again). One option would be to have archive instances & resource paths copied to each thread, with changes queued up / logged and picked up when each thread needs them.
  7. So from a resource point of view, this is a lot like OGRE_THREAD_SUPPORT==2, except that Resource isn't threadsafe (actually, nothing is!), because it's only accessed in the main thread.
  8. We make this the default when Boost / POCO / TBB are detected
  9. Over time we expand this data-driven, lock-free model for future threading within Ogre

This will effectively eliminate any additional overheads when using threaded behaviour in OGRE, since none of the regular classes will be thread safe. Note that even though SharedPtr may be used in (CPU-side) data structures used by the background thread, beacuse the 'handover' of data only occurs in one place - the WorkQueue Request/Response system - there is no risk of parallel access and therefore it can be lock-free (provided the user doesn't allow the pointer to point to a shared object of course! This is key, data has to be solely owned, the SharedPtr is just for type / structure convenience like VertexData). So long as the data that is used by the background process is entirely encapsulated, and the contents only visible to one thread at a time, we get background processing with no locks except for the queueing system (and for that I may investigate a lock-free queue too as an extension).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment