Skip to content
Snippets Groups Projects
Commit e7eb5073 authored by Avi Kivity's avatar Avi Kivity Committed by Pekka Enberg
Browse files

rcu: add a Disposer template parameter so an rcu_ptr<> can own its resource

parent f113ab1f
No related branches found
No related tags found
No related merge requests found
......@@ -88,10 +88,21 @@ extern preempt_lock_in_rcu_type preempt_lock_in_rcu;
extern rcu_lock_in_preempt_type rcu_read_lock_in_preempt_disabled;
template <typename T>
struct rcu_no_delete {
void operator()(T* p) {}
};
// use rcu_ptr<T, rcu_deleter<T>> to auto-delete
template <typename T>
using rcu_deleter = std::default_delete<T>;
template <typename T, typename Disposer = rcu_no_delete<T>>
class rcu_ptr {
public:
rcu_ptr() {}
explicit rcu_ptr(T* p) : _ptr(p) {}
~rcu_ptr();
// Access contents for reading. Note: must be only called once
// for an object within a lock()/unlock() pair.
T* read() const;
......@@ -143,30 +154,40 @@ inline void rcu_lock_type::unlock()
sched::preempt_enable();
}
template <typename T>
template <typename T, typename Disposer>
inline
T* rcu_ptr<T>::read() const
rcu_ptr<T, Disposer>::~rcu_ptr()
{
// there can no longer be any readers
auto p = _ptr.load(std::memory_order_relaxed);
Disposer()(p);
}
template <typename T, typename Disposer>
inline
T* rcu_ptr<T, Disposer>::read() const
{
return _ptr.load(std::memory_order_consume);
}
template <typename T>
template <typename T, typename Disposer>
inline
void rcu_ptr<T>::assign(T* p)
void rcu_ptr<T, Disposer>::assign(T* p)
{
_ptr.store(p, std::memory_order_release);
}
template <typename T>
template <typename T, typename Disposer>
inline
void rcu_ptr<T>::assign(std::nullptr_t p)
void rcu_ptr<T, Disposer>::assign(std::nullptr_t p)
{
_ptr.store(p, std::memory_order_relaxed);
}
template <typename T>
template <typename T, typename Disposer>
inline
rcu_ptr<T>::operator bool() const
rcu_ptr<T, Disposer>::operator bool() const
{
return _ptr.load(std::memory_order_relaxed);
}
......@@ -178,9 +199,9 @@ void rcu_dispose(T* p)
rcu_defer(std::default_delete<T>(), p);
}
template <typename T>
template <typename T, typename Disposer>
inline
T* rcu_ptr<T>::read_by_owner()
T* rcu_ptr<T, Disposer>::read_by_owner()
{
return _ptr.load(std::memory_order_relaxed);
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment