1//===-- tsan_update_shadow_word.inc -----------------------------*- C++ -*-===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8// 9// This file is a part of ThreadSanitizer (TSan), a race detector. 10// 11// Body of the hottest inner loop. 12// If we wrap this body into a function, compilers (both gcc and clang) 13// produce sligtly less efficient code. 14//===----------------------------------------------------------------------===// 15do { 16 const unsigned kAccessSize = 1 << kAccessSizeLog; 17 u64 *sp = &shadow_mem[idx]; 18 old = LoadShadow(sp); 19 if (LIKELY(old.IsZero())) { 20 if (!stored) { 21 StoreIfNotYetStored(sp, &store_word); 22 stored = true; 23 } 24 break; 25 } 26 // is the memory access equal to the previous? 27 if (LIKELY(Shadow::Addr0AndSizeAreEqual(cur, old))) { 28 // same thread? 29 if (LIKELY(Shadow::TidsAreEqual(old, cur))) { 30 if (LIKELY(old.IsRWWeakerOrEqual(kAccessIsWrite, kIsAtomic))) { 31 StoreIfNotYetStored(sp, &store_word); 32 stored = true; 33 } 34 break; 35 } 36 if (HappensBefore(old, thr)) { 37 if (old.IsRWWeakerOrEqual(kAccessIsWrite, kIsAtomic)) { 38 StoreIfNotYetStored(sp, &store_word); 39 stored = true; 40 } 41 break; 42 } 43 if (LIKELY(old.IsBothReadsOrAtomic(kAccessIsWrite, kIsAtomic))) 44 break; 45 goto RACE; 46 } 47 // Do the memory access intersect? 48 if (Shadow::TwoRangesIntersect(old, cur, kAccessSize)) { 49 if (Shadow::TidsAreEqual(old, cur)) 50 break; 51 if (old.IsBothReadsOrAtomic(kAccessIsWrite, kIsAtomic)) 52 break; 53 if (LIKELY(HappensBefore(old, thr))) 54 break; 55 goto RACE; 56 } 57 // The accesses do not intersect. 58 break; 59} while (0); 60