Commit fd295717 authored by Matt Dordal's avatar Matt Dordal Committed by Facebook GitHub Bot

add a method to access a threadlocal without creating an object

Summary:
It may be useful to see if a threadlocal has been created on a thread before accessing it.

One way this could be useful: the data is only relevant to a few threads but will be accessed by many. This would allow you to save the memory on the non-relevant threads.

Differential Revision: D21731260

fbshipit-source-id: 0b1835b454f9b0c457f722ab38f84f89aca383fb
parent 0674ab06
...@@ -70,6 +70,11 @@ class ThreadLocal { ...@@ -70,6 +70,11 @@ class ThreadLocal {
return FOLLY_LIKELY(!!ptr) ? ptr : makeTlp(); return FOLLY_LIKELY(!!ptr) ? ptr : makeTlp();
} }
// may return null
FOLLY_ERASE T* getIfExist() const {
return tlp_.get();
}
T* operator->() const { T* operator->() const {
return get(); return get();
} }
......
...@@ -50,7 +50,11 @@ using namespace folly; ...@@ -50,7 +50,11 @@ using namespace folly;
struct Widget { struct Widget {
static int totalVal_; static int totalVal_;
static int totalMade_;
int val_; int val_;
Widget() : val_(0) {
totalMade_++;
}
~Widget() { ~Widget() {
totalVal_ += val_; totalVal_ += val_;
} }
...@@ -61,6 +65,7 @@ struct Widget { ...@@ -61,6 +65,7 @@ struct Widget {
} }
}; };
int Widget::totalVal_ = 0; int Widget::totalVal_ = 0;
int Widget::totalMade_ = 0;
struct MultiWidget { struct MultiWidget {
int val_{0}; int val_{0};
...@@ -242,6 +247,36 @@ TEST(ThreadLocalPtr, CustomDeleter2) { ...@@ -242,6 +247,36 @@ TEST(ThreadLocalPtr, CustomDeleter2) {
EXPECT_EQ(1010, Widget::totalVal_); EXPECT_EQ(1010, Widget::totalVal_);
} }
TEST(ThreadLocal, GetWithoutCreateUncreated) {
Widget::totalVal_ = 0;
Widget::totalMade_ = 0;
ThreadLocal<Widget> w;
std::thread([&w]() {
auto ptr = w.getIfExist();
if (ptr) {
ptr->val_++;
}
})
.join();
EXPECT_EQ(0, Widget::totalMade_);
}
TEST(ThreadLocal, GetWithoutCreateGets) {
Widget::totalVal_ = 0;
Widget::totalMade_ = 0;
ThreadLocal<Widget> w;
std::thread([&w]() {
w->val_++;
auto ptr = w.getIfExist();
if (ptr) {
ptr->val_++;
}
})
.join();
EXPECT_EQ(1, Widget::totalMade_);
EXPECT_EQ(2, Widget::totalVal_);
}
TEST(ThreadLocal, BasicDestructor) { TEST(ThreadLocal, BasicDestructor) {
Widget::totalVal_ = 0; Widget::totalVal_ = 0;
ThreadLocal<Widget> w; ThreadLocal<Widget> w;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment