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