diff options
| author | Juan Linietsky | 2017-12-24 09:31:17 -0300 |
|---|---|---|
| committer | Juan Linietsky | 2017-12-24 09:32:12 -0300 |
| commit | 021f3c924be29cafe9d8d50bf00ecc6f13675e87 (patch) | |
| tree | 4623e6fa3be55751386d56792f7cc26dab210e27 /core/os/threaded_array_processor.h | |
| parent | 83182ea4a1e6d5c34dd137fdbd7ef9b2c5f33231 (diff) | |
| download | godot-021f3c924be29cafe9d8d50bf00ecc6f13675e87.tar.gz godot-021f3c924be29cafe9d8d50bf00ecc6f13675e87.tar.zst godot-021f3c924be29cafe9d8d50bf00ecc6f13675e87.zip | |
Diffstat (limited to 'core/os/threaded_array_processor.h')
| -rw-r--r-- | core/os/threaded_array_processor.h | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/core/os/threaded_array_processor.h b/core/os/threaded_array_processor.h new file mode 100644 index 000000000..e584fbb19 --- /dev/null +++ b/core/os/threaded_array_processor.h @@ -0,0 +1,80 @@ +#ifndef THREADED_ARRAY_PROCESSOR_H +#define THREADED_ARRAY_PROCESSOR_H + +#include "os/mutex.h" +#include "os/os.h" +#include "os/thread.h" +#include "safe_refcount.h" +#include "thread_safe.h" + +template <class C, class U> +struct ThreadArrayProcessData { + uint32_t elements; + uint32_t index; + C *instance; + U userdata; + void (C::*method)(uint32_t, U); + + void process(uint32_t p_index) { + (instance->*method)(p_index, userdata); + } +}; + +#ifndef NO_THREADS + +template <class T> +void process_array_thread(void *ud) { + + T &data = *(T *)ud; + while (true) { + uint32_t index = atomic_increment(&data.index); + if (index >= data.elements) + break; + data.process(index); + } +} + +template <class C, class M, class U> +void thread_process_array(uint32_t p_elements, C *p_instance, M p_method, U p_userdata) { + + ThreadArrayProcessData<C, U> data; + data.method = p_method; + data.instance = p_instance; + data.userdata = p_userdata; + data.index = 0; + data.elements = p_elements; + data.process(data.index); //process first, let threads increment for next + + Vector<Thread *> threads; + + threads.resize(OS::get_singleton()->get_processor_count()); + + for (int i = 0; i < threads.size(); i++) { + threads[i] = Thread::create(process_array_thread<ThreadArrayProcessData<C, U> >, &data); + } + + for (int i = 0; i < threads.size(); i++) { + Thread::wait_to_finish(threads[i]); + memdelete(threads[i]); + } +} + +#else + +template <class C, class M, class U> +void thread_process_array(uint32_t p_elements, C *p_instance, M p_method, U p_userdata) { + + ThreadArrayProcessData<C, U> data; + data.method = p_method; + data.instance = p_instance; + data.userdata = p_userdata; + data.index = 0; + data.elements = p_elements; + for (uint32_t i = 0; i < p_elements; i++) { + data.process(i); + } +} + +#endif + +#endif // THREADED_ARRAY_PROCESSOR_H |
