From 9ae0bd3829a34d4239521d9c7838089395c2336c Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Tue, 18 Feb 2014 13:16:19 +0100 Subject: [PATCH] clover: Some improvements for the intrusive pointer class. Define some additional convenience operators, clean up the implementation slightly, and rename it to 'intrusive_ptr' for reasons that will be obvious in the next commit. Tested-by: Tom Stellard --- .../state_trackers/clover/api/event.cpp | 8 +-- .../state_trackers/clover/core/event.cpp | 2 +- .../state_trackers/clover/core/event.hpp | 4 +- .../state_trackers/clover/core/platform.hpp | 4 +- .../state_trackers/clover/core/queue.hpp | 4 +- .../state_trackers/clover/util/pointer.hpp | 53 ++++++++++++------- 6 files changed, 45 insertions(+), 30 deletions(-) diff --git a/src/gallium/state_trackers/clover/api/event.cpp b/src/gallium/state_trackers/clover/api/event.cpp index 1aff2c50238..05534c74c99 100644 --- a/src/gallium/state_trackers/clover/api/event.cpp +++ b/src/gallium/state_trackers/clover/api/event.cpp @@ -72,7 +72,7 @@ clWaitForEvents(cl_uint num_evs, const cl_event *d_evs) try { // Create a temporary soft event that depends on all the events in // the wait list - ref_ptr sev = + intrusive_ptr sev = transfer(new soft_event(evs.front().ctx, evs, true)); // ...and wait on it. @@ -132,7 +132,7 @@ clSetEventCallback(cl_event d_ev, cl_int type, // Create a temporary soft event that depends on ev, with // pfn_notify as completion action. - ref_ptr sev = transfer( + intrusive_ptr sev = transfer( new soft_event(ev.ctx, { ev }, true, [=, &ev](event &) { ev.wait(); @@ -206,7 +206,7 @@ clEnqueueWaitForEvents(cl_command_queue d_q, cl_uint num_evs, // Create a hard event that depends on the events in the wait list: // subsequent commands in the same queue will be implicitly // serialized with respect to it -- hard events always are. - ref_ptr hev = transfer(new hard_event(q, 0, evs)); + intrusive_ptr hev = transfer(new hard_event(q, 0, evs)); return CL_SUCCESS; @@ -262,7 +262,7 @@ clFinish(cl_command_queue d_q) try { // Create a temporary hard event -- it implicitly depends on all // the previously queued hard events. - ref_ptr hev = transfer(new hard_event(q, 0, { })); + intrusive_ptr hev = transfer(new hard_event(q, 0, { })); // And wait on it. hev->wait(); diff --git a/src/gallium/state_trackers/clover/core/event.cpp b/src/gallium/state_trackers/clover/core/event.cpp index 97f56357566..3f3e05e289a 100644 --- a/src/gallium/state_trackers/clover/core/event.cpp +++ b/src/gallium/state_trackers/clover/core/event.cpp @@ -186,7 +186,7 @@ soft_event::status() const { return _status; else if (!signalled() || - any_of([](const ref_ptr &ev) { + any_of([](const intrusive_ptr &ev) { return ev->status() != CL_COMPLETE; }, deps)) return CL_SUBMITTED; diff --git a/src/gallium/state_trackers/clover/core/event.hpp b/src/gallium/state_trackers/clover/core/event.hpp index 05bdd2f961f..123304bacc3 100644 --- a/src/gallium/state_trackers/clover/core/event.hpp +++ b/src/gallium/state_trackers/clover/core/event.hpp @@ -76,13 +76,13 @@ namespace clover { void chain(event *ev); cl_int _status; - std::vector> deps; + std::vector> deps; private: unsigned wait_count; action action_ok; action action_fail; - std::vector> _chain; + std::vector> _chain; }; /// diff --git a/src/gallium/state_trackers/clover/core/platform.hpp b/src/gallium/state_trackers/clover/core/platform.hpp index c16229a7512..bcc8e0c1cb5 100644 --- a/src/gallium/state_trackers/clover/core/platform.hpp +++ b/src/gallium/state_trackers/clover/core/platform.hpp @@ -32,7 +32,7 @@ namespace clover { class platform : public _cl_platform_id, public adaptor_range< - derefs, std::vector> &> { + derefs, std::vector> &> { public: platform(); @@ -41,7 +41,7 @@ namespace clover { operator=(const platform &platform) = delete; protected: - std::vector> devs; + std::vector> devs; }; } diff --git a/src/gallium/state_trackers/clover/core/queue.hpp b/src/gallium/state_trackers/clover/core/queue.hpp index e3c4ceb7744..81b9781cf47 100644 --- a/src/gallium/state_trackers/clover/core/queue.hpp +++ b/src/gallium/state_trackers/clover/core/queue.hpp @@ -69,9 +69,7 @@ namespace clover { cl_command_queue_properties _props; pipe_context *pipe; - - typedef ref_ptr event_ptr; - std::deque queued_events; + std::deque> queued_events; }; } diff --git a/src/gallium/state_trackers/clover/util/pointer.hpp b/src/gallium/state_trackers/clover/util/pointer.hpp index f0c5b1618a5..b7a633b523c 100644 --- a/src/gallium/state_trackers/clover/util/pointer.hpp +++ b/src/gallium/state_trackers/clover/util/pointer.hpp @@ -57,35 +57,43 @@ namespace clover { /// clover::ref_counter interface. /// template - class ref_ptr { + class intrusive_ptr { public: - ref_ptr(T *q = NULL) : p(NULL) { - reset(q); + intrusive_ptr(T *q = NULL) : p(q) { + if (p) + p->retain(); } - ref_ptr(const ref_ptr &ref) : p(NULL) { - reset(ref.p); + intrusive_ptr(const intrusive_ptr &ptr) : + intrusive_ptr(ptr.p) { } - ~ref_ptr() { - reset(NULL); + intrusive_ptr(intrusive_ptr &&ptr) : + p(ptr.p) { + ptr.p = NULL; } - void - reset(T *q = NULL) { - if (q) - q->retain(); + ~intrusive_ptr() { if (p && p->release()) delete p; - p = q; } - ref_ptr & - operator=(const ref_ptr &ref) { - reset(ref.p); + intrusive_ptr & + operator=(intrusive_ptr ptr) { + std::swap(ptr.p, p); return *this; } + bool + operator==(const intrusive_ptr &ref) const { + return p == ref.p; + } + + bool + operator!=(const intrusive_ptr &ref) const { + return p != ref.p; + } + T & operator*() const { return *p; @@ -96,22 +104,31 @@ namespace clover { return p; } + T * + operator()() const { + return p; + } + explicit operator bool() const { return p; } + explicit operator T *() const { + return p; + } + private: T *p; }; /// /// Transfer the caller's ownership of a reference-counted object - /// to a clover::ref_ptr smart pointer. + /// to a clover::intrusive_ptr smart pointer. /// template - inline ref_ptr + inline intrusive_ptr transfer(T *p) { - ref_ptr ref { p }; + intrusive_ptr ref { p }; p->release(); return ref; } -- 2.30.2