1cd139dc7SShuo Chen// excerpts from http://code.google.com/p/muduo/
2cd139dc7SShuo Chen//
3cd139dc7SShuo Chen// Use of this source code is governed by a BSD-style license
4cd139dc7SShuo Chen// that can be found in the License file.
5cd139dc7SShuo Chen//
6cd139dc7SShuo Chen// Author: Shuo Chen (giantchen at gmail dot com)
7cd139dc7SShuo Chen
8cd139dc7SShuo Chen#ifndef MUDUO_BASE_ATOMIC_H
9cd139dc7SShuo Chen#define MUDUO_BASE_ATOMIC_H
10cd139dc7SShuo Chen
11cd139dc7SShuo Chen#include <boost/noncopyable.hpp>
12cd139dc7SShuo Chen#include <stdint.h>
13cd139dc7SShuo Chen
14cd139dc7SShuo Chennamespace muduo
15cd139dc7SShuo Chen{
16cd139dc7SShuo Chen
17cd139dc7SShuo Chennamespace detail
18cd139dc7SShuo Chen{
19cd139dc7SShuo Chentemplate<typename T>
20cd139dc7SShuo Chenclass AtomicIntegerT : boost::noncopyable
21cd139dc7SShuo Chen{
22cd139dc7SShuo Chen public:
23cd139dc7SShuo Chen  AtomicIntegerT()
24cd139dc7SShuo Chen    : value_(0)
25cd139dc7SShuo Chen  {
26cd139dc7SShuo Chen  }
27cd139dc7SShuo Chen
280d2d6577SShuo Chen  // uncomment if you need copying and assignment
290d2d6577SShuo Chen  //
300d2d6577SShuo Chen  // AtomicIntegerT(const AtomicIntegerT& that)
310d2d6577SShuo Chen  //   : value_(that.get())
320d2d6577SShuo Chen  // {}
330d2d6577SShuo Chen  //
340d2d6577SShuo Chen  // AtomicIntegerT& operator=(const AtomicIntegerT& that)
350d2d6577SShuo Chen  // {
360d2d6577SShuo Chen  //   getAndSet(that.get());
370d2d6577SShuo Chen  //   return *this;
380d2d6577SShuo Chen  // }
390d2d6577SShuo Chen
40cd139dc7SShuo Chen  T get() const
41cd139dc7SShuo Chen  {
420d2d6577SShuo Chen    return __sync_val_compare_and_swap(const_cast<volatile T*>(&value_), 0, 0);
43cd139dc7SShuo Chen  }
44cd139dc7SShuo Chen
45cd139dc7SShuo Chen  T getAndAdd(T x)
46cd139dc7SShuo Chen  {
47cd139dc7SShuo Chen    return __sync_fetch_and_add(&value_, x);
48cd139dc7SShuo Chen  }
49cd139dc7SShuo Chen
50cd139dc7SShuo Chen  T addAndGet(T x)
51cd139dc7SShuo Chen  {
52cd139dc7SShuo Chen    return getAndAdd(x) + x;
53cd139dc7SShuo Chen  }
54cd139dc7SShuo Chen
55cd139dc7SShuo Chen  T incrementAndGet()
56cd139dc7SShuo Chen  {
57cd139dc7SShuo Chen    return addAndGet(1);
58cd139dc7SShuo Chen  }
59cd139dc7SShuo Chen
60ca443bc0SShuo Chen  void add(T x)
61ca443bc0SShuo Chen  {
62ca443bc0SShuo Chen    getAndAdd(x);
63ca443bc0SShuo Chen  }
64ca443bc0SShuo Chen
65cd139dc7SShuo Chen  void increment()
66cd139dc7SShuo Chen  {
67cd139dc7SShuo Chen    incrementAndGet();
68cd139dc7SShuo Chen  }
69cd139dc7SShuo Chen
70cd139dc7SShuo Chen  void decrement()
71cd139dc7SShuo Chen  {
72cd139dc7SShuo Chen    getAndAdd(-1);
73cd139dc7SShuo Chen  }
74cd139dc7SShuo Chen
75cd139dc7SShuo Chen  T getAndSet(T newValue)
76cd139dc7SShuo Chen  {
77cd139dc7SShuo Chen    return __sync_lock_test_and_set(&value_, newValue);
78cd139dc7SShuo Chen  }
79cd139dc7SShuo Chen
80cd139dc7SShuo Chen private:
81cd139dc7SShuo Chen  volatile T value_;
82cd139dc7SShuo Chen};
83cd139dc7SShuo Chen}
84cd139dc7SShuo Chen
85cd139dc7SShuo Chentypedef detail::AtomicIntegerT<int32_t> AtomicInt32;
86cd139dc7SShuo Chentypedef detail::AtomicIntegerT<int64_t> AtomicInt64;
87cd139dc7SShuo Chen}
88cd139dc7SShuo Chen
89cd139dc7SShuo Chen#endif  // MUDUO_BASE_ATOMIC_H
90