tsan_vector.h 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  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. // Low-fat STL-like vector container.
  12. #ifndef TSAN_VECTOR_H
  13. #define TSAN_VECTOR_H
  14. #include "tsan_defs.h"
  15. #include "tsan_mman.h"
  16. namespace __tsan {
  17. template<typename T>
  18. class Vector {
  19. public:
  20. explicit Vector(MBlockType typ)
  21. : typ_(typ)
  22. , begin_()
  23. , end_()
  24. , last_() {
  25. }
  26. ~Vector() {
  27. if (begin_)
  28. internal_free(begin_);
  29. }
  30. void Reset() {
  31. if (begin_)
  32. internal_free(begin_);
  33. begin_ = 0;
  34. end_ = 0;
  35. last_ = 0;
  36. }
  37. uptr Size() const {
  38. return end_ - begin_;
  39. }
  40. T &operator[](uptr i) {
  41. DCHECK_LT(i, end_ - begin_);
  42. return begin_[i];
  43. }
  44. const T &operator[](uptr i) const {
  45. DCHECK_LT(i, end_ - begin_);
  46. return begin_[i];
  47. }
  48. T *PushBack() {
  49. EnsureSize(Size() + 1);
  50. T *p = &end_[-1];
  51. internal_memset(p, 0, sizeof(*p));
  52. return p;
  53. }
  54. T *PushBack(const T& v) {
  55. EnsureSize(Size() + 1);
  56. T *p = &end_[-1];
  57. internal_memcpy(p, &v, sizeof(*p));
  58. return p;
  59. }
  60. void PopBack() {
  61. DCHECK_GT(end_, begin_);
  62. end_--;
  63. }
  64. void Resize(uptr size) {
  65. if (size == 0) {
  66. end_ = begin_;
  67. return;
  68. }
  69. uptr old_size = Size();
  70. EnsureSize(size);
  71. if (old_size < size) {
  72. for (uptr i = old_size; i < size; i++)
  73. internal_memset(&begin_[i], 0, sizeof(begin_[i]));
  74. }
  75. }
  76. private:
  77. const MBlockType typ_;
  78. T *begin_;
  79. T *end_;
  80. T *last_;
  81. void EnsureSize(uptr size) {
  82. if (size <= Size())
  83. return;
  84. if (size <= (uptr)(last_ - begin_)) {
  85. end_ = begin_ + size;
  86. return;
  87. }
  88. uptr cap0 = last_ - begin_;
  89. uptr cap = cap0 * 5 / 4; // 25% growth
  90. if (cap == 0)
  91. cap = 16;
  92. if (cap < size)
  93. cap = size;
  94. T *p = (T*)internal_alloc(typ_, cap * sizeof(T));
  95. if (cap0) {
  96. internal_memcpy(p, begin_, cap0 * sizeof(T));
  97. internal_free(begin_);
  98. }
  99. begin_ = p;
  100. end_ = begin_ + size;
  101. last_ = begin_ + cap;
  102. }
  103. Vector(const Vector&);
  104. void operator=(const Vector&);
  105. };
  106. } // namespace __tsan
  107. #endif // #ifndef TSAN_VECTOR_H