xref: /netbsd-src/external/gpl3/gcc.old/dist/libsanitizer/tsan/tsan_vector.h (revision 1debfc3d3fad8af6f31804271c18e67f77b4d718)
1 //===-- tsan_vector.h -------------------------------------------*- C++ -*-===//
2 //
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
5 //
6 //===----------------------------------------------------------------------===//
7 //
8 // This file is a part of ThreadSanitizer (TSan), a race detector.
9 //
10 //===----------------------------------------------------------------------===//
11 
12 // Low-fat STL-like vector container.
13 
14 #ifndef TSAN_VECTOR_H
15 #define TSAN_VECTOR_H
16 
17 #include "tsan_defs.h"
18 #include "tsan_mman.h"
19 
20 namespace __tsan {
21 
22 template<typename T>
23 class Vector {
24  public:
Vector(MBlockType typ)25   explicit Vector(MBlockType typ)
26       : typ_(typ)
27       , begin_()
28       , end_()
29       , last_() {
30   }
31 
~Vector()32   ~Vector() {
33     if (begin_)
34       internal_free(begin_);
35   }
36 
Reset()37   void Reset() {
38     if (begin_)
39       internal_free(begin_);
40     begin_ = 0;
41     end_ = 0;
42     last_ = 0;
43   }
44 
Size()45   uptr Size() const {
46     return end_ - begin_;
47   }
48 
49   T &operator[](uptr i) {
50     DCHECK_LT(i, end_ - begin_);
51     return begin_[i];
52   }
53 
54   const T &operator[](uptr i) const {
55     DCHECK_LT(i, end_ - begin_);
56     return begin_[i];
57   }
58 
PushBack()59   T *PushBack() {
60     EnsureSize(Size() + 1);
61     T *p = &end_[-1];
62     internal_memset(p, 0, sizeof(*p));
63     return p;
64   }
65 
PushBack(const T & v)66   T *PushBack(const T& v) {
67     EnsureSize(Size() + 1);
68     T *p = &end_[-1];
69     internal_memcpy(p, &v, sizeof(*p));
70     return p;
71   }
72 
PopBack()73   void PopBack() {
74     DCHECK_GT(end_, begin_);
75     end_--;
76   }
77 
Resize(uptr size)78   void Resize(uptr size) {
79     if (size == 0) {
80       end_ = begin_;
81       return;
82     }
83     uptr old_size = Size();
84     EnsureSize(size);
85     if (old_size < size) {
86       for (uptr i = old_size; i < size; i++)
87         internal_memset(&begin_[i], 0, sizeof(begin_[i]));
88     }
89   }
90 
91  private:
92   const MBlockType typ_;
93   T *begin_;
94   T *end_;
95   T *last_;
96 
EnsureSize(uptr size)97   void EnsureSize(uptr size) {
98     if (size <= Size())
99       return;
100     if (size <= (uptr)(last_ - begin_)) {
101       end_ = begin_ + size;
102       return;
103     }
104     uptr cap0 = last_ - begin_;
105     uptr cap = cap0 * 5 / 4;  // 25% growth
106     if (cap == 0)
107       cap = 16;
108     if (cap < size)
109       cap = size;
110     T *p = (T*)internal_alloc(typ_, cap * sizeof(T));
111     if (cap0) {
112       internal_memcpy(p, begin_, cap0 * sizeof(T));
113       internal_free(begin_);
114     }
115     begin_ = p;
116     end_ = begin_ + size;
117     last_ = begin_ + cap;
118   }
119 
120   Vector(const Vector&);
121   void operator=(const Vector&);
122 };
123 }  // namespace __tsan
124 
125 #endif  // #ifndef TSAN_VECTOR_H
126