text: /*
   * Copyright (c) Facebook, Inc. and its affiliates.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  #include <folly/container/detail/F14Table.h>
  
  #include <atomic>
  #include <chrono>
  
  namespace folly {
  namespace f14 {
  namespace detail {
  
  // If you get a link failure that leads you here, your build has varying
  // compiler flags across compilation units in a way that would break F14.
  // SIMD (SSE2 or NEON) needs to be either on everywhere or off everywhere
  // that uses F14.  If SIMD is on then hardware CRC needs to be enabled
  // everywhere or disabled everywhere.
  void F14LinkCheck<getF14IntrinsicsMode()>::check() noexcept {}
  
  #if FOLLY_F14_VECTOR_INTRINSICS_AVAILABLE
  EmptyTagVectorType kEmptyTagVector = {};
  #endif
  
  //// Debug and ASAN stuff
  
  bool tlsPendingSafeInserts(std::ptrdiff_t delta) {
    static std::atomic<size_t> value_non_tl{0};
    static thread_local std::atomic<size_t> value_tl{0};
    auto& value = kIsDebug || kIsLibrarySanitizeAddress ? value_tl : value_non_tl;
  
    FOLLY_SAFE_DCHECK(delta >= -1, "");
    std::size_t v = value.load(std::memory_order_relaxed);
    if (delta > 0 || (delta == -1 && v > 0)) {
      v += delta;
      v = std::min(std::numeric_limits<std::size_t>::max() / 2, v);
      value.store(v, std::memory_order_relaxed);
    }
    return v != 0;
  }
  
  std::size_t tlsMinstdRand(std::size_t n) {
    static std::atomic<uint32_t> state_non_tl{0};
    static thread_local std::atomic<uint32_t> state_tl{0};
    auto& state = kIsDebug || kIsLibrarySanitizeAddress ? state_tl : state_non_tl;
  
    FOLLY_SAFE_DCHECK(n > 0, "");
  
    auto s = state.load(std::memory_order_relaxed);
    if (s == 0) {
      uint64_t seed = static_cast<uint64_t>(
          std::chrono::steady_clock::now().time_since_epoch().count());
      s = hash::twang_32from64(seed);
    }
  
    s = static_cast<uint32_t>((s * uint64_t{48271}) % uint64_t{2147483647});
    state.store(s, std::memory_order_relaxed);
    return std::size_t{s} % n;
  }
  
  } // namespace detail
  } // namespace f14
  } // namespace folly
  