mirror of
https://github.com/facebook/sapling.git
synced 2024-10-07 23:38:50 +03:00
aa5e6c7295
Summary: Update the copyright & license headers in C++ files to reflect the relicensing to GPLv2 Reviewed By: wez Differential Revision: D15487078 fbshipit-source-id: 19f24c933a64ecad0d3a692d0f8d2a38b4194b1d
56 lines
1.5 KiB
C++
56 lines
1.5 KiB
C++
/*
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
*
|
|
* This software may be used and distributed according to the terms of the
|
|
* GNU General Public License version 2.
|
|
*/
|
|
#include "eden/fs/utils/IDGen.h"
|
|
#include <folly/Likely.h>
|
|
#include <folly/lang/Align.h>
|
|
#include <atomic>
|
|
|
|
namespace {
|
|
/**
|
|
* Allocating one unique ID per nanosecond would wrap around in over 500 years.
|
|
*
|
|
* Allocated to its own cache line.
|
|
*/
|
|
struct alignas(folly::hardware_destructive_interference_size) {
|
|
std::atomic<uint64_t> counter{0};
|
|
} global;
|
|
|
|
thread_local uint64_t localCounter{0};
|
|
|
|
/**
|
|
* Number of unique IDs to hand out to a thread at a time. This avoids cache
|
|
* line contention on globalCounter. kRangeSize should be large enough to reduce
|
|
* contention but small enough that the pathological case of threads being
|
|
* spawned in a tight loop, each allocating one unique ID, does not rapidly
|
|
* exhaust the 64-bit counter space.
|
|
*
|
|
* I haven't measured, but I'd be surprised if a thread could be created in
|
|
* 2000 nanoseconds.
|
|
*/
|
|
constexpr uint64_t kRangeSize = 2048;
|
|
|
|
static_assert(
|
|
(kRangeSize & (kRangeSize - 1)) == 0,
|
|
"kRangeSize must be a power of two");
|
|
} // namespace
|
|
|
|
namespace facebook {
|
|
namespace eden {
|
|
|
|
uint64_t generateUniqueID() noexcept {
|
|
uint64_t current = localCounter;
|
|
if (UNLIKELY(current % kRangeSize == 0)) {
|
|
current = global.counter.fetch_add(kRangeSize, std::memory_order_relaxed);
|
|
}
|
|
++current;
|
|
localCounter = current;
|
|
return current;
|
|
}
|
|
|
|
} // namespace eden
|
|
} // namespace facebook
|