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