]> git.proxmox.com Git - ceph.git/blob - ceph/src/include/atomic.h
bump version to 12.0.3-pve3
[ceph.git] / ceph / src / include / atomic.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 /*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2004-2011 New Dream Network
7 *
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
12 *
13 * @author Sage Weil <sage@newdream.net>
14 */
15
16 #ifndef CEPH_ATOMIC_H
17 #define CEPH_ATOMIC_H
18
19 #ifdef __CEPH__
20 # include "acconfig.h"
21 #endif
22
23 #include <stdlib.h>
24 #include "include/Spinlock.h"
25
26 namespace ceph {
27 template <class T>
28 class atomic_spinlock_t {
29 mutable ceph_spinlock_t lock;
30 T val;
31 public:
32 atomic_spinlock_t(T i=0)
33 : val(i) {
34 ceph_spin_init(&lock);
35 }
36 ~atomic_spinlock_t() {
37 ceph_spin_destroy(&lock);
38 }
39 void set(T v) {
40 ceph_spin_lock(&lock);
41 val = v;
42 ceph_spin_unlock(&lock);
43 }
44 T inc() {
45 ceph_spin_lock(&lock);
46 T r = ++val;
47 ceph_spin_unlock(&lock);
48 return r;
49 }
50 T dec() {
51 ceph_spin_lock(&lock);
52 T r = --val;
53 ceph_spin_unlock(&lock);
54 return r;
55 }
56 void add(T d) {
57 ceph_spin_lock(&lock);
58 val += d;
59 ceph_spin_unlock(&lock);
60 }
61 void sub(T d) {
62 ceph_spin_lock(&lock);
63 val -= d;
64 ceph_spin_unlock(&lock);
65 }
66 T read() const {
67 T ret;
68 ceph_spin_lock(&lock);
69 ret = val;
70 ceph_spin_unlock(&lock);
71 return ret;
72 }
73 bool compare_and_swap(T o, T n) {
74 bool success = false;
75 ceph_spin_lock(&lock);
76 if (val == o) {
77 success = true;
78 val = n;
79 }
80 ceph_spin_unlock(&lock);
81 return success;
82 }
83
84 private:
85 // forbid copying
86 atomic_spinlock_t(const atomic_spinlock_t<T> &other);
87 atomic_spinlock_t &operator=(const atomic_spinlock_t<T> &rhs);
88 };
89 }
90
91 #ifndef NO_ATOMIC_OPS
92
93 // libatomic_ops implementation
94 #define AO_REQUIRE_CAS
95 #include <atomic_ops.h>
96
97 // reinclude our assert to clobber the system one
98 #include "include/assert.h"
99
100 namespace ceph {
101 class atomic_t {
102 AO_t val;
103 public:
104 atomic_t(AO_t i=0) : val(i) {}
105 void set(AO_t v) {
106 AO_store(&val, v);
107 }
108 AO_t inc() {
109 return AO_fetch_and_add1(&val) + 1;
110 }
111 AO_t dec() {
112 return AO_fetch_and_sub1_write(&val) - 1;
113 }
114 AO_t add(AO_t add_me) {
115 return AO_fetch_and_add(&val, add_me) + add_me;
116 }
117 AO_t sub(AO_t sub_me) {
118 AO_t negsub = 0 - sub_me;
119 return AO_fetch_and_add_write(&val, negsub) + negsub;
120 }
121 AO_t read() const {
122 // cast away const on the pointer. this is only needed to build
123 // on lenny, but not newer debians, so the atomic_ops.h got fixed
124 // at some point. this hack can go away someday...
125 return AO_load_full((AO_t *)&val);
126 }
127 bool compare_and_swap(AO_t o, AO_t n) {
128 return AO_compare_and_swap(&val, o, n);
129 }
130
131 private:
132 // forbid copying
133 atomic_t(const atomic_t &other);
134 atomic_t &operator=(const atomic_t &rhs);
135 };
136
137 #if SIZEOF_AO_T == 8
138 typedef atomic_t atomic64_t;
139 #else
140 typedef atomic_spinlock_t<unsigned long long> atomic64_t;
141 #endif
142
143 }
144
145 #else
146 /*
147 * crappy slow implementation that uses a pthreads spinlock.
148 */
149 #include "include/Spinlock.h"
150
151 namespace ceph {
152 typedef atomic_spinlock_t<unsigned> atomic_t;
153 typedef atomic_spinlock_t<unsigned long long> atomic64_t;
154 }
155
156 #endif
157 #endif