6 template<
class ShiftOp,
class T>
13 std::atomic<helper_t *>
next_{
nullptr};
15 ShiftHelper(ShiftOp * op_rec, helper_t *prev, T replaced_value )
18 , replaced_value_(replaced_value) {};
21 bool complete(WFVector *vec,
int pos);
24 using util::Descriptor::on_watch;
25 bool on_watch(std::atomic<void *> *address,
void * value) {
26 typedef util::memory::hp::HazardPointer::SlotID t_SlotID;
28 t_SlotID::SHORTUSE, op_rec_, address, value);
30 if (success && prev_ !=
nullptr) {
31 helper_t temp = prev->next_.load();
32 if (temp ==
nullptr) {
33 if (prev->next_.compare_exchange_strong(temp,
this)) {
40 address->compare_exchange_strong(value, replaced_value_);
47 assert(cas_row_->helper_.load() !=
nullptr);
57 using util::Descriptor::get_logical_value;
59 if (op_rec_->is_complete()) {
60 return next_.load()->replaced_value_;
69 template<
class ShiftType>
73 using util::Descriptor::complete;
74 void * helper_t::complete(
void *value, std::atomic<void *> *address) {
81 template<
class ParentOp>
84 if(this->rvalue==NULL){
85 main->isComplete.store(
true);
95 if (main->isComplete.load()){
99 ArrayElement *spot=vec->getSpot(i);
103 void *current=spot->load();
107 lastHelper=tempHelper;
109 if (lastHelper->rvalue == NOT_VALUE) {
110 main->isComplete.store(
true);
118 else if (Helper::isHelper(current)) {
121 Helper * tHelper= Helper::unmark(current);
123 if(!tHelper->watch(current, spot)){
127 if (tHelper->type == type) {
129 if(tHelper2->main==main){
131 if (lastHelper->next.compare_exchange_strong(temp, tHelper2) || tHelper2 == temp){
134 if(tHelper2->rvalue == NOT_VALUE){
135 main->isComplete.store(
true);
141 assert(main->isComplete.load());
148 else if(tHelper->type == dt_popBack) {
152 tHelper2->
child.compare_exchange_strong(temp, (
void *)0x1);
153 spot->compare_exchange_strong(current, NOT_VALUE);
158 else if(tHelper->type == dt_pushBack) {
162 long tpos=tHelper2->
pos.load();
164 if(tHelper2->
pos.compare_exchange_strong(tpos, i)){
175 else if(tHelper->type >= dt_unknown) {
180 bool helpRes=Helper::remove(vec, i, current);
181 if(!helpRes && rDepth>0){
192 if (spot->compare_exchange_strong(current, Helper::mark(helper))){
195 if (lastHelper->next.compare_exchange_strong(temp, helper) || helper == temp){
198 if(current == NOT_VALUE){
199 main->isComplete.store(
true);
205 void *temp2=Helper::mark(helper);
206 spot->compare_exchange_strong(temp2, current);
208 assert(main->isComplete.load());
215 helper->unsafeFree();
233 ArrayElement *spot=vec->getSpot(pos);
234 void *current=Helper::mark(
this);
238 if(main->next.compare_exchange_strong(temp,
this) || temp==
this){
239 if(!complete_phase1(vec, pos)){
240 assert(rDepth > 0 || main->isComplete.load());
243 assert(main->isComplete.load());
244 spot->compare_exchange_strong(current, main->rvalue);
249 spot->compare_exchange_strong(current, rvalue);
255 if(parent->next.compare_exchange_strong(temp,
this) || temp==
this){
256 if(!complete_phase1(vec, pos)){
257 assert(rDepth > 0 || main->isComplete.load());
260 assert(main->isComplete.load());
261 spot->compare_exchange_strong(current, parent->rvalue);
266 spot->compare_exchange_strong(current, rvalue);
275 ArrayElement *spot=vec->getSpot(pos);
276 void *current=Helper::mark(
this);
282 if (parent == NULL) {
283 success=main->next.compare_exchange_strong(temp,
this) || temp==
this;
286 success=parent->next.compare_exchange_strong(temp,
this) || temp==
this;
290 if(!complete_phase1(vec, pos)){
291 assert(rDepth > 0 || main->isComplete.load());
295 assert(main->isComplete.load());
297 if(next.load() == NULL){
298 spot->compare_exchange_strong(current, NOT_VALUE);
301 spot->compare_exchange_strong(current, next.load()->rvalue);
307 spot->compare_exchange_strong(current, rvalue);
315 template<
class ShiftType>
317 if(pos >= vec->csize){
320 op->isComplete.store(
true);
328 if(fcount++==MAX_FAILURES){
341 op->isComplete.store(
true);
344 else if (temp != NULL) {
349 ArrayElement *spot=vec->getSpot(pos);
350 void *current=spot->load();
351 if (Helper::isHelper(current)) {
353 Helper * tHelper= Helper::unmark(current);
354 if(!tHelper->watch(current, spot)){
358 if (tHelper->type == dt_shifthelper) {
360 if(tHelper2->main==op){
362 if (op->next.compare_exchange_strong(temp, tHelper2) || tHelper2 == temp){
364 if(tHelper2->rvalue == NOT_VALUE){
367 op->isComplete.store(
true);
376 assert(op->next.load());
378 op->isComplete.store(
true);
395 else if(tHelper->type >= dt_unknown) {
397 op->isComplete.store(
true);
401 Helper::remove(vec, pos, current);
407 else if (current == NOT_VALUE) {
410 op->isComplete.store(
true);
420 if (spot->compare_exchange_strong(current, Helper::mark(helper))) {
422 if (op->next.load() != helper) {
429 helper->unsafeFree();
ShiftHelper(ShiftOp *op_rec, helper_t *prev, T replaced_value)
Definition: shift_helper.h:15
const T replaced_value_
Definition: shift_helper.h:12
Definition: shift_helper.h:7
Definition: push_helper.h:2
std::atomic< void * > child
Definition: pop_helper.h:5
bool on_watch(std::atomic< void * > *address, void *value)
This method is optional to implement for each sub class.
Definition: shift_helper.h:25
const helper_t * prev_
Definition: shift_helper.h:10
void unwatch(tervel::util::Descriptor *descr)
This method is used to decrement the reference count of the passed descriptor object.
Definition: descriptor_util.h:139
ShiftHelper< ShiftOp, T > helper_t
Definition: shift_helper.h:8
bool completeShift(ShiftType *op, WFVector *vec, int pos)
Definition: shift_helper.h:316
bool complete(WFVector *vec, int pos)
bool is_watched(tervel::util::Descriptor *descr)
This method is used to determine if the passed descriptor is under rc protection. ...
Definition: descriptor_util.h:78
bool complete(WFVector *vec, int pos)
Definition: push_helper.h:73
void * get_logical_value()
This method is implemented by each sub class.
Definition: shift_helper.h:58
This defines the Descriptor class, this class is designed to be extend and be used in conjunction wit...
Definition: descriptor.h:60
std::atomic< helper_t * > next_
Definition: shift_helper.h:13
bool watch(tervel::util::Descriptor *descr, std::atomic< void * > *address, void *value)
This method is used to increment the reference count of the passed descriptor object.
Definition: descriptor_util.h:105
const ShiftOp * op_rec_
Definition: shift_helper.h:11
Definition: pop_helper.h:3
std::atomic< long > pos
Definition: push_helper.h:5
bool complete_phase1(WFVector *vec, int pos)
Definition: shift_helper.h:82