]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/compiler-rt/lib/tsan/rtl/tsan_mutexset.cc
Update compiler-rt to 3.7.0 release. This also includes the sanitizer
[FreeBSD/FreeBSD.git] / contrib / compiler-rt / lib / tsan / rtl / tsan_mutexset.cc
1 //===-- tsan_mutexset.cc --------------------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file is a part of ThreadSanitizer (TSan), a race detector.
11 //
12 //===----------------------------------------------------------------------===//
13 #include "tsan_mutexset.h"
14 #include "tsan_rtl.h"
15
16 namespace __tsan {
17
18 const uptr MutexSet::kMaxSize;
19
20 MutexSet::MutexSet() {
21   size_ = 0;
22   internal_memset(&descs_, 0, sizeof(descs_));
23 }
24
25 void MutexSet::Add(u64 id, bool write, u64 epoch) {
26   // Look up existing mutex with the same id.
27   for (uptr i = 0; i < size_; i++) {
28     if (descs_[i].id == id) {
29       descs_[i].count++;
30       descs_[i].epoch = epoch;
31       return;
32     }
33   }
34   // On overflow, find the oldest mutex and drop it.
35   if (size_ == kMaxSize) {
36     u64 minepoch = (u64)-1;
37     u64 mini = (u64)-1;
38     for (uptr i = 0; i < size_; i++) {
39       if (descs_[i].epoch < minepoch) {
40         minepoch = descs_[i].epoch;
41         mini = i;
42       }
43     }
44     RemovePos(mini);
45     CHECK_EQ(size_, kMaxSize - 1);
46   }
47   // Add new mutex descriptor.
48   descs_[size_].id = id;
49   descs_[size_].write = write;
50   descs_[size_].epoch = epoch;
51   descs_[size_].count = 1;
52   size_++;
53 }
54
55 void MutexSet::Del(u64 id, bool write) {
56   for (uptr i = 0; i < size_; i++) {
57     if (descs_[i].id == id) {
58       if (--descs_[i].count == 0)
59         RemovePos(i);
60       return;
61     }
62   }
63 }
64
65 void MutexSet::Remove(u64 id) {
66   for (uptr i = 0; i < size_; i++) {
67     if (descs_[i].id == id) {
68       RemovePos(i);
69       return;
70     }
71   }
72 }
73
74 void MutexSet::RemovePos(uptr i) {
75   CHECK_LT(i, size_);
76   descs_[i] = descs_[size_ - 1];
77   size_--;
78 }
79
80 uptr MutexSet::Size() const {
81   return size_;
82 }
83
84 MutexSet::Desc MutexSet::Get(uptr i) const {
85   CHECK_LT(i, size_);
86   return descs_[i];
87 }
88
89 }  // namespace __tsan