25 #ifndef __TERVEL_CONTAINERS_WF_VECTOR_PUSH_OP_H
26 #define __TERVEL_CONTAINERS_WF_VECTOR_PUSH_OP_H
36 #include <tervel/containers/wf/vector/vector.hpp>
39 namespace containers {
59 assert(temp !=
nullptr);
63 static size_t execute(Vector<T> *vec, T val) {
65 size_t placed_pos = vec->size();
67 std::atomic<T> *spot = vec->internal_array.get_spot(placed_pos);
69 T current = spot->load();
73 if (current == Vector<T>::c_not_value_) {
74 if (placed_pos == 0) {
75 if (spot->compare_exchange_strong(current, val)) {
87 helper->
set_prev_spot(vec->internal_array.get_spot(placed_pos-1));
89 if (!spot->compare_exchange_strong(current, help_t)) {
93 helper->
complete(reinterpret_cast<void *>(help_t),
94 reinterpret_cast< std::atomic<void *> *
>(spot));
95 bool op_res = helper->
result();
103 spot = vec->internal_array.get_spot(placed_pos);
104 current = spot->load();
106 }
else if (vec->internal_array.is_descriptor(current, spot)) {
107 assert((current & 2) == 0);
111 spot = vec->internal_array.get_spot(placed_pos);
112 current = spot->load();
121 placed_pos = pushOp->
result();
132 assert(temp !=
nullptr);
144 size_t placed_pos =
vec_->size();
146 std::atomic<T> *spot =
vec_->internal_array.get_spot(placed_pos);
147 T current = spot->load();
149 while (
helper_.load() ==
nullptr) {
150 if (current == Vector<T>::c_not_value_) {
152 if (!spot->compare_exchange_strong(current, help_t)) {
155 helper->
complete(reinterpret_cast<void *>(help_t),
156 reinterpret_cast< std::atomic<void *> *
>(spot));
158 bool op_res = helper->
result();
169 spot =
vec_->internal_array.get_spot(placed_pos);
170 current = spot->load();
172 }
else if (
vec_->internal_array.is_descriptor(current, spot)) {
176 spot =
vec_->internal_array.get_spot(placed_pos);
177 current = spot->load();
187 if (temp ==
nullptr) {
191 return temp->is_watched();
198 std::atomic<PushOpHelper<T> *>
helper_ {
nullptr};
223 success_.compare_exchange_strong(temp, 1);
224 return temp == 0 || temp == 1;
229 success_.compare_exchange_strong(temp, 2);
237 return reinterpret_cast<void *
>(
val_);
239 return reinterpret_cast<void *
>(Vector<T>::c_not_value_);
244 void *
complete(
void *value, std::atomic<void *> *address) {
245 std::atomic<T> * spot =
reinterpret_cast<std::atomic<T> *
>(address);
251 if (current_prev == Vector<T>::c_not_value_) {
254 }
else if (
vec_->internal_array.is_descriptor(current_prev,
prev_spot_)) {
274 if (spot->compare_exchange_strong(new_current,
val_)) {
280 if (spot->compare_exchange_strong(new_current,
281 reinterpret_cast<T>(Vector<T>::c_not_value_))) {
282 new_current =
reinterpret_cast<T
>(Vector<T>::c_not_value_);
286 return reinterpret_cast<void *
>(new_current);
323 }
else if (
op_->helper_.load() ==
nullptr) {
325 }
else if (
op_->helper_.load() ==
this) {
328 assert(
op_->helper_.load() !=
nullptr);
336 bool res =
op_->helper_.compare_exchange_strong(temp_null,
this);
337 if (res || temp_null ==
this) {
338 assert(
op_->helper_.load() ==
this);
341 assert(
op_->helper_.load() !=
this);
348 if ( (
success_.compare_exchange_strong(temp, 1) || temp == 1)
350 assert(
op_->helper_.load() ==
this);
361 if (
success_.compare_exchange_strong(temp, 2) || temp == 2) {
374 void *
complete(
void *value, std::atomic<void *> *address) {
375 std::atomic<T> * spot =
reinterpret_cast<std::atomic<T> *
>(address);
381 std::atomic<T> *spot_prev =
op_->vec_->internal_array.get_spot(
idx_-1);
382 T current_prev = spot_prev->load();
385 if (current_prev == Vector<T>::c_not_value_) {
387 }
else if (
op_->vec_->internal_array.is_descriptor(
388 current_prev, spot_prev)) {
405 assert(reinterpret_cast<T>(value) == new_current);
407 if (spot->compare_exchange_strong(new_current,
op_->new_val_)) {
408 new_current =
op_->new_val_;
411 if (spot->compare_exchange_strong(new_current,
412 reinterpret_cast<T>(Vector<T>::c_not_value_))) {
413 new_current =
reinterpret_cast<T
>(Vector<T>::c_not_value_);
417 return reinterpret_cast<void *
>(new_current);
423 return reinterpret_cast<void *
>(Vector<T>::c_not_value_);
425 return reinterpret_cast<void *
>(
op_->new_val_);
438 bool on_watch(std::atomic<void *> *address,
void * value) {
441 t_SlotID::SHORTUSE,
op_, address, value);
460 #endif // __TERVEL_CONTAINERS_WF_VECTOR_PUSH_OP_H
DescrType * get_descriptor(Args &&...args)
Constructs and returns a descriptor.
Definition: descriptor_util.h:50
virtual void * get_logical_value()=0
This method is implemented by each sub class.
static size_t execute(Vector< T > *vec, T val)
Definition: pushback_op.h:63
void * complete(void *value, std::atomic< void * > *address)
This method is implemented by each sub class and must guarantee that upon return that the descriptor ...
Definition: pushback_op.h:244
__thread void * tl_control_word
uint64_t idx()
Definition: pushback_op.h:311
Definition: pushback_op.h:51
void * mark_first(tervel::util::Descriptor *descr)
This returns the passed reference with its least signifcant bit set to 1.
Definition: descriptor_util.h:157
void * get_logical_value()
This method is implemented by each sub class.
Definition: pushback_op.h:234
void free_descriptor(tervel::util::Descriptor *descr, bool dont_check=false)
Once a user is done with a descriptor, they should free it with this method.
Definition: descriptor_util.h:65
TODO(steven):
Definition: mcas.h:36
void set_prev_spot(std::atomic< T > *prev_spot)
Definition: pushback_op.h:208
PushOpHelper(PushOp< T > *op)
Definition: pushback_op.h:304
std::atomic< uint64_t > success_
Definition: pushback_op.h:453
bool in_progress()
Definition: pushback_op.h:212
bool associate()
Definition: pushback_op.h:333
~PushOp()
Definition: pushback_op.h:57
void set_idx(uint64_t i)
Definition: pushback_op.h:307
T new_val_
Definition: pushback_op.h:197
bool in_progress()
Definition: pushback_op.h:315
bool fail()
Definition: pushback_op.h:359
std::atomic< uint64_t > success_
Definition: pushback_op.h:298
void set_control_word()
Definition: pushback_op.h:289
static void make_announcement(OpRecord *op, const uint64_t tid=tervel::tl_thread_info->get_thread_id(), ProgressAssurance *const prog_assur=tervel::tl_thread_info->get_progress_assurance())
This function places the.
Definition: progress_assurance.h:172
Vector< T > * vec_
Definition: pushback_op.h:196
void help_complete()
Implementations of this function that upon its return the operation described in the OpRecord has bee...
Definition: pushback_op.h:136
This defines the Descriptor class, this class is designed to be extend and be used in conjunction wit...
Definition: descriptor.h:60
void * get_logical_value()
This method is implemented by each sub class.
Definition: pushback_op.h:421
T val_
Definition: pushback_op.h:295
static bool watch(SlotID slot_id, Element *elem, std::atomic< void * > *address, void *expected, HazardPointer *const hazard_pointer=tervel::tl_thread_info->get_hazard_pointer())
This method is used to achieve a hazard pointer watch on the the based descr.
virtual void * complete(void *current, std::atomic< void * > *address)=0
This method is implemented by each sub class and must guarantee that upon return that the descriptor ...
PushDescr(T val, Vector< T > *vec)
Definition: pushback_op.h:204
void safe_delete(bool no_check=false, ElementList *const element_list=tervel::tl_thread_info->get_hp_element_list())
This function is used to free a hazard pointer protected object if it is safe to do so OR add it to a...
Definition: hp_element.h:67
This class is used to create Operation Records.
Definition: progress_assurance.h:52
Definition: pushback_op.h:47
bool success()
Definition: pushback_op.h:346
uint64_t idx_
Definition: pushback_op.h:452
PushOp< T > * op_
Definition: pushback_op.h:447
virtual bool on_watch(std::atomic< void * > *, void *)
This method is optional to implement for each sub class.
Definition: descriptor.h:99
bool result()
Definition: pushback_op.h:216
Vector< T > * vec_
Definition: pushback_op.h:296
void * complete(void *value, std::atomic< void * > *address)
This method is implemented by each sub class and must guarantee that upon return that the descriptor ...
Definition: pushback_op.h:374
bool on_watch(std::atomic< void * > *address, void *value)
This method is optional to implement for each sub class.
Definition: pushback_op.h:438
PushOp(Vector< T > *vec, T val)
Definition: pushback_op.h:53
bool isDelayed(size_t val=1)
Definition: progress_assurance.h:125
uint64_t result()
Definition: pushback_op.h:130
Definition: pushback_op.h:44
bool result()
Definition: pushback_op.h:319
Definition: progress_assurance.h:120
bool fail()
Definition: pushback_op.h:227
bool is_watched()
Definition: pushback_op.h:184
std::atomic< T > * prev_spot_
Definition: pushback_op.h:297
bool success()
Definition: pushback_op.h:221
SlotID
Definition: hazard_pointer.h:58
std::atomic< PushOpHelper< T > * > helper_
Definition: pushback_op.h:198