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