Tervel  1.0.0
A collection of wait-free containers and algorithms.
pop_op.h
Go to the documentation of this file.
1 
2 class PopOp:public OpRecord{
3 public:
4  std::atomic<PopHelper *> assoc;
5 
6  PopOp(){
7  assert(sizeof(PopOp) <= ALIGNLEN);
8  type=dt_popOp;
9  assoc.store(NULL);
10  }
11 
12  void * begin(WFVector *vec);
13 
14  void * s_execute(WFVector *vec);
15 
16  void execute(WFVector *vec){
17  s_execute(vec);
18  return;
19  };
20 
21  bool tryFree();
22 
23 };
24 
25 
26 
27 
28 
29 void * PopOp::begin(WFVector *vec){
30 
31  PopHelper *ph=new PopHelper();
32  controlWord=&(ph->child);
33 
34  int popPos=vec->csize.load();
35  while(true){// TO BOUND
36 
37  if(fcount++ == MAX_FAILURES){
38  ph->unsafeFree();
39  vec->announceOp(this);
40  void *res= this->s_execute(vec);
41  vec->resetMyOp();
42  return res;
43  }
44 
45  if(popPos<=0){
46  ph->unsafeFree();
47  return NOT_VALUE;
48  }
49 
50  ArrayElement *spot=vec->getSpot(popPos);
51  void *expected= spot->load();
52 
53  if( expected==NOT_VALUE){
54  if(spot->compare_exchange_strong(expected, Helper::mark(ph)) ){
55 
56  ph->complete(vec, popPos);
57 
58  void *value;
59  if(ph->getResult(value)){//returns true if was success
60 
61  assert(Value::isValid(value));
62 
63  ph->safeFree();
64 
65  return value;
66  }
67  else{//must have shrunk
68  ph->safeFree();
69  ph=new PopHelper();
70  controlWord=&(ph->child);
71  popPos--;
72  continue;
73  }
74  }
75 
76  }
77  else if(Helper::isHelper(expected)){
78  Helper *tHelper=Helper::unmark(expected);
79 
80  if(!tHelper->watch(expected, spot)){
81  continue;
82  }
83  bool helpRes=Helper::remove(vec, popPos,expected );
84  tHelper->unwatch();
85 
86  assert(rDepth==0);
87 
88  if(!helpRes){
89  ph->unsafeFree();
90  vec->announceOp((void *)this);
91  void *res= this->s_execute(vec);
92  vec->resetMyOp();
93  return res;
94  }
95  continue;
96  }
97  else{//its value
98  popPos++;
99  }
100  }//End While
101 
102 }
103 
104 void * PopOp::s_execute(WFVector *vec){
105 
106  PopHelper *ph=new PopHelper(this);
107  controlWord=(std::atomic<void *> *)&(assoc);
108 
109  int popPos=vec->csize.load();
110  while(true){
111 
112  if(popPos<=0){
113  ph->unsafeFree();
114 
115  PopHelper *temp1=NULL;
116  PopHelper *temp2=(PopHelper *) 0x1;
117  if(assoc.compare_exchange_strong(temp1, temp2) || temp1 == temp2){
118  return NOT_VALUE;
119  }
120  else{
121  void *value;
122  bool res=temp1->getResult(value);
123  assert(res);
124  return value;
125  }
126 
127  }
128 
129  ArrayElement *spot=vec->getSpot(popPos);
130  void *expected= spot->load();
131 
132  if( expected==NOT_VALUE){
133  if (spot->compare_exchange_strong(expected, Helper::mark(ph)) ) {
134 
135  ph->complete(vec, popPos);
136  void *value;
137  if(ph->getResult(value)){//returns true if was success
138  assert(Value::isValid(value));
139  return value;
140  }
141  else{//must have shrunk
142  ph->safeFree();
143  ph=new PopHelper(this);
144  popPos--;
145  continue;
146  }
147  }
148 
149  }
150  else if (Helper::isHelper(expected)) {
151  Helper *tHelper=Helper::unmark(expected);
152  if(!tHelper->watch(expected, spot)){
153  continue;
154  }
155 
156  Helper::remove(vec, popPos,expected);
157  tHelper->unwatch();
158 
159  assert(rDepth==0);
160  continue;
161  }
162  else {//its value
163  popPos++;
164  }
165  }//End While
166 
167 }
bool isValid(void *value)
Returns whether or not the passed value is has one of the reserved bits set to 1. ...
Definition: util.h:155
bool getResult(void *&v)
Definition: pop_helper.h:191
std::atomic< void * > child
Definition: pop_helper.h:5
bool complete(WFVector *vec, int pos)
Definition: pop_helper.h:214
PopOp()
Definition: pop_op.h:6
void * begin(WFVector *vec)
Definition: pop_op.h:29
std::atomic< PopHelper * > assoc
Definition: pop_op.h:4
Definition: pop_helper.h:3
bool tryFree()
Definition: pop_helper.h:278
void execute(WFVector *vec)
Definition: pop_op.h:16
void * s_execute(WFVector *vec)
Definition: pop_op.h:104
Definition: pop_op.h:2