summaryrefslogtreecommitdiffstats
path: root/thirdparty/embree/common/tasking/taskschedulerinternal.h
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/embree/common/tasking/taskschedulerinternal.h')
-rw-r--r--thirdparty/embree/common/tasking/taskschedulerinternal.h95
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;