• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
MutexSet()20 MutexSet::MutexSet() {
21   size_ = 0;
22   internal_memset(&descs_, 0, sizeof(descs_));
23 }
24 
Add(u64 id,bool write,u64 epoch)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 
Del(u64 id,bool write)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 
Remove(u64 id)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 
RemovePos(uptr i)74 void MutexSet::RemovePos(uptr i) {
75   CHECK_LT(i, size_);
76   descs_[i] = descs_[size_ - 1];
77   size_--;
78 }
79 
Size() const80 uptr MutexSet::Size() const {
81   return size_;
82 }
83 
Get(uptr i) const84 MutexSet::Desc MutexSet::Get(uptr i) const {
85   CHECK_LT(i, size_);
86   return descs_[i];
87 }
88 
89 }  // namespace __tsan
90