diff options
Diffstat (limited to 'thirdparty/embree/common/tasking/taskschedulerinternal.h')
-rw-r--r-- | thirdparty/embree/common/tasking/taskschedulerinternal.h | 95 |
1 files changed, 52 insertions, 43 deletions
diff --git a/thirdparty/embree/common/tasking/taskschedulerinternal.h b/thirdparty/embree/common/tasking/taskschedulerinternal.h index 6cc2495195..e72d3b72ba 100644 --- a/thirdparty/embree/common/tasking/taskschedulerinternal.h +++ b/thirdparty/embree/common/tasking/taskschedulerinternal.h @@ -12,7 +12,7 @@ #include "../sys/ref.h" #include "../sys/atomic.h" #include "../math/range.h" -#include "../../include/embree3/rtcore.h" +#include "../../include/embree4/rtcore.h" #include <list> @@ -38,6 +38,13 @@ namespace embree virtual void execute() = 0; }; + + struct TaskGroupContext { + TaskGroupContext() : cancellingException(nullptr) {} + + std::exception_ptr cancellingException; + }; + /*! builds a task interface from a closure */ template<typename Closure> struct ClosureTaskFunction : public TaskFunction @@ -76,16 +83,16 @@ namespace embree : state(DONE) {} /*! construction of new task */ - __forceinline Task (TaskFunction* closure, Task* parent, size_t stackPtr, size_t N) - : dependencies(1), stealable(true), closure(closure), parent(parent), stackPtr(stackPtr), N(N) + __forceinline Task (TaskFunction* closure, Task* parent, TaskGroupContext* context, size_t stackPtr, size_t N) + : dependencies(1), stealable(true), closure(closure), parent(parent), context(context), stackPtr(stackPtr), N(N) { if (parent) parent->add_dependencies(+1); switch_state(DONE,INITIALIZED); } /*! construction of stolen task, stealing thread will decrement initial dependency */ - __forceinline Task (TaskFunction* closure, Task* parent) - : dependencies(1), stealable(false), closure(closure), parent(parent), stackPtr(-1), N(1) + __forceinline Task (TaskFunction* closure, Task* parent, TaskGroupContext* context) + : dependencies(1), stealable(false), closure(closure), parent(parent), context(context), stackPtr(-1), N(1) { switch_state(DONE,INITIALIZED); } @@ -95,7 +102,7 @@ namespace embree { if (!stealable) return false; if (!try_switch_state(INITIALIZED,DONE)) return false; - new (&child) Task(closure, this); + new (&child) Task(closure, this, context); return true; } @@ -110,6 +117,7 @@ namespace embree std::atomic<bool> stealable; //!< true if task can be stolen TaskFunction* closure; //!< the closure to execute Task* parent; //!< parent task to signal when we are finished + TaskGroupContext* context; size_t stackPtr; //!< stack location where closure is stored size_t N; //!< approximative size of task }; @@ -122,28 +130,32 @@ namespace embree __forceinline void* alloc(size_t bytes, size_t align = 64) { size_t ofs = bytes + ((align - stackPtr) & (align-1)); - if (stackPtr + ofs > CLOSURE_STACK_SIZE) - // -- GODOT start -- - // throw std::runtime_error("closure stack overflow"); + // -- GODOT start -- + // if (stackPtr + ofs > CLOSURE_STACK_SIZE) + // throw std::runtime_error("closure stack overflow"); + if (stackPtr + ofs > CLOSURE_STACK_SIZE) { abort(); - // -- GODOT end -- + } + // -- GODOT end -- stackPtr += ofs; return &stack[stackPtr-bytes]; } template<typename Closure> - __forceinline void push_right(Thread& thread, const size_t size, const Closure& closure) + __forceinline void push_right(Thread& thread, const size_t size, const Closure& closure, TaskGroupContext* context) { - if (right >= TASK_STACK_SIZE) - // -- GODOT start -- - // throw std::runtime_error("task stack overflow"); - abort(); - // -- GODOT end -- + // -- GODOT start -- + // if (right >= TASK_STACK_SIZE) + // throw std::runtime_error("task stack overflow"); + if (right >= TASK_STACK_SIZE) { + abort(); + } + // -- GODOT end -- /* allocate new task on right side of stack */ size_t oldStackPtr = stackPtr; TaskFunction* func = new (alloc(sizeof(ClosureTaskFunction<Closure>))) ClosureTaskFunction<Closure>(closure); - new (&(tasks[right.load()])) Task(func,thread.task,oldStackPtr,size); + new (&tasks[right.load()]) Task(func,thread.task,context,oldStackPtr,size); right++; /* also move left pointer */ @@ -178,7 +190,7 @@ namespace embree : threadIndex(threadIndex), task(nullptr), scheduler(scheduler) {} __forceinline size_t threadCount() { - return scheduler->threadCounter; + return scheduler->threadCounter; } size_t threadIndex; //!< ID of this thread @@ -244,10 +256,7 @@ namespace embree void wait_for_threads(size_t threadCount); /*! thread loop for all worker threads */ - // -- GODOT start -- - // std::exception_ptr thread_loop(size_t threadIndex); void thread_loop(size_t threadIndex); - // -- GODOT end -- /*! steals a task from a different thread */ bool steal_from_other_threads(Thread& thread); @@ -257,7 +266,7 @@ namespace embree /* spawn a new task at the top of the threads task stack */ template<typename Closure> - void spawn_root(const Closure& closure, size_t size = 1, bool useThreadPool = true) + void spawn_root(const Closure& closure, TaskGroupContext* context, size_t size = 1, bool useThreadPool = true) { if (useThreadPool) startThreads(); @@ -267,7 +276,7 @@ namespace embree assert(threadLocal[threadIndex].load() == nullptr); threadLocal[threadIndex] = &thread; Thread* oldThread = swapThread(&thread); - thread.tasks.push_right(thread,size,closure); + thread.tasks.push_right(thread,size,closure,context); { Lock<MutexSys> lock(mutex); anyTasksRunning++; @@ -286,51 +295,52 @@ namespace embree /* remember exception to throw */ std::exception_ptr except = nullptr; - if (cancellingException != nullptr) except = cancellingException; + if (context->cancellingException != nullptr) except = context->cancellingException; /* wait for all threads to terminate */ threadCounter--; while (threadCounter > 0) yield(); - cancellingException = nullptr; + context->cancellingException = nullptr; /* re-throw proper exception */ - if (except != nullptr) + if (except != nullptr) { std::rethrow_exception(except); + } } /* spawn a new task at the top of the threads task stack */ template<typename Closure> - static __forceinline void spawn(size_t size, const Closure& closure) + static __forceinline void spawn(size_t size, const Closure& closure, TaskGroupContext* context) { Thread* thread = TaskScheduler::thread(); - if (likely(thread != nullptr)) thread->tasks.push_right(*thread,size,closure); - else instance()->spawn_root(closure,size); + if (likely(thread != nullptr)) thread->tasks.push_right(*thread,size,closure,context); + else instance()->spawn_root(closure,context,size); } /* spawn a new task at the top of the threads task stack */ template<typename Closure> - static __forceinline void spawn(const Closure& closure) { - spawn(1,closure); + static __forceinline void spawn(const Closure& closure, TaskGroupContext* taskGroupContext) { + spawn(1,closure,taskGroupContext); } /* spawn a new task set */ template<typename Index, typename Closure> - static void spawn(const Index begin, const Index end, const Index blockSize, const Closure& closure) + static void spawn(const Index begin, const Index end, const Index blockSize, const Closure& closure, TaskGroupContext* context) { spawn(end-begin, [=]() - { - if (end-begin <= blockSize) { - return closure(range<Index>(begin,end)); - } - const Index center = (begin+end)/2; - spawn(begin,center,blockSize,closure); - spawn(center,end ,blockSize,closure); - wait(); - }); + { + if (end-begin <= blockSize) { + return closure(range<Index>(begin,end)); + } + const Index center = (begin+end)/2; + spawn(begin,center,blockSize,closure,context); + spawn(center,end ,blockSize,closure,context); + wait(); + },context); } /* work on spawned subtasks and wait until all have finished */ - dll_export static bool wait(); + dll_export static void wait(); /* returns the ID of the current thread */ dll_export static size_t threadID(); @@ -366,7 +376,6 @@ namespace embree std::atomic<size_t> threadCounter; std::atomic<size_t> anyTasksRunning; std::atomic<bool> hasRootTask; - std::exception_ptr cancellingException; MutexSys mutex; ConditionSys condition; |