Commit 9b61f262 authored by Shih-Hao Tseng's avatar Shih-Hao Tseng Committed by Facebook GitHub Bot

Implement tryPost

Summary: Implement tryPost and include some simple tests

Reviewed By: magedm

Differential Revision: D33586443

fbshipit-source-id: 27c90ddf7e8578cb45c53e0083aa39910e5b0982
parent 7c7597c2
...@@ -365,6 +365,17 @@ struct LifoSemBase { ...@@ -365,6 +365,17 @@ struct LifoSemBase {
LifoSemBase(LifoSemBase const&) = delete; LifoSemBase(LifoSemBase const&) = delete;
LifoSemBase& operator=(LifoSemBase const&) = delete; LifoSemBase& operator=(LifoSemBase const&) = delete;
/// Returns true on a successful handoff, and return false without changing
/// the value of the semaphore if there are no waiters
bool tryPost() {
auto idx = incrOrPop(1, true);
if (idx != 0) {
idxToNode(idx).handoff().post();
return true;
}
return false;
}
/// Silently saturates if value is already 2^32-1 /// Silently saturates if value is already 2^32-1
bool post() { bool post() {
auto idx = incrOrPop(1); auto idx = incrOrPop(1);
...@@ -661,7 +672,7 @@ struct LifoSemBase { ...@@ -661,7 +672,7 @@ struct LifoSemBase {
/// Either increments by n and returns 0, or pops a node and returns it. /// Either increments by n and returns 0, or pops a node and returns it.
/// If n + the stripe's value overflows, then the stripe's value /// If n + the stripe's value overflows, then the stripe's value
/// saturates silently at 2^32-1 /// saturates silently at 2^32-1
uint32_t incrOrPop(uint32_t n) { uint32_t incrOrPop(uint32_t n, const bool skip_increment = false) {
while (true) { while (true) {
assert(n > 0); assert(n > 0);
...@@ -679,6 +690,8 @@ struct LifoSemBase { ...@@ -679,6 +690,8 @@ struct LifoSemBase {
return head.idx(); return head.idx();
} }
} else { } else {
if (skip_increment)
return 0;
auto after = head.withValueIncr(n); auto after = head.withValueIncr(n);
if (head_->compare_exchange_strong(head, after)) { if (head_->compare_exchange_strong(head, after)) {
// successful incr // successful incr
......
...@@ -41,6 +41,7 @@ class LifoSemTest : public testing::Test { ...@@ -41,6 +41,7 @@ class LifoSemTest : public testing::Test {
TEST(LifoSem, basic) { TEST(LifoSem, basic) {
LifoSem sem; LifoSem sem;
EXPECT_FALSE(sem.tryPost());
EXPECT_FALSE(sem.tryWait()); EXPECT_FALSE(sem.tryWait());
sem.post(); sem.post();
EXPECT_TRUE(sem.tryWait()); EXPECT_TRUE(sem.tryWait());
...@@ -400,6 +401,14 @@ BENCHMARK(single_thread_lifo_postwait, iters) { ...@@ -400,6 +401,14 @@ BENCHMARK(single_thread_lifo_postwait, iters) {
} }
} }
BENCHMARK(single_thread_lifo_trypost, iters) {
LifoSem sem;
for (size_t n = 0; n < iters; ++n) {
EXPECT_FALSE(sem.tryPost());
asm_volatile_memory();
}
}
BENCHMARK(single_thread_lifo_trywait, iters) { BENCHMARK(single_thread_lifo_trywait, iters) {
LifoSem sem; LifoSem sem;
for (size_t n = 0; n < iters; ++n) { for (size_t n = 0; n < iters; ++n) {
......
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