From 984455690956615e6f324ea42a7af3682b4d435e Mon Sep 17 00:00:00 2001 From: Yichao Yu Date: Sat, 21 Jun 2014 08:50:40 +0800 Subject: [PATCH] one thread per callback --- setup.py | 1 - src/c_wrapper/async.cpp | 90 ----------------------------------------- src/c_wrapper/async.h | 15 ------- src/c_wrapper/event.cpp | 54 ++++--------------------- src/c_wrapper/event.h | 23 ++++++++++- 5 files changed, 29 insertions(+), 154 deletions(-) delete mode 100644 src/c_wrapper/async.cpp delete mode 100644 src/c_wrapper/async.h diff --git a/setup.py b/setup.py index 59bf27de..d489196f 100644 --- a/setup.py +++ b/setup.py @@ -235,7 +235,6 @@ def main(): "src/c_wrapper/wrap_constants.cpp", "src/c_wrapper/bitlog.cpp", "src/c_wrapper/pyhelper.cpp", - "src/c_wrapper/async.cpp", "src/c_wrapper/platform.cpp", "src/c_wrapper/device.cpp", "src/c_wrapper/context.cpp", diff --git a/src/c_wrapper/async.cpp b/src/c_wrapper/async.cpp deleted file mode 100644 index 69d76a16..00000000 --- a/src/c_wrapper/async.cpp +++ /dev/null @@ -1,90 +0,0 @@ -#include "async.h" -#include "function.h" - -#include -#include -#include -#include - -namespace pyopencl { - -template -class Queue { -private: - std::queue m_queue; - std::mutex m_mutex; - std::condition_variable m_cond; -public: - PYOPENCL_INLINE T - pop() - { - std::unique_lock mlock(m_mutex); - while (m_queue.empty()) { - m_cond.wait(mlock); - } - auto item = m_queue.front(); - m_queue.pop(); - return item; - } - PYOPENCL_INLINE void - push(const T &item) - { - { - // Sub scope for the lock - std::unique_lock mlock(m_mutex); - m_queue.push(item); - } - m_cond.notify_one(); - } -}; - -class AsyncCaller { -private: - Queue > m_queue; - std::once_flag m_flag; - void - worker() - { - while (true) { - try { - auto func = m_queue.pop(); - func(); - } catch (...) { - } - } - } - void - start_thread() - { - std::thread t(&AsyncCaller::worker, this); - t.detach(); - } -public: - PYOPENCL_INLINE void - ensure_thread() - { - std::call_once(m_flag, &AsyncCaller::start_thread, this); - } - PYOPENCL_INLINE void - push(const std::function &func) - { - ensure_thread(); - m_queue.push(func); - } -}; - -static AsyncCaller async_caller; - -void -call_async(const std::function &func) -{ - async_caller.push(func); -} - -void -init_async() -{ - async_caller.ensure_thread(); -} - -} diff --git a/src/c_wrapper/async.h b/src/c_wrapper/async.h deleted file mode 100644 index 43fb60f5..00000000 --- a/src/c_wrapper/async.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef __PYOPENCL_ASYNC_H -#define __PYOPENCL_ASYNC_H - -#include - -namespace pyopencl { - -// Start the helper thread -void init_async(); -// Call @func in the helper thread -void call_async(const std::function &func); - -} - -#endif diff --git a/src/c_wrapper/event.cpp b/src/c_wrapper/event.cpp index 8104d9ae..5b7eb3af 100644 --- a/src/c_wrapper/event.cpp +++ b/src/c_wrapper/event.cpp @@ -1,11 +1,9 @@ #include "event.h" #include "command_queue.h" #include "context.h" -#include "async.h" #include "pyhelper.h" #include -#include namespace pyopencl { @@ -38,28 +36,6 @@ public: } }; -#if PYOPENCL_CL_VERSION >= 0x1010 -class event_callback { - std::function m_func; - event_callback(const std::function &func) noexcept - : m_func(func) - {} - static void - cl_call_and_free(cl_event, cl_int status, void *data) noexcept - { - auto cb = static_cast(data); - auto func = cb->m_func; - try { - call_async([func, status] {func(status);}); - } catch (...) { - } - delete cb; - } - - friend class event; -}; -#endif - event::event(cl_event event, bool retain, event_private *p) : clobj(event), m_p(p) { @@ -84,13 +60,13 @@ event::release_private() noexcept } #if PYOPENCL_CL_VERSION >= 0x1010 if (support_cb) { - pyopencl_call_guarded_cleanup(clSetEventCallback, this, CL_COMPLETE, - [] (cl_event, cl_int, void *data) { - event_private *p = - static_cast(data); - p->call_finish(); - delete p; - }, (void*)m_p); + pyopencl_call_guarded_cleanup( + clSetEventCallback, this, CL_COMPLETE, + [] (cl_event, cl_int, void *data) { + event_private *p = static_cast(data); + p->call_finish(); + delete p; + }, (void*)m_p); } else { #endif std::thread t([] (cl_event evt, event_private *p) { @@ -156,22 +132,6 @@ event::wait() const } } -#if PYOPENCL_CL_VERSION >= 0x1010 -void -event::set_callback(cl_int type, const std::function &func) -{ - auto cb = new event_callback(func); - try { - pyopencl_call_guarded(clSetEventCallback, this, type, - &event_callback::cl_call_and_free, cb); - } catch (...) { - delete cb; - throw; - } - init_async(); -} -#endif - class nanny_event_private : public event_private { void *m_ward; void finished() noexcept diff --git a/src/c_wrapper/event.h b/src/c_wrapper/event.h index 68ce507e..2e90c0e8 100644 --- a/src/c_wrapper/event.h +++ b/src/c_wrapper/event.h @@ -1,4 +1,5 @@ #include "clhelper.h" +#include #ifndef __PYOPENCL_EVENT_H #define __PYOPENCL_EVENT_H @@ -33,7 +34,27 @@ public: void wait() const; #if PYOPENCL_CL_VERSION >= 0x1010 bool support_cb; - void set_callback(cl_int type, const std::function &func); + template + PYOPENCL_INLINE void + set_callback(cl_int type, Func &&_func) + { + auto func = new rm_ref_t(std::forward(_func)); + try { + pyopencl_call_guarded( + clSetEventCallback, this, type, + [] (cl_event, cl_int status, void *data) { + rm_ref_t *func = static_cast*>(data); + std::thread t([func, status] () { + (*func)(status); + delete func; + }); + t.detach(); + }, (void*)func); + } catch (...) { + delete func; + throw; + } + } #endif }; static PYOPENCL_INLINE auto -- GitLab