Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / third_party / pigweed / repo / pw_sync / mutex_facade_test.cc
1 // Copyright 2020 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14
15 #include <chrono>
16
17 #include "gtest/gtest.h"
18 #include "pw_chrono/system_clock.h"
19 #include "pw_sync/mutex.h"
20
21 using pw::chrono::SystemClock;
22 using namespace std::chrono_literals;
23
24 namespace pw::sync {
25 namespace {
26
27 extern "C" {
28
29 // Functions defined in mutex_facade_test_c.c which call the API from C.
30 void pw_sync_Mutex_CallLock(pw_sync_Mutex* mutex);
31 bool pw_sync_Mutex_CallTryLock(pw_sync_Mutex* mutex);
32 bool pw_sync_Mutex_CallTryLockFor(pw_sync_Mutex* mutex,
33                                   pw_chrono_SystemClock_Duration for_at_least);
34 bool pw_sync_Mutex_CallTryLockUntil(
35     pw_sync_Mutex* mutex, pw_chrono_SystemClock_TimePoint until_at_least);
36 void pw_sync_Mutex_CallUnlock(pw_sync_Mutex* mutex);
37
38 }  // extern "C"
39
40 // We can't control the SystemClock's period configuration, so just in case
41 // duration cannot be accurately expressed in integer ticks, round the
42 // duration w/ ceil.
43 constexpr auto kRoundedArbitraryDuration =
44     std::chrono::ceil<SystemClock::duration>(42ms);
45 constexpr pw_chrono_SystemClock_Duration kRoundedArbitraryDurationInC =
46     PW_SYSTEM_CLOCK_MS(42);
47
48 // TODO(pwbug/291): Add real concurrency tests once we have pw::thread.
49
50 TEST(Mutex, LockUnlock) {
51   pw::sync::Mutex mutex;
52   mutex.lock();
53   // TODO(pwbug/291): Ensure it fails to lock when already held.
54   // EXPECT_FALSE(mutex.try_lock());
55   mutex.unlock();
56 }
57
58 Mutex static_mutex;
59 TEST(Mutex, LockUnlockStatic) {
60   static_mutex.lock();
61   // TODO(pwbug/291): Ensure it fails to lock when already held.
62   // EXPECT_FALSE(static_mutex.try_lock());
63   static_mutex.unlock();
64 }
65
66 TEST(Mutex, TryLockUnlock) {
67   pw::sync::Mutex mutex;
68   ASSERT_TRUE(mutex.try_lock());
69   // TODO(pwbug/291): Ensure it fails to lock when already held.
70   // EXPECT_FALSE(mutex.try_lock());
71   mutex.unlock();
72 }
73
74 TEST(Mutex, TryLockUnlockFor) {
75   pw::sync::Mutex mutex;
76
77   SystemClock::time_point before = SystemClock::now();
78   ASSERT_TRUE(mutex.try_lock_for(kRoundedArbitraryDuration));
79   SystemClock::duration time_elapsed = SystemClock::now() - before;
80   EXPECT_LT(time_elapsed, kRoundedArbitraryDuration);
81
82   // TODO(pwbug/291): Ensure it blocks fails to lock when already held.
83   // before = SystemClock::now();
84   // EXPECT_FALSE(mutex.try_lock_for(kRoundedArbitraryDuration));
85   // time_elapsed = SystemClock::now() - before;
86   /// EXPECT_GE(time_elapsed, kRoundedArbitraryDuration);
87
88   mutex.unlock();
89 }
90
91 TEST(Mutex, TryLockUnlockUntil) {
92   pw::sync::Mutex mutex;
93
94   const SystemClock::time_point deadline =
95       SystemClock::now() + kRoundedArbitraryDuration;
96   ASSERT_TRUE(mutex.try_lock_until(deadline));
97   EXPECT_LT(SystemClock::now(), deadline);
98
99   // TODO(pwbug/291): Ensure it blocks fails to lock when already held.
100   // EXPECT_FALSE(
101   //     mutex.try_lock_until(SystemClock::now() + kRoundedArbitraryDuration));
102   // EXPECT_GE(SystemClock::now(), deadline);
103
104   mutex.unlock();
105 }
106
107 TEST(Mutex, LockUnlockInC) {
108   pw::sync::Mutex mutex;
109   pw_sync_Mutex_CallLock(&mutex);
110   pw_sync_Mutex_CallUnlock(&mutex);
111 }
112
113 TEST(Mutex, TryLockUnlockInC) {
114   pw::sync::Mutex mutex;
115   ASSERT_TRUE(pw_sync_Mutex_CallTryLock(&mutex));
116   // TODO(pwbug/291): Ensure it fails to lock when already held.
117   // EXPECT_FALSE(pw_sync_Mutex_CallTryLock(&mutex));
118   pw_sync_Mutex_CallUnlock(&mutex);
119 }
120
121 TEST(Mutex, TryLockUnlockForInC) {
122   pw::sync::Mutex mutex;
123
124   pw_chrono_SystemClock_TimePoint before = pw_chrono_SystemClock_Now();
125   ASSERT_TRUE(
126       pw_sync_Mutex_CallTryLockFor(&mutex, kRoundedArbitraryDurationInC));
127   pw_chrono_SystemClock_Duration time_elapsed =
128       pw_chrono_SystemClock_TimeElapsed(before, pw_chrono_SystemClock_Now());
129   EXPECT_LT(time_elapsed.ticks, kRoundedArbitraryDurationInC.ticks);
130
131   // TODO(pwbug/291): Ensure it blocks fails to lock when already held.
132   // before = pw_chrono_SystemClock_Now();
133   // EXPECT_FALSE(
134   //     pw_sync_Mutex_CallTryLockFor(&mutex, kRoundedArbitraryDurationInC));
135   // time_elapsed =
136   //    pw_chrono_SystemClock_TimeElapsed(before, pw_chrono_SystemClock_Now());
137   // EXPECT_GE(time_elapsed.ticks, kRoundedArbitraryDurationInC.ticks);
138
139   pw_sync_Mutex_CallUnlock(&mutex);
140 }
141
142 TEST(Mutex, TryLockUnlockUntilInC) {
143   pw::sync::Mutex mutex;
144   pw_chrono_SystemClock_TimePoint deadline;
145   deadline.duration_since_epoch.ticks =
146       pw_chrono_SystemClock_Now().duration_since_epoch.ticks +
147       kRoundedArbitraryDurationInC.ticks;
148   ASSERT_TRUE(pw_sync_Mutex_CallTryLockUntil(&mutex, deadline));
149   EXPECT_LT(pw_chrono_SystemClock_Now().duration_since_epoch.ticks,
150             deadline.duration_since_epoch.ticks);
151
152   // TODO(pwbug/291): Ensure it blocks fails to lock when already held.
153   // EXPECT_FALSE(pw_sync_Mutex_CallTryLockUntil(&mutex, deadline));
154   // EXPECT_GE(pw_chrono_SystemClock_Now().duration_since_epoch.ticks,
155   //           deadline.duration_since_epoch.ticks);
156
157   mutex.unlock();
158 }
159
160 }  // namespace
161 }  // namespace pw::sync