Tervel  1.0.0
A collection of wait-free containers and algorithms.
push_op.h
Go to the documentation of this file.
1 #ifndef __VECTOR_PUSH_OP_H_
2 #define __VECTOR_PUSH_OP_H_
3 
4 template<class T>
5 class PushOp: public OpRecord {
6  public:
7  std::atomic<PushHelper<T> *> helper_{nullptr};
8  std::atomic<size_t> pos_{-1};
9  const Vector vector_
10  const T value_;
11  PushOp(Vector vector, T value)
12  : vector_(vector)
13  , value_(value) {};
14 
15  size_t begin();
16 
17  void execute();
18 
19 };
20 
21 template<class T>
22 size_t PushOp::begin(){
23  tl_control_word = (std::atomic<void *> *)(&(helper_));
24 
25  size_t pushed_pos = vector_->size();
26 
27  while(true){
28 
29  if (pushedPos <0 ) {
30  pushedPos = 0;
31  }
32 
33  if (fcount++ < util::ProgressAssurance::MAX_FAILURES) {
34  util::ProgressAssurance::make_announcement(
35  reinterpret_cast<tervel::util::OpRecord *>(op));
36 
37  pushed_pos = op->result();
38  op->safe_delete();
39  return pushed_pos;
40  }
41 
42  ArrayElement *spot=vec->getSpot(pushedPos);
43  void *expected= spot->load();
44 
45  if( expected==NOT_VALUE){
46 
47  if(pushedPos==0){
48  if(spot->compare_exchange_strong(expected, value)){
49  return 0;
50  }
51  else{
52  pushedPos++;
53  spot=vec->getSpot(pushedPos);
54  }
55  }
56 
57  assert(pushedPos >=1);
58 
59  PushHelper *ph=new PushHelper(value);
60 
61  if(spot->compare_exchange_strong(expected, Helper::mark(ph)) ){
62 
63  ph->complete(vec, pushedPos);
64  long res=ph->pos.load();
65  ph->safeFree();
66  assert(res != -1);
67  if(res != -2 ){//returns true if was success
68  return pushedPos;
69  }
70  else{//must have shrunk
71  pushedPos--;
72  continue;
73  }
74  }
75  }
76  else if(Helper::isHelper(expected)){
77  Helper *tHelper=Helper::unmark(expected);
78  if(!tHelper->watch(expected, spot)){
79  continue;
80  }
81 
82  bool helpRes=Helper::remove(vec, pushedPos,expected );
83  tHelper->unwatch();
84  assert(rDepth == 0);
85 
86  if(!helpRes){
87  vec->announceOp(this);
88  long res= this->s_execute(vec);
89  vec->resetMyOp();
90  return res;
91  }
92  continue;
93  }
94  else{//its value
95  pushedPos++;
96  }
97  }//End While
98 }
99 
100 
101 template<class T>
102 size_t PushOp::s_execute(WFVector *vec){//only this op can call it
103 
104  controlWord=(std::atomic<void *> *)(&(assoc));
105 
106  long pushedPos=vec->csize.load();
107  while(this->assoc.load() == NULL){// Implicit BOUND by threads
108  assert(rDepth == 0);
109  if (pushedPos <0 )
110  pushedPos=0;
111 
112  ArrayElement *spot=vec->getSpot(pushedPos);
113  void *expected= spot->load();
114 
115  if( expected==NOT_VALUE){
116 
117  PushHelper *ph=new PushHelper(value, this);
118  if(spot->compare_exchange_strong(expected, Helper::mark(ph)) ){
119 
120  ph->complete(vec, pushedPos);
121  long res=ph->pos;
122  assert(res != -1);
123  if(pos != -2){
124  return res;
125  }
126  else{
127  pushedPos--;
128  ph->safeFree();
129  continue;
130  }
131 
132  }//End If successful Cas
133  }
134  else if(Helper::isHelper(expected)){
135  Helper *tHelper=Helper::unmark(expected);
136  if(!tHelper->watch(expected, spot)){
137  continue;
138  }
139  Helper::remove(vec, pushedPos, expected );
140  tHelper->unwatch();
141  continue;
142  }
143  else{//its value
144  pushedPos++;
145  }
146  }//End While
147 
148  return this->assoc.load()->pos;
149 }
150 
151 
152 bool PushOp::tryFree(){
153  if(this->isWatched()){
154  return false;
155  }
156  else{
157  PushHelper *ph= assoc.load();
158  if (ph && ph->isWatched() )
159  return false;
160  else if(ph)
161  ph->unsafeFree();
162 
163  this->unsafeFree();
164  return true;
165  }
166 }
167 
168 
169 #endif // __VECTOR_PUSH_OP_H_
__thread void * tl_control_word
std::atomic< size_t > pos_
Definition: push_op.h:8
Definition: push_helper.h:2
PushOp(Vector vector, T value)
Definition: push_op.h:11
Definition: push_op.h:5
size_t begin()
Definition: push_op.h:22
bool isWatched()
Definition: push_helper.h:57
bool complete(WFVector *vec, int pos)
Definition: push_helper.h:73
void execute()
std::atomic< PushHelper< T > * > helper_
Definition: push_op.h:7
const Vector vector_ const T value_
Definition: push_op.h:10
std::atomic< long > pos
Definition: push_helper.h:5