Line data Source code
1 : #ifndef UTESTUTILS_HPP 2 : #define UTESTUTILS_HPP 3 : 4 : #include <unordered_map> 5 : #include <mutex> 6 : #include <string> 7 : #include <sstream> 8 : 9 : class UTestRaceChecker { 10 : std::unordered_map<const void*,int> counterAccess; 11 : std::mutex counterAccessMutex; 12 : 13 0 : static std::string PtrToString(const void* ptr){ 14 0 : std::stringstream ss; 15 0 : ss << ptr; 16 0 : return ss.str(); 17 : } 18 : 19 : public: 20 8 : UTestRaceChecker() = default; 21 : 22 8 : ~UTestRaceChecker() noexcept(false) { 23 79 : for(auto iter : counterAccess){ 24 71 : if(iter.second != 0){ 25 0 : throw std::runtime_error("Error in ~UTestRaceChecker for address : " + PtrToString(iter.first)); 26 : } 27 : } 28 8 : } 29 : 30 112 : void lock(){ 31 112 : counterAccessMutex.lock(); 32 112 : } 33 : 34 112 : void unlock(){ 35 112 : counterAccessMutex.unlock(); 36 112 : } 37 : 38 : UTestRaceChecker(const UTestRaceChecker&) = delete; 39 : UTestRaceChecker(UTestRaceChecker&&) = delete; 40 : UTestRaceChecker& operator=(const UTestRaceChecker&) = delete; 41 : UTestRaceChecker& operator=(UTestRaceChecker&&) = delete; 42 : 43 280 : void addRead(const void* ptr){ 44 280 : if(counterAccess.find(ptr) != counterAccess.end() 45 280 : && counterAccess[ptr] < 0){ 46 0 : throw std::runtime_error("Error in addRead for address : " + PtrToString(ptr)); 47 : } 48 280 : counterAccess[ptr] += 1; 49 280 : } 50 : 51 56 : void addWrite(const void* ptr){ 52 56 : if(counterAccess.find(ptr) != counterAccess.end() 53 56 : && counterAccess[ptr] != 0){ 54 0 : throw std::runtime_error("Error in addWrite for address : " + PtrToString(ptr)); 55 : } 56 56 : counterAccess[ptr] = -1; 57 56 : } 58 : 59 280 : void releaseRead(const void* ptr){ 60 280 : if(counterAccess.find(ptr) == counterAccess.end() 61 280 : || counterAccess[ptr] <= 0){ 62 0 : throw std::runtime_error("Error in releaseRead for address : " + PtrToString(ptr)); 63 : } 64 280 : counterAccess[ptr] -= 1; 65 280 : } 66 : 67 56 : void releaseWrite(const void* ptr){ 68 56 : if(counterAccess.find(ptr) == counterAccess.end() 69 56 : || counterAccess[ptr] != -1){ 70 0 : throw std::runtime_error("Error in releaseWrite for address : " + PtrToString(ptr)); 71 : } 72 56 : counterAccess.erase(ptr); 73 56 : } 74 : }; 75 : 76 : 77 : #endif