1 /* 2 * Copyright (c) Facebook, Inc. and its affiliates. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <folly/SharedMutex.h> 18 19 #include <folly/Indestructible.h> 20 21 namespace folly { 22 // Explicitly instantiate SharedMutex here: 23 template class SharedMutexImpl<true>; 24 template class SharedMutexImpl<false>; 25 26 namespace shared_mutex_detail { annotationGuard(void * ptr)27std::unique_lock<std::mutex> annotationGuard(void* ptr) { 28 if (folly::kIsSanitizeThread) { 29 // On TSAN builds, we have an array of mutexes and index into them based on 30 // the address. If the array is of prime size things will work out okay 31 // without a complicated hash function. 32 static constexpr std::size_t kNumAnnotationMutexes = 251; 33 static Indestructible<std::array<std::mutex, kNumAnnotationMutexes>> 34 kAnnotationMutexes; 35 auto index = reinterpret_cast<uintptr_t>(ptr) % kNumAnnotationMutexes; 36 return std::unique_lock<std::mutex>((*kAnnotationMutexes)[index]); 37 } else { 38 return std::unique_lock<std::mutex>(); 39 } 40 } 41 getMaxDeferredReadersSlow(std::atomic<uint32_t> & cache)42uint32_t getMaxDeferredReadersSlow(std::atomic<uint32_t>& cache) { 43 uint32_t maxDeferredReaders = std::min( 44 static_cast<uint32_t>( 45 folly::nextPowTwo(CacheLocality::system().numCpus) << 1), 46 shared_mutex_detail::kMaxDeferredReadersAllocated); 47 // maxDeferredReaders must be a power of 2 48 assert(!(maxDeferredReaders & (maxDeferredReaders - 1))); 49 cache.store(maxDeferredReaders, std::memory_order_release); 50 return maxDeferredReaders; 51 } 52 } // namespace shared_mutex_detail 53 } // namespace folly 54