Fix copyright lines
[folly.git] / folly / experimental / hazptr / example / WideCAS.h
1 /*
2  * Copyright 2016-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17
18 #include <folly/experimental/hazptr/debug.h>
19 #include <folly/experimental/hazptr/hazptr.h>
20
21 #include <string>
22
23 namespace folly {
24 namespace hazptr {
25
26 /** Wide CAS.
27  */
28 class WideCAS {
29   using T = std::string;
30   class Node : public hazptr_obj_base<Node> {
31     friend WideCAS;
32     T val_;
33     Node() : val_(T()) { DEBUG_PRINT(this << " " << val_); }
34     explicit Node(T v) : val_(v) { DEBUG_PRINT(this << " " << v); }
35    public:
36     ~Node() { DEBUG_PRINT(this); }
37   };
38
39   std::atomic<Node*> p_ = {new Node()};
40
41  public:
42   WideCAS() = default;
43   ~WideCAS() {
44     DEBUG_PRINT(this << " " << p_.load());
45     delete p_.load();
46   }
47
48   bool cas(T& u, T& v) {
49     DEBUG_PRINT(this << " " << u << " " << v);
50     Node* n = new Node(v);
51     hazptr_holder hptr;
52     Node* p;
53     do {
54       p = hptr.get_protected(p_);
55       if (p->val_ != u) { delete n; return false; }
56       if (p_.compare_exchange_weak(p, n)) {
57         break;
58       }
59     } while (true);
60     hptr.reset();
61     p->retire();
62     DEBUG_PRINT(this << " " << p << " " << u << " " << n << " " << v);
63     return true;
64   }
65 };
66
67 } // namespace hazptr
68 } // namespace folly