Skip to content
This repository was archived by the owner on Mar 22, 2023. It is now read-only.

Commit 5c931ce

Browse files
authored
Merge pull request #1229 from lukaszstolarczuk/add-assignment-op-for-pa_ptr
Add deleted assignment operator for persistent_aware ptr
2 parents 9fd40df + c3ef517 commit 5c931ce

File tree

1 file changed

+47
-18
lines changed

1 file changed

+47
-18
lines changed

include/libpmemobj++/experimental/atomic_persistent_aware_ptr.hpp

Lines changed: 47 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,12 @@ namespace experimental
3232
*
3333
* In a multi-threaded scenario, the persistence of this ptr is guaranteed when
3434
* it is visible to (or read by) other threads. Performance-wise, two different
35-
* options are provided: Read-optimized and Write-optimized. See corresponding
36-
* store/load functions for details.
35+
* versions of this struct are provided:
36+
* - Read-optimized - data is flushed along the write operation. If more reads
37+
* are expected it's probably better to use this scenario.
38+
* - Write-optimized - data is lazily flushed with a read operation. In this
39+
* approach data storing is expected to be faster, but data is
40+
*guranteed to be flushed only after consequent read.
3741
*/
3842
template <typename T, typename ReadOptimized>
3943
struct atomic_persistent_aware_ptr {
@@ -55,18 +59,27 @@ struct atomic_persistent_aware_ptr {
5559
/**
5660
* Constructors
5761
*/
62+
63+
/**
64+
* Store constructor.
65+
*
66+
* @param value to be stored in the atomic_persistent_aware_ptr.
67+
*/
5868
atomic_persistent_aware_ptr(value_type value) : ptr()
5969
{
6070
store(value);
6171
}
72+
73+
/**
74+
* Deleted copy constructor.
75+
*/
6276
atomic_persistent_aware_ptr(const atomic_persistent_aware_ptr &) =
6377
delete;
6478

6579
/**
66-
* Read-optimized store does the flush in store function, and clear the
67-
* dirty marker after flush.
80+
* Read-optimized store does the flush already in the store function.
6881
*
69-
* @param[in] desired the self_relative_ptr (no dirty flag) to be stored
82+
* @param[in] desired the self_relative_ptr to be stored.
7083
*
7184
*/
7285
template <typename OPT = ReadOptimized>
@@ -87,10 +100,9 @@ struct atomic_persistent_aware_ptr {
87100
}
88101

89102
/**
90-
* Write-optimized store updates the ptr with the dirty flag, relies on
91-
* consequent load to do the flush.
103+
* Write-optimized store relies on a consequent load to do the flush.
92104
*
93-
* @param[in] desired the self_relative_ptr (no dirty flag) to be stored
105+
* @param[in] desired the self_relative_ptr to be stored.
94106
*
95107
*/
96108
template <typename OPT = ReadOptimized>
@@ -102,18 +114,18 @@ struct atomic_persistent_aware_ptr {
102114
}
103115

104116
/**
105-
* Read-optimized load retries upon dirty ptr, relies on the store
106-
* function to clear the dirty before continue.
107-
* But for correctness, just flush the dirty ptr and return the clear
108-
* ptr for now.
117+
* Read-optimized load. It relies on a store function to flush the data.
109118
*
110-
* @return the self_relative_ptr (no dirty flag)
119+
* @return the value_type.
111120
*/
112121
template <typename OPT = ReadOptimized>
113122
typename std::enable_if<std::is_same<OPT, std::true_type>::value,
114123
value_type>::type
115124
load(std::memory_order order = std::memory_order_seq_cst) noexcept
116125
{
126+
/* This load relies on the store function to clear the dirty
127+
* flag. For correctness though, it flushes the dirty ptr and
128+
* returns the clear ptr for now. */
117129
auto val = ptr.load(order);
118130
if (is_dirty(val)) {
119131
pool_by_vptr(this).persist(&ptr, sizeof(ptr));
@@ -122,18 +134,19 @@ struct atomic_persistent_aware_ptr {
122134
}
123135

124136
/**
125-
* Write-optimized load flushes the ptr with the dirty flag, clears the
126-
* flag using CAS after flush.
127-
* If CAS failed, simply return the old clear ptr, rely on later load to
128-
* clear the dirty flag.
137+
* Write-optimized load flushes the data.
129138
*
130-
* @return the self_relative_ptr (no dirty flag)
139+
* @return the value_type.
131140
*/
132141
template <typename OPT = ReadOptimized>
133142
typename std::enable_if<!std::is_same<OPT, std::true_type>::value,
134143
value_type>::type
135144
load(std::memory_order order = std::memory_order_seq_cst) noexcept
136145
{
146+
/* It flushes the ptr with the dirty flag - clears the flag
147+
* using CAS after flush. If CAS failed it simply returns the
148+
* old clear ptr and relies on a later load to clear the dirty
149+
* flag. */
137150
auto val = ptr.load(order);
138151
if (is_dirty(val)) {
139152
pool_by_vptr(this).persist(&ptr, sizeof(ptr));
@@ -156,18 +169,34 @@ struct atomic_persistent_aware_ptr {
156169
/*
157170
* Operators
158171
*/
172+
173+
/**
174+
* Returns the value of the atomic_persistent_aware_ptr.
175+
*/
159176
operator value_type() const noexcept
160177
{
161178
return load();
162179
}
163180

181+
/**
182+
* Assignment operator.
183+
*
184+
* @param desired value to be stored in the atomic_persistent_aware_ptr.
185+
* @return assigned value.
186+
*/
164187
value_type
165188
operator=(value_type desired) noexcept
166189
{
167190
store(desired);
168191
return desired;
169192
}
170193

194+
/**
195+
* Deleted assignment operator.
196+
*/
197+
atomic_persistent_aware_ptr &
198+
operator=(const atomic_persistent_aware_ptr &) = delete;
199+
171200
private:
172201
value_type
173202
mark_dirty(value_type ptr) const

0 commit comments

Comments
 (0)