1#include <gtest/gtest.h>
2
3#include "AllocationTestHarness.h"
4
5#include <base/logging.h>
6#include <sys/select.h>
7#include <unistd.h>
8
9#include "osi/include/osi.h"
10#include "osi/include/reactor.h"
11#include "osi/include/semaphore.h"
12#include "osi/include/thread.h"
13
14struct SemaphoreTestSequenceHelper {
15  semaphore_t* semaphore;
16  int counter;
17};
18
19namespace {
20void sleep_then_increment_counter(void* context) {
21  SemaphoreTestSequenceHelper* helper =
22      reinterpret_cast<SemaphoreTestSequenceHelper*>(context);
23  CHECK(helper);
24  CHECK(helper->semaphore);
25  sleep(1);
26  ++helper->counter;
27  semaphore_post(helper->semaphore);
28}
29}  // namespace
30
31class SemaphoreTest : public AllocationTestHarness {};
32
33TEST_F(SemaphoreTest, test_new_simple) {
34  semaphore_t* semaphore = semaphore_new(0);
35  ASSERT_TRUE(semaphore != NULL);
36  semaphore_free(semaphore);
37}
38
39TEST_F(SemaphoreTest, test_new_with_value) {
40  semaphore_t* semaphore = semaphore_new(3);
41  ASSERT_TRUE(semaphore != NULL);
42
43  EXPECT_TRUE(semaphore_try_wait(semaphore));
44  EXPECT_TRUE(semaphore_try_wait(semaphore));
45  EXPECT_TRUE(semaphore_try_wait(semaphore));
46  EXPECT_FALSE(semaphore_try_wait(semaphore));
47
48  semaphore_free(semaphore);
49}
50
51TEST_F(SemaphoreTest, test_try_wait) {
52  semaphore_t* semaphore = semaphore_new(0);
53  ASSERT_TRUE(semaphore != NULL);
54
55  EXPECT_FALSE(semaphore_try_wait(semaphore));
56  semaphore_post(semaphore);
57  EXPECT_TRUE(semaphore_try_wait(semaphore));
58  EXPECT_FALSE(semaphore_try_wait(semaphore));
59
60  semaphore_free(semaphore);
61}
62
63TEST_F(SemaphoreTest, test_wait_after_post) {
64  semaphore_t* semaphore = semaphore_new(0);
65  ASSERT_TRUE(semaphore != NULL);
66  semaphore_post(semaphore);
67  semaphore_wait(semaphore);
68  semaphore_free(semaphore);
69}
70
71TEST_F(SemaphoreTest, test_ensure_wait) {
72  semaphore_t* semaphore = semaphore_new(0);
73  ASSERT_TRUE(semaphore != NULL);
74  thread_t* thread = thread_new("semaphore_test_thread");
75  ASSERT_TRUE(thread != NULL);
76
77  EXPECT_FALSE(semaphore_try_wait(semaphore));
78  SemaphoreTestSequenceHelper sequence_helper = {semaphore, 0};
79  thread_post(thread, sleep_then_increment_counter, &sequence_helper);
80  semaphore_wait(semaphore);
81  EXPECT_EQ(sequence_helper.counter, 1)
82      << "semaphore_wait() did not wait for counter to increment";
83
84  semaphore_free(semaphore);
85  thread_free(thread);
86}
87