Skip to content

[pull] main from facebook:main #343

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Jun 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ gh_facebook_buck2_shims_meta = git

[external_cell_gh_facebook_buck2_shims_meta]
git_origin = https://github.com/facebook/buck2-shims-meta.git
commit_hash = 8eb7590f14888d39273dc7b86a044588063a209b
commit_hash = 931437d6413b3836dfd4ce72aa61fdb9bc634dce
48 changes: 48 additions & 0 deletions folly/detail/ThreadLocalDetail.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,27 @@ bool ThreadEntrySet::basicSanity() const {
});
}

bool ThreadEntry::cachedInSetMatchesElementsArray(uint32_t id) {
if constexpr (!kIsDebug) {
return true;
}

if (removed_) {
// Pointer in entry set and elements array need not match anymore.
return true;
}

auto rlock = meta->allId2ThreadEntrySets_[id].tryRLock();
if (!rlock) {
// Try lock failed. Skip checking in this case. Avoids
// getting stuck in case this validation is called when
// already holding the entry set lock.
return true;
}

return elements[id].ptr == rlock->getPtrForThread(this);
}

void ThreadEntrySet::compress() {
assert(compressible());
// compress the vector
Expand Down Expand Up @@ -561,6 +582,33 @@ void ThreadEntry::cleanupElement(uint32_t id) {
elements[id].cleanup();
}

void ThreadEntry::resetElementImplAfterSet(
const ElementWrapper& element, uint32_t id) {
auto& set = meta->allId2ThreadEntrySets_[id];
auto rlock = set.rlock();
cleanupElement(id);
elements[id] = element;
if (removed_) {
// Elements no longer being mirrored in the ThreadEntrySet.
// Thread must have cleared itself from the set when it started exiting.
DCHECK(!rlock->contains(this));
return;
}
if (element.ptr != nullptr && !rlock->contains(this)) {
meta->ensureThreadEntryIsInSet(this, set, rlock);
}
auto slot = rlock->getIndexFor(this);
if (slot < 0) {
// Not present in ThreadEntrySet implies the value was never set to be
// non-null and new value in element.ptr is nullptr as well.
DCHECK(!element.ptr);
DCHECK(!elements[id].ptr);
return;
}
size_t uslot = static_cast<size_t>(slot);
rlock.asNonConstUnsafe().threadElements[uslot].wrapper = element;
}

FOLLY_STATIC_CTOR_PRIORITY_MAX
PthreadKeyUnregister PthreadKeyUnregister::instance_;
#if defined(__GLIBC__)
Expand Down
65 changes: 12 additions & 53 deletions folly/detail/ThreadLocalDetail.h
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,10 @@ struct ThreadEntry {

template <class Ptr, class Deleter>
void resetElement(Ptr p, Deleter& d, uint32_t id);

void resetElementImplAfterSet(const ElementWrapper& element, uint32_t id);

bool cachedInSetMatchesElementsArray(uint32_t id);
};

struct ThreadEntryList {
Expand Down Expand Up @@ -667,63 +671,21 @@ struct FakeUniqueInstance {
*/
template <class Ptr>
void ThreadEntry::resetElement(Ptr p, uint32_t id) {
auto& set = meta->allId2ThreadEntrySets_[id];
auto rlock = set.rlock();
cleanupElement(id);
elements[id].set(p);
if (removed_) {
// Elements no longer being mirrored in the ThreadEntrySet.
// Thread must have cleared itself from the set when it started exiting.
DCHECK(!rlock->contains(this));
return;
}
if (p != nullptr && !rlock->contains(this)) {
meta->ensureThreadEntryIsInSet(this, set, rlock);
}
auto slot = rlock->getIndexFor(this);
if (slot < 0) {
// Not present in ThreadEntrySet implies the value was never set to be
// non-null and new value 'p' is nullptr as well.
DCHECK(!p);
DCHECK(!elements[id].ptr);
return;
}
size_t uslot = static_cast<size_t>(slot);
auto& wrapper = rlock.asNonConstUnsafe().threadElements[uslot].wrapper;
wrapper = elements[id];
ElementWrapper element;
element.set(p);
resetElementImplAfterSet(element, id);
}

/*
* Resets element from ThreadEntry::elements at index @id.
* call set() on the element to reset it.
* This is a templated method for when a deleter is not provided.
* This is a templated method for when a deleter is provided.
*/
template <class Ptr, class Deleter>
void ThreadEntry::resetElement(Ptr p, Deleter& d, uint32_t id) {
auto& set = meta->allId2ThreadEntrySets_[id];
auto rlock = set.rlock();
cleanupElement(id);
elements[id].set(p, d);
if (removed_) {
// Elements no longer being mirrored in the ThreadEntrySet.
// Thread must have cleared itself from the set when it started exiting.
DCHECK(!rlock->contains(this));
return;
}
if (p != nullptr && !rlock->contains(this)) {
meta->ensureThreadEntryIsInSet(this, set, rlock);
}
auto slot = rlock->getIndexFor(this);
if (slot < 0) {
// Not present in ThreadEntrySet implies the value was never set to be
// non-null and new value 'p' is nullptr as well.
DCHECK(!p);
DCHECK(!elements[id].ptr);
return;
}
size_t uslot = static_cast<size_t>(slot);
auto& wrapper = rlock.asNonConstUnsafe().threadElements[uslot].wrapper;
wrapper = elements[id];
ElementWrapper element;
element.set(p, d);
resetElementImplAfterSet(element, id);
}

// Held in a singleton to track our global instances.
Expand Down Expand Up @@ -783,10 +745,7 @@ struct FOLLY_EXPORT StaticMeta final : StaticMetaBase {
uint32_t id = ent->getOrInvalid();
// Only valid index into the the elements array
DCHECK_NE(id, kEntryIDInvalid);
DCHECK(
te->removed_ ||
te->elements[id].ptr ==
te->meta->allId2ThreadEntrySets_[id].rlock()->getPtrForThread(te));
DCHECK(te->cachedInSetMatchesElementsArray(id));
return te->elements[id];
}

Expand Down
7 changes: 0 additions & 7 deletions folly/executors/test/BUCK
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,9 @@ fbcode_target(
headers = [],
deps = [
"//folly:benchmark",
"//folly:benchmark_util",
"//folly:mpmc_queue",
"//folly/executors:cpu_thread_pool_executor",
"//folly/executors:edf_thread_pool_executor",
"//folly/executors:soft_real_time_executor",
"//folly/executors:thread_pool_executor",
],
)
Expand Down Expand Up @@ -93,10 +91,8 @@ fbcode_target(
deps = [
"//folly/executors:cpu_thread_pool_executor",
"//folly/executors:global_executor",
"//folly/executors:io_executor",
"//folly/executors:io_thread_pool_executor",
"//folly/portability:gtest",
"//folly/synchronization:baton",
],
)

Expand All @@ -107,10 +103,8 @@ fbcode_target(
deps = [
"//folly/executors:cpu_thread_pool_executor",
"//folly/executors:global_executor",
"//folly/executors:io_executor",
"//folly/executors:io_thread_pool_executor",
"//folly/portability:gtest",
"//folly/synchronization:baton",
],
)

Expand All @@ -123,7 +117,6 @@ fbcode_target(
"//folly/executors:cpu_thread_pool_executor",
"//folly/executors:global_executor",
"//folly/executors:inline_executor",
"//folly/executors:io_executor",
"//folly/portability:gtest",
"//folly/synchronization:baton",
],
Expand Down
2 changes: 0 additions & 2 deletions folly/executors/test/EDFThreadPoolExecutorBenchmark.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,9 @@
#include <thread>

#include <folly/Benchmark.h>
#include <folly/BenchmarkUtil.h>
#include <folly/MPMCQueue.h>
#include <folly/executors/CPUThreadPoolExecutor.h>
#include <folly/executors/EDFThreadPoolExecutor.h>
#include <folly/executors/SoftRealTimeExecutor.h>
#include <folly/executors/ThreadPoolExecutor.h>

using namespace folly;
Expand Down
2 changes: 0 additions & 2 deletions folly/executors/test/GlobalCPUExecutorTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,8 @@
#include <folly/executors/GlobalExecutor.h>

#include <folly/executors/CPUThreadPoolExecutor.h>
#include <folly/executors/IOExecutor.h>
#include <folly/executors/IOThreadPoolExecutor.h>
#include <folly/portability/GTest.h>
#include <folly/synchronization/Baton.h>

TEST(GlobalCPUExecutorTest, CPUThreadCountFlagSet) {
folly::gflags::FlagSaver flagsaver;
Expand Down
1 change: 0 additions & 1 deletion folly/executors/test/GlobalExecutorAssignmentTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
#include <folly/Singleton.h>
#include <folly/executors/CPUThreadPoolExecutor.h>
#include <folly/executors/GlobalExecutor.h>
#include <folly/executors/IOExecutor.h>
#include <folly/executors/InlineExecutor.h>
#include <folly/portability/GTest.h>
#include <folly/synchronization/Baton.h>
Expand Down
1 change: 0 additions & 1 deletion folly/executors/test/StrandExecutorTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

#include <atomic>
#include <chrono>
#include <stdexcept>
#include <thread>
#include <vector>

Expand Down
1 change: 0 additions & 1 deletion folly/executors/test/ThreadPoolExecutorTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@

#include <folly/Exception.h>
#include <folly/container/F14Map.h>
#include <folly/executors/CPUThreadPoolExecutor.h>
#include <folly/executors/EDFThreadPoolExecutor.h>
#include <folly/executors/FutureExecutor.h>
#include <folly/executors/IOThreadPoolExecutor.h>
Expand Down
1 change: 1 addition & 0 deletions folly/fibers/BUCK
Original file line number Diff line number Diff line change
Expand Up @@ -748,6 +748,7 @@ fbcode_target(
"//folly:portability",
"//folly:spin_lock",
"//folly/synchronization:call_once",
"//folly/synchronization/detail:sleeper",
],
)

Expand Down
Loading