From 4a422db79e1be0f212692655137ef24616b9c6b3 Mon Sep 17 00:00:00 2001 From: Yichao Yu <yyc1992@gmail.com> Date: Sat, 24 May 2014 12:56:59 -0400 Subject: [PATCH] nanny_event --- pyopencl/_cffi.py | 2 +- src/c_wrapper/pyhelper.cpp | 8 +++++-- src/c_wrapper/wrap_cl.cpp | 48 +++++++++++++++++++++++++++++++++++--- 3 files changed, 52 insertions(+), 6 deletions(-) diff --git a/pyopencl/_cffi.py b/pyopencl/_cffi.py index eeeb7d84..5775078f 100644 --- a/pyopencl/_cffi.py +++ b/pyopencl/_cffi.py @@ -182,6 +182,6 @@ def _get_insert_func(obj): return _insert def _find_obj(_id): - return _pyref[_id] + return _pyref.get(_id, None) _lib.set_deref(_py_deref) diff --git a/src/c_wrapper/pyhelper.cpp b/src/c_wrapper/pyhelper.cpp index 4ea2113e..cc490c30 100644 --- a/src/c_wrapper/pyhelper.cpp +++ b/src/c_wrapper/pyhelper.cpp @@ -4,11 +4,15 @@ namespace pyopencl { -static std::atomic<unsigned long> pyobj_id = ATOMIC_VAR_INIT(0ul); +static std::atomic<unsigned long> pyobj_id = ATOMIC_VAR_INIT(1ul); unsigned long next_obj_id() { - return std::atomic_fetch_add(&pyobj_id, 1ul); + unsigned long id; + do { + id = std::atomic_fetch_add(&pyobj_id, 1ul); + } while (id == 0); + return id; } static int diff --git a/src/c_wrapper/wrap_cl.cpp b/src/c_wrapper/wrap_cl.cpp index 7478675b..350d6f53 100644 --- a/src/c_wrapper/wrap_cl.cpp +++ b/src/c_wrapper/wrap_cl.cpp @@ -743,15 +743,57 @@ public: } } virtual void - wait() const + finished() + {} + void + wait() { pyopencl_call_guarded(clWaitForEvents, 1, &data()); + finished(); + } +}; + +class nanny_event : public event { +private: + unsigned int m_ward; +public: + nanny_event(cl_event evt, bool retain, void (*reffunc)(unsigned long)=0) + : event(evt, retain), m_ward(0) + { + if (reffunc) { + m_ward = next_obj_id(); + reffunc(m_ward); + } + } + ~nanny_event() + { + if (m_ward) { + wait(); + } + } + unsigned int + get_ward() const + { + return m_ward; + } + void + finished() + { + // No lock needed because multiple release is safe here. + unsigned long ward = m_ward; + m_ward = 0; + python_deref(ward); } }; + static inline event* -new_event(cl_event evt) +new_event(cl_event evt, void (*reffunc)(unsigned long)=0) { - return pyopencl_convert_obj(event, clReleaseEvent, evt); + if (reffunc) { + return pyopencl_convert_obj(nanny_event, clReleaseEvent, evt, reffunc); + } else { + return pyopencl_convert_obj(event, clReleaseEvent, evt); + } } // }}} -- GitLab