1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef BASE_ATOMIC_SEQUENCE_NUM_H_
6#define BASE_ATOMIC_SEQUENCE_NUM_H_
7
8#include "base/atomicops.h"
9#include "base/macros.h"
10
11namespace base {
12
13class AtomicSequenceNumber;
14
15// Static (POD) AtomicSequenceNumber that MUST be used in global scope (or
16// non-function scope) ONLY. This implementation does not generate any static
17// initializer.  Note that it does not implement any constructor which means
18// that its fields are not initialized except when it is stored in the global
19// data section (.data in ELF). If you want to allocate an atomic sequence
20// number on the stack (or heap), please use the AtomicSequenceNumber class
21// declared below.
22class StaticAtomicSequenceNumber {
23 public:
24  inline int GetNext() {
25    return static_cast<int>(
26        base::subtle::NoBarrier_AtomicIncrement(&seq_, 1) - 1);
27  }
28
29 private:
30  friend class AtomicSequenceNumber;
31
32  inline void Reset() {
33    base::subtle::Release_Store(&seq_, 0);
34  }
35
36  base::subtle::Atomic32 seq_;
37};
38
39// AtomicSequenceNumber that can be stored and used safely (i.e. its fields are
40// always initialized as opposed to StaticAtomicSequenceNumber declared above).
41// Please use StaticAtomicSequenceNumber if you want to declare an atomic
42// sequence number in the global scope.
43class AtomicSequenceNumber {
44 public:
45  AtomicSequenceNumber() {
46    seq_.Reset();
47  }
48
49  inline int GetNext() {
50    return seq_.GetNext();
51  }
52
53 private:
54  StaticAtomicSequenceNumber seq_;
55  DISALLOW_COPY_AND_ASSIGN(AtomicSequenceNumber);
56};
57
58}  // namespace base
59
60#endif  // BASE_ATOMIC_SEQUENCE_NUM_H_
61