xref: /aosp_15_r20/bionic/tests/pthread_test.cpp (revision 8d67ca893c1523eb926b9080dbe4e2ffd2a27ba1)
1*8d67ca89SAndroid Build Coastguard Worker /*
2*8d67ca89SAndroid Build Coastguard Worker  * Copyright (C) 2012 The Android Open Source Project
3*8d67ca89SAndroid Build Coastguard Worker  *
4*8d67ca89SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*8d67ca89SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*8d67ca89SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*8d67ca89SAndroid Build Coastguard Worker  *
8*8d67ca89SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*8d67ca89SAndroid Build Coastguard Worker  *
10*8d67ca89SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*8d67ca89SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*8d67ca89SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*8d67ca89SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*8d67ca89SAndroid Build Coastguard Worker  * limitations under the License.
15*8d67ca89SAndroid Build Coastguard Worker  */
16*8d67ca89SAndroid Build Coastguard Worker 
17*8d67ca89SAndroid Build Coastguard Worker #include <gtest/gtest.h>
18*8d67ca89SAndroid Build Coastguard Worker 
19*8d67ca89SAndroid Build Coastguard Worker #include <errno.h>
20*8d67ca89SAndroid Build Coastguard Worker #include <inttypes.h>
21*8d67ca89SAndroid Build Coastguard Worker #include <limits.h>
22*8d67ca89SAndroid Build Coastguard Worker #include <malloc.h>
23*8d67ca89SAndroid Build Coastguard Worker #include <pthread.h>
24*8d67ca89SAndroid Build Coastguard Worker #include <signal.h>
25*8d67ca89SAndroid Build Coastguard Worker #include <stdio.h>
26*8d67ca89SAndroid Build Coastguard Worker #include <sys/cdefs.h>
27*8d67ca89SAndroid Build Coastguard Worker #include <sys/mman.h>
28*8d67ca89SAndroid Build Coastguard Worker #include <sys/param.h>
29*8d67ca89SAndroid Build Coastguard Worker #include <sys/prctl.h>
30*8d67ca89SAndroid Build Coastguard Worker #include <sys/resource.h>
31*8d67ca89SAndroid Build Coastguard Worker #include <sys/syscall.h>
32*8d67ca89SAndroid Build Coastguard Worker #include <time.h>
33*8d67ca89SAndroid Build Coastguard Worker #include <unistd.h>
34*8d67ca89SAndroid Build Coastguard Worker #include <unwind.h>
35*8d67ca89SAndroid Build Coastguard Worker 
36*8d67ca89SAndroid Build Coastguard Worker #include <atomic>
37*8d67ca89SAndroid Build Coastguard Worker #include <future>
38*8d67ca89SAndroid Build Coastguard Worker #include <vector>
39*8d67ca89SAndroid Build Coastguard Worker 
40*8d67ca89SAndroid Build Coastguard Worker #include <android-base/macros.h>
41*8d67ca89SAndroid Build Coastguard Worker #include <android-base/parseint.h>
42*8d67ca89SAndroid Build Coastguard Worker #include <android-base/scopeguard.h>
43*8d67ca89SAndroid Build Coastguard Worker #include <android-base/silent_death_test.h>
44*8d67ca89SAndroid Build Coastguard Worker #include <android-base/strings.h>
45*8d67ca89SAndroid Build Coastguard Worker #include <android-base/test_utils.h>
46*8d67ca89SAndroid Build Coastguard Worker 
47*8d67ca89SAndroid Build Coastguard Worker #include "private/bionic_constants.h"
48*8d67ca89SAndroid Build Coastguard Worker #include "private/bionic_time_conversions.h"
49*8d67ca89SAndroid Build Coastguard Worker #include "SignalUtils.h"
50*8d67ca89SAndroid Build Coastguard Worker #include "utils.h"
51*8d67ca89SAndroid Build Coastguard Worker 
52*8d67ca89SAndroid Build Coastguard Worker using pthread_DeathTest = SilentDeathTest;
53*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_key_create)54*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_key_create) {
55*8d67ca89SAndroid Build Coastguard Worker   pthread_key_t key;
56*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_key_create(&key, nullptr));
57*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_key_delete(key));
58*8d67ca89SAndroid Build Coastguard Worker   // Can't delete a key that's already been deleted.
59*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(EINVAL, pthread_key_delete(key));
60*8d67ca89SAndroid Build Coastguard Worker }
61*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_keys_max)62*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_keys_max) {
63*8d67ca89SAndroid Build Coastguard Worker   // POSIX says PTHREAD_KEYS_MAX should be at least _POSIX_THREAD_KEYS_MAX.
64*8d67ca89SAndroid Build Coastguard Worker   ASSERT_GE(PTHREAD_KEYS_MAX, _POSIX_THREAD_KEYS_MAX);
65*8d67ca89SAndroid Build Coastguard Worker }
66*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,sysconf_SC_THREAD_KEYS_MAX_eq_PTHREAD_KEYS_MAX)67*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, sysconf_SC_THREAD_KEYS_MAX_eq_PTHREAD_KEYS_MAX) {
68*8d67ca89SAndroid Build Coastguard Worker   int sysconf_max = sysconf(_SC_THREAD_KEYS_MAX);
69*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(sysconf_max, PTHREAD_KEYS_MAX);
70*8d67ca89SAndroid Build Coastguard Worker }
71*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_key_many_distinct)72*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_key_many_distinct) {
73*8d67ca89SAndroid Build Coastguard Worker   // As gtest uses pthread keys, we can't allocate exactly PTHREAD_KEYS_MAX
74*8d67ca89SAndroid Build Coastguard Worker   // pthread keys, but We should be able to allocate at least this many keys.
75*8d67ca89SAndroid Build Coastguard Worker   int nkeys = PTHREAD_KEYS_MAX / 2;
76*8d67ca89SAndroid Build Coastguard Worker   std::vector<pthread_key_t> keys;
77*8d67ca89SAndroid Build Coastguard Worker 
78*8d67ca89SAndroid Build Coastguard Worker   auto scope_guard = android::base::make_scope_guard([&keys] {
79*8d67ca89SAndroid Build Coastguard Worker     for (const auto& key : keys) {
80*8d67ca89SAndroid Build Coastguard Worker       EXPECT_EQ(0, pthread_key_delete(key));
81*8d67ca89SAndroid Build Coastguard Worker     }
82*8d67ca89SAndroid Build Coastguard Worker   });
83*8d67ca89SAndroid Build Coastguard Worker 
84*8d67ca89SAndroid Build Coastguard Worker   for (int i = 0; i < nkeys; ++i) {
85*8d67ca89SAndroid Build Coastguard Worker     pthread_key_t key;
86*8d67ca89SAndroid Build Coastguard Worker     // If this fails, it's likely that LIBC_PTHREAD_KEY_RESERVED_COUNT is wrong.
87*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_key_create(&key, nullptr)) << i << " of " << nkeys;
88*8d67ca89SAndroid Build Coastguard Worker     keys.push_back(key);
89*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_setspecific(key, reinterpret_cast<void*>(i)));
90*8d67ca89SAndroid Build Coastguard Worker   }
91*8d67ca89SAndroid Build Coastguard Worker 
92*8d67ca89SAndroid Build Coastguard Worker   for (int i = keys.size() - 1; i >= 0; --i) {
93*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(reinterpret_cast<void*>(i), pthread_getspecific(keys.back()));
94*8d67ca89SAndroid Build Coastguard Worker     pthread_key_t key = keys.back();
95*8d67ca89SAndroid Build Coastguard Worker     keys.pop_back();
96*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_key_delete(key));
97*8d67ca89SAndroid Build Coastguard Worker   }
98*8d67ca89SAndroid Build Coastguard Worker }
99*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_key_not_exceed_PTHREAD_KEYS_MAX)100*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_key_not_exceed_PTHREAD_KEYS_MAX) {
101*8d67ca89SAndroid Build Coastguard Worker   std::vector<pthread_key_t> keys;
102*8d67ca89SAndroid Build Coastguard Worker   int rv = 0;
103*8d67ca89SAndroid Build Coastguard Worker 
104*8d67ca89SAndroid Build Coastguard Worker   // Pthread keys are used by gtest, so PTHREAD_KEYS_MAX should
105*8d67ca89SAndroid Build Coastguard Worker   // be more than we are allowed to allocate now.
106*8d67ca89SAndroid Build Coastguard Worker   for (int i = 0; i < PTHREAD_KEYS_MAX; i++) {
107*8d67ca89SAndroid Build Coastguard Worker     pthread_key_t key;
108*8d67ca89SAndroid Build Coastguard Worker     rv = pthread_key_create(&key, nullptr);
109*8d67ca89SAndroid Build Coastguard Worker     if (rv == EAGAIN) {
110*8d67ca89SAndroid Build Coastguard Worker       break;
111*8d67ca89SAndroid Build Coastguard Worker     }
112*8d67ca89SAndroid Build Coastguard Worker     EXPECT_EQ(0, rv);
113*8d67ca89SAndroid Build Coastguard Worker     keys.push_back(key);
114*8d67ca89SAndroid Build Coastguard Worker   }
115*8d67ca89SAndroid Build Coastguard Worker 
116*8d67ca89SAndroid Build Coastguard Worker   // Don't leak keys.
117*8d67ca89SAndroid Build Coastguard Worker   for (const auto& key : keys) {
118*8d67ca89SAndroid Build Coastguard Worker     EXPECT_EQ(0, pthread_key_delete(key));
119*8d67ca89SAndroid Build Coastguard Worker   }
120*8d67ca89SAndroid Build Coastguard Worker   keys.clear();
121*8d67ca89SAndroid Build Coastguard Worker 
122*8d67ca89SAndroid Build Coastguard Worker   // We should have eventually reached the maximum number of keys and received
123*8d67ca89SAndroid Build Coastguard Worker   // EAGAIN.
124*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(EAGAIN, rv);
125*8d67ca89SAndroid Build Coastguard Worker }
126*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_key_delete)127*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_key_delete) {
128*8d67ca89SAndroid Build Coastguard Worker   void* expected = reinterpret_cast<void*>(1234);
129*8d67ca89SAndroid Build Coastguard Worker   pthread_key_t key;
130*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_key_create(&key, nullptr));
131*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_setspecific(key, expected));
132*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(expected, pthread_getspecific(key));
133*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_key_delete(key));
134*8d67ca89SAndroid Build Coastguard Worker   // After deletion, pthread_getspecific returns nullptr.
135*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(nullptr, pthread_getspecific(key));
136*8d67ca89SAndroid Build Coastguard Worker   // And you can't use pthread_setspecific with the deleted key.
137*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(EINVAL, pthread_setspecific(key, expected));
138*8d67ca89SAndroid Build Coastguard Worker }
139*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_key_fork)140*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_key_fork) {
141*8d67ca89SAndroid Build Coastguard Worker   void* expected = reinterpret_cast<void*>(1234);
142*8d67ca89SAndroid Build Coastguard Worker   pthread_key_t key;
143*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_key_create(&key, nullptr));
144*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_setspecific(key, expected));
145*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(expected, pthread_getspecific(key));
146*8d67ca89SAndroid Build Coastguard Worker 
147*8d67ca89SAndroid Build Coastguard Worker   pid_t pid = fork();
148*8d67ca89SAndroid Build Coastguard Worker   ASSERT_NE(-1, pid) << strerror(errno);
149*8d67ca89SAndroid Build Coastguard Worker 
150*8d67ca89SAndroid Build Coastguard Worker   if (pid == 0) {
151*8d67ca89SAndroid Build Coastguard Worker     // The surviving thread inherits all the forking thread's TLS values...
152*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(expected, pthread_getspecific(key));
153*8d67ca89SAndroid Build Coastguard Worker     _exit(99);
154*8d67ca89SAndroid Build Coastguard Worker   }
155*8d67ca89SAndroid Build Coastguard Worker 
156*8d67ca89SAndroid Build Coastguard Worker   AssertChildExited(pid, 99);
157*8d67ca89SAndroid Build Coastguard Worker 
158*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(expected, pthread_getspecific(key));
159*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_key_delete(key));
160*8d67ca89SAndroid Build Coastguard Worker }
161*8d67ca89SAndroid Build Coastguard Worker 
DirtyKeyFn(void * key)162*8d67ca89SAndroid Build Coastguard Worker static void* DirtyKeyFn(void* key) {
163*8d67ca89SAndroid Build Coastguard Worker   return pthread_getspecific(*reinterpret_cast<pthread_key_t*>(key));
164*8d67ca89SAndroid Build Coastguard Worker }
165*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_key_dirty)166*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_key_dirty) {
167*8d67ca89SAndroid Build Coastguard Worker   pthread_key_t key;
168*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_key_create(&key, nullptr));
169*8d67ca89SAndroid Build Coastguard Worker 
170*8d67ca89SAndroid Build Coastguard Worker   size_t stack_size = 640 * 1024;
171*8d67ca89SAndroid Build Coastguard Worker   void* stack = mmap(nullptr, stack_size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
172*8d67ca89SAndroid Build Coastguard Worker   ASSERT_NE(MAP_FAILED, stack);
173*8d67ca89SAndroid Build Coastguard Worker   memset(stack, 0xff, stack_size);
174*8d67ca89SAndroid Build Coastguard Worker 
175*8d67ca89SAndroid Build Coastguard Worker   pthread_attr_t attr;
176*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_init(&attr));
177*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_setstack(&attr, stack, stack_size));
178*8d67ca89SAndroid Build Coastguard Worker 
179*8d67ca89SAndroid Build Coastguard Worker   pthread_t t;
180*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_create(&t, &attr, DirtyKeyFn, &key));
181*8d67ca89SAndroid Build Coastguard Worker 
182*8d67ca89SAndroid Build Coastguard Worker   void* result;
183*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_join(t, &result));
184*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(nullptr, result); // Not ~0!
185*8d67ca89SAndroid Build Coastguard Worker 
186*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, munmap(stack, stack_size));
187*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_key_delete(key));
188*8d67ca89SAndroid Build Coastguard Worker }
189*8d67ca89SAndroid Build Coastguard Worker 
FnWithStackFrame(void *)190*8d67ca89SAndroid Build Coastguard Worker static void* FnWithStackFrame(void*) {
191*8d67ca89SAndroid Build Coastguard Worker   int x;
192*8d67ca89SAndroid Build Coastguard Worker   *const_cast<volatile int*>(&x) = 1;
193*8d67ca89SAndroid Build Coastguard Worker   return nullptr;
194*8d67ca89SAndroid Build Coastguard Worker }
195*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_heap_allocated_stack)196*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_heap_allocated_stack) {
197*8d67ca89SAndroid Build Coastguard Worker   SKIP_WITH_HWASAN; // TODO(b/148982147): Re-enable when fixed.
198*8d67ca89SAndroid Build Coastguard Worker 
199*8d67ca89SAndroid Build Coastguard Worker   size_t stack_size = 640 * 1024;
200*8d67ca89SAndroid Build Coastguard Worker   std::unique_ptr<char[]> stack(new (std::align_val_t(getpagesize())) char[stack_size]);
201*8d67ca89SAndroid Build Coastguard Worker   memset(stack.get(), '\xff', stack_size);
202*8d67ca89SAndroid Build Coastguard Worker 
203*8d67ca89SAndroid Build Coastguard Worker   pthread_attr_t attr;
204*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_init(&attr));
205*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_setstack(&attr, stack.get(), stack_size));
206*8d67ca89SAndroid Build Coastguard Worker 
207*8d67ca89SAndroid Build Coastguard Worker   pthread_t t;
208*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_create(&t, &attr, FnWithStackFrame, nullptr));
209*8d67ca89SAndroid Build Coastguard Worker 
210*8d67ca89SAndroid Build Coastguard Worker   void* result;
211*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_join(t, &result));
212*8d67ca89SAndroid Build Coastguard Worker }
213*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,static_pthread_key_used_before_creation)214*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, static_pthread_key_used_before_creation) {
215*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
216*8d67ca89SAndroid Build Coastguard Worker   // See http://b/19625804. The bug is about a static/global pthread key being used before creation.
217*8d67ca89SAndroid Build Coastguard Worker   // So here tests if the static/global default value 0 can be detected as invalid key.
218*8d67ca89SAndroid Build Coastguard Worker   static pthread_key_t key;
219*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(nullptr, pthread_getspecific(key));
220*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(EINVAL, pthread_setspecific(key, nullptr));
221*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(EINVAL, pthread_key_delete(key));
222*8d67ca89SAndroid Build Coastguard Worker #else
223*8d67ca89SAndroid Build Coastguard Worker   GTEST_SKIP() << "bionic-only test";
224*8d67ca89SAndroid Build Coastguard Worker #endif
225*8d67ca89SAndroid Build Coastguard Worker }
226*8d67ca89SAndroid Build Coastguard Worker 
IdFn(void * arg)227*8d67ca89SAndroid Build Coastguard Worker static void* IdFn(void* arg) {
228*8d67ca89SAndroid Build Coastguard Worker   return arg;
229*8d67ca89SAndroid Build Coastguard Worker }
230*8d67ca89SAndroid Build Coastguard Worker 
231*8d67ca89SAndroid Build Coastguard Worker class SpinFunctionHelper {
232*8d67ca89SAndroid Build Coastguard Worker  public:
SpinFunctionHelper()233*8d67ca89SAndroid Build Coastguard Worker   SpinFunctionHelper() {
234*8d67ca89SAndroid Build Coastguard Worker     SpinFunctionHelper::spin_flag_ = true;
235*8d67ca89SAndroid Build Coastguard Worker   }
236*8d67ca89SAndroid Build Coastguard Worker 
~SpinFunctionHelper()237*8d67ca89SAndroid Build Coastguard Worker   ~SpinFunctionHelper() {
238*8d67ca89SAndroid Build Coastguard Worker     UnSpin();
239*8d67ca89SAndroid Build Coastguard Worker   }
240*8d67ca89SAndroid Build Coastguard Worker 
GetFunction()241*8d67ca89SAndroid Build Coastguard Worker   auto GetFunction() -> void* (*)(void*) {
242*8d67ca89SAndroid Build Coastguard Worker     return SpinFunctionHelper::SpinFn;
243*8d67ca89SAndroid Build Coastguard Worker   }
244*8d67ca89SAndroid Build Coastguard Worker 
UnSpin()245*8d67ca89SAndroid Build Coastguard Worker   void UnSpin() {
246*8d67ca89SAndroid Build Coastguard Worker     SpinFunctionHelper::spin_flag_ = false;
247*8d67ca89SAndroid Build Coastguard Worker   }
248*8d67ca89SAndroid Build Coastguard Worker 
249*8d67ca89SAndroid Build Coastguard Worker  private:
SpinFn(void *)250*8d67ca89SAndroid Build Coastguard Worker   static void* SpinFn(void*) {
251*8d67ca89SAndroid Build Coastguard Worker     while (spin_flag_) {}
252*8d67ca89SAndroid Build Coastguard Worker     return nullptr;
253*8d67ca89SAndroid Build Coastguard Worker   }
254*8d67ca89SAndroid Build Coastguard Worker   static std::atomic<bool> spin_flag_;
255*8d67ca89SAndroid Build Coastguard Worker };
256*8d67ca89SAndroid Build Coastguard Worker 
257*8d67ca89SAndroid Build Coastguard Worker // It doesn't matter if spin_flag_ is used in several tests,
258*8d67ca89SAndroid Build Coastguard Worker // because it is always set to false after each test. Each thread
259*8d67ca89SAndroid Build Coastguard Worker // loops on spin_flag_ can find it becomes false at some time.
260*8d67ca89SAndroid Build Coastguard Worker std::atomic<bool> SpinFunctionHelper::spin_flag_;
261*8d67ca89SAndroid Build Coastguard Worker 
JoinFn(void * arg)262*8d67ca89SAndroid Build Coastguard Worker static void* JoinFn(void* arg) {
263*8d67ca89SAndroid Build Coastguard Worker   return reinterpret_cast<void*>(pthread_join(reinterpret_cast<pthread_t>(arg), nullptr));
264*8d67ca89SAndroid Build Coastguard Worker }
265*8d67ca89SAndroid Build Coastguard Worker 
AssertDetached(pthread_t t,bool is_detached)266*8d67ca89SAndroid Build Coastguard Worker static void AssertDetached(pthread_t t, bool is_detached) {
267*8d67ca89SAndroid Build Coastguard Worker   pthread_attr_t attr;
268*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_getattr_np(t, &attr));
269*8d67ca89SAndroid Build Coastguard Worker   int detach_state;
270*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_getdetachstate(&attr, &detach_state));
271*8d67ca89SAndroid Build Coastguard Worker   pthread_attr_destroy(&attr);
272*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(is_detached, (detach_state == PTHREAD_CREATE_DETACHED));
273*8d67ca89SAndroid Build Coastguard Worker }
274*8d67ca89SAndroid Build Coastguard Worker 
MakeDeadThread(pthread_t & t)275*8d67ca89SAndroid Build Coastguard Worker static void MakeDeadThread(pthread_t& t) {
276*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_create(&t, nullptr, IdFn, nullptr));
277*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_join(t, nullptr));
278*8d67ca89SAndroid Build Coastguard Worker }
279*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_create)280*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_create) {
281*8d67ca89SAndroid Build Coastguard Worker   void* expected_result = reinterpret_cast<void*>(123);
282*8d67ca89SAndroid Build Coastguard Worker   // Can we create a thread?
283*8d67ca89SAndroid Build Coastguard Worker   pthread_t t;
284*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_create(&t, nullptr, IdFn, expected_result));
285*8d67ca89SAndroid Build Coastguard Worker   // If we join, do we get the expected value back?
286*8d67ca89SAndroid Build Coastguard Worker   void* result;
287*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_join(t, &result));
288*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(expected_result, result);
289*8d67ca89SAndroid Build Coastguard Worker }
290*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_create_EAGAIN)291*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_create_EAGAIN) {
292*8d67ca89SAndroid Build Coastguard Worker   pthread_attr_t attributes;
293*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_init(&attributes));
294*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_setstacksize(&attributes, static_cast<size_t>(-1) & ~(getpagesize() - 1)));
295*8d67ca89SAndroid Build Coastguard Worker 
296*8d67ca89SAndroid Build Coastguard Worker   pthread_t t;
297*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(EAGAIN, pthread_create(&t, &attributes, IdFn, nullptr));
298*8d67ca89SAndroid Build Coastguard Worker }
299*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_no_join_after_detach)300*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_no_join_after_detach) {
301*8d67ca89SAndroid Build Coastguard Worker   SpinFunctionHelper spin_helper;
302*8d67ca89SAndroid Build Coastguard Worker 
303*8d67ca89SAndroid Build Coastguard Worker   pthread_t t1;
304*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_create(&t1, nullptr, spin_helper.GetFunction(), nullptr));
305*8d67ca89SAndroid Build Coastguard Worker 
306*8d67ca89SAndroid Build Coastguard Worker   // After a pthread_detach...
307*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_detach(t1));
308*8d67ca89SAndroid Build Coastguard Worker   AssertDetached(t1, true);
309*8d67ca89SAndroid Build Coastguard Worker 
310*8d67ca89SAndroid Build Coastguard Worker   // ...pthread_join should fail.
311*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(EINVAL, pthread_join(t1, nullptr));
312*8d67ca89SAndroid Build Coastguard Worker }
313*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_no_op_detach_after_join)314*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_no_op_detach_after_join) {
315*8d67ca89SAndroid Build Coastguard Worker   SpinFunctionHelper spin_helper;
316*8d67ca89SAndroid Build Coastguard Worker 
317*8d67ca89SAndroid Build Coastguard Worker   pthread_t t1;
318*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_create(&t1, nullptr, spin_helper.GetFunction(), nullptr));
319*8d67ca89SAndroid Build Coastguard Worker 
320*8d67ca89SAndroid Build Coastguard Worker   // If thread 2 is already waiting to join thread 1...
321*8d67ca89SAndroid Build Coastguard Worker   pthread_t t2;
322*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_create(&t2, nullptr, JoinFn, reinterpret_cast<void*>(t1)));
323*8d67ca89SAndroid Build Coastguard Worker 
324*8d67ca89SAndroid Build Coastguard Worker   sleep(1); // (Give t2 a chance to call pthread_join.)
325*8d67ca89SAndroid Build Coastguard Worker 
326*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
327*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(EINVAL, pthread_detach(t1));
328*8d67ca89SAndroid Build Coastguard Worker #else
329*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_detach(t1));
330*8d67ca89SAndroid Build Coastguard Worker #endif
331*8d67ca89SAndroid Build Coastguard Worker   AssertDetached(t1, false);
332*8d67ca89SAndroid Build Coastguard Worker 
333*8d67ca89SAndroid Build Coastguard Worker   spin_helper.UnSpin();
334*8d67ca89SAndroid Build Coastguard Worker 
335*8d67ca89SAndroid Build Coastguard Worker   // ...but t2's join on t1 still goes ahead (which we can tell because our join on t2 finishes).
336*8d67ca89SAndroid Build Coastguard Worker   void* join_result;
337*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_join(t2, &join_result));
338*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(join_result));
339*8d67ca89SAndroid Build Coastguard Worker }
340*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_join_self)341*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_join_self) {
342*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(EDEADLK, pthread_join(pthread_self(), nullptr));
343*8d67ca89SAndroid Build Coastguard Worker }
344*8d67ca89SAndroid Build Coastguard Worker 
345*8d67ca89SAndroid Build Coastguard Worker struct TestBug37410 {
346*8d67ca89SAndroid Build Coastguard Worker   pthread_t main_thread;
347*8d67ca89SAndroid Build Coastguard Worker   pthread_mutex_t mutex;
348*8d67ca89SAndroid Build Coastguard Worker 
mainTestBug37410349*8d67ca89SAndroid Build Coastguard Worker   static void main() {
350*8d67ca89SAndroid Build Coastguard Worker     TestBug37410 data;
351*8d67ca89SAndroid Build Coastguard Worker     data.main_thread = pthread_self();
352*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_mutex_init(&data.mutex, nullptr));
353*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_mutex_lock(&data.mutex));
354*8d67ca89SAndroid Build Coastguard Worker 
355*8d67ca89SAndroid Build Coastguard Worker     pthread_t t;
356*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_create(&t, nullptr, TestBug37410::thread_fn, reinterpret_cast<void*>(&data)));
357*8d67ca89SAndroid Build Coastguard Worker 
358*8d67ca89SAndroid Build Coastguard Worker     // Wait for the thread to be running...
359*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_mutex_lock(&data.mutex));
360*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_mutex_unlock(&data.mutex));
361*8d67ca89SAndroid Build Coastguard Worker 
362*8d67ca89SAndroid Build Coastguard Worker     // ...and exit.
363*8d67ca89SAndroid Build Coastguard Worker     pthread_exit(nullptr);
364*8d67ca89SAndroid Build Coastguard Worker   }
365*8d67ca89SAndroid Build Coastguard Worker 
366*8d67ca89SAndroid Build Coastguard Worker  private:
thread_fnTestBug37410367*8d67ca89SAndroid Build Coastguard Worker   static void* thread_fn(void* arg) {
368*8d67ca89SAndroid Build Coastguard Worker     TestBug37410* data = reinterpret_cast<TestBug37410*>(arg);
369*8d67ca89SAndroid Build Coastguard Worker 
370*8d67ca89SAndroid Build Coastguard Worker     // Unlocking data->mutex will cause the main thread to exit, invalidating *data. Save the handle.
371*8d67ca89SAndroid Build Coastguard Worker     pthread_t main_thread = data->main_thread;
372*8d67ca89SAndroid Build Coastguard Worker 
373*8d67ca89SAndroid Build Coastguard Worker     // Let the main thread know we're running.
374*8d67ca89SAndroid Build Coastguard Worker     pthread_mutex_unlock(&data->mutex);
375*8d67ca89SAndroid Build Coastguard Worker 
376*8d67ca89SAndroid Build Coastguard Worker     // And wait for the main thread to exit.
377*8d67ca89SAndroid Build Coastguard Worker     pthread_join(main_thread, nullptr);
378*8d67ca89SAndroid Build Coastguard Worker 
379*8d67ca89SAndroid Build Coastguard Worker     return nullptr;
380*8d67ca89SAndroid Build Coastguard Worker   }
381*8d67ca89SAndroid Build Coastguard Worker };
382*8d67ca89SAndroid Build Coastguard Worker 
383*8d67ca89SAndroid Build Coastguard Worker // Even though this isn't really a death test, we have to say "DeathTest" here so gtest knows to
384*8d67ca89SAndroid Build Coastguard Worker // run this test (which exits normally) in its own process.
TEST_F(pthread_DeathTest,pthread_bug_37410)385*8d67ca89SAndroid Build Coastguard Worker TEST_F(pthread_DeathTest, pthread_bug_37410) {
386*8d67ca89SAndroid Build Coastguard Worker   // http://code.google.com/p/android/issues/detail?id=37410
387*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EXIT(TestBug37410::main(), ::testing::ExitedWithCode(0), "");
388*8d67ca89SAndroid Build Coastguard Worker }
389*8d67ca89SAndroid Build Coastguard Worker 
SignalHandlerFn(void * arg)390*8d67ca89SAndroid Build Coastguard Worker static void* SignalHandlerFn(void* arg) {
391*8d67ca89SAndroid Build Coastguard Worker   sigset64_t wait_set;
392*8d67ca89SAndroid Build Coastguard Worker   sigfillset64(&wait_set);
393*8d67ca89SAndroid Build Coastguard Worker   return reinterpret_cast<void*>(sigwait64(&wait_set, reinterpret_cast<int*>(arg)));
394*8d67ca89SAndroid Build Coastguard Worker }
395*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_sigmask)396*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_sigmask) {
397*8d67ca89SAndroid Build Coastguard Worker   // Check that SIGUSR1 isn't blocked.
398*8d67ca89SAndroid Build Coastguard Worker   sigset_t original_set;
399*8d67ca89SAndroid Build Coastguard Worker   sigemptyset(&original_set);
400*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_sigmask(SIG_BLOCK, nullptr, &original_set));
401*8d67ca89SAndroid Build Coastguard Worker   ASSERT_FALSE(sigismember(&original_set, SIGUSR1));
402*8d67ca89SAndroid Build Coastguard Worker 
403*8d67ca89SAndroid Build Coastguard Worker   // Block SIGUSR1.
404*8d67ca89SAndroid Build Coastguard Worker   sigset_t set;
405*8d67ca89SAndroid Build Coastguard Worker   sigemptyset(&set);
406*8d67ca89SAndroid Build Coastguard Worker   sigaddset(&set, SIGUSR1);
407*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_sigmask(SIG_BLOCK, &set, nullptr));
408*8d67ca89SAndroid Build Coastguard Worker 
409*8d67ca89SAndroid Build Coastguard Worker   // Check that SIGUSR1 is blocked.
410*8d67ca89SAndroid Build Coastguard Worker   sigset_t final_set;
411*8d67ca89SAndroid Build Coastguard Worker   sigemptyset(&final_set);
412*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_sigmask(SIG_BLOCK, nullptr, &final_set));
413*8d67ca89SAndroid Build Coastguard Worker   ASSERT_TRUE(sigismember(&final_set, SIGUSR1));
414*8d67ca89SAndroid Build Coastguard Worker   // ...and that sigprocmask agrees with pthread_sigmask.
415*8d67ca89SAndroid Build Coastguard Worker   sigemptyset(&final_set);
416*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, sigprocmask(SIG_BLOCK, nullptr, &final_set));
417*8d67ca89SAndroid Build Coastguard Worker   ASSERT_TRUE(sigismember(&final_set, SIGUSR1));
418*8d67ca89SAndroid Build Coastguard Worker 
419*8d67ca89SAndroid Build Coastguard Worker   // Spawn a thread that calls sigwait and tells us what it received.
420*8d67ca89SAndroid Build Coastguard Worker   pthread_t signal_thread;
421*8d67ca89SAndroid Build Coastguard Worker   int received_signal = -1;
422*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_create(&signal_thread, nullptr, SignalHandlerFn, &received_signal));
423*8d67ca89SAndroid Build Coastguard Worker 
424*8d67ca89SAndroid Build Coastguard Worker   // Send that thread SIGUSR1.
425*8d67ca89SAndroid Build Coastguard Worker   pthread_kill(signal_thread, SIGUSR1);
426*8d67ca89SAndroid Build Coastguard Worker 
427*8d67ca89SAndroid Build Coastguard Worker   // See what it got.
428*8d67ca89SAndroid Build Coastguard Worker   void* join_result;
429*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_join(signal_thread, &join_result));
430*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(SIGUSR1, received_signal);
431*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(join_result));
432*8d67ca89SAndroid Build Coastguard Worker 
433*8d67ca89SAndroid Build Coastguard Worker   // Restore the original signal mask.
434*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_sigmask(SIG_SETMASK, &original_set, nullptr));
435*8d67ca89SAndroid Build Coastguard Worker }
436*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_sigmask64_SIGTRMIN)437*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_sigmask64_SIGTRMIN) {
438*8d67ca89SAndroid Build Coastguard Worker   // Check that SIGRTMIN isn't blocked.
439*8d67ca89SAndroid Build Coastguard Worker   sigset64_t original_set;
440*8d67ca89SAndroid Build Coastguard Worker   sigemptyset64(&original_set);
441*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_sigmask64(SIG_BLOCK, nullptr, &original_set));
442*8d67ca89SAndroid Build Coastguard Worker   ASSERT_FALSE(sigismember64(&original_set, SIGRTMIN));
443*8d67ca89SAndroid Build Coastguard Worker 
444*8d67ca89SAndroid Build Coastguard Worker   // Block SIGRTMIN.
445*8d67ca89SAndroid Build Coastguard Worker   sigset64_t set;
446*8d67ca89SAndroid Build Coastguard Worker   sigemptyset64(&set);
447*8d67ca89SAndroid Build Coastguard Worker   sigaddset64(&set, SIGRTMIN);
448*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_sigmask64(SIG_BLOCK, &set, nullptr));
449*8d67ca89SAndroid Build Coastguard Worker 
450*8d67ca89SAndroid Build Coastguard Worker   // Check that SIGRTMIN is blocked.
451*8d67ca89SAndroid Build Coastguard Worker   sigset64_t final_set;
452*8d67ca89SAndroid Build Coastguard Worker   sigemptyset64(&final_set);
453*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_sigmask64(SIG_BLOCK, nullptr, &final_set));
454*8d67ca89SAndroid Build Coastguard Worker   ASSERT_TRUE(sigismember64(&final_set, SIGRTMIN));
455*8d67ca89SAndroid Build Coastguard Worker   // ...and that sigprocmask64 agrees with pthread_sigmask64.
456*8d67ca89SAndroid Build Coastguard Worker   sigemptyset64(&final_set);
457*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, sigprocmask64(SIG_BLOCK, nullptr, &final_set));
458*8d67ca89SAndroid Build Coastguard Worker   ASSERT_TRUE(sigismember64(&final_set, SIGRTMIN));
459*8d67ca89SAndroid Build Coastguard Worker 
460*8d67ca89SAndroid Build Coastguard Worker   // Spawn a thread that calls sigwait64 and tells us what it received.
461*8d67ca89SAndroid Build Coastguard Worker   pthread_t signal_thread;
462*8d67ca89SAndroid Build Coastguard Worker   int received_signal = -1;
463*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_create(&signal_thread, nullptr, SignalHandlerFn, &received_signal));
464*8d67ca89SAndroid Build Coastguard Worker 
465*8d67ca89SAndroid Build Coastguard Worker   // Send that thread SIGRTMIN.
466*8d67ca89SAndroid Build Coastguard Worker   pthread_kill(signal_thread, SIGRTMIN);
467*8d67ca89SAndroid Build Coastguard Worker 
468*8d67ca89SAndroid Build Coastguard Worker   // See what it got.
469*8d67ca89SAndroid Build Coastguard Worker   void* join_result;
470*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_join(signal_thread, &join_result));
471*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(SIGRTMIN, received_signal);
472*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(join_result));
473*8d67ca89SAndroid Build Coastguard Worker 
474*8d67ca89SAndroid Build Coastguard Worker   // Restore the original signal mask.
475*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_sigmask64(SIG_SETMASK, &original_set, nullptr));
476*8d67ca89SAndroid Build Coastguard Worker }
477*8d67ca89SAndroid Build Coastguard Worker 
test_pthread_setname_np__pthread_getname_np(pthread_t t)478*8d67ca89SAndroid Build Coastguard Worker static void test_pthread_setname_np__pthread_getname_np(pthread_t t) {
479*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_setname_np(t, "short"));
480*8d67ca89SAndroid Build Coastguard Worker   char name[32];
481*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_getname_np(t, name, sizeof(name)));
482*8d67ca89SAndroid Build Coastguard Worker   ASSERT_STREQ("short", name);
483*8d67ca89SAndroid Build Coastguard Worker 
484*8d67ca89SAndroid Build Coastguard Worker   // The limit is 15 characters --- the kernel's buffer is 16, but includes a NUL.
485*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_setname_np(t, "123456789012345"));
486*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_getname_np(t, name, sizeof(name)));
487*8d67ca89SAndroid Build Coastguard Worker   ASSERT_STREQ("123456789012345", name);
488*8d67ca89SAndroid Build Coastguard Worker 
489*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(ERANGE, pthread_setname_np(t, "1234567890123456"));
490*8d67ca89SAndroid Build Coastguard Worker 
491*8d67ca89SAndroid Build Coastguard Worker   // The passed-in buffer should be at least 16 bytes.
492*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_getname_np(t, name, 16));
493*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(ERANGE, pthread_getname_np(t, name, 15));
494*8d67ca89SAndroid Build Coastguard Worker }
495*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_setname_np__pthread_getname_np__self)496*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_setname_np__pthread_getname_np__self) {
497*8d67ca89SAndroid Build Coastguard Worker   test_pthread_setname_np__pthread_getname_np(pthread_self());
498*8d67ca89SAndroid Build Coastguard Worker }
499*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_setname_np__pthread_getname_np__other)500*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_setname_np__pthread_getname_np__other) {
501*8d67ca89SAndroid Build Coastguard Worker   SpinFunctionHelper spin_helper;
502*8d67ca89SAndroid Build Coastguard Worker 
503*8d67ca89SAndroid Build Coastguard Worker   pthread_t t;
504*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_create(&t, nullptr, spin_helper.GetFunction(), nullptr));
505*8d67ca89SAndroid Build Coastguard Worker   test_pthread_setname_np__pthread_getname_np(t);
506*8d67ca89SAndroid Build Coastguard Worker   spin_helper.UnSpin();
507*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_join(t, nullptr));
508*8d67ca89SAndroid Build Coastguard Worker }
509*8d67ca89SAndroid Build Coastguard Worker 
510*8d67ca89SAndroid Build Coastguard Worker // http://b/28051133: a kernel misfeature means that you can't change the
511*8d67ca89SAndroid Build Coastguard Worker // name of another thread if you've set PR_SET_DUMPABLE to 0.
TEST(pthread,pthread_setname_np__pthread_getname_np__other_PR_SET_DUMPABLE)512*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_setname_np__pthread_getname_np__other_PR_SET_DUMPABLE) {
513*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, prctl(PR_SET_DUMPABLE, 0)) << strerror(errno);
514*8d67ca89SAndroid Build Coastguard Worker 
515*8d67ca89SAndroid Build Coastguard Worker   SpinFunctionHelper spin_helper;
516*8d67ca89SAndroid Build Coastguard Worker 
517*8d67ca89SAndroid Build Coastguard Worker   pthread_t t;
518*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_create(&t, nullptr, spin_helper.GetFunction(), nullptr));
519*8d67ca89SAndroid Build Coastguard Worker   test_pthread_setname_np__pthread_getname_np(t);
520*8d67ca89SAndroid Build Coastguard Worker   spin_helper.UnSpin();
521*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_join(t, nullptr));
522*8d67ca89SAndroid Build Coastguard Worker }
523*8d67ca89SAndroid Build Coastguard Worker 
TEST_F(pthread_DeathTest,pthread_setname_np__no_such_thread)524*8d67ca89SAndroid Build Coastguard Worker TEST_F(pthread_DeathTest, pthread_setname_np__no_such_thread) {
525*8d67ca89SAndroid Build Coastguard Worker   pthread_t dead_thread;
526*8d67ca89SAndroid Build Coastguard Worker   MakeDeadThread(dead_thread);
527*8d67ca89SAndroid Build Coastguard Worker 
528*8d67ca89SAndroid Build Coastguard Worker   EXPECT_DEATH(pthread_setname_np(dead_thread, "short 3"),
529*8d67ca89SAndroid Build Coastguard Worker                "invalid pthread_t (.*) passed to pthread_setname_np");
530*8d67ca89SAndroid Build Coastguard Worker }
531*8d67ca89SAndroid Build Coastguard Worker 
TEST_F(pthread_DeathTest,pthread_setname_np__null_thread)532*8d67ca89SAndroid Build Coastguard Worker TEST_F(pthread_DeathTest, pthread_setname_np__null_thread) {
533*8d67ca89SAndroid Build Coastguard Worker   pthread_t null_thread = 0;
534*8d67ca89SAndroid Build Coastguard Worker   EXPECT_EQ(ENOENT, pthread_setname_np(null_thread, "short 3"));
535*8d67ca89SAndroid Build Coastguard Worker }
536*8d67ca89SAndroid Build Coastguard Worker 
TEST_F(pthread_DeathTest,pthread_getname_np__no_such_thread)537*8d67ca89SAndroid Build Coastguard Worker TEST_F(pthread_DeathTest, pthread_getname_np__no_such_thread) {
538*8d67ca89SAndroid Build Coastguard Worker   pthread_t dead_thread;
539*8d67ca89SAndroid Build Coastguard Worker   MakeDeadThread(dead_thread);
540*8d67ca89SAndroid Build Coastguard Worker 
541*8d67ca89SAndroid Build Coastguard Worker   char name[64];
542*8d67ca89SAndroid Build Coastguard Worker   EXPECT_DEATH(pthread_getname_np(dead_thread, name, sizeof(name)),
543*8d67ca89SAndroid Build Coastguard Worker                "invalid pthread_t (.*) passed to pthread_getname_np");
544*8d67ca89SAndroid Build Coastguard Worker }
545*8d67ca89SAndroid Build Coastguard Worker 
TEST_F(pthread_DeathTest,pthread_getname_np__null_thread)546*8d67ca89SAndroid Build Coastguard Worker TEST_F(pthread_DeathTest, pthread_getname_np__null_thread) {
547*8d67ca89SAndroid Build Coastguard Worker   pthread_t null_thread = 0;
548*8d67ca89SAndroid Build Coastguard Worker 
549*8d67ca89SAndroid Build Coastguard Worker   char name[64];
550*8d67ca89SAndroid Build Coastguard Worker   EXPECT_EQ(ENOENT, pthread_getname_np(null_thread, name, sizeof(name)));
551*8d67ca89SAndroid Build Coastguard Worker }
552*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_kill__0)553*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_kill__0) {
554*8d67ca89SAndroid Build Coastguard Worker   // Signal 0 just tests that the thread exists, so it's safe to call on ourselves.
555*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_kill(pthread_self(), 0));
556*8d67ca89SAndroid Build Coastguard Worker }
557*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_kill__invalid_signal)558*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_kill__invalid_signal) {
559*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(EINVAL, pthread_kill(pthread_self(), -1));
560*8d67ca89SAndroid Build Coastguard Worker }
561*8d67ca89SAndroid Build Coastguard Worker 
pthread_kill__in_signal_handler_helper(int signal_number)562*8d67ca89SAndroid Build Coastguard Worker static void pthread_kill__in_signal_handler_helper(int signal_number) {
563*8d67ca89SAndroid Build Coastguard Worker   static int count = 0;
564*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(SIGALRM, signal_number);
565*8d67ca89SAndroid Build Coastguard Worker   if (++count == 1) {
566*8d67ca89SAndroid Build Coastguard Worker     // Can we call pthread_kill from a signal handler?
567*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_kill(pthread_self(), SIGALRM));
568*8d67ca89SAndroid Build Coastguard Worker   }
569*8d67ca89SAndroid Build Coastguard Worker }
570*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_kill__in_signal_handler)571*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_kill__in_signal_handler) {
572*8d67ca89SAndroid Build Coastguard Worker   ScopedSignalHandler ssh(SIGALRM, pthread_kill__in_signal_handler_helper);
573*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_kill(pthread_self(), SIGALRM));
574*8d67ca89SAndroid Build Coastguard Worker }
575*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_kill__exited_thread)576*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_kill__exited_thread) {
577*8d67ca89SAndroid Build Coastguard Worker   static std::promise<pid_t> tid_promise;
578*8d67ca89SAndroid Build Coastguard Worker   pthread_t thread;
579*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_create(&thread, nullptr,
580*8d67ca89SAndroid Build Coastguard Worker                               [](void*) -> void* {
581*8d67ca89SAndroid Build Coastguard Worker                                 tid_promise.set_value(gettid());
582*8d67ca89SAndroid Build Coastguard Worker                                 return nullptr;
583*8d67ca89SAndroid Build Coastguard Worker                               },
584*8d67ca89SAndroid Build Coastguard Worker                               nullptr));
585*8d67ca89SAndroid Build Coastguard Worker 
586*8d67ca89SAndroid Build Coastguard Worker   pid_t tid = tid_promise.get_future().get();
587*8d67ca89SAndroid Build Coastguard Worker   while (TEMP_FAILURE_RETRY(syscall(__NR_tgkill, getpid(), tid, 0)) != -1) {
588*8d67ca89SAndroid Build Coastguard Worker     continue;
589*8d67ca89SAndroid Build Coastguard Worker   }
590*8d67ca89SAndroid Build Coastguard Worker   ASSERT_ERRNO(ESRCH);
591*8d67ca89SAndroid Build Coastguard Worker 
592*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(ESRCH, pthread_kill(thread, 0));
593*8d67ca89SAndroid Build Coastguard Worker }
594*8d67ca89SAndroid Build Coastguard Worker 
TEST_F(pthread_DeathTest,pthread_detach__no_such_thread)595*8d67ca89SAndroid Build Coastguard Worker TEST_F(pthread_DeathTest, pthread_detach__no_such_thread) {
596*8d67ca89SAndroid Build Coastguard Worker   pthread_t dead_thread;
597*8d67ca89SAndroid Build Coastguard Worker   MakeDeadThread(dead_thread);
598*8d67ca89SAndroid Build Coastguard Worker 
599*8d67ca89SAndroid Build Coastguard Worker   EXPECT_DEATH(pthread_detach(dead_thread),
600*8d67ca89SAndroid Build Coastguard Worker                "invalid pthread_t (.*) passed to pthread_detach");
601*8d67ca89SAndroid Build Coastguard Worker }
602*8d67ca89SAndroid Build Coastguard Worker 
TEST_F(pthread_DeathTest,pthread_detach__null_thread)603*8d67ca89SAndroid Build Coastguard Worker TEST_F(pthread_DeathTest, pthread_detach__null_thread) {
604*8d67ca89SAndroid Build Coastguard Worker   pthread_t null_thread = 0;
605*8d67ca89SAndroid Build Coastguard Worker   EXPECT_EQ(ESRCH, pthread_detach(null_thread));
606*8d67ca89SAndroid Build Coastguard Worker }
607*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_getcpuclockid__clock_gettime)608*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_getcpuclockid__clock_gettime) {
609*8d67ca89SAndroid Build Coastguard Worker   SpinFunctionHelper spin_helper;
610*8d67ca89SAndroid Build Coastguard Worker 
611*8d67ca89SAndroid Build Coastguard Worker   pthread_t t;
612*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_create(&t, nullptr, spin_helper.GetFunction(), nullptr));
613*8d67ca89SAndroid Build Coastguard Worker 
614*8d67ca89SAndroid Build Coastguard Worker   clockid_t c;
615*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_getcpuclockid(t, &c));
616*8d67ca89SAndroid Build Coastguard Worker   timespec ts;
617*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, clock_gettime(c, &ts));
618*8d67ca89SAndroid Build Coastguard Worker   spin_helper.UnSpin();
619*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_join(t, nullptr));
620*8d67ca89SAndroid Build Coastguard Worker }
621*8d67ca89SAndroid Build Coastguard Worker 
TEST_F(pthread_DeathTest,pthread_getcpuclockid__no_such_thread)622*8d67ca89SAndroid Build Coastguard Worker TEST_F(pthread_DeathTest, pthread_getcpuclockid__no_such_thread) {
623*8d67ca89SAndroid Build Coastguard Worker   pthread_t dead_thread;
624*8d67ca89SAndroid Build Coastguard Worker   MakeDeadThread(dead_thread);
625*8d67ca89SAndroid Build Coastguard Worker 
626*8d67ca89SAndroid Build Coastguard Worker   clockid_t c;
627*8d67ca89SAndroid Build Coastguard Worker   EXPECT_DEATH(pthread_getcpuclockid(dead_thread, &c),
628*8d67ca89SAndroid Build Coastguard Worker                "invalid pthread_t (.*) passed to pthread_getcpuclockid");
629*8d67ca89SAndroid Build Coastguard Worker }
630*8d67ca89SAndroid Build Coastguard Worker 
TEST_F(pthread_DeathTest,pthread_getcpuclockid__null_thread)631*8d67ca89SAndroid Build Coastguard Worker TEST_F(pthread_DeathTest, pthread_getcpuclockid__null_thread) {
632*8d67ca89SAndroid Build Coastguard Worker   pthread_t null_thread = 0;
633*8d67ca89SAndroid Build Coastguard Worker   clockid_t c;
634*8d67ca89SAndroid Build Coastguard Worker   EXPECT_EQ(ESRCH, pthread_getcpuclockid(null_thread, &c));
635*8d67ca89SAndroid Build Coastguard Worker }
636*8d67ca89SAndroid Build Coastguard Worker 
TEST_F(pthread_DeathTest,pthread_getschedparam__no_such_thread)637*8d67ca89SAndroid Build Coastguard Worker TEST_F(pthread_DeathTest, pthread_getschedparam__no_such_thread) {
638*8d67ca89SAndroid Build Coastguard Worker   pthread_t dead_thread;
639*8d67ca89SAndroid Build Coastguard Worker   MakeDeadThread(dead_thread);
640*8d67ca89SAndroid Build Coastguard Worker 
641*8d67ca89SAndroid Build Coastguard Worker   int policy;
642*8d67ca89SAndroid Build Coastguard Worker   sched_param param;
643*8d67ca89SAndroid Build Coastguard Worker   EXPECT_DEATH(pthread_getschedparam(dead_thread, &policy, &param),
644*8d67ca89SAndroid Build Coastguard Worker                "invalid pthread_t (.*) passed to pthread_getschedparam");
645*8d67ca89SAndroid Build Coastguard Worker }
646*8d67ca89SAndroid Build Coastguard Worker 
TEST_F(pthread_DeathTest,pthread_getschedparam__null_thread)647*8d67ca89SAndroid Build Coastguard Worker TEST_F(pthread_DeathTest, pthread_getschedparam__null_thread) {
648*8d67ca89SAndroid Build Coastguard Worker   pthread_t null_thread = 0;
649*8d67ca89SAndroid Build Coastguard Worker   int policy;
650*8d67ca89SAndroid Build Coastguard Worker   sched_param param;
651*8d67ca89SAndroid Build Coastguard Worker   EXPECT_EQ(ESRCH, pthread_getschedparam(null_thread, &policy, &param));
652*8d67ca89SAndroid Build Coastguard Worker }
653*8d67ca89SAndroid Build Coastguard Worker 
TEST_F(pthread_DeathTest,pthread_setschedparam__no_such_thread)654*8d67ca89SAndroid Build Coastguard Worker TEST_F(pthread_DeathTest, pthread_setschedparam__no_such_thread) {
655*8d67ca89SAndroid Build Coastguard Worker   pthread_t dead_thread;
656*8d67ca89SAndroid Build Coastguard Worker   MakeDeadThread(dead_thread);
657*8d67ca89SAndroid Build Coastguard Worker 
658*8d67ca89SAndroid Build Coastguard Worker   int policy = 0;
659*8d67ca89SAndroid Build Coastguard Worker   sched_param param;
660*8d67ca89SAndroid Build Coastguard Worker   EXPECT_DEATH(pthread_setschedparam(dead_thread, policy, &param),
661*8d67ca89SAndroid Build Coastguard Worker                "invalid pthread_t (.*) passed to pthread_setschedparam");
662*8d67ca89SAndroid Build Coastguard Worker }
663*8d67ca89SAndroid Build Coastguard Worker 
TEST_F(pthread_DeathTest,pthread_setschedparam__null_thread)664*8d67ca89SAndroid Build Coastguard Worker TEST_F(pthread_DeathTest, pthread_setschedparam__null_thread) {
665*8d67ca89SAndroid Build Coastguard Worker   pthread_t null_thread = 0;
666*8d67ca89SAndroid Build Coastguard Worker   int policy = 0;
667*8d67ca89SAndroid Build Coastguard Worker   sched_param param;
668*8d67ca89SAndroid Build Coastguard Worker   EXPECT_EQ(ESRCH, pthread_setschedparam(null_thread, policy, &param));
669*8d67ca89SAndroid Build Coastguard Worker }
670*8d67ca89SAndroid Build Coastguard Worker 
TEST_F(pthread_DeathTest,pthread_setschedprio__no_such_thread)671*8d67ca89SAndroid Build Coastguard Worker TEST_F(pthread_DeathTest, pthread_setschedprio__no_such_thread) {
672*8d67ca89SAndroid Build Coastguard Worker   pthread_t dead_thread;
673*8d67ca89SAndroid Build Coastguard Worker   MakeDeadThread(dead_thread);
674*8d67ca89SAndroid Build Coastguard Worker 
675*8d67ca89SAndroid Build Coastguard Worker   EXPECT_DEATH(pthread_setschedprio(dead_thread, 123),
676*8d67ca89SAndroid Build Coastguard Worker                "invalid pthread_t (.*) passed to pthread_setschedprio");
677*8d67ca89SAndroid Build Coastguard Worker }
678*8d67ca89SAndroid Build Coastguard Worker 
TEST_F(pthread_DeathTest,pthread_setschedprio__null_thread)679*8d67ca89SAndroid Build Coastguard Worker TEST_F(pthread_DeathTest, pthread_setschedprio__null_thread) {
680*8d67ca89SAndroid Build Coastguard Worker   pthread_t null_thread = 0;
681*8d67ca89SAndroid Build Coastguard Worker   EXPECT_EQ(ESRCH, pthread_setschedprio(null_thread, 123));
682*8d67ca89SAndroid Build Coastguard Worker }
683*8d67ca89SAndroid Build Coastguard Worker 
TEST_F(pthread_DeathTest,pthread_join__no_such_thread)684*8d67ca89SAndroid Build Coastguard Worker TEST_F(pthread_DeathTest, pthread_join__no_such_thread) {
685*8d67ca89SAndroid Build Coastguard Worker   pthread_t dead_thread;
686*8d67ca89SAndroid Build Coastguard Worker   MakeDeadThread(dead_thread);
687*8d67ca89SAndroid Build Coastguard Worker 
688*8d67ca89SAndroid Build Coastguard Worker   EXPECT_DEATH(pthread_join(dead_thread, nullptr),
689*8d67ca89SAndroid Build Coastguard Worker                "invalid pthread_t (.*) passed to pthread_join");
690*8d67ca89SAndroid Build Coastguard Worker }
691*8d67ca89SAndroid Build Coastguard Worker 
TEST_F(pthread_DeathTest,pthread_join__null_thread)692*8d67ca89SAndroid Build Coastguard Worker TEST_F(pthread_DeathTest, pthread_join__null_thread) {
693*8d67ca89SAndroid Build Coastguard Worker   pthread_t null_thread = 0;
694*8d67ca89SAndroid Build Coastguard Worker   EXPECT_EQ(ESRCH, pthread_join(null_thread, nullptr));
695*8d67ca89SAndroid Build Coastguard Worker }
696*8d67ca89SAndroid Build Coastguard Worker 
TEST_F(pthread_DeathTest,pthread_kill__no_such_thread)697*8d67ca89SAndroid Build Coastguard Worker TEST_F(pthread_DeathTest, pthread_kill__no_such_thread) {
698*8d67ca89SAndroid Build Coastguard Worker   pthread_t dead_thread;
699*8d67ca89SAndroid Build Coastguard Worker   MakeDeadThread(dead_thread);
700*8d67ca89SAndroid Build Coastguard Worker 
701*8d67ca89SAndroid Build Coastguard Worker   EXPECT_DEATH(pthread_kill(dead_thread, 0),
702*8d67ca89SAndroid Build Coastguard Worker                "invalid pthread_t (.*) passed to pthread_kill");
703*8d67ca89SAndroid Build Coastguard Worker }
704*8d67ca89SAndroid Build Coastguard Worker 
TEST_F(pthread_DeathTest,pthread_kill__null_thread)705*8d67ca89SAndroid Build Coastguard Worker TEST_F(pthread_DeathTest, pthread_kill__null_thread) {
706*8d67ca89SAndroid Build Coastguard Worker   pthread_t null_thread = 0;
707*8d67ca89SAndroid Build Coastguard Worker   EXPECT_EQ(ESRCH, pthread_kill(null_thread, 0));
708*8d67ca89SAndroid Build Coastguard Worker }
709*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_join__multijoin)710*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_join__multijoin) {
711*8d67ca89SAndroid Build Coastguard Worker   SpinFunctionHelper spin_helper;
712*8d67ca89SAndroid Build Coastguard Worker 
713*8d67ca89SAndroid Build Coastguard Worker   pthread_t t1;
714*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_create(&t1, nullptr, spin_helper.GetFunction(), nullptr));
715*8d67ca89SAndroid Build Coastguard Worker 
716*8d67ca89SAndroid Build Coastguard Worker   pthread_t t2;
717*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_create(&t2, nullptr, JoinFn, reinterpret_cast<void*>(t1)));
718*8d67ca89SAndroid Build Coastguard Worker 
719*8d67ca89SAndroid Build Coastguard Worker   sleep(1); // (Give t2 a chance to call pthread_join.)
720*8d67ca89SAndroid Build Coastguard Worker 
721*8d67ca89SAndroid Build Coastguard Worker   // Multiple joins to the same thread should fail.
722*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(EINVAL, pthread_join(t1, nullptr));
723*8d67ca89SAndroid Build Coastguard Worker 
724*8d67ca89SAndroid Build Coastguard Worker   spin_helper.UnSpin();
725*8d67ca89SAndroid Build Coastguard Worker 
726*8d67ca89SAndroid Build Coastguard Worker   // ...but t2's join on t1 still goes ahead (which we can tell because our join on t2 finishes).
727*8d67ca89SAndroid Build Coastguard Worker   void* join_result;
728*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_join(t2, &join_result));
729*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(join_result));
730*8d67ca89SAndroid Build Coastguard Worker }
731*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_join__race)732*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_join__race) {
733*8d67ca89SAndroid Build Coastguard Worker   // http://b/11693195 --- pthread_join could return before the thread had actually exited.
734*8d67ca89SAndroid Build Coastguard Worker   // If the joiner unmapped the thread's stack, that could lead to SIGSEGV in the thread.
735*8d67ca89SAndroid Build Coastguard Worker   for (size_t i = 0; i < 1024; ++i) {
736*8d67ca89SAndroid Build Coastguard Worker     size_t stack_size = 640*1024;
737*8d67ca89SAndroid Build Coastguard Worker     void* stack = mmap(nullptr, stack_size, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
738*8d67ca89SAndroid Build Coastguard Worker 
739*8d67ca89SAndroid Build Coastguard Worker     pthread_attr_t a;
740*8d67ca89SAndroid Build Coastguard Worker     pthread_attr_init(&a);
741*8d67ca89SAndroid Build Coastguard Worker     pthread_attr_setstack(&a, stack, stack_size);
742*8d67ca89SAndroid Build Coastguard Worker 
743*8d67ca89SAndroid Build Coastguard Worker     pthread_t t;
744*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_create(&t, &a, IdFn, nullptr));
745*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_join(t, nullptr));
746*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, munmap(stack, stack_size));
747*8d67ca89SAndroid Build Coastguard Worker   }
748*8d67ca89SAndroid Build Coastguard Worker }
749*8d67ca89SAndroid Build Coastguard Worker 
GetActualGuardSizeFn(void * arg)750*8d67ca89SAndroid Build Coastguard Worker static void* GetActualGuardSizeFn(void* arg) {
751*8d67ca89SAndroid Build Coastguard Worker   pthread_attr_t attributes;
752*8d67ca89SAndroid Build Coastguard Worker   pthread_getattr_np(pthread_self(), &attributes);
753*8d67ca89SAndroid Build Coastguard Worker   pthread_attr_getguardsize(&attributes, reinterpret_cast<size_t*>(arg));
754*8d67ca89SAndroid Build Coastguard Worker   return nullptr;
755*8d67ca89SAndroid Build Coastguard Worker }
756*8d67ca89SAndroid Build Coastguard Worker 
GetActualGuardSize(const pthread_attr_t & attributes)757*8d67ca89SAndroid Build Coastguard Worker static size_t GetActualGuardSize(const pthread_attr_t& attributes) {
758*8d67ca89SAndroid Build Coastguard Worker   size_t result;
759*8d67ca89SAndroid Build Coastguard Worker   pthread_t t;
760*8d67ca89SAndroid Build Coastguard Worker   pthread_create(&t, &attributes, GetActualGuardSizeFn, &result);
761*8d67ca89SAndroid Build Coastguard Worker   pthread_join(t, nullptr);
762*8d67ca89SAndroid Build Coastguard Worker   return result;
763*8d67ca89SAndroid Build Coastguard Worker }
764*8d67ca89SAndroid Build Coastguard Worker 
GetActualStackSizeFn(void * arg)765*8d67ca89SAndroid Build Coastguard Worker static void* GetActualStackSizeFn(void* arg) {
766*8d67ca89SAndroid Build Coastguard Worker   pthread_attr_t attributes;
767*8d67ca89SAndroid Build Coastguard Worker   pthread_getattr_np(pthread_self(), &attributes);
768*8d67ca89SAndroid Build Coastguard Worker   pthread_attr_getstacksize(&attributes, reinterpret_cast<size_t*>(arg));
769*8d67ca89SAndroid Build Coastguard Worker   return nullptr;
770*8d67ca89SAndroid Build Coastguard Worker }
771*8d67ca89SAndroid Build Coastguard Worker 
GetActualStackSize(const pthread_attr_t & attributes)772*8d67ca89SAndroid Build Coastguard Worker static size_t GetActualStackSize(const pthread_attr_t& attributes) {
773*8d67ca89SAndroid Build Coastguard Worker   size_t result;
774*8d67ca89SAndroid Build Coastguard Worker   pthread_t t;
775*8d67ca89SAndroid Build Coastguard Worker   pthread_create(&t, &attributes, GetActualStackSizeFn, &result);
776*8d67ca89SAndroid Build Coastguard Worker   pthread_join(t, nullptr);
777*8d67ca89SAndroid Build Coastguard Worker   return result;
778*8d67ca89SAndroid Build Coastguard Worker }
779*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_attr_setguardsize_tiny)780*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_attr_setguardsize_tiny) {
781*8d67ca89SAndroid Build Coastguard Worker   pthread_attr_t attributes;
782*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_init(&attributes));
783*8d67ca89SAndroid Build Coastguard Worker 
784*8d67ca89SAndroid Build Coastguard Worker   // No such thing as too small: will be rounded up to one page by pthread_create.
785*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_setguardsize(&attributes, 128));
786*8d67ca89SAndroid Build Coastguard Worker   size_t guard_size;
787*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_getguardsize(&attributes, &guard_size));
788*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(128U, guard_size);
789*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(static_cast<unsigned long>(getpagesize()), GetActualGuardSize(attributes));
790*8d67ca89SAndroid Build Coastguard Worker }
791*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_attr_setguardsize_reasonable)792*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_attr_setguardsize_reasonable) {
793*8d67ca89SAndroid Build Coastguard Worker   pthread_attr_t attributes;
794*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_init(&attributes));
795*8d67ca89SAndroid Build Coastguard Worker 
796*8d67ca89SAndroid Build Coastguard Worker   // Large enough and a multiple of the page size.
797*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_setguardsize(&attributes, 32*1024));
798*8d67ca89SAndroid Build Coastguard Worker   size_t guard_size;
799*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_getguardsize(&attributes, &guard_size));
800*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(32*1024U, guard_size);
801*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(32*1024U, GetActualGuardSize(attributes));
802*8d67ca89SAndroid Build Coastguard Worker }
803*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_attr_setguardsize_needs_rounding)804*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_attr_setguardsize_needs_rounding) {
805*8d67ca89SAndroid Build Coastguard Worker   pthread_attr_t attributes;
806*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_init(&attributes));
807*8d67ca89SAndroid Build Coastguard Worker 
808*8d67ca89SAndroid Build Coastguard Worker   // Large enough but not a multiple of the page size.
809*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_setguardsize(&attributes, 32*1024 + 1));
810*8d67ca89SAndroid Build Coastguard Worker   size_t guard_size;
811*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_getguardsize(&attributes, &guard_size));
812*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(32*1024U + 1, guard_size);
813*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(roundup(32 * 1024U + 1, getpagesize()), GetActualGuardSize(attributes));
814*8d67ca89SAndroid Build Coastguard Worker }
815*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_attr_setguardsize_enormous)816*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_attr_setguardsize_enormous) {
817*8d67ca89SAndroid Build Coastguard Worker   pthread_attr_t attributes;
818*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_init(&attributes));
819*8d67ca89SAndroid Build Coastguard Worker 
820*8d67ca89SAndroid Build Coastguard Worker   // Larger than the stack itself. (Historically we mistakenly carved
821*8d67ca89SAndroid Build Coastguard Worker   // the guard out of the stack itself, rather than adding it after the
822*8d67ca89SAndroid Build Coastguard Worker   // end.)
823*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_setguardsize(&attributes, 32*1024*1024));
824*8d67ca89SAndroid Build Coastguard Worker   size_t guard_size;
825*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_getguardsize(&attributes, &guard_size));
826*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(32*1024*1024U, guard_size);
827*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(32*1024*1024U, GetActualGuardSize(attributes));
828*8d67ca89SAndroid Build Coastguard Worker }
829*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_attr_setstacksize)830*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_attr_setstacksize) {
831*8d67ca89SAndroid Build Coastguard Worker   pthread_attr_t attributes;
832*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_init(&attributes));
833*8d67ca89SAndroid Build Coastguard Worker 
834*8d67ca89SAndroid Build Coastguard Worker   // Get the default stack size.
835*8d67ca89SAndroid Build Coastguard Worker   size_t default_stack_size;
836*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &default_stack_size));
837*8d67ca89SAndroid Build Coastguard Worker 
838*8d67ca89SAndroid Build Coastguard Worker   // Too small.
839*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(EINVAL, pthread_attr_setstacksize(&attributes, 128));
840*8d67ca89SAndroid Build Coastguard Worker   size_t stack_size;
841*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &stack_size));
842*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(default_stack_size, stack_size);
843*8d67ca89SAndroid Build Coastguard Worker   ASSERT_GE(GetActualStackSize(attributes), default_stack_size);
844*8d67ca89SAndroid Build Coastguard Worker 
845*8d67ca89SAndroid Build Coastguard Worker   // Large enough and a multiple of the page size; may be rounded up by pthread_create.
846*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_setstacksize(&attributes, 32*1024));
847*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &stack_size));
848*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(32*1024U, stack_size);
849*8d67ca89SAndroid Build Coastguard Worker   ASSERT_GE(GetActualStackSize(attributes), 32*1024U);
850*8d67ca89SAndroid Build Coastguard Worker 
851*8d67ca89SAndroid Build Coastguard Worker   // Large enough but not aligned; will be rounded up by pthread_create.
852*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_setstacksize(&attributes, 32*1024 + 1));
853*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &stack_size));
854*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(32*1024U + 1, stack_size);
855*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
856*8d67ca89SAndroid Build Coastguard Worker   ASSERT_GT(GetActualStackSize(attributes), 32*1024U + 1);
857*8d67ca89SAndroid Build Coastguard Worker #else // __BIONIC__
858*8d67ca89SAndroid Build Coastguard Worker   // glibc rounds down, in violation of POSIX. They document this in their BUGS section.
859*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(GetActualStackSize(attributes), 32*1024U);
860*8d67ca89SAndroid Build Coastguard Worker #endif // __BIONIC__
861*8d67ca89SAndroid Build Coastguard Worker }
862*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_rwlockattr_smoke)863*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_rwlockattr_smoke) {
864*8d67ca89SAndroid Build Coastguard Worker   pthread_rwlockattr_t attr;
865*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlockattr_init(&attr));
866*8d67ca89SAndroid Build Coastguard Worker 
867*8d67ca89SAndroid Build Coastguard Worker   int pshared_value_array[] = {PTHREAD_PROCESS_PRIVATE, PTHREAD_PROCESS_SHARED};
868*8d67ca89SAndroid Build Coastguard Worker   for (size_t i = 0; i < sizeof(pshared_value_array) / sizeof(pshared_value_array[0]); ++i) {
869*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_rwlockattr_setpshared(&attr, pshared_value_array[i]));
870*8d67ca89SAndroid Build Coastguard Worker     int pshared;
871*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_rwlockattr_getpshared(&attr, &pshared));
872*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(pshared_value_array[i], pshared);
873*8d67ca89SAndroid Build Coastguard Worker   }
874*8d67ca89SAndroid Build Coastguard Worker 
875*8d67ca89SAndroid Build Coastguard Worker #if !defined(ANDROID_HOST_MUSL)
876*8d67ca89SAndroid Build Coastguard Worker   // musl doesn't have pthread_rwlockattr_setkind_np
877*8d67ca89SAndroid Build Coastguard Worker   int kind_array[] = {PTHREAD_RWLOCK_PREFER_READER_NP,
878*8d67ca89SAndroid Build Coastguard Worker                       PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP};
879*8d67ca89SAndroid Build Coastguard Worker   for (size_t i = 0; i < sizeof(kind_array) / sizeof(kind_array[0]); ++i) {
880*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_rwlockattr_setkind_np(&attr, kind_array[i]));
881*8d67ca89SAndroid Build Coastguard Worker     int kind;
882*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_rwlockattr_getkind_np(&attr, &kind));
883*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(kind_array[i], kind);
884*8d67ca89SAndroid Build Coastguard Worker   }
885*8d67ca89SAndroid Build Coastguard Worker #endif
886*8d67ca89SAndroid Build Coastguard Worker 
887*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlockattr_destroy(&attr));
888*8d67ca89SAndroid Build Coastguard Worker }
889*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_rwlock_init_same_as_PTHREAD_RWLOCK_INITIALIZER)890*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_rwlock_init_same_as_PTHREAD_RWLOCK_INITIALIZER) {
891*8d67ca89SAndroid Build Coastguard Worker   pthread_rwlock_t lock1 = PTHREAD_RWLOCK_INITIALIZER;
892*8d67ca89SAndroid Build Coastguard Worker   pthread_rwlock_t lock2;
893*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_init(&lock2, nullptr));
894*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, memcmp(&lock1, &lock2, sizeof(lock1)));
895*8d67ca89SAndroid Build Coastguard Worker }
896*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_rwlock_smoke)897*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_rwlock_smoke) {
898*8d67ca89SAndroid Build Coastguard Worker   pthread_rwlock_t l;
899*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_init(&l, nullptr));
900*8d67ca89SAndroid Build Coastguard Worker 
901*8d67ca89SAndroid Build Coastguard Worker   // Single read lock
902*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_rdlock(&l));
903*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_unlock(&l));
904*8d67ca89SAndroid Build Coastguard Worker 
905*8d67ca89SAndroid Build Coastguard Worker   // Multiple read lock
906*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_rdlock(&l));
907*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_rdlock(&l));
908*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_unlock(&l));
909*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_unlock(&l));
910*8d67ca89SAndroid Build Coastguard Worker 
911*8d67ca89SAndroid Build Coastguard Worker   // Write lock
912*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_wrlock(&l));
913*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_unlock(&l));
914*8d67ca89SAndroid Build Coastguard Worker 
915*8d67ca89SAndroid Build Coastguard Worker   // Try writer lock
916*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_trywrlock(&l));
917*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(EBUSY, pthread_rwlock_trywrlock(&l));
918*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(EBUSY, pthread_rwlock_tryrdlock(&l));
919*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_unlock(&l));
920*8d67ca89SAndroid Build Coastguard Worker 
921*8d67ca89SAndroid Build Coastguard Worker   // Try reader lock
922*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_tryrdlock(&l));
923*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_tryrdlock(&l));
924*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(EBUSY, pthread_rwlock_trywrlock(&l));
925*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_unlock(&l));
926*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_unlock(&l));
927*8d67ca89SAndroid Build Coastguard Worker 
928*8d67ca89SAndroid Build Coastguard Worker   // Try writer lock after unlock
929*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_wrlock(&l));
930*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_unlock(&l));
931*8d67ca89SAndroid Build Coastguard Worker 
932*8d67ca89SAndroid Build Coastguard Worker   // EDEADLK in "read after write"
933*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_wrlock(&l));
934*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(EDEADLK, pthread_rwlock_rdlock(&l));
935*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_unlock(&l));
936*8d67ca89SAndroid Build Coastguard Worker 
937*8d67ca89SAndroid Build Coastguard Worker   // EDEADLK in "write after write"
938*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_wrlock(&l));
939*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(EDEADLK, pthread_rwlock_wrlock(&l));
940*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_unlock(&l));
941*8d67ca89SAndroid Build Coastguard Worker 
942*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_destroy(&l));
943*8d67ca89SAndroid Build Coastguard Worker }
944*8d67ca89SAndroid Build Coastguard Worker 
945*8d67ca89SAndroid Build Coastguard Worker struct RwlockWakeupHelperArg {
946*8d67ca89SAndroid Build Coastguard Worker   pthread_rwlock_t lock;
947*8d67ca89SAndroid Build Coastguard Worker   enum Progress {
948*8d67ca89SAndroid Build Coastguard Worker     LOCK_INITIALIZED,
949*8d67ca89SAndroid Build Coastguard Worker     LOCK_WAITING,
950*8d67ca89SAndroid Build Coastguard Worker     LOCK_RELEASED,
951*8d67ca89SAndroid Build Coastguard Worker     LOCK_ACCESSED,
952*8d67ca89SAndroid Build Coastguard Worker     LOCK_TIMEDOUT,
953*8d67ca89SAndroid Build Coastguard Worker   };
954*8d67ca89SAndroid Build Coastguard Worker   std::atomic<Progress> progress;
955*8d67ca89SAndroid Build Coastguard Worker   std::atomic<pid_t> tid;
956*8d67ca89SAndroid Build Coastguard Worker   std::function<int (pthread_rwlock_t*)> trylock_function;
957*8d67ca89SAndroid Build Coastguard Worker   std::function<int (pthread_rwlock_t*)> lock_function;
958*8d67ca89SAndroid Build Coastguard Worker   std::function<int (pthread_rwlock_t*, const timespec*)> timed_lock_function;
959*8d67ca89SAndroid Build Coastguard Worker   clockid_t clock;
960*8d67ca89SAndroid Build Coastguard Worker };
961*8d67ca89SAndroid Build Coastguard Worker 
pthread_rwlock_wakeup_helper(RwlockWakeupHelperArg * arg)962*8d67ca89SAndroid Build Coastguard Worker static void pthread_rwlock_wakeup_helper(RwlockWakeupHelperArg* arg) {
963*8d67ca89SAndroid Build Coastguard Worker   arg->tid = gettid();
964*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(RwlockWakeupHelperArg::LOCK_INITIALIZED, arg->progress);
965*8d67ca89SAndroid Build Coastguard Worker   arg->progress = RwlockWakeupHelperArg::LOCK_WAITING;
966*8d67ca89SAndroid Build Coastguard Worker 
967*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(EBUSY, arg->trylock_function(&arg->lock));
968*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, arg->lock_function(&arg->lock));
969*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(RwlockWakeupHelperArg::LOCK_RELEASED, arg->progress);
970*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_unlock(&arg->lock));
971*8d67ca89SAndroid Build Coastguard Worker 
972*8d67ca89SAndroid Build Coastguard Worker   arg->progress = RwlockWakeupHelperArg::LOCK_ACCESSED;
973*8d67ca89SAndroid Build Coastguard Worker }
974*8d67ca89SAndroid Build Coastguard Worker 
test_pthread_rwlock_reader_wakeup_writer(std::function<int (pthread_rwlock_t *)> lock_function)975*8d67ca89SAndroid Build Coastguard Worker static void test_pthread_rwlock_reader_wakeup_writer(std::function<int (pthread_rwlock_t*)> lock_function) {
976*8d67ca89SAndroid Build Coastguard Worker   RwlockWakeupHelperArg wakeup_arg;
977*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_init(&wakeup_arg.lock, nullptr));
978*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_rdlock(&wakeup_arg.lock));
979*8d67ca89SAndroid Build Coastguard Worker   wakeup_arg.progress = RwlockWakeupHelperArg::LOCK_INITIALIZED;
980*8d67ca89SAndroid Build Coastguard Worker   wakeup_arg.tid = 0;
981*8d67ca89SAndroid Build Coastguard Worker   wakeup_arg.trylock_function = &pthread_rwlock_trywrlock;
982*8d67ca89SAndroid Build Coastguard Worker   wakeup_arg.lock_function = lock_function;
983*8d67ca89SAndroid Build Coastguard Worker 
984*8d67ca89SAndroid Build Coastguard Worker   pthread_t thread;
985*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_create(&thread, nullptr,
986*8d67ca89SAndroid Build Coastguard Worker     reinterpret_cast<void* (*)(void*)>(pthread_rwlock_wakeup_helper), &wakeup_arg));
987*8d67ca89SAndroid Build Coastguard Worker   WaitUntilThreadSleep(wakeup_arg.tid);
988*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(RwlockWakeupHelperArg::LOCK_WAITING, wakeup_arg.progress);
989*8d67ca89SAndroid Build Coastguard Worker 
990*8d67ca89SAndroid Build Coastguard Worker   wakeup_arg.progress = RwlockWakeupHelperArg::LOCK_RELEASED;
991*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_unlock(&wakeup_arg.lock));
992*8d67ca89SAndroid Build Coastguard Worker 
993*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_join(thread, nullptr));
994*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(RwlockWakeupHelperArg::LOCK_ACCESSED, wakeup_arg.progress);
995*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_destroy(&wakeup_arg.lock));
996*8d67ca89SAndroid Build Coastguard Worker }
997*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_rwlock_reader_wakeup_writer)998*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_rwlock_reader_wakeup_writer) {
999*8d67ca89SAndroid Build Coastguard Worker   test_pthread_rwlock_reader_wakeup_writer(pthread_rwlock_wrlock);
1000*8d67ca89SAndroid Build Coastguard Worker }
1001*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_rwlock_reader_wakeup_writer_timedwait)1002*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_rwlock_reader_wakeup_writer_timedwait) {
1003*8d67ca89SAndroid Build Coastguard Worker   timespec ts;
1004*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, clock_gettime(CLOCK_REALTIME, &ts));
1005*8d67ca89SAndroid Build Coastguard Worker   ts.tv_sec += 1;
1006*8d67ca89SAndroid Build Coastguard Worker   test_pthread_rwlock_reader_wakeup_writer([&](pthread_rwlock_t* lock) {
1007*8d67ca89SAndroid Build Coastguard Worker     return pthread_rwlock_timedwrlock(lock, &ts);
1008*8d67ca89SAndroid Build Coastguard Worker   });
1009*8d67ca89SAndroid Build Coastguard Worker }
1010*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_rwlock_reader_wakeup_writer_timedwait_monotonic_np)1011*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_rwlock_reader_wakeup_writer_timedwait_monotonic_np) {
1012*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
1013*8d67ca89SAndroid Build Coastguard Worker   timespec ts;
1014*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, clock_gettime(CLOCK_MONOTONIC, &ts));
1015*8d67ca89SAndroid Build Coastguard Worker   ts.tv_sec += 1;
1016*8d67ca89SAndroid Build Coastguard Worker   test_pthread_rwlock_reader_wakeup_writer(
1017*8d67ca89SAndroid Build Coastguard Worker       [&](pthread_rwlock_t* lock) { return pthread_rwlock_timedwrlock_monotonic_np(lock, &ts); });
1018*8d67ca89SAndroid Build Coastguard Worker #else   // __BIONIC__
1019*8d67ca89SAndroid Build Coastguard Worker   GTEST_SKIP() << "pthread_rwlock_timedwrlock_monotonic_np not available";
1020*8d67ca89SAndroid Build Coastguard Worker #endif  // __BIONIC__
1021*8d67ca89SAndroid Build Coastguard Worker }
1022*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_rwlock_reader_wakeup_writer_clockwait)1023*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_rwlock_reader_wakeup_writer_clockwait) {
1024*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
1025*8d67ca89SAndroid Build Coastguard Worker   timespec ts;
1026*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, clock_gettime(CLOCK_MONOTONIC, &ts));
1027*8d67ca89SAndroid Build Coastguard Worker   ts.tv_sec += 1;
1028*8d67ca89SAndroid Build Coastguard Worker   test_pthread_rwlock_reader_wakeup_writer([&](pthread_rwlock_t* lock) {
1029*8d67ca89SAndroid Build Coastguard Worker     return pthread_rwlock_clockwrlock(lock, CLOCK_MONOTONIC, &ts);
1030*8d67ca89SAndroid Build Coastguard Worker   });
1031*8d67ca89SAndroid Build Coastguard Worker 
1032*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, clock_gettime(CLOCK_REALTIME, &ts));
1033*8d67ca89SAndroid Build Coastguard Worker   ts.tv_sec += 1;
1034*8d67ca89SAndroid Build Coastguard Worker   test_pthread_rwlock_reader_wakeup_writer([&](pthread_rwlock_t* lock) {
1035*8d67ca89SAndroid Build Coastguard Worker     return pthread_rwlock_clockwrlock(lock, CLOCK_REALTIME, &ts);
1036*8d67ca89SAndroid Build Coastguard Worker   });
1037*8d67ca89SAndroid Build Coastguard Worker #else   // __BIONIC__
1038*8d67ca89SAndroid Build Coastguard Worker   GTEST_SKIP() << "pthread_rwlock_clockwrlock not available";
1039*8d67ca89SAndroid Build Coastguard Worker #endif  // __BIONIC__
1040*8d67ca89SAndroid Build Coastguard Worker }
1041*8d67ca89SAndroid Build Coastguard Worker 
test_pthread_rwlock_writer_wakeup_reader(std::function<int (pthread_rwlock_t *)> lock_function)1042*8d67ca89SAndroid Build Coastguard Worker static void test_pthread_rwlock_writer_wakeup_reader(std::function<int (pthread_rwlock_t*)> lock_function) {
1043*8d67ca89SAndroid Build Coastguard Worker   RwlockWakeupHelperArg wakeup_arg;
1044*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_init(&wakeup_arg.lock, nullptr));
1045*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_wrlock(&wakeup_arg.lock));
1046*8d67ca89SAndroid Build Coastguard Worker   wakeup_arg.progress = RwlockWakeupHelperArg::LOCK_INITIALIZED;
1047*8d67ca89SAndroid Build Coastguard Worker   wakeup_arg.tid = 0;
1048*8d67ca89SAndroid Build Coastguard Worker   wakeup_arg.trylock_function = &pthread_rwlock_tryrdlock;
1049*8d67ca89SAndroid Build Coastguard Worker   wakeup_arg.lock_function = lock_function;
1050*8d67ca89SAndroid Build Coastguard Worker 
1051*8d67ca89SAndroid Build Coastguard Worker   pthread_t thread;
1052*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_create(&thread, nullptr,
1053*8d67ca89SAndroid Build Coastguard Worker     reinterpret_cast<void* (*)(void*)>(pthread_rwlock_wakeup_helper), &wakeup_arg));
1054*8d67ca89SAndroid Build Coastguard Worker   WaitUntilThreadSleep(wakeup_arg.tid);
1055*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(RwlockWakeupHelperArg::LOCK_WAITING, wakeup_arg.progress);
1056*8d67ca89SAndroid Build Coastguard Worker 
1057*8d67ca89SAndroid Build Coastguard Worker   wakeup_arg.progress = RwlockWakeupHelperArg::LOCK_RELEASED;
1058*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_unlock(&wakeup_arg.lock));
1059*8d67ca89SAndroid Build Coastguard Worker 
1060*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_join(thread, nullptr));
1061*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(RwlockWakeupHelperArg::LOCK_ACCESSED, wakeup_arg.progress);
1062*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_destroy(&wakeup_arg.lock));
1063*8d67ca89SAndroid Build Coastguard Worker }
1064*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_rwlock_writer_wakeup_reader)1065*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_rwlock_writer_wakeup_reader) {
1066*8d67ca89SAndroid Build Coastguard Worker   test_pthread_rwlock_writer_wakeup_reader(pthread_rwlock_rdlock);
1067*8d67ca89SAndroid Build Coastguard Worker }
1068*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_rwlock_writer_wakeup_reader_timedwait)1069*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_rwlock_writer_wakeup_reader_timedwait) {
1070*8d67ca89SAndroid Build Coastguard Worker   timespec ts;
1071*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, clock_gettime(CLOCK_REALTIME, &ts));
1072*8d67ca89SAndroid Build Coastguard Worker   ts.tv_sec += 1;
1073*8d67ca89SAndroid Build Coastguard Worker   test_pthread_rwlock_writer_wakeup_reader([&](pthread_rwlock_t* lock) {
1074*8d67ca89SAndroid Build Coastguard Worker     return pthread_rwlock_timedrdlock(lock, &ts);
1075*8d67ca89SAndroid Build Coastguard Worker   });
1076*8d67ca89SAndroid Build Coastguard Worker }
1077*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_rwlock_writer_wakeup_reader_timedwait_monotonic_np)1078*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_rwlock_writer_wakeup_reader_timedwait_monotonic_np) {
1079*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
1080*8d67ca89SAndroid Build Coastguard Worker   timespec ts;
1081*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, clock_gettime(CLOCK_MONOTONIC, &ts));
1082*8d67ca89SAndroid Build Coastguard Worker   ts.tv_sec += 1;
1083*8d67ca89SAndroid Build Coastguard Worker   test_pthread_rwlock_writer_wakeup_reader(
1084*8d67ca89SAndroid Build Coastguard Worker       [&](pthread_rwlock_t* lock) { return pthread_rwlock_timedrdlock_monotonic_np(lock, &ts); });
1085*8d67ca89SAndroid Build Coastguard Worker #else   // __BIONIC__
1086*8d67ca89SAndroid Build Coastguard Worker   GTEST_SKIP() << "pthread_rwlock_timedrdlock_monotonic_np not available";
1087*8d67ca89SAndroid Build Coastguard Worker #endif  // __BIONIC__
1088*8d67ca89SAndroid Build Coastguard Worker }
1089*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_rwlock_writer_wakeup_reader_clockwait)1090*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_rwlock_writer_wakeup_reader_clockwait) {
1091*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
1092*8d67ca89SAndroid Build Coastguard Worker   timespec ts;
1093*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, clock_gettime(CLOCK_MONOTONIC, &ts));
1094*8d67ca89SAndroid Build Coastguard Worker   ts.tv_sec += 1;
1095*8d67ca89SAndroid Build Coastguard Worker   test_pthread_rwlock_writer_wakeup_reader([&](pthread_rwlock_t* lock) {
1096*8d67ca89SAndroid Build Coastguard Worker     return pthread_rwlock_clockrdlock(lock, CLOCK_MONOTONIC, &ts);
1097*8d67ca89SAndroid Build Coastguard Worker   });
1098*8d67ca89SAndroid Build Coastguard Worker 
1099*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, clock_gettime(CLOCK_REALTIME, &ts));
1100*8d67ca89SAndroid Build Coastguard Worker   ts.tv_sec += 1;
1101*8d67ca89SAndroid Build Coastguard Worker   test_pthread_rwlock_writer_wakeup_reader([&](pthread_rwlock_t* lock) {
1102*8d67ca89SAndroid Build Coastguard Worker     return pthread_rwlock_clockrdlock(lock, CLOCK_REALTIME, &ts);
1103*8d67ca89SAndroid Build Coastguard Worker   });
1104*8d67ca89SAndroid Build Coastguard Worker #else   // __BIONIC__
1105*8d67ca89SAndroid Build Coastguard Worker   GTEST_SKIP() << "pthread_rwlock_clockrdlock not available";
1106*8d67ca89SAndroid Build Coastguard Worker #endif  // __BIONIC__
1107*8d67ca89SAndroid Build Coastguard Worker }
1108*8d67ca89SAndroid Build Coastguard Worker 
pthread_rwlock_wakeup_timeout_helper(RwlockWakeupHelperArg * arg)1109*8d67ca89SAndroid Build Coastguard Worker static void pthread_rwlock_wakeup_timeout_helper(RwlockWakeupHelperArg* arg) {
1110*8d67ca89SAndroid Build Coastguard Worker   arg->tid = gettid();
1111*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(RwlockWakeupHelperArg::LOCK_INITIALIZED, arg->progress);
1112*8d67ca89SAndroid Build Coastguard Worker   arg->progress = RwlockWakeupHelperArg::LOCK_WAITING;
1113*8d67ca89SAndroid Build Coastguard Worker 
1114*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(EBUSY, arg->trylock_function(&arg->lock));
1115*8d67ca89SAndroid Build Coastguard Worker 
1116*8d67ca89SAndroid Build Coastguard Worker   timespec ts;
1117*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, clock_gettime(arg->clock, &ts));
1118*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(ETIMEDOUT, arg->timed_lock_function(&arg->lock, &ts));
1119*8d67ca89SAndroid Build Coastguard Worker   ts.tv_nsec = -1;
1120*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(EINVAL, arg->timed_lock_function(&arg->lock, &ts));
1121*8d67ca89SAndroid Build Coastguard Worker   ts.tv_nsec = NS_PER_S;
1122*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(EINVAL, arg->timed_lock_function(&arg->lock, &ts));
1123*8d67ca89SAndroid Build Coastguard Worker   ts.tv_nsec = NS_PER_S - 1;
1124*8d67ca89SAndroid Build Coastguard Worker   ts.tv_sec = -1;
1125*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(ETIMEDOUT, arg->timed_lock_function(&arg->lock, &ts));
1126*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, clock_gettime(arg->clock, &ts));
1127*8d67ca89SAndroid Build Coastguard Worker   ts.tv_sec += 1;
1128*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(ETIMEDOUT, arg->timed_lock_function(&arg->lock, &ts));
1129*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(RwlockWakeupHelperArg::LOCK_WAITING, arg->progress);
1130*8d67ca89SAndroid Build Coastguard Worker   arg->progress = RwlockWakeupHelperArg::LOCK_TIMEDOUT;
1131*8d67ca89SAndroid Build Coastguard Worker }
1132*8d67ca89SAndroid Build Coastguard Worker 
pthread_rwlock_timedrdlock_timeout_helper(clockid_t clock,int (* lock_function)(pthread_rwlock_t * __rwlock,const timespec * __timeout))1133*8d67ca89SAndroid Build Coastguard Worker static void pthread_rwlock_timedrdlock_timeout_helper(
1134*8d67ca89SAndroid Build Coastguard Worker     clockid_t clock, int (*lock_function)(pthread_rwlock_t* __rwlock, const timespec* __timeout)) {
1135*8d67ca89SAndroid Build Coastguard Worker   RwlockWakeupHelperArg wakeup_arg;
1136*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_init(&wakeup_arg.lock, nullptr));
1137*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_wrlock(&wakeup_arg.lock));
1138*8d67ca89SAndroid Build Coastguard Worker   wakeup_arg.progress = RwlockWakeupHelperArg::LOCK_INITIALIZED;
1139*8d67ca89SAndroid Build Coastguard Worker   wakeup_arg.tid = 0;
1140*8d67ca89SAndroid Build Coastguard Worker   wakeup_arg.trylock_function = &pthread_rwlock_tryrdlock;
1141*8d67ca89SAndroid Build Coastguard Worker   wakeup_arg.timed_lock_function = lock_function;
1142*8d67ca89SAndroid Build Coastguard Worker   wakeup_arg.clock = clock;
1143*8d67ca89SAndroid Build Coastguard Worker 
1144*8d67ca89SAndroid Build Coastguard Worker   pthread_t thread;
1145*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_create(&thread, nullptr,
1146*8d67ca89SAndroid Build Coastguard Worker       reinterpret_cast<void* (*)(void*)>(pthread_rwlock_wakeup_timeout_helper), &wakeup_arg));
1147*8d67ca89SAndroid Build Coastguard Worker   WaitUntilThreadSleep(wakeup_arg.tid);
1148*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(RwlockWakeupHelperArg::LOCK_WAITING, wakeup_arg.progress);
1149*8d67ca89SAndroid Build Coastguard Worker 
1150*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_join(thread, nullptr));
1151*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(RwlockWakeupHelperArg::LOCK_TIMEDOUT, wakeup_arg.progress);
1152*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_unlock(&wakeup_arg.lock));
1153*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_destroy(&wakeup_arg.lock));
1154*8d67ca89SAndroid Build Coastguard Worker }
1155*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_rwlock_timedrdlock_timeout)1156*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_rwlock_timedrdlock_timeout) {
1157*8d67ca89SAndroid Build Coastguard Worker   pthread_rwlock_timedrdlock_timeout_helper(CLOCK_REALTIME, pthread_rwlock_timedrdlock);
1158*8d67ca89SAndroid Build Coastguard Worker }
1159*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_rwlock_timedrdlock_monotonic_np_timeout)1160*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_rwlock_timedrdlock_monotonic_np_timeout) {
1161*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
1162*8d67ca89SAndroid Build Coastguard Worker   pthread_rwlock_timedrdlock_timeout_helper(CLOCK_MONOTONIC,
1163*8d67ca89SAndroid Build Coastguard Worker                                             pthread_rwlock_timedrdlock_monotonic_np);
1164*8d67ca89SAndroid Build Coastguard Worker #else   // __BIONIC__
1165*8d67ca89SAndroid Build Coastguard Worker   GTEST_SKIP() << "pthread_rwlock_timedrdlock_monotonic_np not available";
1166*8d67ca89SAndroid Build Coastguard Worker #endif  // __BIONIC__
1167*8d67ca89SAndroid Build Coastguard Worker }
1168*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_rwlock_clockrdlock_monotonic_timeout)1169*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_rwlock_clockrdlock_monotonic_timeout) {
1170*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
1171*8d67ca89SAndroid Build Coastguard Worker   pthread_rwlock_timedrdlock_timeout_helper(
1172*8d67ca89SAndroid Build Coastguard Worker       CLOCK_MONOTONIC, [](pthread_rwlock_t* __rwlock, const timespec* __timeout) {
1173*8d67ca89SAndroid Build Coastguard Worker         return pthread_rwlock_clockrdlock(__rwlock, CLOCK_MONOTONIC, __timeout);
1174*8d67ca89SAndroid Build Coastguard Worker       });
1175*8d67ca89SAndroid Build Coastguard Worker #else   // __BIONIC__
1176*8d67ca89SAndroid Build Coastguard Worker   GTEST_SKIP() << "pthread_rwlock_clockrdlock not available";
1177*8d67ca89SAndroid Build Coastguard Worker #endif  // __BIONIC__
1178*8d67ca89SAndroid Build Coastguard Worker }
1179*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_rwlock_clockrdlock_realtime_timeout)1180*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_rwlock_clockrdlock_realtime_timeout) {
1181*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
1182*8d67ca89SAndroid Build Coastguard Worker   pthread_rwlock_timedrdlock_timeout_helper(
1183*8d67ca89SAndroid Build Coastguard Worker       CLOCK_REALTIME, [](pthread_rwlock_t* __rwlock, const timespec* __timeout) {
1184*8d67ca89SAndroid Build Coastguard Worker         return pthread_rwlock_clockrdlock(__rwlock, CLOCK_REALTIME, __timeout);
1185*8d67ca89SAndroid Build Coastguard Worker       });
1186*8d67ca89SAndroid Build Coastguard Worker #else   // __BIONIC__
1187*8d67ca89SAndroid Build Coastguard Worker   GTEST_SKIP() << "pthread_rwlock_clockrdlock not available";
1188*8d67ca89SAndroid Build Coastguard Worker #endif  // __BIONIC__
1189*8d67ca89SAndroid Build Coastguard Worker }
1190*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_rwlock_clockrdlock_invalid)1191*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_rwlock_clockrdlock_invalid) {
1192*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
1193*8d67ca89SAndroid Build Coastguard Worker   pthread_rwlock_t lock = PTHREAD_RWLOCK_INITIALIZER;
1194*8d67ca89SAndroid Build Coastguard Worker   timespec ts;
1195*8d67ca89SAndroid Build Coastguard Worker   EXPECT_EQ(EINVAL, pthread_rwlock_clockrdlock(&lock, CLOCK_PROCESS_CPUTIME_ID, &ts));
1196*8d67ca89SAndroid Build Coastguard Worker #else   // __BIONIC__
1197*8d67ca89SAndroid Build Coastguard Worker   GTEST_SKIP() << "pthread_rwlock_clockrdlock not available";
1198*8d67ca89SAndroid Build Coastguard Worker #endif  // __BIONIC__
1199*8d67ca89SAndroid Build Coastguard Worker }
1200*8d67ca89SAndroid Build Coastguard Worker 
pthread_rwlock_timedwrlock_timeout_helper(clockid_t clock,int (* lock_function)(pthread_rwlock_t * __rwlock,const timespec * __timeout))1201*8d67ca89SAndroid Build Coastguard Worker static void pthread_rwlock_timedwrlock_timeout_helper(
1202*8d67ca89SAndroid Build Coastguard Worker     clockid_t clock, int (*lock_function)(pthread_rwlock_t* __rwlock, const timespec* __timeout)) {
1203*8d67ca89SAndroid Build Coastguard Worker   RwlockWakeupHelperArg wakeup_arg;
1204*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_init(&wakeup_arg.lock, nullptr));
1205*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_rdlock(&wakeup_arg.lock));
1206*8d67ca89SAndroid Build Coastguard Worker   wakeup_arg.progress = RwlockWakeupHelperArg::LOCK_INITIALIZED;
1207*8d67ca89SAndroid Build Coastguard Worker   wakeup_arg.tid = 0;
1208*8d67ca89SAndroid Build Coastguard Worker   wakeup_arg.trylock_function = &pthread_rwlock_trywrlock;
1209*8d67ca89SAndroid Build Coastguard Worker   wakeup_arg.timed_lock_function = lock_function;
1210*8d67ca89SAndroid Build Coastguard Worker   wakeup_arg.clock = clock;
1211*8d67ca89SAndroid Build Coastguard Worker 
1212*8d67ca89SAndroid Build Coastguard Worker   pthread_t thread;
1213*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_create(&thread, nullptr,
1214*8d67ca89SAndroid Build Coastguard Worker       reinterpret_cast<void* (*)(void*)>(pthread_rwlock_wakeup_timeout_helper), &wakeup_arg));
1215*8d67ca89SAndroid Build Coastguard Worker   WaitUntilThreadSleep(wakeup_arg.tid);
1216*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(RwlockWakeupHelperArg::LOCK_WAITING, wakeup_arg.progress);
1217*8d67ca89SAndroid Build Coastguard Worker 
1218*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_join(thread, nullptr));
1219*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(RwlockWakeupHelperArg::LOCK_TIMEDOUT, wakeup_arg.progress);
1220*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_unlock(&wakeup_arg.lock));
1221*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_destroy(&wakeup_arg.lock));
1222*8d67ca89SAndroid Build Coastguard Worker }
1223*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_rwlock_timedwrlock_timeout)1224*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_rwlock_timedwrlock_timeout) {
1225*8d67ca89SAndroid Build Coastguard Worker   pthread_rwlock_timedwrlock_timeout_helper(CLOCK_REALTIME, pthread_rwlock_timedwrlock);
1226*8d67ca89SAndroid Build Coastguard Worker }
1227*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_rwlock_timedwrlock_monotonic_np_timeout)1228*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_rwlock_timedwrlock_monotonic_np_timeout) {
1229*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
1230*8d67ca89SAndroid Build Coastguard Worker   pthread_rwlock_timedwrlock_timeout_helper(CLOCK_MONOTONIC,
1231*8d67ca89SAndroid Build Coastguard Worker                                             pthread_rwlock_timedwrlock_monotonic_np);
1232*8d67ca89SAndroid Build Coastguard Worker #else   // __BIONIC__
1233*8d67ca89SAndroid Build Coastguard Worker   GTEST_SKIP() << "pthread_rwlock_timedwrlock_monotonic_np not available";
1234*8d67ca89SAndroid Build Coastguard Worker #endif  // __BIONIC__
1235*8d67ca89SAndroid Build Coastguard Worker }
1236*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_rwlock_clockwrlock_monotonic_timeout)1237*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_rwlock_clockwrlock_monotonic_timeout) {
1238*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
1239*8d67ca89SAndroid Build Coastguard Worker   pthread_rwlock_timedwrlock_timeout_helper(
1240*8d67ca89SAndroid Build Coastguard Worker       CLOCK_MONOTONIC, [](pthread_rwlock_t* __rwlock, const timespec* __timeout) {
1241*8d67ca89SAndroid Build Coastguard Worker         return pthread_rwlock_clockwrlock(__rwlock, CLOCK_MONOTONIC, __timeout);
1242*8d67ca89SAndroid Build Coastguard Worker       });
1243*8d67ca89SAndroid Build Coastguard Worker #else   // __BIONIC__
1244*8d67ca89SAndroid Build Coastguard Worker   GTEST_SKIP() << "pthread_rwlock_clockwrlock not available";
1245*8d67ca89SAndroid Build Coastguard Worker #endif  // __BIONIC__
1246*8d67ca89SAndroid Build Coastguard Worker }
1247*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_rwlock_clockwrlock_realtime_timeout)1248*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_rwlock_clockwrlock_realtime_timeout) {
1249*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
1250*8d67ca89SAndroid Build Coastguard Worker   pthread_rwlock_timedwrlock_timeout_helper(
1251*8d67ca89SAndroid Build Coastguard Worker       CLOCK_REALTIME, [](pthread_rwlock_t* __rwlock, const timespec* __timeout) {
1252*8d67ca89SAndroid Build Coastguard Worker         return pthread_rwlock_clockwrlock(__rwlock, CLOCK_REALTIME, __timeout);
1253*8d67ca89SAndroid Build Coastguard Worker       });
1254*8d67ca89SAndroid Build Coastguard Worker #else   // __BIONIC__
1255*8d67ca89SAndroid Build Coastguard Worker   GTEST_SKIP() << "pthread_rwlock_clockwrlock not available";
1256*8d67ca89SAndroid Build Coastguard Worker #endif  // __BIONIC__
1257*8d67ca89SAndroid Build Coastguard Worker }
1258*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_rwlock_clockwrlock_invalid)1259*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_rwlock_clockwrlock_invalid) {
1260*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
1261*8d67ca89SAndroid Build Coastguard Worker   pthread_rwlock_t lock = PTHREAD_RWLOCK_INITIALIZER;
1262*8d67ca89SAndroid Build Coastguard Worker   timespec ts;
1263*8d67ca89SAndroid Build Coastguard Worker   EXPECT_EQ(EINVAL, pthread_rwlock_clockwrlock(&lock, CLOCK_PROCESS_CPUTIME_ID, &ts));
1264*8d67ca89SAndroid Build Coastguard Worker #else   // __BIONIC__
1265*8d67ca89SAndroid Build Coastguard Worker   GTEST_SKIP() << "pthread_rwlock_clockrwlock not available";
1266*8d67ca89SAndroid Build Coastguard Worker #endif  // __BIONIC__
1267*8d67ca89SAndroid Build Coastguard Worker }
1268*8d67ca89SAndroid Build Coastguard Worker 
1269*8d67ca89SAndroid Build Coastguard Worker #if !defined(ANDROID_HOST_MUSL)
1270*8d67ca89SAndroid Build Coastguard Worker // musl doesn't have pthread_rwlockattr_setkind_np
1271*8d67ca89SAndroid Build Coastguard Worker class RwlockKindTestHelper {
1272*8d67ca89SAndroid Build Coastguard Worker  private:
1273*8d67ca89SAndroid Build Coastguard Worker   struct ThreadArg {
1274*8d67ca89SAndroid Build Coastguard Worker     RwlockKindTestHelper* helper;
1275*8d67ca89SAndroid Build Coastguard Worker     std::atomic<pid_t>& tid;
1276*8d67ca89SAndroid Build Coastguard Worker 
ThreadArgRwlockKindTestHelper::ThreadArg1277*8d67ca89SAndroid Build Coastguard Worker     ThreadArg(RwlockKindTestHelper* helper, std::atomic<pid_t>& tid)
1278*8d67ca89SAndroid Build Coastguard Worker       : helper(helper), tid(tid) { }
1279*8d67ca89SAndroid Build Coastguard Worker   };
1280*8d67ca89SAndroid Build Coastguard Worker 
1281*8d67ca89SAndroid Build Coastguard Worker  public:
1282*8d67ca89SAndroid Build Coastguard Worker   pthread_rwlock_t lock;
1283*8d67ca89SAndroid Build Coastguard Worker 
1284*8d67ca89SAndroid Build Coastguard Worker  public:
RwlockKindTestHelper(int kind_type)1285*8d67ca89SAndroid Build Coastguard Worker   explicit RwlockKindTestHelper(int kind_type) {
1286*8d67ca89SAndroid Build Coastguard Worker     InitRwlock(kind_type);
1287*8d67ca89SAndroid Build Coastguard Worker   }
1288*8d67ca89SAndroid Build Coastguard Worker 
~RwlockKindTestHelper()1289*8d67ca89SAndroid Build Coastguard Worker   ~RwlockKindTestHelper() {
1290*8d67ca89SAndroid Build Coastguard Worker     DestroyRwlock();
1291*8d67ca89SAndroid Build Coastguard Worker   }
1292*8d67ca89SAndroid Build Coastguard Worker 
CreateWriterThread(pthread_t & thread,std::atomic<pid_t> & tid)1293*8d67ca89SAndroid Build Coastguard Worker   void CreateWriterThread(pthread_t& thread, std::atomic<pid_t>& tid) {
1294*8d67ca89SAndroid Build Coastguard Worker     tid = 0;
1295*8d67ca89SAndroid Build Coastguard Worker     ThreadArg* arg = new ThreadArg(this, tid);
1296*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_create(&thread, nullptr,
1297*8d67ca89SAndroid Build Coastguard Worker                                 reinterpret_cast<void* (*)(void*)>(WriterThreadFn), arg));
1298*8d67ca89SAndroid Build Coastguard Worker   }
1299*8d67ca89SAndroid Build Coastguard Worker 
CreateReaderThread(pthread_t & thread,std::atomic<pid_t> & tid)1300*8d67ca89SAndroid Build Coastguard Worker   void CreateReaderThread(pthread_t& thread, std::atomic<pid_t>& tid) {
1301*8d67ca89SAndroid Build Coastguard Worker     tid = 0;
1302*8d67ca89SAndroid Build Coastguard Worker     ThreadArg* arg = new ThreadArg(this, tid);
1303*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_create(&thread, nullptr,
1304*8d67ca89SAndroid Build Coastguard Worker                                 reinterpret_cast<void* (*)(void*)>(ReaderThreadFn), arg));
1305*8d67ca89SAndroid Build Coastguard Worker   }
1306*8d67ca89SAndroid Build Coastguard Worker 
1307*8d67ca89SAndroid Build Coastguard Worker  private:
InitRwlock(int kind_type)1308*8d67ca89SAndroid Build Coastguard Worker   void InitRwlock(int kind_type) {
1309*8d67ca89SAndroid Build Coastguard Worker     pthread_rwlockattr_t attr;
1310*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_rwlockattr_init(&attr));
1311*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_rwlockattr_setkind_np(&attr, kind_type));
1312*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_rwlock_init(&lock, &attr));
1313*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_rwlockattr_destroy(&attr));
1314*8d67ca89SAndroid Build Coastguard Worker   }
1315*8d67ca89SAndroid Build Coastguard Worker 
DestroyRwlock()1316*8d67ca89SAndroid Build Coastguard Worker   void DestroyRwlock() {
1317*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_rwlock_destroy(&lock));
1318*8d67ca89SAndroid Build Coastguard Worker   }
1319*8d67ca89SAndroid Build Coastguard Worker 
WriterThreadFn(ThreadArg * arg)1320*8d67ca89SAndroid Build Coastguard Worker   static void WriterThreadFn(ThreadArg* arg) {
1321*8d67ca89SAndroid Build Coastguard Worker     arg->tid = gettid();
1322*8d67ca89SAndroid Build Coastguard Worker 
1323*8d67ca89SAndroid Build Coastguard Worker     RwlockKindTestHelper* helper = arg->helper;
1324*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_rwlock_wrlock(&helper->lock));
1325*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_rwlock_unlock(&helper->lock));
1326*8d67ca89SAndroid Build Coastguard Worker     delete arg;
1327*8d67ca89SAndroid Build Coastguard Worker   }
1328*8d67ca89SAndroid Build Coastguard Worker 
ReaderThreadFn(ThreadArg * arg)1329*8d67ca89SAndroid Build Coastguard Worker   static void ReaderThreadFn(ThreadArg* arg) {
1330*8d67ca89SAndroid Build Coastguard Worker     arg->tid = gettid();
1331*8d67ca89SAndroid Build Coastguard Worker 
1332*8d67ca89SAndroid Build Coastguard Worker     RwlockKindTestHelper* helper = arg->helper;
1333*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_rwlock_rdlock(&helper->lock));
1334*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_rwlock_unlock(&helper->lock));
1335*8d67ca89SAndroid Build Coastguard Worker     delete arg;
1336*8d67ca89SAndroid Build Coastguard Worker   }
1337*8d67ca89SAndroid Build Coastguard Worker };
1338*8d67ca89SAndroid Build Coastguard Worker #endif
1339*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_rwlock_kind_PTHREAD_RWLOCK_PREFER_READER_NP)1340*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_rwlock_kind_PTHREAD_RWLOCK_PREFER_READER_NP) {
1341*8d67ca89SAndroid Build Coastguard Worker #if !defined(ANDROID_HOST_MUSL)
1342*8d67ca89SAndroid Build Coastguard Worker   RwlockKindTestHelper helper(PTHREAD_RWLOCK_PREFER_READER_NP);
1343*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_rdlock(&helper.lock));
1344*8d67ca89SAndroid Build Coastguard Worker 
1345*8d67ca89SAndroid Build Coastguard Worker   pthread_t writer_thread;
1346*8d67ca89SAndroid Build Coastguard Worker   std::atomic<pid_t> writer_tid;
1347*8d67ca89SAndroid Build Coastguard Worker   helper.CreateWriterThread(writer_thread, writer_tid);
1348*8d67ca89SAndroid Build Coastguard Worker   WaitUntilThreadSleep(writer_tid);
1349*8d67ca89SAndroid Build Coastguard Worker 
1350*8d67ca89SAndroid Build Coastguard Worker   pthread_t reader_thread;
1351*8d67ca89SAndroid Build Coastguard Worker   std::atomic<pid_t> reader_tid;
1352*8d67ca89SAndroid Build Coastguard Worker   helper.CreateReaderThread(reader_thread, reader_tid);
1353*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_join(reader_thread, nullptr));
1354*8d67ca89SAndroid Build Coastguard Worker 
1355*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_unlock(&helper.lock));
1356*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_join(writer_thread, nullptr));
1357*8d67ca89SAndroid Build Coastguard Worker #else
1358*8d67ca89SAndroid Build Coastguard Worker   GTEST_SKIP() << "musl doesn't have pthread_rwlockattr_setkind_np";
1359*8d67ca89SAndroid Build Coastguard Worker #endif
1360*8d67ca89SAndroid Build Coastguard Worker }
1361*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_rwlock_kind_PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP)1362*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_rwlock_kind_PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP) {
1363*8d67ca89SAndroid Build Coastguard Worker #if !defined(ANDROID_HOST_MUSL)
1364*8d67ca89SAndroid Build Coastguard Worker   RwlockKindTestHelper helper(PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
1365*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_rdlock(&helper.lock));
1366*8d67ca89SAndroid Build Coastguard Worker 
1367*8d67ca89SAndroid Build Coastguard Worker   pthread_t writer_thread;
1368*8d67ca89SAndroid Build Coastguard Worker   std::atomic<pid_t> writer_tid;
1369*8d67ca89SAndroid Build Coastguard Worker   helper.CreateWriterThread(writer_thread, writer_tid);
1370*8d67ca89SAndroid Build Coastguard Worker   WaitUntilThreadSleep(writer_tid);
1371*8d67ca89SAndroid Build Coastguard Worker 
1372*8d67ca89SAndroid Build Coastguard Worker   pthread_t reader_thread;
1373*8d67ca89SAndroid Build Coastguard Worker   std::atomic<pid_t> reader_tid;
1374*8d67ca89SAndroid Build Coastguard Worker   helper.CreateReaderThread(reader_thread, reader_tid);
1375*8d67ca89SAndroid Build Coastguard Worker   WaitUntilThreadSleep(reader_tid);
1376*8d67ca89SAndroid Build Coastguard Worker 
1377*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_unlock(&helper.lock));
1378*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_join(writer_thread, nullptr));
1379*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_join(reader_thread, nullptr));
1380*8d67ca89SAndroid Build Coastguard Worker #else
1381*8d67ca89SAndroid Build Coastguard Worker   GTEST_SKIP() << "musl doesn't have pthread_rwlockattr_setkind_np";
1382*8d67ca89SAndroid Build Coastguard Worker #endif
1383*8d67ca89SAndroid Build Coastguard Worker }
1384*8d67ca89SAndroid Build Coastguard Worker 
1385*8d67ca89SAndroid Build Coastguard Worker static int g_once_fn_call_count = 0;
OnceFn()1386*8d67ca89SAndroid Build Coastguard Worker static void OnceFn() {
1387*8d67ca89SAndroid Build Coastguard Worker   ++g_once_fn_call_count;
1388*8d67ca89SAndroid Build Coastguard Worker }
1389*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_once_smoke)1390*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_once_smoke) {
1391*8d67ca89SAndroid Build Coastguard Worker   pthread_once_t once_control = PTHREAD_ONCE_INIT;
1392*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_once(&once_control, OnceFn));
1393*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_once(&once_control, OnceFn));
1394*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(1, g_once_fn_call_count);
1395*8d67ca89SAndroid Build Coastguard Worker }
1396*8d67ca89SAndroid Build Coastguard Worker 
1397*8d67ca89SAndroid Build Coastguard Worker static std::string pthread_once_1934122_result = "";
1398*8d67ca89SAndroid Build Coastguard Worker 
Routine2()1399*8d67ca89SAndroid Build Coastguard Worker static void Routine2() {
1400*8d67ca89SAndroid Build Coastguard Worker   pthread_once_1934122_result += "2";
1401*8d67ca89SAndroid Build Coastguard Worker }
1402*8d67ca89SAndroid Build Coastguard Worker 
Routine1()1403*8d67ca89SAndroid Build Coastguard Worker static void Routine1() {
1404*8d67ca89SAndroid Build Coastguard Worker   pthread_once_t once_control_2 = PTHREAD_ONCE_INIT;
1405*8d67ca89SAndroid Build Coastguard Worker   pthread_once_1934122_result += "1";
1406*8d67ca89SAndroid Build Coastguard Worker   pthread_once(&once_control_2, &Routine2);
1407*8d67ca89SAndroid Build Coastguard Worker }
1408*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_once_1934122)1409*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_once_1934122) {
1410*8d67ca89SAndroid Build Coastguard Worker   // Very old versions of Android couldn't call pthread_once from a
1411*8d67ca89SAndroid Build Coastguard Worker   // pthread_once init routine. http://b/1934122.
1412*8d67ca89SAndroid Build Coastguard Worker   pthread_once_t once_control_1 = PTHREAD_ONCE_INIT;
1413*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_once(&once_control_1, &Routine1));
1414*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ("12", pthread_once_1934122_result);
1415*8d67ca89SAndroid Build Coastguard Worker }
1416*8d67ca89SAndroid Build Coastguard Worker 
1417*8d67ca89SAndroid Build Coastguard Worker static int g_atfork_prepare_calls = 0;
AtForkPrepare1()1418*8d67ca89SAndroid Build Coastguard Worker static void AtForkPrepare1() { g_atfork_prepare_calls = (g_atfork_prepare_calls * 10) + 1; }
AtForkPrepare2()1419*8d67ca89SAndroid Build Coastguard Worker static void AtForkPrepare2() { g_atfork_prepare_calls = (g_atfork_prepare_calls * 10) + 2; }
1420*8d67ca89SAndroid Build Coastguard Worker static int g_atfork_parent_calls = 0;
AtForkParent1()1421*8d67ca89SAndroid Build Coastguard Worker static void AtForkParent1() { g_atfork_parent_calls = (g_atfork_parent_calls * 10) + 1; }
AtForkParent2()1422*8d67ca89SAndroid Build Coastguard Worker static void AtForkParent2() { g_atfork_parent_calls = (g_atfork_parent_calls * 10) + 2; }
1423*8d67ca89SAndroid Build Coastguard Worker static int g_atfork_child_calls = 0;
AtForkChild1()1424*8d67ca89SAndroid Build Coastguard Worker static void AtForkChild1() { g_atfork_child_calls = (g_atfork_child_calls * 10) + 1; }
AtForkChild2()1425*8d67ca89SAndroid Build Coastguard Worker static void AtForkChild2() { g_atfork_child_calls = (g_atfork_child_calls * 10) + 2; }
1426*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_atfork_smoke_fork)1427*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_atfork_smoke_fork) {
1428*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_atfork(AtForkPrepare1, AtForkParent1, AtForkChild1));
1429*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_atfork(AtForkPrepare2, AtForkParent2, AtForkChild2));
1430*8d67ca89SAndroid Build Coastguard Worker 
1431*8d67ca89SAndroid Build Coastguard Worker   g_atfork_prepare_calls = g_atfork_parent_calls = g_atfork_child_calls = 0;
1432*8d67ca89SAndroid Build Coastguard Worker   pid_t pid = fork();
1433*8d67ca89SAndroid Build Coastguard Worker   ASSERT_NE(-1, pid) << strerror(errno);
1434*8d67ca89SAndroid Build Coastguard Worker 
1435*8d67ca89SAndroid Build Coastguard Worker   // Child and parent calls are made in the order they were registered.
1436*8d67ca89SAndroid Build Coastguard Worker   if (pid == 0) {
1437*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(12, g_atfork_child_calls);
1438*8d67ca89SAndroid Build Coastguard Worker     _exit(0);
1439*8d67ca89SAndroid Build Coastguard Worker   }
1440*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(12, g_atfork_parent_calls);
1441*8d67ca89SAndroid Build Coastguard Worker 
1442*8d67ca89SAndroid Build Coastguard Worker   // Prepare calls are made in the reverse order.
1443*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(21, g_atfork_prepare_calls);
1444*8d67ca89SAndroid Build Coastguard Worker   AssertChildExited(pid, 0);
1445*8d67ca89SAndroid Build Coastguard Worker }
1446*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_atfork_smoke_vfork)1447*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_atfork_smoke_vfork) {
1448*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_atfork(AtForkPrepare1, AtForkParent1, AtForkChild1));
1449*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_atfork(AtForkPrepare2, AtForkParent2, AtForkChild2));
1450*8d67ca89SAndroid Build Coastguard Worker 
1451*8d67ca89SAndroid Build Coastguard Worker   g_atfork_prepare_calls = g_atfork_parent_calls = g_atfork_child_calls = 0;
1452*8d67ca89SAndroid Build Coastguard Worker   pid_t pid = vfork();
1453*8d67ca89SAndroid Build Coastguard Worker   ASSERT_NE(-1, pid) << strerror(errno);
1454*8d67ca89SAndroid Build Coastguard Worker 
1455*8d67ca89SAndroid Build Coastguard Worker   // atfork handlers are not called.
1456*8d67ca89SAndroid Build Coastguard Worker   if (pid == 0) {
1457*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, g_atfork_child_calls);
1458*8d67ca89SAndroid Build Coastguard Worker     _exit(0);
1459*8d67ca89SAndroid Build Coastguard Worker   }
1460*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, g_atfork_parent_calls);
1461*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, g_atfork_prepare_calls);
1462*8d67ca89SAndroid Build Coastguard Worker   AssertChildExited(pid, 0);
1463*8d67ca89SAndroid Build Coastguard Worker }
1464*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_atfork_smoke__Fork)1465*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_atfork_smoke__Fork) {
1466*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
1467*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_atfork(AtForkPrepare1, AtForkParent1, AtForkChild1));
1468*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_atfork(AtForkPrepare2, AtForkParent2, AtForkChild2));
1469*8d67ca89SAndroid Build Coastguard Worker 
1470*8d67ca89SAndroid Build Coastguard Worker   g_atfork_prepare_calls = g_atfork_parent_calls = g_atfork_child_calls = 0;
1471*8d67ca89SAndroid Build Coastguard Worker   pid_t pid = _Fork();
1472*8d67ca89SAndroid Build Coastguard Worker   ASSERT_NE(-1, pid) << strerror(errno);
1473*8d67ca89SAndroid Build Coastguard Worker 
1474*8d67ca89SAndroid Build Coastguard Worker   // atfork handlers are not called.
1475*8d67ca89SAndroid Build Coastguard Worker   if (pid == 0) {
1476*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, g_atfork_child_calls);
1477*8d67ca89SAndroid Build Coastguard Worker     _exit(0);
1478*8d67ca89SAndroid Build Coastguard Worker   }
1479*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, g_atfork_parent_calls);
1480*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, g_atfork_prepare_calls);
1481*8d67ca89SAndroid Build Coastguard Worker   AssertChildExited(pid, 0);
1482*8d67ca89SAndroid Build Coastguard Worker #endif
1483*8d67ca89SAndroid Build Coastguard Worker }
1484*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_attr_getscope)1485*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_attr_getscope) {
1486*8d67ca89SAndroid Build Coastguard Worker   pthread_attr_t attr;
1487*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_init(&attr));
1488*8d67ca89SAndroid Build Coastguard Worker 
1489*8d67ca89SAndroid Build Coastguard Worker   int scope;
1490*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_getscope(&attr, &scope));
1491*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(PTHREAD_SCOPE_SYSTEM, scope);
1492*8d67ca89SAndroid Build Coastguard Worker }
1493*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_condattr_init)1494*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_condattr_init) {
1495*8d67ca89SAndroid Build Coastguard Worker   pthread_condattr_t attr;
1496*8d67ca89SAndroid Build Coastguard Worker   pthread_condattr_init(&attr);
1497*8d67ca89SAndroid Build Coastguard Worker 
1498*8d67ca89SAndroid Build Coastguard Worker   clockid_t clock;
1499*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_condattr_getclock(&attr, &clock));
1500*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(CLOCK_REALTIME, clock);
1501*8d67ca89SAndroid Build Coastguard Worker 
1502*8d67ca89SAndroid Build Coastguard Worker   int pshared;
1503*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_condattr_getpshared(&attr, &pshared));
1504*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(PTHREAD_PROCESS_PRIVATE, pshared);
1505*8d67ca89SAndroid Build Coastguard Worker }
1506*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_condattr_setclock)1507*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_condattr_setclock) {
1508*8d67ca89SAndroid Build Coastguard Worker   pthread_condattr_t attr;
1509*8d67ca89SAndroid Build Coastguard Worker   pthread_condattr_init(&attr);
1510*8d67ca89SAndroid Build Coastguard Worker 
1511*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_condattr_setclock(&attr, CLOCK_REALTIME));
1512*8d67ca89SAndroid Build Coastguard Worker   clockid_t clock;
1513*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_condattr_getclock(&attr, &clock));
1514*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(CLOCK_REALTIME, clock);
1515*8d67ca89SAndroid Build Coastguard Worker 
1516*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_condattr_setclock(&attr, CLOCK_MONOTONIC));
1517*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_condattr_getclock(&attr, &clock));
1518*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(CLOCK_MONOTONIC, clock);
1519*8d67ca89SAndroid Build Coastguard Worker 
1520*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(EINVAL, pthread_condattr_setclock(&attr, CLOCK_PROCESS_CPUTIME_ID));
1521*8d67ca89SAndroid Build Coastguard Worker }
1522*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_cond_broadcast__preserves_condattr_flags)1523*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_cond_broadcast__preserves_condattr_flags) {
1524*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
1525*8d67ca89SAndroid Build Coastguard Worker   pthread_condattr_t attr;
1526*8d67ca89SAndroid Build Coastguard Worker   pthread_condattr_init(&attr);
1527*8d67ca89SAndroid Build Coastguard Worker 
1528*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_condattr_setclock(&attr, CLOCK_MONOTONIC));
1529*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_condattr_setpshared(&attr, PTHREAD_PROCESS_SHARED));
1530*8d67ca89SAndroid Build Coastguard Worker 
1531*8d67ca89SAndroid Build Coastguard Worker   pthread_cond_t cond_var;
1532*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_cond_init(&cond_var, &attr));
1533*8d67ca89SAndroid Build Coastguard Worker 
1534*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_cond_signal(&cond_var));
1535*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_cond_broadcast(&cond_var));
1536*8d67ca89SAndroid Build Coastguard Worker 
1537*8d67ca89SAndroid Build Coastguard Worker   attr = static_cast<pthread_condattr_t>(*reinterpret_cast<uint32_t*>(cond_var.__private));
1538*8d67ca89SAndroid Build Coastguard Worker   clockid_t clock;
1539*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_condattr_getclock(&attr, &clock));
1540*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(CLOCK_MONOTONIC, clock);
1541*8d67ca89SAndroid Build Coastguard Worker   int pshared;
1542*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_condattr_getpshared(&attr, &pshared));
1543*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(PTHREAD_PROCESS_SHARED, pshared);
1544*8d67ca89SAndroid Build Coastguard Worker #else  // !defined(__BIONIC__)
1545*8d67ca89SAndroid Build Coastguard Worker   GTEST_SKIP() << "bionic-only test";
1546*8d67ca89SAndroid Build Coastguard Worker #endif  // !defined(__BIONIC__)
1547*8d67ca89SAndroid Build Coastguard Worker }
1548*8d67ca89SAndroid Build Coastguard Worker 
1549*8d67ca89SAndroid Build Coastguard Worker class pthread_CondWakeupTest : public ::testing::Test {
1550*8d67ca89SAndroid Build Coastguard Worker  protected:
1551*8d67ca89SAndroid Build Coastguard Worker   pthread_mutex_t mutex;
1552*8d67ca89SAndroid Build Coastguard Worker   pthread_cond_t cond;
1553*8d67ca89SAndroid Build Coastguard Worker 
1554*8d67ca89SAndroid Build Coastguard Worker   enum Progress {
1555*8d67ca89SAndroid Build Coastguard Worker     INITIALIZED,
1556*8d67ca89SAndroid Build Coastguard Worker     WAITING,
1557*8d67ca89SAndroid Build Coastguard Worker     SIGNALED,
1558*8d67ca89SAndroid Build Coastguard Worker     FINISHED,
1559*8d67ca89SAndroid Build Coastguard Worker   };
1560*8d67ca89SAndroid Build Coastguard Worker   std::atomic<Progress> progress;
1561*8d67ca89SAndroid Build Coastguard Worker   pthread_t thread;
1562*8d67ca89SAndroid Build Coastguard Worker   timespec ts;
1563*8d67ca89SAndroid Build Coastguard Worker   std::function<int (pthread_cond_t* cond, pthread_mutex_t* mutex)> wait_function;
1564*8d67ca89SAndroid Build Coastguard Worker 
1565*8d67ca89SAndroid Build Coastguard Worker  protected:
SetUp()1566*8d67ca89SAndroid Build Coastguard Worker   void SetUp() override {
1567*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_mutex_init(&mutex, nullptr));
1568*8d67ca89SAndroid Build Coastguard Worker   }
1569*8d67ca89SAndroid Build Coastguard Worker 
InitCond(clockid_t clock=CLOCK_REALTIME)1570*8d67ca89SAndroid Build Coastguard Worker   void InitCond(clockid_t clock=CLOCK_REALTIME) {
1571*8d67ca89SAndroid Build Coastguard Worker     pthread_condattr_t attr;
1572*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_condattr_init(&attr));
1573*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_condattr_setclock(&attr, clock));
1574*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_cond_init(&cond, &attr));
1575*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_condattr_destroy(&attr));
1576*8d67ca89SAndroid Build Coastguard Worker   }
1577*8d67ca89SAndroid Build Coastguard Worker 
StartWaitingThread(std::function<int (pthread_cond_t * cond,pthread_mutex_t * mutex)> wait_function)1578*8d67ca89SAndroid Build Coastguard Worker   void StartWaitingThread(
1579*8d67ca89SAndroid Build Coastguard Worker       std::function<int(pthread_cond_t* cond, pthread_mutex_t* mutex)> wait_function) {
1580*8d67ca89SAndroid Build Coastguard Worker     progress = INITIALIZED;
1581*8d67ca89SAndroid Build Coastguard Worker     this->wait_function = wait_function;
1582*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_create(&thread, nullptr, reinterpret_cast<void* (*)(void*)>(WaitThreadFn),
1583*8d67ca89SAndroid Build Coastguard Worker                                 this));
1584*8d67ca89SAndroid Build Coastguard Worker     while (progress != WAITING) {
1585*8d67ca89SAndroid Build Coastguard Worker       usleep(5000);
1586*8d67ca89SAndroid Build Coastguard Worker     }
1587*8d67ca89SAndroid Build Coastguard Worker     usleep(5000);
1588*8d67ca89SAndroid Build Coastguard Worker   }
1589*8d67ca89SAndroid Build Coastguard Worker 
RunTimedTest(clockid_t clock,std::function<int (pthread_cond_t * cond,pthread_mutex_t * mutex,const timespec * timeout)> wait_function)1590*8d67ca89SAndroid Build Coastguard Worker   void RunTimedTest(
1591*8d67ca89SAndroid Build Coastguard Worker       clockid_t clock,
1592*8d67ca89SAndroid Build Coastguard Worker       std::function<int(pthread_cond_t* cond, pthread_mutex_t* mutex, const timespec* timeout)>
1593*8d67ca89SAndroid Build Coastguard Worker           wait_function) {
1594*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, clock_gettime(clock, &ts));
1595*8d67ca89SAndroid Build Coastguard Worker     ts.tv_sec += 1;
1596*8d67ca89SAndroid Build Coastguard Worker 
1597*8d67ca89SAndroid Build Coastguard Worker     StartWaitingThread([&wait_function, this](pthread_cond_t* cond, pthread_mutex_t* mutex) {
1598*8d67ca89SAndroid Build Coastguard Worker       return wait_function(cond, mutex, &ts);
1599*8d67ca89SAndroid Build Coastguard Worker     });
1600*8d67ca89SAndroid Build Coastguard Worker 
1601*8d67ca89SAndroid Build Coastguard Worker     progress = SIGNALED;
1602*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_cond_signal(&cond));
1603*8d67ca89SAndroid Build Coastguard Worker   }
1604*8d67ca89SAndroid Build Coastguard Worker 
RunTimedTest(clockid_t clock,std::function<int (pthread_cond_t * cond,pthread_mutex_t * mutex,clockid_t clock,const timespec * timeout)> wait_function)1605*8d67ca89SAndroid Build Coastguard Worker   void RunTimedTest(clockid_t clock, std::function<int(pthread_cond_t* cond, pthread_mutex_t* mutex,
1606*8d67ca89SAndroid Build Coastguard Worker                                                        clockid_t clock, const timespec* timeout)>
1607*8d67ca89SAndroid Build Coastguard Worker                                          wait_function) {
1608*8d67ca89SAndroid Build Coastguard Worker     RunTimedTest(clock, [clock, &wait_function](pthread_cond_t* cond, pthread_mutex_t* mutex,
1609*8d67ca89SAndroid Build Coastguard Worker                                                 const timespec* timeout) {
1610*8d67ca89SAndroid Build Coastguard Worker       return wait_function(cond, mutex, clock, timeout);
1611*8d67ca89SAndroid Build Coastguard Worker     });
1612*8d67ca89SAndroid Build Coastguard Worker   }
1613*8d67ca89SAndroid Build Coastguard Worker 
TearDown()1614*8d67ca89SAndroid Build Coastguard Worker   void TearDown() override {
1615*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_join(thread, nullptr));
1616*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(FINISHED, progress);
1617*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_cond_destroy(&cond));
1618*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_mutex_destroy(&mutex));
1619*8d67ca89SAndroid Build Coastguard Worker   }
1620*8d67ca89SAndroid Build Coastguard Worker 
1621*8d67ca89SAndroid Build Coastguard Worker  private:
WaitThreadFn(pthread_CondWakeupTest * test)1622*8d67ca89SAndroid Build Coastguard Worker   static void WaitThreadFn(pthread_CondWakeupTest* test) {
1623*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_mutex_lock(&test->mutex));
1624*8d67ca89SAndroid Build Coastguard Worker     test->progress = WAITING;
1625*8d67ca89SAndroid Build Coastguard Worker     while (test->progress == WAITING) {
1626*8d67ca89SAndroid Build Coastguard Worker       ASSERT_EQ(0, test->wait_function(&test->cond, &test->mutex));
1627*8d67ca89SAndroid Build Coastguard Worker     }
1628*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(SIGNALED, test->progress);
1629*8d67ca89SAndroid Build Coastguard Worker     test->progress = FINISHED;
1630*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_mutex_unlock(&test->mutex));
1631*8d67ca89SAndroid Build Coastguard Worker   }
1632*8d67ca89SAndroid Build Coastguard Worker };
1633*8d67ca89SAndroid Build Coastguard Worker 
TEST_F(pthread_CondWakeupTest,signal_wait)1634*8d67ca89SAndroid Build Coastguard Worker TEST_F(pthread_CondWakeupTest, signal_wait) {
1635*8d67ca89SAndroid Build Coastguard Worker   InitCond();
1636*8d67ca89SAndroid Build Coastguard Worker   StartWaitingThread([](pthread_cond_t* cond, pthread_mutex_t* mutex) {
1637*8d67ca89SAndroid Build Coastguard Worker     return pthread_cond_wait(cond, mutex);
1638*8d67ca89SAndroid Build Coastguard Worker   });
1639*8d67ca89SAndroid Build Coastguard Worker   progress = SIGNALED;
1640*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_cond_signal(&cond));
1641*8d67ca89SAndroid Build Coastguard Worker }
1642*8d67ca89SAndroid Build Coastguard Worker 
TEST_F(pthread_CondWakeupTest,broadcast_wait)1643*8d67ca89SAndroid Build Coastguard Worker TEST_F(pthread_CondWakeupTest, broadcast_wait) {
1644*8d67ca89SAndroid Build Coastguard Worker   InitCond();
1645*8d67ca89SAndroid Build Coastguard Worker   StartWaitingThread([](pthread_cond_t* cond, pthread_mutex_t* mutex) {
1646*8d67ca89SAndroid Build Coastguard Worker     return pthread_cond_wait(cond, mutex);
1647*8d67ca89SAndroid Build Coastguard Worker   });
1648*8d67ca89SAndroid Build Coastguard Worker   progress = SIGNALED;
1649*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_cond_broadcast(&cond));
1650*8d67ca89SAndroid Build Coastguard Worker }
1651*8d67ca89SAndroid Build Coastguard Worker 
TEST_F(pthread_CondWakeupTest,signal_timedwait_CLOCK_REALTIME)1652*8d67ca89SAndroid Build Coastguard Worker TEST_F(pthread_CondWakeupTest, signal_timedwait_CLOCK_REALTIME) {
1653*8d67ca89SAndroid Build Coastguard Worker   InitCond(CLOCK_REALTIME);
1654*8d67ca89SAndroid Build Coastguard Worker   RunTimedTest(CLOCK_REALTIME, pthread_cond_timedwait);
1655*8d67ca89SAndroid Build Coastguard Worker }
1656*8d67ca89SAndroid Build Coastguard Worker 
TEST_F(pthread_CondWakeupTest,signal_timedwait_CLOCK_MONOTONIC)1657*8d67ca89SAndroid Build Coastguard Worker TEST_F(pthread_CondWakeupTest, signal_timedwait_CLOCK_MONOTONIC) {
1658*8d67ca89SAndroid Build Coastguard Worker   InitCond(CLOCK_MONOTONIC);
1659*8d67ca89SAndroid Build Coastguard Worker   RunTimedTest(CLOCK_MONOTONIC, pthread_cond_timedwait);
1660*8d67ca89SAndroid Build Coastguard Worker }
1661*8d67ca89SAndroid Build Coastguard Worker 
TEST_F(pthread_CondWakeupTest,signal_timedwait_CLOCK_MONOTONIC_np)1662*8d67ca89SAndroid Build Coastguard Worker TEST_F(pthread_CondWakeupTest, signal_timedwait_CLOCK_MONOTONIC_np) {
1663*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
1664*8d67ca89SAndroid Build Coastguard Worker   InitCond(CLOCK_REALTIME);
1665*8d67ca89SAndroid Build Coastguard Worker   RunTimedTest(CLOCK_MONOTONIC, pthread_cond_timedwait_monotonic_np);
1666*8d67ca89SAndroid Build Coastguard Worker #else   // __BIONIC__
1667*8d67ca89SAndroid Build Coastguard Worker   GTEST_SKIP() << "pthread_cond_timedwait_monotonic_np not available";
1668*8d67ca89SAndroid Build Coastguard Worker #endif  // __BIONIC__
1669*8d67ca89SAndroid Build Coastguard Worker }
1670*8d67ca89SAndroid Build Coastguard Worker 
TEST_F(pthread_CondWakeupTest,signal_clockwait_monotonic_monotonic)1671*8d67ca89SAndroid Build Coastguard Worker TEST_F(pthread_CondWakeupTest, signal_clockwait_monotonic_monotonic) {
1672*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
1673*8d67ca89SAndroid Build Coastguard Worker   InitCond(CLOCK_MONOTONIC);
1674*8d67ca89SAndroid Build Coastguard Worker   RunTimedTest(CLOCK_MONOTONIC, pthread_cond_clockwait);
1675*8d67ca89SAndroid Build Coastguard Worker #else   // __BIONIC__
1676*8d67ca89SAndroid Build Coastguard Worker   GTEST_SKIP() << "pthread_cond_clockwait not available";
1677*8d67ca89SAndroid Build Coastguard Worker #endif  // __BIONIC__
1678*8d67ca89SAndroid Build Coastguard Worker }
1679*8d67ca89SAndroid Build Coastguard Worker 
TEST_F(pthread_CondWakeupTest,signal_clockwait_monotonic_realtime)1680*8d67ca89SAndroid Build Coastguard Worker TEST_F(pthread_CondWakeupTest, signal_clockwait_monotonic_realtime) {
1681*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
1682*8d67ca89SAndroid Build Coastguard Worker   InitCond(CLOCK_MONOTONIC);
1683*8d67ca89SAndroid Build Coastguard Worker   RunTimedTest(CLOCK_REALTIME, pthread_cond_clockwait);
1684*8d67ca89SAndroid Build Coastguard Worker #else   // __BIONIC__
1685*8d67ca89SAndroid Build Coastguard Worker   GTEST_SKIP() << "pthread_cond_clockwait not available";
1686*8d67ca89SAndroid Build Coastguard Worker #endif  // __BIONIC__
1687*8d67ca89SAndroid Build Coastguard Worker }
1688*8d67ca89SAndroid Build Coastguard Worker 
TEST_F(pthread_CondWakeupTest,signal_clockwait_realtime_monotonic)1689*8d67ca89SAndroid Build Coastguard Worker TEST_F(pthread_CondWakeupTest, signal_clockwait_realtime_monotonic) {
1690*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
1691*8d67ca89SAndroid Build Coastguard Worker   InitCond(CLOCK_REALTIME);
1692*8d67ca89SAndroid Build Coastguard Worker   RunTimedTest(CLOCK_MONOTONIC, pthread_cond_clockwait);
1693*8d67ca89SAndroid Build Coastguard Worker #else   // __BIONIC__
1694*8d67ca89SAndroid Build Coastguard Worker   GTEST_SKIP() << "pthread_cond_clockwait not available";
1695*8d67ca89SAndroid Build Coastguard Worker #endif  // __BIONIC__
1696*8d67ca89SAndroid Build Coastguard Worker }
1697*8d67ca89SAndroid Build Coastguard Worker 
TEST_F(pthread_CondWakeupTest,signal_clockwait_realtime_realtime)1698*8d67ca89SAndroid Build Coastguard Worker TEST_F(pthread_CondWakeupTest, signal_clockwait_realtime_realtime) {
1699*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
1700*8d67ca89SAndroid Build Coastguard Worker   InitCond(CLOCK_REALTIME);
1701*8d67ca89SAndroid Build Coastguard Worker   RunTimedTest(CLOCK_REALTIME, pthread_cond_clockwait);
1702*8d67ca89SAndroid Build Coastguard Worker #else   // __BIONIC__
1703*8d67ca89SAndroid Build Coastguard Worker   GTEST_SKIP() << "pthread_cond_clockwait not available";
1704*8d67ca89SAndroid Build Coastguard Worker #endif  // __BIONIC__
1705*8d67ca89SAndroid Build Coastguard Worker }
1706*8d67ca89SAndroid Build Coastguard Worker 
pthread_cond_timedwait_timeout_helper(bool init_monotonic,clockid_t clock,int (* wait_function)(pthread_cond_t * __cond,pthread_mutex_t * __mutex,const timespec * __timeout))1707*8d67ca89SAndroid Build Coastguard Worker static void pthread_cond_timedwait_timeout_helper(bool init_monotonic, clockid_t clock,
1708*8d67ca89SAndroid Build Coastguard Worker                                                   int (*wait_function)(pthread_cond_t* __cond,
1709*8d67ca89SAndroid Build Coastguard Worker                                                                        pthread_mutex_t* __mutex,
1710*8d67ca89SAndroid Build Coastguard Worker                                                                        const timespec* __timeout)) {
1711*8d67ca89SAndroid Build Coastguard Worker   pthread_mutex_t mutex;
1712*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_mutex_init(&mutex, nullptr));
1713*8d67ca89SAndroid Build Coastguard Worker   pthread_cond_t cond;
1714*8d67ca89SAndroid Build Coastguard Worker 
1715*8d67ca89SAndroid Build Coastguard Worker   if (init_monotonic) {
1716*8d67ca89SAndroid Build Coastguard Worker     pthread_condattr_t attr;
1717*8d67ca89SAndroid Build Coastguard Worker     pthread_condattr_init(&attr);
1718*8d67ca89SAndroid Build Coastguard Worker 
1719*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_condattr_setclock(&attr, CLOCK_MONOTONIC));
1720*8d67ca89SAndroid Build Coastguard Worker     clockid_t clock;
1721*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_condattr_getclock(&attr, &clock));
1722*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(CLOCK_MONOTONIC, clock);
1723*8d67ca89SAndroid Build Coastguard Worker 
1724*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_cond_init(&cond, &attr));
1725*8d67ca89SAndroid Build Coastguard Worker   } else {
1726*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_cond_init(&cond, nullptr));
1727*8d67ca89SAndroid Build Coastguard Worker   }
1728*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_mutex_lock(&mutex));
1729*8d67ca89SAndroid Build Coastguard Worker 
1730*8d67ca89SAndroid Build Coastguard Worker   timespec ts;
1731*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, clock_gettime(clock, &ts));
1732*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(ETIMEDOUT, wait_function(&cond, &mutex, &ts));
1733*8d67ca89SAndroid Build Coastguard Worker   ts.tv_nsec = -1;
1734*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(EINVAL, wait_function(&cond, &mutex, &ts));
1735*8d67ca89SAndroid Build Coastguard Worker   ts.tv_nsec = NS_PER_S;
1736*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(EINVAL, wait_function(&cond, &mutex, &ts));
1737*8d67ca89SAndroid Build Coastguard Worker   ts.tv_nsec = NS_PER_S - 1;
1738*8d67ca89SAndroid Build Coastguard Worker   ts.tv_sec = -1;
1739*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(ETIMEDOUT, wait_function(&cond, &mutex, &ts));
1740*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_mutex_unlock(&mutex));
1741*8d67ca89SAndroid Build Coastguard Worker }
1742*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_cond_timedwait_timeout)1743*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_cond_timedwait_timeout) {
1744*8d67ca89SAndroid Build Coastguard Worker   pthread_cond_timedwait_timeout_helper(false, CLOCK_REALTIME, pthread_cond_timedwait);
1745*8d67ca89SAndroid Build Coastguard Worker }
1746*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_cond_timedwait_monotonic_np_timeout)1747*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_cond_timedwait_monotonic_np_timeout) {
1748*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
1749*8d67ca89SAndroid Build Coastguard Worker   pthread_cond_timedwait_timeout_helper(false, CLOCK_MONOTONIC, pthread_cond_timedwait_monotonic_np);
1750*8d67ca89SAndroid Build Coastguard Worker   pthread_cond_timedwait_timeout_helper(true, CLOCK_MONOTONIC, pthread_cond_timedwait_monotonic_np);
1751*8d67ca89SAndroid Build Coastguard Worker #else   // __BIONIC__
1752*8d67ca89SAndroid Build Coastguard Worker   GTEST_SKIP() << "pthread_cond_timedwait_monotonic_np not available";
1753*8d67ca89SAndroid Build Coastguard Worker #endif  // __BIONIC__
1754*8d67ca89SAndroid Build Coastguard Worker }
1755*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_cond_clockwait_timeout)1756*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_cond_clockwait_timeout) {
1757*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
1758*8d67ca89SAndroid Build Coastguard Worker   pthread_cond_timedwait_timeout_helper(
1759*8d67ca89SAndroid Build Coastguard Worker       false, CLOCK_MONOTONIC,
1760*8d67ca89SAndroid Build Coastguard Worker       [](pthread_cond_t* __cond, pthread_mutex_t* __mutex, const timespec* __timeout) {
1761*8d67ca89SAndroid Build Coastguard Worker         return pthread_cond_clockwait(__cond, __mutex, CLOCK_MONOTONIC, __timeout);
1762*8d67ca89SAndroid Build Coastguard Worker       });
1763*8d67ca89SAndroid Build Coastguard Worker   pthread_cond_timedwait_timeout_helper(
1764*8d67ca89SAndroid Build Coastguard Worker       true, CLOCK_MONOTONIC,
1765*8d67ca89SAndroid Build Coastguard Worker       [](pthread_cond_t* __cond, pthread_mutex_t* __mutex, const timespec* __timeout) {
1766*8d67ca89SAndroid Build Coastguard Worker         return pthread_cond_clockwait(__cond, __mutex, CLOCK_MONOTONIC, __timeout);
1767*8d67ca89SAndroid Build Coastguard Worker       });
1768*8d67ca89SAndroid Build Coastguard Worker   pthread_cond_timedwait_timeout_helper(
1769*8d67ca89SAndroid Build Coastguard Worker       false, CLOCK_REALTIME,
1770*8d67ca89SAndroid Build Coastguard Worker       [](pthread_cond_t* __cond, pthread_mutex_t* __mutex, const timespec* __timeout) {
1771*8d67ca89SAndroid Build Coastguard Worker         return pthread_cond_clockwait(__cond, __mutex, CLOCK_REALTIME, __timeout);
1772*8d67ca89SAndroid Build Coastguard Worker       });
1773*8d67ca89SAndroid Build Coastguard Worker   pthread_cond_timedwait_timeout_helper(
1774*8d67ca89SAndroid Build Coastguard Worker       true, CLOCK_REALTIME,
1775*8d67ca89SAndroid Build Coastguard Worker       [](pthread_cond_t* __cond, pthread_mutex_t* __mutex, const timespec* __timeout) {
1776*8d67ca89SAndroid Build Coastguard Worker         return pthread_cond_clockwait(__cond, __mutex, CLOCK_REALTIME, __timeout);
1777*8d67ca89SAndroid Build Coastguard Worker       });
1778*8d67ca89SAndroid Build Coastguard Worker #else   // __BIONIC__
1779*8d67ca89SAndroid Build Coastguard Worker   GTEST_SKIP() << "pthread_cond_clockwait not available";
1780*8d67ca89SAndroid Build Coastguard Worker #endif  // __BIONIC__
1781*8d67ca89SAndroid Build Coastguard Worker }
1782*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_cond_clockwait_invalid)1783*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_cond_clockwait_invalid) {
1784*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
1785*8d67ca89SAndroid Build Coastguard Worker   pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
1786*8d67ca89SAndroid Build Coastguard Worker   pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
1787*8d67ca89SAndroid Build Coastguard Worker   timespec ts;
1788*8d67ca89SAndroid Build Coastguard Worker   EXPECT_EQ(EINVAL, pthread_cond_clockwait(&cond, &mutex, CLOCK_PROCESS_CPUTIME_ID, &ts));
1789*8d67ca89SAndroid Build Coastguard Worker 
1790*8d67ca89SAndroid Build Coastguard Worker #else   // __BIONIC__
1791*8d67ca89SAndroid Build Coastguard Worker   GTEST_SKIP() << "pthread_cond_clockwait not available";
1792*8d67ca89SAndroid Build Coastguard Worker #endif  // __BIONIC__
1793*8d67ca89SAndroid Build Coastguard Worker }
1794*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_attr_getstack__main_thread)1795*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_attr_getstack__main_thread) {
1796*8d67ca89SAndroid Build Coastguard Worker   // This test is only meaningful for the main thread, so make sure we're running on it!
1797*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(getpid(), syscall(__NR_gettid));
1798*8d67ca89SAndroid Build Coastguard Worker 
1799*8d67ca89SAndroid Build Coastguard Worker   // Get the main thread's attributes.
1800*8d67ca89SAndroid Build Coastguard Worker   pthread_attr_t attributes;
1801*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_getattr_np(pthread_self(), &attributes));
1802*8d67ca89SAndroid Build Coastguard Worker 
1803*8d67ca89SAndroid Build Coastguard Worker   // Check that we correctly report that the main thread has no guard page.
1804*8d67ca89SAndroid Build Coastguard Worker   size_t guard_size;
1805*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_getguardsize(&attributes, &guard_size));
1806*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0U, guard_size); // The main thread has no guard page.
1807*8d67ca89SAndroid Build Coastguard Worker 
1808*8d67ca89SAndroid Build Coastguard Worker   // Get the stack base and the stack size (both ways).
1809*8d67ca89SAndroid Build Coastguard Worker   void* stack_base;
1810*8d67ca89SAndroid Build Coastguard Worker   size_t stack_size;
1811*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_getstack(&attributes, &stack_base, &stack_size));
1812*8d67ca89SAndroid Build Coastguard Worker   size_t stack_size2;
1813*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &stack_size2));
1814*8d67ca89SAndroid Build Coastguard Worker 
1815*8d67ca89SAndroid Build Coastguard Worker   // The two methods of asking for the stack size should agree.
1816*8d67ca89SAndroid Build Coastguard Worker   EXPECT_EQ(stack_size, stack_size2);
1817*8d67ca89SAndroid Build Coastguard Worker 
1818*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
1819*8d67ca89SAndroid Build Coastguard Worker   // Find stack in /proc/self/maps using a pointer to the stack.
1820*8d67ca89SAndroid Build Coastguard Worker   //
1821*8d67ca89SAndroid Build Coastguard Worker   // We do not use "[stack]" label because in native-bridge environment it is not
1822*8d67ca89SAndroid Build Coastguard Worker   // guaranteed to point to the right stack. A native bridge implementation may
1823*8d67ca89SAndroid Build Coastguard Worker   // keep separate stack for the guest code.
1824*8d67ca89SAndroid Build Coastguard Worker   void* maps_stack_hi = nullptr;
1825*8d67ca89SAndroid Build Coastguard Worker   std::vector<map_record> maps;
1826*8d67ca89SAndroid Build Coastguard Worker   ASSERT_TRUE(Maps::parse_maps(&maps));
1827*8d67ca89SAndroid Build Coastguard Worker   uintptr_t stack_address = reinterpret_cast<uintptr_t>(untag_address(&maps_stack_hi));
1828*8d67ca89SAndroid Build Coastguard Worker   for (const auto& map : maps) {
1829*8d67ca89SAndroid Build Coastguard Worker     if (map.addr_start <= stack_address && map.addr_end > stack_address){
1830*8d67ca89SAndroid Build Coastguard Worker       maps_stack_hi = reinterpret_cast<void*>(map.addr_end);
1831*8d67ca89SAndroid Build Coastguard Worker       break;
1832*8d67ca89SAndroid Build Coastguard Worker     }
1833*8d67ca89SAndroid Build Coastguard Worker   }
1834*8d67ca89SAndroid Build Coastguard Worker 
1835*8d67ca89SAndroid Build Coastguard Worker   // The high address of the /proc/self/maps stack region should equal stack_base + stack_size.
1836*8d67ca89SAndroid Build Coastguard Worker   // Remember that the stack grows down (and is mapped in on demand), so the low address of the
1837*8d67ca89SAndroid Build Coastguard Worker   // region isn't very interesting.
1838*8d67ca89SAndroid Build Coastguard Worker   EXPECT_EQ(maps_stack_hi, reinterpret_cast<uint8_t*>(stack_base) + stack_size);
1839*8d67ca89SAndroid Build Coastguard Worker 
1840*8d67ca89SAndroid Build Coastguard Worker   // The stack size should correspond to RLIMIT_STACK.
1841*8d67ca89SAndroid Build Coastguard Worker   rlimit rl;
1842*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, getrlimit(RLIMIT_STACK, &rl));
1843*8d67ca89SAndroid Build Coastguard Worker   uint64_t original_rlim_cur = rl.rlim_cur;
1844*8d67ca89SAndroid Build Coastguard Worker   if (rl.rlim_cur == RLIM_INFINITY) {
1845*8d67ca89SAndroid Build Coastguard Worker     rl.rlim_cur = 8 * 1024 * 1024; // Bionic reports unlimited stacks as 8MiB.
1846*8d67ca89SAndroid Build Coastguard Worker   }
1847*8d67ca89SAndroid Build Coastguard Worker   EXPECT_EQ(rl.rlim_cur, stack_size);
1848*8d67ca89SAndroid Build Coastguard Worker 
1849*8d67ca89SAndroid Build Coastguard Worker   auto guard = android::base::make_scope_guard([&rl, original_rlim_cur]() {
1850*8d67ca89SAndroid Build Coastguard Worker     rl.rlim_cur = original_rlim_cur;
1851*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, setrlimit(RLIMIT_STACK, &rl));
1852*8d67ca89SAndroid Build Coastguard Worker   });
1853*8d67ca89SAndroid Build Coastguard Worker 
1854*8d67ca89SAndroid Build Coastguard Worker   //
1855*8d67ca89SAndroid Build Coastguard Worker   // What if RLIMIT_STACK is smaller than the stack's current extent?
1856*8d67ca89SAndroid Build Coastguard Worker   //
1857*8d67ca89SAndroid Build Coastguard Worker   rl.rlim_cur = rl.rlim_max = 1024; // 1KiB. We know the stack must be at least a page already.
1858*8d67ca89SAndroid Build Coastguard Worker   rl.rlim_max = RLIM_INFINITY;
1859*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, setrlimit(RLIMIT_STACK, &rl));
1860*8d67ca89SAndroid Build Coastguard Worker 
1861*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_getattr_np(pthread_self(), &attributes));
1862*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_getstack(&attributes, &stack_base, &stack_size));
1863*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &stack_size2));
1864*8d67ca89SAndroid Build Coastguard Worker 
1865*8d67ca89SAndroid Build Coastguard Worker   EXPECT_EQ(stack_size, stack_size2);
1866*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(1024U, stack_size);
1867*8d67ca89SAndroid Build Coastguard Worker 
1868*8d67ca89SAndroid Build Coastguard Worker   //
1869*8d67ca89SAndroid Build Coastguard Worker   // What if RLIMIT_STACK isn't a whole number of pages?
1870*8d67ca89SAndroid Build Coastguard Worker   //
1871*8d67ca89SAndroid Build Coastguard Worker   rl.rlim_cur = rl.rlim_max = 6666; // Not a whole number of pages.
1872*8d67ca89SAndroid Build Coastguard Worker   rl.rlim_max = RLIM_INFINITY;
1873*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, setrlimit(RLIMIT_STACK, &rl));
1874*8d67ca89SAndroid Build Coastguard Worker 
1875*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_getattr_np(pthread_self(), &attributes));
1876*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_getstack(&attributes, &stack_base, &stack_size));
1877*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &stack_size2));
1878*8d67ca89SAndroid Build Coastguard Worker 
1879*8d67ca89SAndroid Build Coastguard Worker   EXPECT_EQ(stack_size, stack_size2);
1880*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(6666U, stack_size);
1881*8d67ca89SAndroid Build Coastguard Worker #endif
1882*8d67ca89SAndroid Build Coastguard Worker }
1883*8d67ca89SAndroid Build Coastguard Worker 
1884*8d67ca89SAndroid Build Coastguard Worker struct GetStackSignalHandlerArg {
1885*8d67ca89SAndroid Build Coastguard Worker   volatile bool done;
1886*8d67ca89SAndroid Build Coastguard Worker   void* signal_stack_base;
1887*8d67ca89SAndroid Build Coastguard Worker   size_t signal_stack_size;
1888*8d67ca89SAndroid Build Coastguard Worker   void* main_stack_base;
1889*8d67ca89SAndroid Build Coastguard Worker   size_t main_stack_size;
1890*8d67ca89SAndroid Build Coastguard Worker };
1891*8d67ca89SAndroid Build Coastguard Worker 
1892*8d67ca89SAndroid Build Coastguard Worker static GetStackSignalHandlerArg getstack_signal_handler_arg;
1893*8d67ca89SAndroid Build Coastguard Worker 
getstack_signal_handler(int sig)1894*8d67ca89SAndroid Build Coastguard Worker static void getstack_signal_handler(int sig) {
1895*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(SIGUSR1, sig);
1896*8d67ca89SAndroid Build Coastguard Worker   // Use sleep() to make current thread be switched out by the kernel to provoke the error.
1897*8d67ca89SAndroid Build Coastguard Worker   sleep(1);
1898*8d67ca89SAndroid Build Coastguard Worker   pthread_attr_t attr;
1899*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_getattr_np(pthread_self(), &attr));
1900*8d67ca89SAndroid Build Coastguard Worker   void* stack_base;
1901*8d67ca89SAndroid Build Coastguard Worker   size_t stack_size;
1902*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_getstack(&attr, &stack_base, &stack_size));
1903*8d67ca89SAndroid Build Coastguard Worker 
1904*8d67ca89SAndroid Build Coastguard Worker   // Verify if the stack used by the signal handler is the alternate stack just registered.
1905*8d67ca89SAndroid Build Coastguard Worker   ASSERT_LE(getstack_signal_handler_arg.signal_stack_base, &attr);
1906*8d67ca89SAndroid Build Coastguard Worker   ASSERT_LT(static_cast<void*>(untag_address(&attr)),
1907*8d67ca89SAndroid Build Coastguard Worker             static_cast<char*>(getstack_signal_handler_arg.signal_stack_base) +
1908*8d67ca89SAndroid Build Coastguard Worker                 getstack_signal_handler_arg.signal_stack_size);
1909*8d67ca89SAndroid Build Coastguard Worker 
1910*8d67ca89SAndroid Build Coastguard Worker   // Verify if the main thread's stack got in the signal handler is correct.
1911*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(getstack_signal_handler_arg.main_stack_base, stack_base);
1912*8d67ca89SAndroid Build Coastguard Worker   ASSERT_LE(getstack_signal_handler_arg.main_stack_size, stack_size);
1913*8d67ca89SAndroid Build Coastguard Worker 
1914*8d67ca89SAndroid Build Coastguard Worker   getstack_signal_handler_arg.done = true;
1915*8d67ca89SAndroid Build Coastguard Worker }
1916*8d67ca89SAndroid Build Coastguard Worker 
1917*8d67ca89SAndroid Build Coastguard Worker // The previous code obtained the main thread's stack by reading the entry in
1918*8d67ca89SAndroid Build Coastguard Worker // /proc/self/task/<pid>/maps that was labeled [stack]. Unfortunately, on x86/x86_64, the kernel
1919*8d67ca89SAndroid Build Coastguard Worker // relies on sp0 in task state segment(tss) to label the stack map with [stack]. If the kernel
1920*8d67ca89SAndroid Build Coastguard Worker // switches a process while the main thread is in an alternate stack, then the kernel will label
1921*8d67ca89SAndroid Build Coastguard Worker // the wrong map with [stack]. This test verifies that when the above situation happens, the main
1922*8d67ca89SAndroid Build Coastguard Worker // thread's stack is found correctly.
TEST(pthread,pthread_attr_getstack_in_signal_handler)1923*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_attr_getstack_in_signal_handler) {
1924*8d67ca89SAndroid Build Coastguard Worker   // This test is only meaningful for the main thread, so make sure we're running on it!
1925*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(getpid(), syscall(__NR_gettid));
1926*8d67ca89SAndroid Build Coastguard Worker 
1927*8d67ca89SAndroid Build Coastguard Worker   const size_t sig_stack_size = 16 * 1024;
1928*8d67ca89SAndroid Build Coastguard Worker   void* sig_stack = mmap(nullptr, sig_stack_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS,
1929*8d67ca89SAndroid Build Coastguard Worker                          -1, 0);
1930*8d67ca89SAndroid Build Coastguard Worker   ASSERT_NE(MAP_FAILED, sig_stack);
1931*8d67ca89SAndroid Build Coastguard Worker   stack_t ss;
1932*8d67ca89SAndroid Build Coastguard Worker   ss.ss_sp = sig_stack;
1933*8d67ca89SAndroid Build Coastguard Worker   ss.ss_size = sig_stack_size;
1934*8d67ca89SAndroid Build Coastguard Worker   ss.ss_flags = 0;
1935*8d67ca89SAndroid Build Coastguard Worker   stack_t oss;
1936*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, sigaltstack(&ss, &oss));
1937*8d67ca89SAndroid Build Coastguard Worker 
1938*8d67ca89SAndroid Build Coastguard Worker   pthread_attr_t attr;
1939*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_getattr_np(pthread_self(), &attr));
1940*8d67ca89SAndroid Build Coastguard Worker   void* main_stack_base;
1941*8d67ca89SAndroid Build Coastguard Worker   size_t main_stack_size;
1942*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_getstack(&attr, &main_stack_base, &main_stack_size));
1943*8d67ca89SAndroid Build Coastguard Worker 
1944*8d67ca89SAndroid Build Coastguard Worker   ScopedSignalHandler handler(SIGUSR1, getstack_signal_handler, SA_ONSTACK);
1945*8d67ca89SAndroid Build Coastguard Worker   getstack_signal_handler_arg.done = false;
1946*8d67ca89SAndroid Build Coastguard Worker   getstack_signal_handler_arg.signal_stack_base = sig_stack;
1947*8d67ca89SAndroid Build Coastguard Worker   getstack_signal_handler_arg.signal_stack_size = sig_stack_size;
1948*8d67ca89SAndroid Build Coastguard Worker   getstack_signal_handler_arg.main_stack_base = main_stack_base;
1949*8d67ca89SAndroid Build Coastguard Worker   getstack_signal_handler_arg.main_stack_size = main_stack_size;
1950*8d67ca89SAndroid Build Coastguard Worker   kill(getpid(), SIGUSR1);
1951*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(true, getstack_signal_handler_arg.done);
1952*8d67ca89SAndroid Build Coastguard Worker 
1953*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, sigaltstack(&oss, nullptr));
1954*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, munmap(sig_stack, sig_stack_size));
1955*8d67ca89SAndroid Build Coastguard Worker }
1956*8d67ca89SAndroid Build Coastguard Worker 
pthread_attr_getstack_18908062_helper(void *)1957*8d67ca89SAndroid Build Coastguard Worker static void pthread_attr_getstack_18908062_helper(void*) {
1958*8d67ca89SAndroid Build Coastguard Worker   char local_variable;
1959*8d67ca89SAndroid Build Coastguard Worker   pthread_attr_t attributes;
1960*8d67ca89SAndroid Build Coastguard Worker   pthread_getattr_np(pthread_self(), &attributes);
1961*8d67ca89SAndroid Build Coastguard Worker   void* stack_base;
1962*8d67ca89SAndroid Build Coastguard Worker   size_t stack_size;
1963*8d67ca89SAndroid Build Coastguard Worker   pthread_attr_getstack(&attributes, &stack_base, &stack_size);
1964*8d67ca89SAndroid Build Coastguard Worker 
1965*8d67ca89SAndroid Build Coastguard Worker   // Test whether &local_variable is in [stack_base, stack_base + stack_size).
1966*8d67ca89SAndroid Build Coastguard Worker   ASSERT_LE(reinterpret_cast<char*>(stack_base), &local_variable);
1967*8d67ca89SAndroid Build Coastguard Worker   ASSERT_LT(untag_address(&local_variable), reinterpret_cast<char*>(stack_base) + stack_size);
1968*8d67ca89SAndroid Build Coastguard Worker }
1969*8d67ca89SAndroid Build Coastguard Worker 
1970*8d67ca89SAndroid Build Coastguard Worker // Check whether something on stack is in the range of
1971*8d67ca89SAndroid Build Coastguard Worker // [stack_base, stack_base + stack_size). see b/18908062.
TEST(pthread,pthread_attr_getstack_18908062)1972*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_attr_getstack_18908062) {
1973*8d67ca89SAndroid Build Coastguard Worker   pthread_t t;
1974*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_create(&t, nullptr,
1975*8d67ca89SAndroid Build Coastguard Worker             reinterpret_cast<void* (*)(void*)>(pthread_attr_getstack_18908062_helper),
1976*8d67ca89SAndroid Build Coastguard Worker             nullptr));
1977*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_join(t, nullptr));
1978*8d67ca89SAndroid Build Coastguard Worker }
1979*8d67ca89SAndroid Build Coastguard Worker 
1980*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
1981*8d67ca89SAndroid Build Coastguard Worker static pthread_mutex_t pthread_gettid_np_mutex = PTHREAD_MUTEX_INITIALIZER;
1982*8d67ca89SAndroid Build Coastguard Worker 
pthread_gettid_np_helper(void * arg)1983*8d67ca89SAndroid Build Coastguard Worker static void* pthread_gettid_np_helper(void* arg) {
1984*8d67ca89SAndroid Build Coastguard Worker   *reinterpret_cast<pid_t*>(arg) = gettid();
1985*8d67ca89SAndroid Build Coastguard Worker 
1986*8d67ca89SAndroid Build Coastguard Worker   // Wait for our parent to call pthread_gettid_np on us before exiting.
1987*8d67ca89SAndroid Build Coastguard Worker   pthread_mutex_lock(&pthread_gettid_np_mutex);
1988*8d67ca89SAndroid Build Coastguard Worker   pthread_mutex_unlock(&pthread_gettid_np_mutex);
1989*8d67ca89SAndroid Build Coastguard Worker   return nullptr;
1990*8d67ca89SAndroid Build Coastguard Worker }
1991*8d67ca89SAndroid Build Coastguard Worker #endif
1992*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_gettid_np)1993*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_gettid_np) {
1994*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
1995*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(gettid(), pthread_gettid_np(pthread_self()));
1996*8d67ca89SAndroid Build Coastguard Worker 
1997*8d67ca89SAndroid Build Coastguard Worker   // Ensure the other thread doesn't exit until after we've called
1998*8d67ca89SAndroid Build Coastguard Worker   // pthread_gettid_np on it.
1999*8d67ca89SAndroid Build Coastguard Worker   pthread_mutex_lock(&pthread_gettid_np_mutex);
2000*8d67ca89SAndroid Build Coastguard Worker 
2001*8d67ca89SAndroid Build Coastguard Worker   pid_t t_gettid_result;
2002*8d67ca89SAndroid Build Coastguard Worker   pthread_t t;
2003*8d67ca89SAndroid Build Coastguard Worker   pthread_create(&t, nullptr, pthread_gettid_np_helper, &t_gettid_result);
2004*8d67ca89SAndroid Build Coastguard Worker 
2005*8d67ca89SAndroid Build Coastguard Worker   pid_t t_pthread_gettid_np_result = pthread_gettid_np(t);
2006*8d67ca89SAndroid Build Coastguard Worker 
2007*8d67ca89SAndroid Build Coastguard Worker   // Release the other thread and wait for it to exit.
2008*8d67ca89SAndroid Build Coastguard Worker   pthread_mutex_unlock(&pthread_gettid_np_mutex);
2009*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_join(t, nullptr));
2010*8d67ca89SAndroid Build Coastguard Worker 
2011*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(t_gettid_result, t_pthread_gettid_np_result);
2012*8d67ca89SAndroid Build Coastguard Worker #else
2013*8d67ca89SAndroid Build Coastguard Worker   GTEST_SKIP() << "pthread_gettid_np not available";
2014*8d67ca89SAndroid Build Coastguard Worker #endif
2015*8d67ca89SAndroid Build Coastguard Worker }
2016*8d67ca89SAndroid Build Coastguard Worker 
2017*8d67ca89SAndroid Build Coastguard Worker static size_t cleanup_counter = 0;
2018*8d67ca89SAndroid Build Coastguard Worker 
AbortCleanupRoutine(void *)2019*8d67ca89SAndroid Build Coastguard Worker static void AbortCleanupRoutine(void*) {
2020*8d67ca89SAndroid Build Coastguard Worker   abort();
2021*8d67ca89SAndroid Build Coastguard Worker }
2022*8d67ca89SAndroid Build Coastguard Worker 
CountCleanupRoutine(void *)2023*8d67ca89SAndroid Build Coastguard Worker static void CountCleanupRoutine(void*) {
2024*8d67ca89SAndroid Build Coastguard Worker   ++cleanup_counter;
2025*8d67ca89SAndroid Build Coastguard Worker }
2026*8d67ca89SAndroid Build Coastguard Worker 
PthreadCleanupTester()2027*8d67ca89SAndroid Build Coastguard Worker static void PthreadCleanupTester() {
2028*8d67ca89SAndroid Build Coastguard Worker   pthread_cleanup_push(CountCleanupRoutine, nullptr);
2029*8d67ca89SAndroid Build Coastguard Worker   pthread_cleanup_push(CountCleanupRoutine, nullptr);
2030*8d67ca89SAndroid Build Coastguard Worker   pthread_cleanup_push(AbortCleanupRoutine, nullptr);
2031*8d67ca89SAndroid Build Coastguard Worker 
2032*8d67ca89SAndroid Build Coastguard Worker   pthread_cleanup_pop(0); // Pop the abort without executing it.
2033*8d67ca89SAndroid Build Coastguard Worker   pthread_cleanup_pop(1); // Pop one count while executing it.
2034*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(1U, cleanup_counter);
2035*8d67ca89SAndroid Build Coastguard Worker   // Exit while the other count is still on the cleanup stack.
2036*8d67ca89SAndroid Build Coastguard Worker   pthread_exit(nullptr);
2037*8d67ca89SAndroid Build Coastguard Worker 
2038*8d67ca89SAndroid Build Coastguard Worker   // Calls to pthread_cleanup_pop/pthread_cleanup_push must always be balanced.
2039*8d67ca89SAndroid Build Coastguard Worker   pthread_cleanup_pop(0);
2040*8d67ca89SAndroid Build Coastguard Worker }
2041*8d67ca89SAndroid Build Coastguard Worker 
PthreadCleanupStartRoutine(void *)2042*8d67ca89SAndroid Build Coastguard Worker static void* PthreadCleanupStartRoutine(void*) {
2043*8d67ca89SAndroid Build Coastguard Worker   PthreadCleanupTester();
2044*8d67ca89SAndroid Build Coastguard Worker   return nullptr;
2045*8d67ca89SAndroid Build Coastguard Worker }
2046*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_cleanup_push__pthread_cleanup_pop)2047*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_cleanup_push__pthread_cleanup_pop) {
2048*8d67ca89SAndroid Build Coastguard Worker   pthread_t t;
2049*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_create(&t, nullptr, PthreadCleanupStartRoutine, nullptr));
2050*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_join(t, nullptr));
2051*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(2U, cleanup_counter);
2052*8d67ca89SAndroid Build Coastguard Worker }
2053*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,PTHREAD_MUTEX_DEFAULT_is_PTHREAD_MUTEX_NORMAL)2054*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, PTHREAD_MUTEX_DEFAULT_is_PTHREAD_MUTEX_NORMAL) {
2055*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(PTHREAD_MUTEX_NORMAL, PTHREAD_MUTEX_DEFAULT);
2056*8d67ca89SAndroid Build Coastguard Worker }
2057*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_mutexattr_gettype)2058*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_mutexattr_gettype) {
2059*8d67ca89SAndroid Build Coastguard Worker   pthread_mutexattr_t attr;
2060*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_mutexattr_init(&attr));
2061*8d67ca89SAndroid Build Coastguard Worker 
2062*8d67ca89SAndroid Build Coastguard Worker   int attr_type;
2063*8d67ca89SAndroid Build Coastguard Worker 
2064*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL));
2065*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_mutexattr_gettype(&attr, &attr_type));
2066*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(PTHREAD_MUTEX_NORMAL, attr_type);
2067*8d67ca89SAndroid Build Coastguard Worker 
2068*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK));
2069*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_mutexattr_gettype(&attr, &attr_type));
2070*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(PTHREAD_MUTEX_ERRORCHECK, attr_type);
2071*8d67ca89SAndroid Build Coastguard Worker 
2072*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE));
2073*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_mutexattr_gettype(&attr, &attr_type));
2074*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(PTHREAD_MUTEX_RECURSIVE, attr_type);
2075*8d67ca89SAndroid Build Coastguard Worker 
2076*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_mutexattr_destroy(&attr));
2077*8d67ca89SAndroid Build Coastguard Worker }
2078*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_mutexattr_protocol)2079*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_mutexattr_protocol) {
2080*8d67ca89SAndroid Build Coastguard Worker   pthread_mutexattr_t attr;
2081*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_mutexattr_init(&attr));
2082*8d67ca89SAndroid Build Coastguard Worker 
2083*8d67ca89SAndroid Build Coastguard Worker   int protocol;
2084*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_mutexattr_getprotocol(&attr, &protocol));
2085*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(PTHREAD_PRIO_NONE, protocol);
2086*8d67ca89SAndroid Build Coastguard Worker   for (size_t repeat = 0; repeat < 2; ++repeat) {
2087*8d67ca89SAndroid Build Coastguard Worker     for (int set_protocol : {PTHREAD_PRIO_NONE, PTHREAD_PRIO_INHERIT}) {
2088*8d67ca89SAndroid Build Coastguard Worker       ASSERT_EQ(0, pthread_mutexattr_setprotocol(&attr, set_protocol));
2089*8d67ca89SAndroid Build Coastguard Worker       ASSERT_EQ(0, pthread_mutexattr_getprotocol(&attr, &protocol));
2090*8d67ca89SAndroid Build Coastguard Worker       ASSERT_EQ(protocol, set_protocol);
2091*8d67ca89SAndroid Build Coastguard Worker     }
2092*8d67ca89SAndroid Build Coastguard Worker   }
2093*8d67ca89SAndroid Build Coastguard Worker }
2094*8d67ca89SAndroid Build Coastguard Worker 
2095*8d67ca89SAndroid Build Coastguard Worker struct PthreadMutex {
2096*8d67ca89SAndroid Build Coastguard Worker   pthread_mutex_t lock;
2097*8d67ca89SAndroid Build Coastguard Worker 
PthreadMutexPthreadMutex2098*8d67ca89SAndroid Build Coastguard Worker   explicit PthreadMutex(int mutex_type, int protocol = PTHREAD_PRIO_NONE) {
2099*8d67ca89SAndroid Build Coastguard Worker     init(mutex_type, protocol);
2100*8d67ca89SAndroid Build Coastguard Worker   }
2101*8d67ca89SAndroid Build Coastguard Worker 
~PthreadMutexPthreadMutex2102*8d67ca89SAndroid Build Coastguard Worker   ~PthreadMutex() {
2103*8d67ca89SAndroid Build Coastguard Worker     destroy();
2104*8d67ca89SAndroid Build Coastguard Worker   }
2105*8d67ca89SAndroid Build Coastguard Worker 
2106*8d67ca89SAndroid Build Coastguard Worker  private:
initPthreadMutex2107*8d67ca89SAndroid Build Coastguard Worker   void init(int mutex_type, int protocol) {
2108*8d67ca89SAndroid Build Coastguard Worker     pthread_mutexattr_t attr;
2109*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_mutexattr_init(&attr));
2110*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_mutexattr_settype(&attr, mutex_type));
2111*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_mutexattr_setprotocol(&attr, protocol));
2112*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_mutex_init(&lock, &attr));
2113*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_mutexattr_destroy(&attr));
2114*8d67ca89SAndroid Build Coastguard Worker   }
2115*8d67ca89SAndroid Build Coastguard Worker 
destroyPthreadMutex2116*8d67ca89SAndroid Build Coastguard Worker   void destroy() {
2117*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_mutex_destroy(&lock));
2118*8d67ca89SAndroid Build Coastguard Worker   }
2119*8d67ca89SAndroid Build Coastguard Worker 
2120*8d67ca89SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(PthreadMutex);
2121*8d67ca89SAndroid Build Coastguard Worker };
2122*8d67ca89SAndroid Build Coastguard Worker 
UnlockFromAnotherThread(pthread_mutex_t * mutex)2123*8d67ca89SAndroid Build Coastguard Worker static int UnlockFromAnotherThread(pthread_mutex_t* mutex) {
2124*8d67ca89SAndroid Build Coastguard Worker   pthread_t thread;
2125*8d67ca89SAndroid Build Coastguard Worker   pthread_create(&thread, nullptr, [](void* mutex_voidp) -> void* {
2126*8d67ca89SAndroid Build Coastguard Worker     pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(mutex_voidp);
2127*8d67ca89SAndroid Build Coastguard Worker     intptr_t result = pthread_mutex_unlock(mutex);
2128*8d67ca89SAndroid Build Coastguard Worker     return reinterpret_cast<void*>(result);
2129*8d67ca89SAndroid Build Coastguard Worker   }, mutex);
2130*8d67ca89SAndroid Build Coastguard Worker   void* result;
2131*8d67ca89SAndroid Build Coastguard Worker   EXPECT_EQ(0, pthread_join(thread, &result));
2132*8d67ca89SAndroid Build Coastguard Worker   return reinterpret_cast<intptr_t>(result);
2133*8d67ca89SAndroid Build Coastguard Worker };
2134*8d67ca89SAndroid Build Coastguard Worker 
TestPthreadMutexLockNormal(int protocol)2135*8d67ca89SAndroid Build Coastguard Worker static void TestPthreadMutexLockNormal(int protocol) {
2136*8d67ca89SAndroid Build Coastguard Worker   PthreadMutex m(PTHREAD_MUTEX_NORMAL, protocol);
2137*8d67ca89SAndroid Build Coastguard Worker 
2138*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_mutex_lock(&m.lock));
2139*8d67ca89SAndroid Build Coastguard Worker   if (protocol == PTHREAD_PRIO_INHERIT) {
2140*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(EPERM, UnlockFromAnotherThread(&m.lock));
2141*8d67ca89SAndroid Build Coastguard Worker   }
2142*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_mutex_unlock(&m.lock));
2143*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_mutex_trylock(&m.lock));
2144*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(EBUSY, pthread_mutex_trylock(&m.lock));
2145*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_mutex_unlock(&m.lock));
2146*8d67ca89SAndroid Build Coastguard Worker }
2147*8d67ca89SAndroid Build Coastguard Worker 
TestPthreadMutexLockErrorCheck(int protocol)2148*8d67ca89SAndroid Build Coastguard Worker static void TestPthreadMutexLockErrorCheck(int protocol) {
2149*8d67ca89SAndroid Build Coastguard Worker   PthreadMutex m(PTHREAD_MUTEX_ERRORCHECK, protocol);
2150*8d67ca89SAndroid Build Coastguard Worker 
2151*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_mutex_lock(&m.lock));
2152*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(EPERM, UnlockFromAnotherThread(&m.lock));
2153*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(EDEADLK, pthread_mutex_lock(&m.lock));
2154*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_mutex_unlock(&m.lock));
2155*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_mutex_trylock(&m.lock));
2156*8d67ca89SAndroid Build Coastguard Worker   if (protocol == PTHREAD_PRIO_NONE) {
2157*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(EBUSY, pthread_mutex_trylock(&m.lock));
2158*8d67ca89SAndroid Build Coastguard Worker   } else {
2159*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(EDEADLK, pthread_mutex_trylock(&m.lock));
2160*8d67ca89SAndroid Build Coastguard Worker   }
2161*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_mutex_unlock(&m.lock));
2162*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(EPERM, pthread_mutex_unlock(&m.lock));
2163*8d67ca89SAndroid Build Coastguard Worker }
2164*8d67ca89SAndroid Build Coastguard Worker 
TestPthreadMutexLockRecursive(int protocol)2165*8d67ca89SAndroid Build Coastguard Worker static void TestPthreadMutexLockRecursive(int protocol) {
2166*8d67ca89SAndroid Build Coastguard Worker   PthreadMutex m(PTHREAD_MUTEX_RECURSIVE, protocol);
2167*8d67ca89SAndroid Build Coastguard Worker 
2168*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_mutex_lock(&m.lock));
2169*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(EPERM, UnlockFromAnotherThread(&m.lock));
2170*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_mutex_lock(&m.lock));
2171*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(EPERM, UnlockFromAnotherThread(&m.lock));
2172*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_mutex_unlock(&m.lock));
2173*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_mutex_unlock(&m.lock));
2174*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_mutex_trylock(&m.lock));
2175*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_mutex_trylock(&m.lock));
2176*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_mutex_unlock(&m.lock));
2177*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_mutex_unlock(&m.lock));
2178*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(EPERM, pthread_mutex_unlock(&m.lock));
2179*8d67ca89SAndroid Build Coastguard Worker }
2180*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_mutex_lock_NORMAL)2181*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_mutex_lock_NORMAL) {
2182*8d67ca89SAndroid Build Coastguard Worker   TestPthreadMutexLockNormal(PTHREAD_PRIO_NONE);
2183*8d67ca89SAndroid Build Coastguard Worker }
2184*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_mutex_lock_ERRORCHECK)2185*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_mutex_lock_ERRORCHECK) {
2186*8d67ca89SAndroid Build Coastguard Worker   TestPthreadMutexLockErrorCheck(PTHREAD_PRIO_NONE);
2187*8d67ca89SAndroid Build Coastguard Worker }
2188*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_mutex_lock_RECURSIVE)2189*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_mutex_lock_RECURSIVE) {
2190*8d67ca89SAndroid Build Coastguard Worker   TestPthreadMutexLockRecursive(PTHREAD_PRIO_NONE);
2191*8d67ca89SAndroid Build Coastguard Worker }
2192*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_mutex_lock_pi)2193*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_mutex_lock_pi) {
2194*8d67ca89SAndroid Build Coastguard Worker   TestPthreadMutexLockNormal(PTHREAD_PRIO_INHERIT);
2195*8d67ca89SAndroid Build Coastguard Worker   TestPthreadMutexLockErrorCheck(PTHREAD_PRIO_INHERIT);
2196*8d67ca89SAndroid Build Coastguard Worker   TestPthreadMutexLockRecursive(PTHREAD_PRIO_INHERIT);
2197*8d67ca89SAndroid Build Coastguard Worker }
2198*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_mutex_pi_count_limit)2199*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_mutex_pi_count_limit) {
2200*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__) && !defined(__LP64__)
2201*8d67ca89SAndroid Build Coastguard Worker   // Bionic only supports 65536 pi mutexes in 32-bit programs.
2202*8d67ca89SAndroid Build Coastguard Worker   pthread_mutexattr_t attr;
2203*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_mutexattr_init(&attr));
2204*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT));
2205*8d67ca89SAndroid Build Coastguard Worker   std::vector<pthread_mutex_t> mutexes(65536);
2206*8d67ca89SAndroid Build Coastguard Worker   // Test if we can use 65536 pi mutexes at the same time.
2207*8d67ca89SAndroid Build Coastguard Worker   // Run 2 times to check if freed pi mutexes can be recycled.
2208*8d67ca89SAndroid Build Coastguard Worker   for (int repeat = 0; repeat < 2; ++repeat) {
2209*8d67ca89SAndroid Build Coastguard Worker     for (auto& m : mutexes) {
2210*8d67ca89SAndroid Build Coastguard Worker       ASSERT_EQ(0, pthread_mutex_init(&m, &attr));
2211*8d67ca89SAndroid Build Coastguard Worker     }
2212*8d67ca89SAndroid Build Coastguard Worker     pthread_mutex_t m;
2213*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(ENOMEM, pthread_mutex_init(&m, &attr));
2214*8d67ca89SAndroid Build Coastguard Worker     for (auto& m : mutexes) {
2215*8d67ca89SAndroid Build Coastguard Worker       ASSERT_EQ(0, pthread_mutex_lock(&m));
2216*8d67ca89SAndroid Build Coastguard Worker     }
2217*8d67ca89SAndroid Build Coastguard Worker     for (auto& m : mutexes) {
2218*8d67ca89SAndroid Build Coastguard Worker       ASSERT_EQ(0, pthread_mutex_unlock(&m));
2219*8d67ca89SAndroid Build Coastguard Worker     }
2220*8d67ca89SAndroid Build Coastguard Worker     for (auto& m : mutexes) {
2221*8d67ca89SAndroid Build Coastguard Worker       ASSERT_EQ(0, pthread_mutex_destroy(&m));
2222*8d67ca89SAndroid Build Coastguard Worker     }
2223*8d67ca89SAndroid Build Coastguard Worker   }
2224*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_mutexattr_destroy(&attr));
2225*8d67ca89SAndroid Build Coastguard Worker #else
2226*8d67ca89SAndroid Build Coastguard Worker   GTEST_SKIP() << "pi mutex count not limited to 64Ki";
2227*8d67ca89SAndroid Build Coastguard Worker #endif
2228*8d67ca89SAndroid Build Coastguard Worker }
2229*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_mutex_init_same_as_static_initializers)2230*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_mutex_init_same_as_static_initializers) {
2231*8d67ca89SAndroid Build Coastguard Worker   pthread_mutex_t lock_normal = PTHREAD_MUTEX_INITIALIZER;
2232*8d67ca89SAndroid Build Coastguard Worker   PthreadMutex m1(PTHREAD_MUTEX_NORMAL);
2233*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, memcmp(&lock_normal, &m1.lock, sizeof(pthread_mutex_t)));
2234*8d67ca89SAndroid Build Coastguard Worker   pthread_mutex_destroy(&lock_normal);
2235*8d67ca89SAndroid Build Coastguard Worker 
2236*8d67ca89SAndroid Build Coastguard Worker #if !defined(ANDROID_HOST_MUSL)
2237*8d67ca89SAndroid Build Coastguard Worker   // musl doesn't support PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP or
2238*8d67ca89SAndroid Build Coastguard Worker   // PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP.
2239*8d67ca89SAndroid Build Coastguard Worker   pthread_mutex_t lock_errorcheck = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
2240*8d67ca89SAndroid Build Coastguard Worker   PthreadMutex m2(PTHREAD_MUTEX_ERRORCHECK);
2241*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, memcmp(&lock_errorcheck, &m2.lock, sizeof(pthread_mutex_t)));
2242*8d67ca89SAndroid Build Coastguard Worker   pthread_mutex_destroy(&lock_errorcheck);
2243*8d67ca89SAndroid Build Coastguard Worker 
2244*8d67ca89SAndroid Build Coastguard Worker   pthread_mutex_t lock_recursive = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
2245*8d67ca89SAndroid Build Coastguard Worker   PthreadMutex m3(PTHREAD_MUTEX_RECURSIVE);
2246*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, memcmp(&lock_recursive, &m3.lock, sizeof(pthread_mutex_t)));
2247*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_mutex_destroy(&lock_recursive));
2248*8d67ca89SAndroid Build Coastguard Worker #endif
2249*8d67ca89SAndroid Build Coastguard Worker }
2250*8d67ca89SAndroid Build Coastguard Worker 
2251*8d67ca89SAndroid Build Coastguard Worker class MutexWakeupHelper {
2252*8d67ca89SAndroid Build Coastguard Worker  private:
2253*8d67ca89SAndroid Build Coastguard Worker   PthreadMutex m;
2254*8d67ca89SAndroid Build Coastguard Worker   enum Progress {
2255*8d67ca89SAndroid Build Coastguard Worker     LOCK_INITIALIZED,
2256*8d67ca89SAndroid Build Coastguard Worker     LOCK_WAITING,
2257*8d67ca89SAndroid Build Coastguard Worker     LOCK_RELEASED,
2258*8d67ca89SAndroid Build Coastguard Worker     LOCK_ACCESSED
2259*8d67ca89SAndroid Build Coastguard Worker   };
2260*8d67ca89SAndroid Build Coastguard Worker   std::atomic<Progress> progress;
2261*8d67ca89SAndroid Build Coastguard Worker   std::atomic<pid_t> tid;
2262*8d67ca89SAndroid Build Coastguard Worker 
thread_fn(MutexWakeupHelper * helper)2263*8d67ca89SAndroid Build Coastguard Worker   static void thread_fn(MutexWakeupHelper* helper) {
2264*8d67ca89SAndroid Build Coastguard Worker     helper->tid = gettid();
2265*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(LOCK_INITIALIZED, helper->progress);
2266*8d67ca89SAndroid Build Coastguard Worker     helper->progress = LOCK_WAITING;
2267*8d67ca89SAndroid Build Coastguard Worker 
2268*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_mutex_lock(&helper->m.lock));
2269*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(LOCK_RELEASED, helper->progress);
2270*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_mutex_unlock(&helper->m.lock));
2271*8d67ca89SAndroid Build Coastguard Worker 
2272*8d67ca89SAndroid Build Coastguard Worker     helper->progress = LOCK_ACCESSED;
2273*8d67ca89SAndroid Build Coastguard Worker   }
2274*8d67ca89SAndroid Build Coastguard Worker 
2275*8d67ca89SAndroid Build Coastguard Worker  public:
MutexWakeupHelper(int mutex_type)2276*8d67ca89SAndroid Build Coastguard Worker   explicit MutexWakeupHelper(int mutex_type) : m(mutex_type) {
2277*8d67ca89SAndroid Build Coastguard Worker   }
2278*8d67ca89SAndroid Build Coastguard Worker 
test()2279*8d67ca89SAndroid Build Coastguard Worker   void test() {
2280*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_mutex_lock(&m.lock));
2281*8d67ca89SAndroid Build Coastguard Worker     progress = LOCK_INITIALIZED;
2282*8d67ca89SAndroid Build Coastguard Worker     tid = 0;
2283*8d67ca89SAndroid Build Coastguard Worker 
2284*8d67ca89SAndroid Build Coastguard Worker     pthread_t thread;
2285*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_create(&thread, nullptr,
2286*8d67ca89SAndroid Build Coastguard Worker       reinterpret_cast<void* (*)(void*)>(MutexWakeupHelper::thread_fn), this));
2287*8d67ca89SAndroid Build Coastguard Worker 
2288*8d67ca89SAndroid Build Coastguard Worker     WaitUntilThreadSleep(tid);
2289*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(LOCK_WAITING, progress);
2290*8d67ca89SAndroid Build Coastguard Worker 
2291*8d67ca89SAndroid Build Coastguard Worker     progress = LOCK_RELEASED;
2292*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_mutex_unlock(&m.lock));
2293*8d67ca89SAndroid Build Coastguard Worker 
2294*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_join(thread, nullptr));
2295*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(LOCK_ACCESSED, progress);
2296*8d67ca89SAndroid Build Coastguard Worker   }
2297*8d67ca89SAndroid Build Coastguard Worker };
2298*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_mutex_NORMAL_wakeup)2299*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_mutex_NORMAL_wakeup) {
2300*8d67ca89SAndroid Build Coastguard Worker   MutexWakeupHelper helper(PTHREAD_MUTEX_NORMAL);
2301*8d67ca89SAndroid Build Coastguard Worker   helper.test();
2302*8d67ca89SAndroid Build Coastguard Worker }
2303*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_mutex_ERRORCHECK_wakeup)2304*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_mutex_ERRORCHECK_wakeup) {
2305*8d67ca89SAndroid Build Coastguard Worker   MutexWakeupHelper helper(PTHREAD_MUTEX_ERRORCHECK);
2306*8d67ca89SAndroid Build Coastguard Worker   helper.test();
2307*8d67ca89SAndroid Build Coastguard Worker }
2308*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_mutex_RECURSIVE_wakeup)2309*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_mutex_RECURSIVE_wakeup) {
2310*8d67ca89SAndroid Build Coastguard Worker   MutexWakeupHelper helper(PTHREAD_MUTEX_RECURSIVE);
2311*8d67ca89SAndroid Build Coastguard Worker   helper.test();
2312*8d67ca89SAndroid Build Coastguard Worker }
2313*8d67ca89SAndroid Build Coastguard Worker 
GetThreadPriority(pid_t tid)2314*8d67ca89SAndroid Build Coastguard Worker static int GetThreadPriority(pid_t tid) {
2315*8d67ca89SAndroid Build Coastguard Worker   // sched_getparam() returns the static priority of a thread, which can't reflect a thread's
2316*8d67ca89SAndroid Build Coastguard Worker   // priority after priority inheritance. So read /proc/<pid>/stat to get the dynamic priority.
2317*8d67ca89SAndroid Build Coastguard Worker   std::string filename = android::base::StringPrintf("/proc/%d/stat", tid);
2318*8d67ca89SAndroid Build Coastguard Worker   std::string content;
2319*8d67ca89SAndroid Build Coastguard Worker   int result = INT_MAX;
2320*8d67ca89SAndroid Build Coastguard Worker   if (!android::base::ReadFileToString(filename, &content)) {
2321*8d67ca89SAndroid Build Coastguard Worker     return result;
2322*8d67ca89SAndroid Build Coastguard Worker   }
2323*8d67ca89SAndroid Build Coastguard Worker   std::vector<std::string> strs = android::base::Split(content, " ");
2324*8d67ca89SAndroid Build Coastguard Worker   if (strs.size() < 18) {
2325*8d67ca89SAndroid Build Coastguard Worker     return result;
2326*8d67ca89SAndroid Build Coastguard Worker   }
2327*8d67ca89SAndroid Build Coastguard Worker   if (!android::base::ParseInt(strs[17], &result)) {
2328*8d67ca89SAndroid Build Coastguard Worker     return INT_MAX;
2329*8d67ca89SAndroid Build Coastguard Worker   }
2330*8d67ca89SAndroid Build Coastguard Worker   return result;
2331*8d67ca89SAndroid Build Coastguard Worker }
2332*8d67ca89SAndroid Build Coastguard Worker 
2333*8d67ca89SAndroid Build Coastguard Worker class PIMutexWakeupHelper {
2334*8d67ca89SAndroid Build Coastguard Worker private:
2335*8d67ca89SAndroid Build Coastguard Worker   PthreadMutex m;
2336*8d67ca89SAndroid Build Coastguard Worker   int protocol;
2337*8d67ca89SAndroid Build Coastguard Worker   enum Progress {
2338*8d67ca89SAndroid Build Coastguard Worker     LOCK_INITIALIZED,
2339*8d67ca89SAndroid Build Coastguard Worker     LOCK_CHILD_READY,
2340*8d67ca89SAndroid Build Coastguard Worker     LOCK_WAITING,
2341*8d67ca89SAndroid Build Coastguard Worker     LOCK_RELEASED,
2342*8d67ca89SAndroid Build Coastguard Worker   };
2343*8d67ca89SAndroid Build Coastguard Worker   std::atomic<Progress> progress;
2344*8d67ca89SAndroid Build Coastguard Worker   std::atomic<pid_t> main_tid;
2345*8d67ca89SAndroid Build Coastguard Worker   std::atomic<pid_t> child_tid;
2346*8d67ca89SAndroid Build Coastguard Worker   PthreadMutex start_thread_m;
2347*8d67ca89SAndroid Build Coastguard Worker 
thread_fn(PIMutexWakeupHelper * helper)2348*8d67ca89SAndroid Build Coastguard Worker   static void thread_fn(PIMutexWakeupHelper* helper) {
2349*8d67ca89SAndroid Build Coastguard Worker     helper->child_tid = gettid();
2350*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(LOCK_INITIALIZED, helper->progress);
2351*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, setpriority(PRIO_PROCESS, gettid(), 1));
2352*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(21, GetThreadPriority(gettid()));
2353*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_mutex_lock(&helper->m.lock));
2354*8d67ca89SAndroid Build Coastguard Worker     helper->progress = LOCK_CHILD_READY;
2355*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_mutex_lock(&helper->start_thread_m.lock));
2356*8d67ca89SAndroid Build Coastguard Worker 
2357*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_mutex_unlock(&helper->start_thread_m.lock));
2358*8d67ca89SAndroid Build Coastguard Worker     WaitUntilThreadSleep(helper->main_tid);
2359*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(LOCK_WAITING, helper->progress);
2360*8d67ca89SAndroid Build Coastguard Worker 
2361*8d67ca89SAndroid Build Coastguard Worker     if (helper->protocol == PTHREAD_PRIO_INHERIT) {
2362*8d67ca89SAndroid Build Coastguard Worker       ASSERT_EQ(20, GetThreadPriority(gettid()));
2363*8d67ca89SAndroid Build Coastguard Worker     } else {
2364*8d67ca89SAndroid Build Coastguard Worker       ASSERT_EQ(21, GetThreadPriority(gettid()));
2365*8d67ca89SAndroid Build Coastguard Worker     }
2366*8d67ca89SAndroid Build Coastguard Worker     helper->progress = LOCK_RELEASED;
2367*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_mutex_unlock(&helper->m.lock));
2368*8d67ca89SAndroid Build Coastguard Worker   }
2369*8d67ca89SAndroid Build Coastguard Worker 
2370*8d67ca89SAndroid Build Coastguard Worker public:
PIMutexWakeupHelper(int mutex_type,int protocol)2371*8d67ca89SAndroid Build Coastguard Worker   explicit PIMutexWakeupHelper(int mutex_type, int protocol)
2372*8d67ca89SAndroid Build Coastguard Worker       : m(mutex_type, protocol), protocol(protocol), start_thread_m(PTHREAD_MUTEX_NORMAL) {
2373*8d67ca89SAndroid Build Coastguard Worker   }
2374*8d67ca89SAndroid Build Coastguard Worker 
test()2375*8d67ca89SAndroid Build Coastguard Worker   void test() {
2376*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_mutex_lock(&start_thread_m.lock));
2377*8d67ca89SAndroid Build Coastguard Worker     main_tid = gettid();
2378*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(20, GetThreadPriority(main_tid));
2379*8d67ca89SAndroid Build Coastguard Worker     progress = LOCK_INITIALIZED;
2380*8d67ca89SAndroid Build Coastguard Worker     child_tid = 0;
2381*8d67ca89SAndroid Build Coastguard Worker 
2382*8d67ca89SAndroid Build Coastguard Worker     pthread_t thread;
2383*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_create(&thread, nullptr,
2384*8d67ca89SAndroid Build Coastguard Worker               reinterpret_cast<void* (*)(void*)>(PIMutexWakeupHelper::thread_fn), this));
2385*8d67ca89SAndroid Build Coastguard Worker 
2386*8d67ca89SAndroid Build Coastguard Worker     WaitUntilThreadSleep(child_tid);
2387*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(LOCK_CHILD_READY, progress);
2388*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_mutex_unlock(&start_thread_m.lock));
2389*8d67ca89SAndroid Build Coastguard Worker     progress = LOCK_WAITING;
2390*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_mutex_lock(&m.lock));
2391*8d67ca89SAndroid Build Coastguard Worker 
2392*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(LOCK_RELEASED, progress);
2393*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_mutex_unlock(&m.lock));
2394*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_join(thread, nullptr));
2395*8d67ca89SAndroid Build Coastguard Worker   }
2396*8d67ca89SAndroid Build Coastguard Worker };
2397*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_mutex_pi_wakeup)2398*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_mutex_pi_wakeup) {
2399*8d67ca89SAndroid Build Coastguard Worker   for (int type : {PTHREAD_MUTEX_NORMAL, PTHREAD_MUTEX_RECURSIVE, PTHREAD_MUTEX_ERRORCHECK}) {
2400*8d67ca89SAndroid Build Coastguard Worker     for (int protocol : {PTHREAD_PRIO_INHERIT}) {
2401*8d67ca89SAndroid Build Coastguard Worker       PIMutexWakeupHelper helper(type, protocol);
2402*8d67ca89SAndroid Build Coastguard Worker       helper.test();
2403*8d67ca89SAndroid Build Coastguard Worker     }
2404*8d67ca89SAndroid Build Coastguard Worker   }
2405*8d67ca89SAndroid Build Coastguard Worker }
2406*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_mutex_owner_tid_limit)2407*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_mutex_owner_tid_limit) {
2408*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__) && !defined(__LP64__)
2409*8d67ca89SAndroid Build Coastguard Worker   FILE* fp = fopen("/proc/sys/kernel/pid_max", "r");
2410*8d67ca89SAndroid Build Coastguard Worker   ASSERT_TRUE(fp != nullptr);
2411*8d67ca89SAndroid Build Coastguard Worker   long pid_max;
2412*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(1, fscanf(fp, "%ld", &pid_max));
2413*8d67ca89SAndroid Build Coastguard Worker   fclose(fp);
2414*8d67ca89SAndroid Build Coastguard Worker   // Bionic's pthread_mutex implementation on 32-bit devices uses 16 bits to represent owner tid.
2415*8d67ca89SAndroid Build Coastguard Worker   ASSERT_LE(pid_max, 65536);
2416*8d67ca89SAndroid Build Coastguard Worker #else
2417*8d67ca89SAndroid Build Coastguard Worker   GTEST_SKIP() << "pthread_mutex supports 32-bit tid";
2418*8d67ca89SAndroid Build Coastguard Worker #endif
2419*8d67ca89SAndroid Build Coastguard Worker }
2420*8d67ca89SAndroid Build Coastguard Worker 
pthread_mutex_timedlock_helper(clockid_t clock,int (* lock_function)(pthread_mutex_t * __mutex,const timespec * __timeout))2421*8d67ca89SAndroid Build Coastguard Worker static void pthread_mutex_timedlock_helper(clockid_t clock,
2422*8d67ca89SAndroid Build Coastguard Worker                                            int (*lock_function)(pthread_mutex_t* __mutex,
2423*8d67ca89SAndroid Build Coastguard Worker                                                                 const timespec* __timeout)) {
2424*8d67ca89SAndroid Build Coastguard Worker   pthread_mutex_t m;
2425*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_mutex_init(&m, nullptr));
2426*8d67ca89SAndroid Build Coastguard Worker 
2427*8d67ca89SAndroid Build Coastguard Worker   // If the mutex is already locked, pthread_mutex_timedlock should time out.
2428*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_mutex_lock(&m));
2429*8d67ca89SAndroid Build Coastguard Worker 
2430*8d67ca89SAndroid Build Coastguard Worker   timespec ts;
2431*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, clock_gettime(clock, &ts));
2432*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(ETIMEDOUT, lock_function(&m, &ts));
2433*8d67ca89SAndroid Build Coastguard Worker   ts.tv_nsec = -1;
2434*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(EINVAL, lock_function(&m, &ts));
2435*8d67ca89SAndroid Build Coastguard Worker   ts.tv_nsec = NS_PER_S;
2436*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(EINVAL, lock_function(&m, &ts));
2437*8d67ca89SAndroid Build Coastguard Worker   ts.tv_nsec = NS_PER_S - 1;
2438*8d67ca89SAndroid Build Coastguard Worker   ts.tv_sec = -1;
2439*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(ETIMEDOUT, lock_function(&m, &ts));
2440*8d67ca89SAndroid Build Coastguard Worker 
2441*8d67ca89SAndroid Build Coastguard Worker   // Check we wait long enough for the lock before timing out...
2442*8d67ca89SAndroid Build Coastguard Worker 
2443*8d67ca89SAndroid Build Coastguard Worker   // What time is it before we start?
2444*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, clock_gettime(clock, &ts));
2445*8d67ca89SAndroid Build Coastguard Worker   const int64_t start_ns = to_ns(ts);
2446*8d67ca89SAndroid Build Coastguard Worker   // Add a second to get deadline, and wait until we time out.
2447*8d67ca89SAndroid Build Coastguard Worker   ts.tv_sec += 1;
2448*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(ETIMEDOUT, lock_function(&m, &ts));
2449*8d67ca89SAndroid Build Coastguard Worker 
2450*8d67ca89SAndroid Build Coastguard Worker   // What time is it now we've timed out?
2451*8d67ca89SAndroid Build Coastguard Worker   timespec ts2;
2452*8d67ca89SAndroid Build Coastguard Worker   clock_gettime(clock, &ts2);
2453*8d67ca89SAndroid Build Coastguard Worker   const int64_t end_ns = to_ns(ts2);
2454*8d67ca89SAndroid Build Coastguard Worker 
2455*8d67ca89SAndroid Build Coastguard Worker   // The timedlock must have waited at least 1 second before returning.
2456*8d67ca89SAndroid Build Coastguard Worker   ASSERT_GE(end_ns - start_ns, NS_PER_S);
2457*8d67ca89SAndroid Build Coastguard Worker 
2458*8d67ca89SAndroid Build Coastguard Worker   // If the mutex is unlocked, pthread_mutex_timedlock should succeed.
2459*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_mutex_unlock(&m));
2460*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, clock_gettime(clock, &ts));
2461*8d67ca89SAndroid Build Coastguard Worker   ts.tv_sec += 1;
2462*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, lock_function(&m, &ts));
2463*8d67ca89SAndroid Build Coastguard Worker 
2464*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_mutex_unlock(&m));
2465*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_mutex_destroy(&m));
2466*8d67ca89SAndroid Build Coastguard Worker }
2467*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_mutex_timedlock)2468*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_mutex_timedlock) {
2469*8d67ca89SAndroid Build Coastguard Worker   pthread_mutex_timedlock_helper(CLOCK_REALTIME, pthread_mutex_timedlock);
2470*8d67ca89SAndroid Build Coastguard Worker }
2471*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_mutex_timedlock_monotonic_np)2472*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_mutex_timedlock_monotonic_np) {
2473*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
2474*8d67ca89SAndroid Build Coastguard Worker   pthread_mutex_timedlock_helper(CLOCK_MONOTONIC, pthread_mutex_timedlock_monotonic_np);
2475*8d67ca89SAndroid Build Coastguard Worker #else   // __BIONIC__
2476*8d67ca89SAndroid Build Coastguard Worker   GTEST_SKIP() << "pthread_mutex_timedlock_monotonic_np not available";
2477*8d67ca89SAndroid Build Coastguard Worker #endif  // __BIONIC__
2478*8d67ca89SAndroid Build Coastguard Worker }
2479*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_mutex_clocklock_MONOTONIC)2480*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_mutex_clocklock_MONOTONIC) {
2481*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
2482*8d67ca89SAndroid Build Coastguard Worker   pthread_mutex_timedlock_helper(
2483*8d67ca89SAndroid Build Coastguard Worker       CLOCK_MONOTONIC, [](pthread_mutex_t* __mutex, const timespec* __timeout) {
2484*8d67ca89SAndroid Build Coastguard Worker         return pthread_mutex_clocklock(__mutex, CLOCK_MONOTONIC, __timeout);
2485*8d67ca89SAndroid Build Coastguard Worker       });
2486*8d67ca89SAndroid Build Coastguard Worker #else   // __BIONIC__
2487*8d67ca89SAndroid Build Coastguard Worker   GTEST_SKIP() << "pthread_mutex_clocklock not available";
2488*8d67ca89SAndroid Build Coastguard Worker #endif  // __BIONIC__
2489*8d67ca89SAndroid Build Coastguard Worker }
2490*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_mutex_clocklock_REALTIME)2491*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_mutex_clocklock_REALTIME) {
2492*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
2493*8d67ca89SAndroid Build Coastguard Worker   pthread_mutex_timedlock_helper(
2494*8d67ca89SAndroid Build Coastguard Worker       CLOCK_REALTIME, [](pthread_mutex_t* __mutex, const timespec* __timeout) {
2495*8d67ca89SAndroid Build Coastguard Worker         return pthread_mutex_clocklock(__mutex, CLOCK_REALTIME, __timeout);
2496*8d67ca89SAndroid Build Coastguard Worker       });
2497*8d67ca89SAndroid Build Coastguard Worker #else   // __BIONIC__
2498*8d67ca89SAndroid Build Coastguard Worker   GTEST_SKIP() << "pthread_mutex_clocklock not available";
2499*8d67ca89SAndroid Build Coastguard Worker #endif  // __BIONIC__
2500*8d67ca89SAndroid Build Coastguard Worker }
2501*8d67ca89SAndroid Build Coastguard Worker 
pthread_mutex_timedlock_pi_helper(clockid_t clock,int (* lock_function)(pthread_mutex_t * __mutex,const timespec * __timeout))2502*8d67ca89SAndroid Build Coastguard Worker static void pthread_mutex_timedlock_pi_helper(clockid_t clock,
2503*8d67ca89SAndroid Build Coastguard Worker                                               int (*lock_function)(pthread_mutex_t* __mutex,
2504*8d67ca89SAndroid Build Coastguard Worker                                                                    const timespec* __timeout)) {
2505*8d67ca89SAndroid Build Coastguard Worker   PthreadMutex m(PTHREAD_MUTEX_NORMAL, PTHREAD_PRIO_INHERIT);
2506*8d67ca89SAndroid Build Coastguard Worker 
2507*8d67ca89SAndroid Build Coastguard Worker   timespec ts;
2508*8d67ca89SAndroid Build Coastguard Worker   clock_gettime(clock, &ts);
2509*8d67ca89SAndroid Build Coastguard Worker   const int64_t start_ns = ts.tv_sec * NS_PER_S + ts.tv_nsec;
2510*8d67ca89SAndroid Build Coastguard Worker 
2511*8d67ca89SAndroid Build Coastguard Worker   // add a second to get deadline.
2512*8d67ca89SAndroid Build Coastguard Worker   ts.tv_sec += 1;
2513*8d67ca89SAndroid Build Coastguard Worker 
2514*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, lock_function(&m.lock, &ts));
2515*8d67ca89SAndroid Build Coastguard Worker 
2516*8d67ca89SAndroid Build Coastguard Worker   struct ThreadArgs {
2517*8d67ca89SAndroid Build Coastguard Worker     clockid_t clock;
2518*8d67ca89SAndroid Build Coastguard Worker     int (*lock_function)(pthread_mutex_t* __mutex, const timespec* __timeout);
2519*8d67ca89SAndroid Build Coastguard Worker     PthreadMutex& m;
2520*8d67ca89SAndroid Build Coastguard Worker   };
2521*8d67ca89SAndroid Build Coastguard Worker 
2522*8d67ca89SAndroid Build Coastguard Worker   ThreadArgs thread_args = {
2523*8d67ca89SAndroid Build Coastguard Worker     .clock = clock,
2524*8d67ca89SAndroid Build Coastguard Worker     .lock_function = lock_function,
2525*8d67ca89SAndroid Build Coastguard Worker     .m = m,
2526*8d67ca89SAndroid Build Coastguard Worker   };
2527*8d67ca89SAndroid Build Coastguard Worker 
2528*8d67ca89SAndroid Build Coastguard Worker   auto ThreadFn = [](void* arg) -> void* {
2529*8d67ca89SAndroid Build Coastguard Worker     auto args = static_cast<ThreadArgs*>(arg);
2530*8d67ca89SAndroid Build Coastguard Worker     timespec ts;
2531*8d67ca89SAndroid Build Coastguard Worker     clock_gettime(args->clock, &ts);
2532*8d67ca89SAndroid Build Coastguard Worker     ts.tv_sec += 1;
2533*8d67ca89SAndroid Build Coastguard Worker     intptr_t result = args->lock_function(&args->m.lock, &ts);
2534*8d67ca89SAndroid Build Coastguard Worker     return reinterpret_cast<void*>(result);
2535*8d67ca89SAndroid Build Coastguard Worker   };
2536*8d67ca89SAndroid Build Coastguard Worker 
2537*8d67ca89SAndroid Build Coastguard Worker   pthread_t thread;
2538*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_create(&thread, nullptr, ThreadFn, &thread_args));
2539*8d67ca89SAndroid Build Coastguard Worker   void* result;
2540*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_join(thread, &result));
2541*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(ETIMEDOUT, reinterpret_cast<intptr_t>(result));
2542*8d67ca89SAndroid Build Coastguard Worker 
2543*8d67ca89SAndroid Build Coastguard Worker   // The timedlock must have waited at least 1 second before returning.
2544*8d67ca89SAndroid Build Coastguard Worker   clock_gettime(clock, &ts);
2545*8d67ca89SAndroid Build Coastguard Worker   const int64_t end_ns = ts.tv_sec * NS_PER_S + ts.tv_nsec;
2546*8d67ca89SAndroid Build Coastguard Worker   ASSERT_GT(end_ns - start_ns, NS_PER_S);
2547*8d67ca89SAndroid Build Coastguard Worker 
2548*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_mutex_unlock(&m.lock));
2549*8d67ca89SAndroid Build Coastguard Worker }
2550*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_mutex_timedlock_pi)2551*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_mutex_timedlock_pi) {
2552*8d67ca89SAndroid Build Coastguard Worker   pthread_mutex_timedlock_pi_helper(CLOCK_REALTIME, pthread_mutex_timedlock);
2553*8d67ca89SAndroid Build Coastguard Worker }
2554*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_mutex_timedlock_monotonic_np_pi)2555*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_mutex_timedlock_monotonic_np_pi) {
2556*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
2557*8d67ca89SAndroid Build Coastguard Worker   pthread_mutex_timedlock_pi_helper(CLOCK_MONOTONIC, pthread_mutex_timedlock_monotonic_np);
2558*8d67ca89SAndroid Build Coastguard Worker #else   // __BIONIC__
2559*8d67ca89SAndroid Build Coastguard Worker   GTEST_SKIP() << "pthread_mutex_timedlock_monotonic_np not available";
2560*8d67ca89SAndroid Build Coastguard Worker #endif  // __BIONIC__
2561*8d67ca89SAndroid Build Coastguard Worker }
2562*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_mutex_clocklock_pi)2563*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_mutex_clocklock_pi) {
2564*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
2565*8d67ca89SAndroid Build Coastguard Worker   pthread_mutex_timedlock_pi_helper(
2566*8d67ca89SAndroid Build Coastguard Worker       CLOCK_MONOTONIC, [](pthread_mutex_t* __mutex, const timespec* __timeout) {
2567*8d67ca89SAndroid Build Coastguard Worker         return pthread_mutex_clocklock(__mutex, CLOCK_MONOTONIC, __timeout);
2568*8d67ca89SAndroid Build Coastguard Worker       });
2569*8d67ca89SAndroid Build Coastguard Worker   pthread_mutex_timedlock_pi_helper(
2570*8d67ca89SAndroid Build Coastguard Worker       CLOCK_REALTIME, [](pthread_mutex_t* __mutex, const timespec* __timeout) {
2571*8d67ca89SAndroid Build Coastguard Worker         return pthread_mutex_clocklock(__mutex, CLOCK_REALTIME, __timeout);
2572*8d67ca89SAndroid Build Coastguard Worker       });
2573*8d67ca89SAndroid Build Coastguard Worker #else   // __BIONIC__
2574*8d67ca89SAndroid Build Coastguard Worker   GTEST_SKIP() << "pthread_mutex_clocklock not available";
2575*8d67ca89SAndroid Build Coastguard Worker #endif  // __BIONIC__
2576*8d67ca89SAndroid Build Coastguard Worker }
2577*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_mutex_clocklock_invalid)2578*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_mutex_clocklock_invalid) {
2579*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
2580*8d67ca89SAndroid Build Coastguard Worker   pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
2581*8d67ca89SAndroid Build Coastguard Worker   timespec ts;
2582*8d67ca89SAndroid Build Coastguard Worker   EXPECT_EQ(EINVAL, pthread_mutex_clocklock(&mutex, CLOCK_PROCESS_CPUTIME_ID, &ts));
2583*8d67ca89SAndroid Build Coastguard Worker #else   // __BIONIC__
2584*8d67ca89SAndroid Build Coastguard Worker   GTEST_SKIP() << "pthread_mutex_clocklock not available";
2585*8d67ca89SAndroid Build Coastguard Worker #endif  // __BIONIC__
2586*8d67ca89SAndroid Build Coastguard Worker }
2587*8d67ca89SAndroid Build Coastguard Worker 
TEST_F(pthread_DeathTest,pthread_mutex_using_destroyed_mutex)2588*8d67ca89SAndroid Build Coastguard Worker TEST_F(pthread_DeathTest, pthread_mutex_using_destroyed_mutex) {
2589*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
2590*8d67ca89SAndroid Build Coastguard Worker   pthread_mutex_t m;
2591*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_mutex_init(&m, nullptr));
2592*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_mutex_destroy(&m));
2593*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EXIT(pthread_mutex_lock(&m), ::testing::KilledBySignal(SIGABRT),
2594*8d67ca89SAndroid Build Coastguard Worker               "pthread_mutex_lock called on a destroyed mutex");
2595*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EXIT(pthread_mutex_unlock(&m), ::testing::KilledBySignal(SIGABRT),
2596*8d67ca89SAndroid Build Coastguard Worker               "pthread_mutex_unlock called on a destroyed mutex");
2597*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EXIT(pthread_mutex_trylock(&m), ::testing::KilledBySignal(SIGABRT),
2598*8d67ca89SAndroid Build Coastguard Worker               "pthread_mutex_trylock called on a destroyed mutex");
2599*8d67ca89SAndroid Build Coastguard Worker   timespec ts;
2600*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EXIT(pthread_mutex_timedlock(&m, &ts), ::testing::KilledBySignal(SIGABRT),
2601*8d67ca89SAndroid Build Coastguard Worker               "pthread_mutex_timedlock called on a destroyed mutex");
2602*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EXIT(pthread_mutex_timedlock_monotonic_np(&m, &ts), ::testing::KilledBySignal(SIGABRT),
2603*8d67ca89SAndroid Build Coastguard Worker               "pthread_mutex_timedlock_monotonic_np called on a destroyed mutex");
2604*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EXIT(pthread_mutex_clocklock(&m, CLOCK_MONOTONIC, &ts), ::testing::KilledBySignal(SIGABRT),
2605*8d67ca89SAndroid Build Coastguard Worker               "pthread_mutex_clocklock called on a destroyed mutex");
2606*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EXIT(pthread_mutex_clocklock(&m, CLOCK_REALTIME, &ts), ::testing::KilledBySignal(SIGABRT),
2607*8d67ca89SAndroid Build Coastguard Worker               "pthread_mutex_clocklock called on a destroyed mutex");
2608*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EXIT(pthread_mutex_clocklock(&m, CLOCK_PROCESS_CPUTIME_ID, &ts),
2609*8d67ca89SAndroid Build Coastguard Worker               ::testing::KilledBySignal(SIGABRT),
2610*8d67ca89SAndroid Build Coastguard Worker               "pthread_mutex_clocklock called on a destroyed mutex");
2611*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EXIT(pthread_mutex_destroy(&m), ::testing::KilledBySignal(SIGABRT),
2612*8d67ca89SAndroid Build Coastguard Worker               "pthread_mutex_destroy called on a destroyed mutex");
2613*8d67ca89SAndroid Build Coastguard Worker #else
2614*8d67ca89SAndroid Build Coastguard Worker   GTEST_SKIP() << "bionic-only test";
2615*8d67ca89SAndroid Build Coastguard Worker #endif
2616*8d67ca89SAndroid Build Coastguard Worker }
2617*8d67ca89SAndroid Build Coastguard Worker 
2618*8d67ca89SAndroid Build Coastguard Worker class StrictAlignmentAllocator {
2619*8d67ca89SAndroid Build Coastguard Worker  public:
allocate(size_t size,size_t alignment)2620*8d67ca89SAndroid Build Coastguard Worker   void* allocate(size_t size, size_t alignment) {
2621*8d67ca89SAndroid Build Coastguard Worker     char* p = new char[size + alignment * 2];
2622*8d67ca89SAndroid Build Coastguard Worker     allocated_array.push_back(p);
2623*8d67ca89SAndroid Build Coastguard Worker     while (!is_strict_aligned(p, alignment)) {
2624*8d67ca89SAndroid Build Coastguard Worker       ++p;
2625*8d67ca89SAndroid Build Coastguard Worker     }
2626*8d67ca89SAndroid Build Coastguard Worker     return p;
2627*8d67ca89SAndroid Build Coastguard Worker   }
2628*8d67ca89SAndroid Build Coastguard Worker 
~StrictAlignmentAllocator()2629*8d67ca89SAndroid Build Coastguard Worker   ~StrictAlignmentAllocator() {
2630*8d67ca89SAndroid Build Coastguard Worker     for (const auto& p : allocated_array) {
2631*8d67ca89SAndroid Build Coastguard Worker       delete[] p;
2632*8d67ca89SAndroid Build Coastguard Worker     }
2633*8d67ca89SAndroid Build Coastguard Worker   }
2634*8d67ca89SAndroid Build Coastguard Worker 
2635*8d67ca89SAndroid Build Coastguard Worker  private:
is_strict_aligned(char * p,size_t alignment)2636*8d67ca89SAndroid Build Coastguard Worker   bool is_strict_aligned(char* p, size_t alignment) {
2637*8d67ca89SAndroid Build Coastguard Worker     return (reinterpret_cast<uintptr_t>(p) % (alignment * 2)) == alignment;
2638*8d67ca89SAndroid Build Coastguard Worker   }
2639*8d67ca89SAndroid Build Coastguard Worker 
2640*8d67ca89SAndroid Build Coastguard Worker   std::vector<char*> allocated_array;
2641*8d67ca89SAndroid Build Coastguard Worker };
2642*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_types_allow_four_bytes_alignment)2643*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_types_allow_four_bytes_alignment) {
2644*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
2645*8d67ca89SAndroid Build Coastguard Worker   // For binary compatibility with old version, we need to allow 4-byte aligned data for pthread types.
2646*8d67ca89SAndroid Build Coastguard Worker   StrictAlignmentAllocator allocator;
2647*8d67ca89SAndroid Build Coastguard Worker   pthread_mutex_t* mutex = reinterpret_cast<pthread_mutex_t*>(
2648*8d67ca89SAndroid Build Coastguard Worker                              allocator.allocate(sizeof(pthread_mutex_t), 4));
2649*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_mutex_init(mutex, nullptr));
2650*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_mutex_lock(mutex));
2651*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_mutex_unlock(mutex));
2652*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_mutex_destroy(mutex));
2653*8d67ca89SAndroid Build Coastguard Worker 
2654*8d67ca89SAndroid Build Coastguard Worker   pthread_cond_t* cond = reinterpret_cast<pthread_cond_t*>(
2655*8d67ca89SAndroid Build Coastguard Worker                            allocator.allocate(sizeof(pthread_cond_t), 4));
2656*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_cond_init(cond, nullptr));
2657*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_cond_signal(cond));
2658*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_cond_broadcast(cond));
2659*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_cond_destroy(cond));
2660*8d67ca89SAndroid Build Coastguard Worker 
2661*8d67ca89SAndroid Build Coastguard Worker   pthread_rwlock_t* rwlock = reinterpret_cast<pthread_rwlock_t*>(
2662*8d67ca89SAndroid Build Coastguard Worker                                allocator.allocate(sizeof(pthread_rwlock_t), 4));
2663*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_init(rwlock, nullptr));
2664*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_rdlock(rwlock));
2665*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_unlock(rwlock));
2666*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_wrlock(rwlock));
2667*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_unlock(rwlock));
2668*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_rwlock_destroy(rwlock));
2669*8d67ca89SAndroid Build Coastguard Worker 
2670*8d67ca89SAndroid Build Coastguard Worker #else
2671*8d67ca89SAndroid Build Coastguard Worker   GTEST_SKIP() << "bionic-only test";
2672*8d67ca89SAndroid Build Coastguard Worker #endif
2673*8d67ca89SAndroid Build Coastguard Worker }
2674*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_mutex_lock_null_32)2675*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_mutex_lock_null_32) {
2676*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__) && !defined(__LP64__)
2677*8d67ca89SAndroid Build Coastguard Worker   // For LP32, the pthread lock/unlock functions allow a NULL mutex and return
2678*8d67ca89SAndroid Build Coastguard Worker   // EINVAL in that case: http://b/19995172.
2679*8d67ca89SAndroid Build Coastguard Worker   //
2680*8d67ca89SAndroid Build Coastguard Worker   // We decorate the public defintion with _Nonnull so that people recompiling
2681*8d67ca89SAndroid Build Coastguard Worker   // their code with get a warning and might fix their bug, but need to pass
2682*8d67ca89SAndroid Build Coastguard Worker   // NULL here to test that we remain compatible.
2683*8d67ca89SAndroid Build Coastguard Worker   pthread_mutex_t* null_value = nullptr;
2684*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(EINVAL, pthread_mutex_lock(null_value));
2685*8d67ca89SAndroid Build Coastguard Worker #else
2686*8d67ca89SAndroid Build Coastguard Worker   GTEST_SKIP() << "32-bit bionic-only test";
2687*8d67ca89SAndroid Build Coastguard Worker #endif
2688*8d67ca89SAndroid Build Coastguard Worker }
2689*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_mutex_unlock_null_32)2690*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_mutex_unlock_null_32) {
2691*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__) && !defined(__LP64__)
2692*8d67ca89SAndroid Build Coastguard Worker   // For LP32, the pthread lock/unlock functions allow a NULL mutex and return
2693*8d67ca89SAndroid Build Coastguard Worker   // EINVAL in that case: http://b/19995172.
2694*8d67ca89SAndroid Build Coastguard Worker   //
2695*8d67ca89SAndroid Build Coastguard Worker   // We decorate the public defintion with _Nonnull so that people recompiling
2696*8d67ca89SAndroid Build Coastguard Worker   // their code with get a warning and might fix their bug, but need to pass
2697*8d67ca89SAndroid Build Coastguard Worker   // NULL here to test that we remain compatible.
2698*8d67ca89SAndroid Build Coastguard Worker   pthread_mutex_t* null_value = nullptr;
2699*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(EINVAL, pthread_mutex_unlock(null_value));
2700*8d67ca89SAndroid Build Coastguard Worker #else
2701*8d67ca89SAndroid Build Coastguard Worker   GTEST_SKIP() << "32-bit bionic-only test";
2702*8d67ca89SAndroid Build Coastguard Worker #endif
2703*8d67ca89SAndroid Build Coastguard Worker }
2704*8d67ca89SAndroid Build Coastguard Worker 
TEST_F(pthread_DeathTest,pthread_mutex_lock_null_64)2705*8d67ca89SAndroid Build Coastguard Worker TEST_F(pthread_DeathTest, pthread_mutex_lock_null_64) {
2706*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__) && defined(__LP64__)
2707*8d67ca89SAndroid Build Coastguard Worker   pthread_mutex_t* null_value = nullptr;
2708*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EXIT(pthread_mutex_lock(null_value), testing::KilledBySignal(SIGSEGV), "");
2709*8d67ca89SAndroid Build Coastguard Worker #else
2710*8d67ca89SAndroid Build Coastguard Worker   GTEST_SKIP() << "64-bit bionic-only test";
2711*8d67ca89SAndroid Build Coastguard Worker #endif
2712*8d67ca89SAndroid Build Coastguard Worker }
2713*8d67ca89SAndroid Build Coastguard Worker 
TEST_F(pthread_DeathTest,pthread_mutex_unlock_null_64)2714*8d67ca89SAndroid Build Coastguard Worker TEST_F(pthread_DeathTest, pthread_mutex_unlock_null_64) {
2715*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__) && defined(__LP64__)
2716*8d67ca89SAndroid Build Coastguard Worker   pthread_mutex_t* null_value = nullptr;
2717*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EXIT(pthread_mutex_unlock(null_value), testing::KilledBySignal(SIGSEGV), "");
2718*8d67ca89SAndroid Build Coastguard Worker #else
2719*8d67ca89SAndroid Build Coastguard Worker   GTEST_SKIP() << "64-bit bionic-only test";
2720*8d67ca89SAndroid Build Coastguard Worker #endif
2721*8d67ca89SAndroid Build Coastguard Worker }
2722*8d67ca89SAndroid Build Coastguard Worker 
2723*8d67ca89SAndroid Build Coastguard Worker extern _Unwind_Reason_Code FrameCounter(_Unwind_Context* ctx, void* arg);
2724*8d67ca89SAndroid Build Coastguard Worker 
2725*8d67ca89SAndroid Build Coastguard Worker static volatile bool signal_handler_on_altstack_done;
2726*8d67ca89SAndroid Build Coastguard Worker 
2727*8d67ca89SAndroid Build Coastguard Worker __attribute__((__noinline__))
signal_handler_backtrace()2728*8d67ca89SAndroid Build Coastguard Worker static void signal_handler_backtrace() {
2729*8d67ca89SAndroid Build Coastguard Worker   // Check if we have enough stack space for unwinding.
2730*8d67ca89SAndroid Build Coastguard Worker   int count = 0;
2731*8d67ca89SAndroid Build Coastguard Worker   _Unwind_Backtrace(FrameCounter, &count);
2732*8d67ca89SAndroid Build Coastguard Worker   ASSERT_GT(count, 0);
2733*8d67ca89SAndroid Build Coastguard Worker }
2734*8d67ca89SAndroid Build Coastguard Worker 
2735*8d67ca89SAndroid Build Coastguard Worker __attribute__((__noinline__))
signal_handler_logging()2736*8d67ca89SAndroid Build Coastguard Worker static void signal_handler_logging() {
2737*8d67ca89SAndroid Build Coastguard Worker   // Check if we have enough stack space for logging.
2738*8d67ca89SAndroid Build Coastguard Worker   std::string s(2048, '*');
2739*8d67ca89SAndroid Build Coastguard Worker   GTEST_LOG_(INFO) << s;
2740*8d67ca89SAndroid Build Coastguard Worker   signal_handler_on_altstack_done = true;
2741*8d67ca89SAndroid Build Coastguard Worker }
2742*8d67ca89SAndroid Build Coastguard Worker 
2743*8d67ca89SAndroid Build Coastguard Worker __attribute__((__noinline__))
signal_handler_snprintf()2744*8d67ca89SAndroid Build Coastguard Worker static void signal_handler_snprintf() {
2745*8d67ca89SAndroid Build Coastguard Worker   // Check if we have enough stack space for snprintf to a PATH_MAX buffer, plus some extra.
2746*8d67ca89SAndroid Build Coastguard Worker   char buf[PATH_MAX + 2048];
2747*8d67ca89SAndroid Build Coastguard Worker   ASSERT_GT(snprintf(buf, sizeof(buf), "/proc/%d/status", getpid()), 0);
2748*8d67ca89SAndroid Build Coastguard Worker }
2749*8d67ca89SAndroid Build Coastguard Worker 
SignalHandlerOnAltStack(int signo,siginfo_t *,void *)2750*8d67ca89SAndroid Build Coastguard Worker static void SignalHandlerOnAltStack(int signo, siginfo_t*, void*) {
2751*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(SIGUSR1, signo);
2752*8d67ca89SAndroid Build Coastguard Worker   signal_handler_backtrace();
2753*8d67ca89SAndroid Build Coastguard Worker   signal_handler_logging();
2754*8d67ca89SAndroid Build Coastguard Worker   signal_handler_snprintf();
2755*8d67ca89SAndroid Build Coastguard Worker }
2756*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,big_enough_signal_stack)2757*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, big_enough_signal_stack) {
2758*8d67ca89SAndroid Build Coastguard Worker   signal_handler_on_altstack_done = false;
2759*8d67ca89SAndroid Build Coastguard Worker   ScopedSignalHandler handler(SIGUSR1, SignalHandlerOnAltStack, SA_SIGINFO | SA_ONSTACK);
2760*8d67ca89SAndroid Build Coastguard Worker   kill(getpid(), SIGUSR1);
2761*8d67ca89SAndroid Build Coastguard Worker   ASSERT_TRUE(signal_handler_on_altstack_done);
2762*8d67ca89SAndroid Build Coastguard Worker }
2763*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_barrierattr_smoke)2764*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_barrierattr_smoke) {
2765*8d67ca89SAndroid Build Coastguard Worker   pthread_barrierattr_t attr;
2766*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_barrierattr_init(&attr));
2767*8d67ca89SAndroid Build Coastguard Worker   int pshared;
2768*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_barrierattr_getpshared(&attr, &pshared));
2769*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(PTHREAD_PROCESS_PRIVATE, pshared);
2770*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_barrierattr_setpshared(&attr, PTHREAD_PROCESS_SHARED));
2771*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_barrierattr_getpshared(&attr, &pshared));
2772*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(PTHREAD_PROCESS_SHARED, pshared);
2773*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_barrierattr_destroy(&attr));
2774*8d67ca89SAndroid Build Coastguard Worker }
2775*8d67ca89SAndroid Build Coastguard Worker 
2776*8d67ca89SAndroid Build Coastguard Worker struct BarrierTestHelperData {
2777*8d67ca89SAndroid Build Coastguard Worker   size_t thread_count;
2778*8d67ca89SAndroid Build Coastguard Worker   pthread_barrier_t barrier;
2779*8d67ca89SAndroid Build Coastguard Worker   std::atomic<int> finished_mask;
2780*8d67ca89SAndroid Build Coastguard Worker   std::atomic<int> serial_thread_count;
2781*8d67ca89SAndroid Build Coastguard Worker   size_t iteration_count;
2782*8d67ca89SAndroid Build Coastguard Worker   std::atomic<size_t> finished_iteration_count;
2783*8d67ca89SAndroid Build Coastguard Worker 
BarrierTestHelperDataBarrierTestHelperData2784*8d67ca89SAndroid Build Coastguard Worker   BarrierTestHelperData(size_t thread_count, size_t iteration_count)
2785*8d67ca89SAndroid Build Coastguard Worker       : thread_count(thread_count), finished_mask(0), serial_thread_count(0),
2786*8d67ca89SAndroid Build Coastguard Worker         iteration_count(iteration_count), finished_iteration_count(0) {
2787*8d67ca89SAndroid Build Coastguard Worker   }
2788*8d67ca89SAndroid Build Coastguard Worker };
2789*8d67ca89SAndroid Build Coastguard Worker 
2790*8d67ca89SAndroid Build Coastguard Worker struct BarrierTestHelperArg {
2791*8d67ca89SAndroid Build Coastguard Worker   int id;
2792*8d67ca89SAndroid Build Coastguard Worker   BarrierTestHelperData* data;
2793*8d67ca89SAndroid Build Coastguard Worker };
2794*8d67ca89SAndroid Build Coastguard Worker 
BarrierTestHelper(BarrierTestHelperArg * arg)2795*8d67ca89SAndroid Build Coastguard Worker static void BarrierTestHelper(BarrierTestHelperArg* arg) {
2796*8d67ca89SAndroid Build Coastguard Worker   for (size_t i = 0; i < arg->data->iteration_count; ++i) {
2797*8d67ca89SAndroid Build Coastguard Worker     int result = pthread_barrier_wait(&arg->data->barrier);
2798*8d67ca89SAndroid Build Coastguard Worker     if (result == PTHREAD_BARRIER_SERIAL_THREAD) {
2799*8d67ca89SAndroid Build Coastguard Worker       arg->data->serial_thread_count++;
2800*8d67ca89SAndroid Build Coastguard Worker     } else {
2801*8d67ca89SAndroid Build Coastguard Worker       ASSERT_EQ(0, result);
2802*8d67ca89SAndroid Build Coastguard Worker     }
2803*8d67ca89SAndroid Build Coastguard Worker     int mask = arg->data->finished_mask.fetch_or(1 << arg->id);
2804*8d67ca89SAndroid Build Coastguard Worker     mask |= 1 << arg->id;
2805*8d67ca89SAndroid Build Coastguard Worker     if (mask == ((1 << arg->data->thread_count) - 1)) {
2806*8d67ca89SAndroid Build Coastguard Worker       ASSERT_EQ(1, arg->data->serial_thread_count);
2807*8d67ca89SAndroid Build Coastguard Worker       arg->data->finished_iteration_count++;
2808*8d67ca89SAndroid Build Coastguard Worker       arg->data->finished_mask = 0;
2809*8d67ca89SAndroid Build Coastguard Worker       arg->data->serial_thread_count = 0;
2810*8d67ca89SAndroid Build Coastguard Worker     }
2811*8d67ca89SAndroid Build Coastguard Worker   }
2812*8d67ca89SAndroid Build Coastguard Worker }
2813*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_barrier_smoke)2814*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_barrier_smoke) {
2815*8d67ca89SAndroid Build Coastguard Worker   const size_t BARRIER_ITERATION_COUNT = 10;
2816*8d67ca89SAndroid Build Coastguard Worker   const size_t BARRIER_THREAD_COUNT = 10;
2817*8d67ca89SAndroid Build Coastguard Worker   BarrierTestHelperData data(BARRIER_THREAD_COUNT, BARRIER_ITERATION_COUNT);
2818*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_barrier_init(&data.barrier, nullptr, data.thread_count));
2819*8d67ca89SAndroid Build Coastguard Worker   std::vector<pthread_t> threads(data.thread_count);
2820*8d67ca89SAndroid Build Coastguard Worker   std::vector<BarrierTestHelperArg> args(threads.size());
2821*8d67ca89SAndroid Build Coastguard Worker   for (size_t i = 0; i < threads.size(); ++i) {
2822*8d67ca89SAndroid Build Coastguard Worker     args[i].id = i;
2823*8d67ca89SAndroid Build Coastguard Worker     args[i].data = &data;
2824*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_create(&threads[i], nullptr,
2825*8d67ca89SAndroid Build Coastguard Worker                                 reinterpret_cast<void* (*)(void*)>(BarrierTestHelper), &args[i]));
2826*8d67ca89SAndroid Build Coastguard Worker   }
2827*8d67ca89SAndroid Build Coastguard Worker   for (size_t i = 0; i < threads.size(); ++i) {
2828*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_join(threads[i], nullptr));
2829*8d67ca89SAndroid Build Coastguard Worker   }
2830*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(data.iteration_count, data.finished_iteration_count);
2831*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_barrier_destroy(&data.barrier));
2832*8d67ca89SAndroid Build Coastguard Worker }
2833*8d67ca89SAndroid Build Coastguard Worker 
2834*8d67ca89SAndroid Build Coastguard Worker struct BarrierDestroyTestArg {
2835*8d67ca89SAndroid Build Coastguard Worker   std::atomic<int> tid;
2836*8d67ca89SAndroid Build Coastguard Worker   pthread_barrier_t* barrier;
2837*8d67ca89SAndroid Build Coastguard Worker };
2838*8d67ca89SAndroid Build Coastguard Worker 
BarrierDestroyTestHelper(BarrierDestroyTestArg * arg)2839*8d67ca89SAndroid Build Coastguard Worker static void BarrierDestroyTestHelper(BarrierDestroyTestArg* arg) {
2840*8d67ca89SAndroid Build Coastguard Worker   arg->tid = gettid();
2841*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_barrier_wait(arg->barrier));
2842*8d67ca89SAndroid Build Coastguard Worker }
2843*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_barrier_destroy)2844*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_barrier_destroy) {
2845*8d67ca89SAndroid Build Coastguard Worker   pthread_barrier_t barrier;
2846*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_barrier_init(&barrier, nullptr, 2));
2847*8d67ca89SAndroid Build Coastguard Worker   pthread_t thread;
2848*8d67ca89SAndroid Build Coastguard Worker   BarrierDestroyTestArg arg;
2849*8d67ca89SAndroid Build Coastguard Worker   arg.tid = 0;
2850*8d67ca89SAndroid Build Coastguard Worker   arg.barrier = &barrier;
2851*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_create(&thread, nullptr,
2852*8d67ca89SAndroid Build Coastguard Worker                               reinterpret_cast<void* (*)(void*)>(BarrierDestroyTestHelper), &arg));
2853*8d67ca89SAndroid Build Coastguard Worker   WaitUntilThreadSleep(arg.tid);
2854*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(EBUSY, pthread_barrier_destroy(&barrier));
2855*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(PTHREAD_BARRIER_SERIAL_THREAD, pthread_barrier_wait(&barrier));
2856*8d67ca89SAndroid Build Coastguard Worker   // Verify if the barrier can be destroyed directly after pthread_barrier_wait().
2857*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_barrier_destroy(&barrier));
2858*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_join(thread, nullptr));
2859*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
2860*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(EINVAL, pthread_barrier_destroy(&barrier));
2861*8d67ca89SAndroid Build Coastguard Worker #endif
2862*8d67ca89SAndroid Build Coastguard Worker }
2863*8d67ca89SAndroid Build Coastguard Worker 
2864*8d67ca89SAndroid Build Coastguard Worker struct BarrierOrderingTestHelperArg {
2865*8d67ca89SAndroid Build Coastguard Worker   pthread_barrier_t* barrier;
2866*8d67ca89SAndroid Build Coastguard Worker   size_t* array;
2867*8d67ca89SAndroid Build Coastguard Worker   size_t array_length;
2868*8d67ca89SAndroid Build Coastguard Worker   size_t id;
2869*8d67ca89SAndroid Build Coastguard Worker };
2870*8d67ca89SAndroid Build Coastguard Worker 
BarrierOrderingTestHelper(BarrierOrderingTestHelperArg * arg)2871*8d67ca89SAndroid Build Coastguard Worker void BarrierOrderingTestHelper(BarrierOrderingTestHelperArg* arg) {
2872*8d67ca89SAndroid Build Coastguard Worker   const size_t ITERATION_COUNT = 10000;
2873*8d67ca89SAndroid Build Coastguard Worker   for (size_t i = 1; i <= ITERATION_COUNT; ++i) {
2874*8d67ca89SAndroid Build Coastguard Worker     arg->array[arg->id] = i;
2875*8d67ca89SAndroid Build Coastguard Worker     int result = pthread_barrier_wait(arg->barrier);
2876*8d67ca89SAndroid Build Coastguard Worker     ASSERT_TRUE(result == 0 || result == PTHREAD_BARRIER_SERIAL_THREAD);
2877*8d67ca89SAndroid Build Coastguard Worker     for (size_t j = 0; j < arg->array_length; ++j) {
2878*8d67ca89SAndroid Build Coastguard Worker       ASSERT_EQ(i, arg->array[j]);
2879*8d67ca89SAndroid Build Coastguard Worker     }
2880*8d67ca89SAndroid Build Coastguard Worker     result = pthread_barrier_wait(arg->barrier);
2881*8d67ca89SAndroid Build Coastguard Worker     ASSERT_TRUE(result == 0 || result == PTHREAD_BARRIER_SERIAL_THREAD);
2882*8d67ca89SAndroid Build Coastguard Worker   }
2883*8d67ca89SAndroid Build Coastguard Worker }
2884*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_barrier_check_ordering)2885*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_barrier_check_ordering) {
2886*8d67ca89SAndroid Build Coastguard Worker   const size_t THREAD_COUNT = 4;
2887*8d67ca89SAndroid Build Coastguard Worker   pthread_barrier_t barrier;
2888*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_barrier_init(&barrier, nullptr, THREAD_COUNT));
2889*8d67ca89SAndroid Build Coastguard Worker   size_t array[THREAD_COUNT];
2890*8d67ca89SAndroid Build Coastguard Worker   std::vector<pthread_t> threads(THREAD_COUNT);
2891*8d67ca89SAndroid Build Coastguard Worker   std::vector<BarrierOrderingTestHelperArg> args(THREAD_COUNT);
2892*8d67ca89SAndroid Build Coastguard Worker   for (size_t i = 0; i < THREAD_COUNT; ++i) {
2893*8d67ca89SAndroid Build Coastguard Worker     args[i].barrier = &barrier;
2894*8d67ca89SAndroid Build Coastguard Worker     args[i].array = array;
2895*8d67ca89SAndroid Build Coastguard Worker     args[i].array_length = THREAD_COUNT;
2896*8d67ca89SAndroid Build Coastguard Worker     args[i].id = i;
2897*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_create(&threads[i], nullptr,
2898*8d67ca89SAndroid Build Coastguard Worker                                 reinterpret_cast<void* (*)(void*)>(BarrierOrderingTestHelper),
2899*8d67ca89SAndroid Build Coastguard Worker                                 &args[i]));
2900*8d67ca89SAndroid Build Coastguard Worker   }
2901*8d67ca89SAndroid Build Coastguard Worker   for (size_t i = 0; i < THREAD_COUNT; ++i) {
2902*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, pthread_join(threads[i], nullptr));
2903*8d67ca89SAndroid Build Coastguard Worker   }
2904*8d67ca89SAndroid Build Coastguard Worker }
2905*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_barrier_init_zero_count)2906*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_barrier_init_zero_count) {
2907*8d67ca89SAndroid Build Coastguard Worker   pthread_barrier_t barrier;
2908*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(EINVAL, pthread_barrier_init(&barrier, nullptr, 0));
2909*8d67ca89SAndroid Build Coastguard Worker }
2910*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_spinlock_smoke)2911*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_spinlock_smoke) {
2912*8d67ca89SAndroid Build Coastguard Worker   pthread_spinlock_t lock;
2913*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_spin_init(&lock, 0));
2914*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_spin_trylock(&lock));
2915*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_spin_unlock(&lock));
2916*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_spin_lock(&lock));
2917*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(EBUSY, pthread_spin_trylock(&lock));
2918*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_spin_unlock(&lock));
2919*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_spin_destroy(&lock));
2920*8d67ca89SAndroid Build Coastguard Worker }
2921*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_attr_getdetachstate__pthread_attr_setdetachstate)2922*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_attr_getdetachstate__pthread_attr_setdetachstate) {
2923*8d67ca89SAndroid Build Coastguard Worker   pthread_attr_t attr;
2924*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_init(&attr));
2925*8d67ca89SAndroid Build Coastguard Worker 
2926*8d67ca89SAndroid Build Coastguard Worker   int state;
2927*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED));
2928*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_getdetachstate(&attr, &state));
2929*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(PTHREAD_CREATE_DETACHED, state);
2930*8d67ca89SAndroid Build Coastguard Worker 
2931*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE));
2932*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_getdetachstate(&attr, &state));
2933*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(PTHREAD_CREATE_JOINABLE, state);
2934*8d67ca89SAndroid Build Coastguard Worker 
2935*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(EINVAL, pthread_attr_setdetachstate(&attr, 123));
2936*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_getdetachstate(&attr, &state));
2937*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(PTHREAD_CREATE_JOINABLE, state);
2938*8d67ca89SAndroid Build Coastguard Worker }
2939*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_create__mmap_failures)2940*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_create__mmap_failures) {
2941*8d67ca89SAndroid Build Coastguard Worker   // After thread is successfully created, native_bridge might need more memory to run it.
2942*8d67ca89SAndroid Build Coastguard Worker   SKIP_WITH_NATIVE_BRIDGE;
2943*8d67ca89SAndroid Build Coastguard Worker 
2944*8d67ca89SAndroid Build Coastguard Worker   pthread_attr_t attr;
2945*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_init(&attr));
2946*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED));
2947*8d67ca89SAndroid Build Coastguard Worker 
2948*8d67ca89SAndroid Build Coastguard Worker   const auto kPageSize = sysconf(_SC_PAGE_SIZE);
2949*8d67ca89SAndroid Build Coastguard Worker 
2950*8d67ca89SAndroid Build Coastguard Worker   // Use up all the VMAs. By default this is 64Ki (though some will already be in use).
2951*8d67ca89SAndroid Build Coastguard Worker   std::vector<void*> pages;
2952*8d67ca89SAndroid Build Coastguard Worker   pages.reserve(64 * 1024);
2953*8d67ca89SAndroid Build Coastguard Worker   int prot = PROT_NONE;
2954*8d67ca89SAndroid Build Coastguard Worker   while (true) {
2955*8d67ca89SAndroid Build Coastguard Worker     void* page = mmap(nullptr, kPageSize, prot, MAP_ANON|MAP_PRIVATE, -1, 0);
2956*8d67ca89SAndroid Build Coastguard Worker     if (page == MAP_FAILED) break;
2957*8d67ca89SAndroid Build Coastguard Worker     pages.push_back(page);
2958*8d67ca89SAndroid Build Coastguard Worker     prot = (prot == PROT_NONE) ? PROT_READ : PROT_NONE;
2959*8d67ca89SAndroid Build Coastguard Worker   }
2960*8d67ca89SAndroid Build Coastguard Worker 
2961*8d67ca89SAndroid Build Coastguard Worker   // Try creating threads, freeing up a page each time we fail.
2962*8d67ca89SAndroid Build Coastguard Worker   size_t EAGAIN_count = 0;
2963*8d67ca89SAndroid Build Coastguard Worker   size_t i = 0;
2964*8d67ca89SAndroid Build Coastguard Worker   for (; i < pages.size(); ++i) {
2965*8d67ca89SAndroid Build Coastguard Worker     pthread_t t;
2966*8d67ca89SAndroid Build Coastguard Worker     int status = pthread_create(&t, &attr, IdFn, nullptr);
2967*8d67ca89SAndroid Build Coastguard Worker     if (status != EAGAIN) break;
2968*8d67ca89SAndroid Build Coastguard Worker     ++EAGAIN_count;
2969*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, munmap(pages[i], kPageSize));
2970*8d67ca89SAndroid Build Coastguard Worker   }
2971*8d67ca89SAndroid Build Coastguard Worker 
2972*8d67ca89SAndroid Build Coastguard Worker   // Creating a thread uses at least three VMAs: the combined stack and TLS, and a guard on each
2973*8d67ca89SAndroid Build Coastguard Worker   // side. So we should have seen at least three failures.
2974*8d67ca89SAndroid Build Coastguard Worker   ASSERT_GE(EAGAIN_count, 3U);
2975*8d67ca89SAndroid Build Coastguard Worker 
2976*8d67ca89SAndroid Build Coastguard Worker   for (; i < pages.size(); ++i) {
2977*8d67ca89SAndroid Build Coastguard Worker     ASSERT_EQ(0, munmap(pages[i], kPageSize));
2978*8d67ca89SAndroid Build Coastguard Worker   }
2979*8d67ca89SAndroid Build Coastguard Worker }
2980*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_setschedparam)2981*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_setschedparam) {
2982*8d67ca89SAndroid Build Coastguard Worker   sched_param p = { .sched_priority = INT_MIN };
2983*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(EINVAL, pthread_setschedparam(pthread_self(), INT_MIN, &p));
2984*8d67ca89SAndroid Build Coastguard Worker }
2985*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_setschedprio)2986*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_setschedprio) {
2987*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(EINVAL, pthread_setschedprio(pthread_self(), INT_MIN));
2988*8d67ca89SAndroid Build Coastguard Worker }
2989*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_attr_getinheritsched__pthread_attr_setinheritsched)2990*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_attr_getinheritsched__pthread_attr_setinheritsched) {
2991*8d67ca89SAndroid Build Coastguard Worker   pthread_attr_t attr;
2992*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_init(&attr));
2993*8d67ca89SAndroid Build Coastguard Worker 
2994*8d67ca89SAndroid Build Coastguard Worker   int state;
2995*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED));
2996*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_getinheritsched(&attr, &state));
2997*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(PTHREAD_INHERIT_SCHED, state);
2998*8d67ca89SAndroid Build Coastguard Worker 
2999*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED));
3000*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_getinheritsched(&attr, &state));
3001*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(PTHREAD_EXPLICIT_SCHED, state);
3002*8d67ca89SAndroid Build Coastguard Worker 
3003*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(EINVAL, pthread_attr_setinheritsched(&attr, 123));
3004*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_getinheritsched(&attr, &state));
3005*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(PTHREAD_EXPLICIT_SCHED, state);
3006*8d67ca89SAndroid Build Coastguard Worker }
3007*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_attr_setinheritsched__PTHREAD_INHERIT_SCHED__PTHREAD_EXPLICIT_SCHED)3008*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_attr_setinheritsched__PTHREAD_INHERIT_SCHED__PTHREAD_EXPLICIT_SCHED) {
3009*8d67ca89SAndroid Build Coastguard Worker   pthread_attr_t attr;
3010*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_init(&attr));
3011*8d67ca89SAndroid Build Coastguard Worker 
3012*8d67ca89SAndroid Build Coastguard Worker   // If we set invalid scheduling attributes but choose to inherit, everything's fine...
3013*8d67ca89SAndroid Build Coastguard Worker   sched_param param = { .sched_priority = sched_get_priority_max(SCHED_FIFO) + 1 };
3014*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_setschedparam(&attr, &param));
3015*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_setschedpolicy(&attr, SCHED_FIFO));
3016*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED));
3017*8d67ca89SAndroid Build Coastguard Worker 
3018*8d67ca89SAndroid Build Coastguard Worker   pthread_t t;
3019*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_create(&t, &attr, IdFn, nullptr));
3020*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_join(t, nullptr));
3021*8d67ca89SAndroid Build Coastguard Worker 
3022*8d67ca89SAndroid Build Coastguard Worker #if defined(__LP64__)
3023*8d67ca89SAndroid Build Coastguard Worker   // If we ask to use them, though, we'll see a failure...
3024*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED));
3025*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(EINVAL, pthread_create(&t, &attr, IdFn, nullptr));
3026*8d67ca89SAndroid Build Coastguard Worker #else
3027*8d67ca89SAndroid Build Coastguard Worker   // For backwards compatibility with broken apps, we just ignore failures
3028*8d67ca89SAndroid Build Coastguard Worker   // to set scheduler attributes on LP32.
3029*8d67ca89SAndroid Build Coastguard Worker #endif
3030*8d67ca89SAndroid Build Coastguard Worker }
3031*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_attr_setinheritsched_PTHREAD_INHERIT_SCHED_takes_effect)3032*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_attr_setinheritsched_PTHREAD_INHERIT_SCHED_takes_effect) {
3033*8d67ca89SAndroid Build Coastguard Worker   sched_param param = { .sched_priority = sched_get_priority_min(SCHED_FIFO) };
3034*8d67ca89SAndroid Build Coastguard Worker   int rc = pthread_setschedparam(pthread_self(), SCHED_FIFO, &param);
3035*8d67ca89SAndroid Build Coastguard Worker   if (rc == EPERM) GTEST_SKIP() << "pthread_setschedparam failed with EPERM";
3036*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, rc);
3037*8d67ca89SAndroid Build Coastguard Worker 
3038*8d67ca89SAndroid Build Coastguard Worker   pthread_attr_t attr;
3039*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_init(&attr));
3040*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED));
3041*8d67ca89SAndroid Build Coastguard Worker 
3042*8d67ca89SAndroid Build Coastguard Worker   SpinFunctionHelper spin_helper;
3043*8d67ca89SAndroid Build Coastguard Worker   pthread_t t;
3044*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_create(&t, &attr, spin_helper.GetFunction(), nullptr));
3045*8d67ca89SAndroid Build Coastguard Worker   int actual_policy;
3046*8d67ca89SAndroid Build Coastguard Worker   sched_param actual_param;
3047*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_getschedparam(t, &actual_policy, &actual_param));
3048*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(SCHED_FIFO, actual_policy);
3049*8d67ca89SAndroid Build Coastguard Worker   spin_helper.UnSpin();
3050*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_join(t, nullptr));
3051*8d67ca89SAndroid Build Coastguard Worker }
3052*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_attr_setinheritsched_PTHREAD_EXPLICIT_SCHED_takes_effect)3053*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_attr_setinheritsched_PTHREAD_EXPLICIT_SCHED_takes_effect) {
3054*8d67ca89SAndroid Build Coastguard Worker   sched_param param = { .sched_priority = sched_get_priority_min(SCHED_FIFO) };
3055*8d67ca89SAndroid Build Coastguard Worker   int rc = pthread_setschedparam(pthread_self(), SCHED_FIFO, &param);
3056*8d67ca89SAndroid Build Coastguard Worker   if (rc == EPERM) GTEST_SKIP() << "pthread_setschedparam failed with EPERM";
3057*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, rc);
3058*8d67ca89SAndroid Build Coastguard Worker 
3059*8d67ca89SAndroid Build Coastguard Worker   pthread_attr_t attr;
3060*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_init(&attr));
3061*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED));
3062*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_setschedpolicy(&attr, SCHED_OTHER));
3063*8d67ca89SAndroid Build Coastguard Worker 
3064*8d67ca89SAndroid Build Coastguard Worker   SpinFunctionHelper spin_helper;
3065*8d67ca89SAndroid Build Coastguard Worker   pthread_t t;
3066*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_create(&t, &attr, spin_helper.GetFunction(), nullptr));
3067*8d67ca89SAndroid Build Coastguard Worker   int actual_policy;
3068*8d67ca89SAndroid Build Coastguard Worker   sched_param actual_param;
3069*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_getschedparam(t, &actual_policy, &actual_param));
3070*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(SCHED_OTHER, actual_policy);
3071*8d67ca89SAndroid Build Coastguard Worker   spin_helper.UnSpin();
3072*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_join(t, nullptr));
3073*8d67ca89SAndroid Build Coastguard Worker }
3074*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_attr_setinheritsched__takes_effect_despite_SCHED_RESET_ON_FORK)3075*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_attr_setinheritsched__takes_effect_despite_SCHED_RESET_ON_FORK) {
3076*8d67ca89SAndroid Build Coastguard Worker   sched_param param = { .sched_priority = sched_get_priority_min(SCHED_FIFO) };
3077*8d67ca89SAndroid Build Coastguard Worker   int rc = pthread_setschedparam(pthread_self(), SCHED_FIFO | SCHED_RESET_ON_FORK, &param);
3078*8d67ca89SAndroid Build Coastguard Worker   if (rc == EPERM) GTEST_SKIP() << "pthread_setschedparam failed with EPERM";
3079*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, rc);
3080*8d67ca89SAndroid Build Coastguard Worker 
3081*8d67ca89SAndroid Build Coastguard Worker   pthread_attr_t attr;
3082*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_init(&attr));
3083*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED));
3084*8d67ca89SAndroid Build Coastguard Worker 
3085*8d67ca89SAndroid Build Coastguard Worker   SpinFunctionHelper spin_helper;
3086*8d67ca89SAndroid Build Coastguard Worker   pthread_t t;
3087*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_create(&t, &attr, spin_helper.GetFunction(), nullptr));
3088*8d67ca89SAndroid Build Coastguard Worker   int actual_policy;
3089*8d67ca89SAndroid Build Coastguard Worker   sched_param actual_param;
3090*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_getschedparam(t, &actual_policy, &actual_param));
3091*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(SCHED_FIFO  | SCHED_RESET_ON_FORK, actual_policy);
3092*8d67ca89SAndroid Build Coastguard Worker   spin_helper.UnSpin();
3093*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_join(t, nullptr));
3094*8d67ca89SAndroid Build Coastguard Worker }
3095*8d67ca89SAndroid Build Coastguard Worker 
3096*8d67ca89SAndroid Build Coastguard Worker extern "C" bool android_run_on_all_threads(bool (*func)(void*), void* arg);
3097*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,run_on_all_threads)3098*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, run_on_all_threads) {
3099*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
3100*8d67ca89SAndroid Build Coastguard Worker   pthread_t t;
3101*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(
3102*8d67ca89SAndroid Build Coastguard Worker       0, pthread_create(
3103*8d67ca89SAndroid Build Coastguard Worker              &t, nullptr,
3104*8d67ca89SAndroid Build Coastguard Worker              [](void*) -> void* {
3105*8d67ca89SAndroid Build Coastguard Worker                pthread_attr_t detached;
3106*8d67ca89SAndroid Build Coastguard Worker                if (pthread_attr_init(&detached) != 0 ||
3107*8d67ca89SAndroid Build Coastguard Worker                    pthread_attr_setdetachstate(&detached, PTHREAD_CREATE_DETACHED) != 0) {
3108*8d67ca89SAndroid Build Coastguard Worker                  return reinterpret_cast<void*>(errno);
3109*8d67ca89SAndroid Build Coastguard Worker                }
3110*8d67ca89SAndroid Build Coastguard Worker 
3111*8d67ca89SAndroid Build Coastguard Worker                for (int i = 0; i != 1000; ++i) {
3112*8d67ca89SAndroid Build Coastguard Worker                  pthread_t t1, t2;
3113*8d67ca89SAndroid Build Coastguard Worker                  if (pthread_create(
3114*8d67ca89SAndroid Build Coastguard Worker                          &t1, &detached, [](void*) -> void* { return nullptr; }, nullptr) != 0 ||
3115*8d67ca89SAndroid Build Coastguard Worker                      pthread_create(
3116*8d67ca89SAndroid Build Coastguard Worker                          &t2, nullptr, [](void*) -> void* { return nullptr; }, nullptr) != 0 ||
3117*8d67ca89SAndroid Build Coastguard Worker                      pthread_join(t2, nullptr) != 0) {
3118*8d67ca89SAndroid Build Coastguard Worker                    return reinterpret_cast<void*>(errno);
3119*8d67ca89SAndroid Build Coastguard Worker                  }
3120*8d67ca89SAndroid Build Coastguard Worker                }
3121*8d67ca89SAndroid Build Coastguard Worker 
3122*8d67ca89SAndroid Build Coastguard Worker                if (pthread_attr_destroy(&detached) != 0) {
3123*8d67ca89SAndroid Build Coastguard Worker                  return reinterpret_cast<void*>(errno);
3124*8d67ca89SAndroid Build Coastguard Worker                }
3125*8d67ca89SAndroid Build Coastguard Worker                return nullptr;
3126*8d67ca89SAndroid Build Coastguard Worker              },
3127*8d67ca89SAndroid Build Coastguard Worker              nullptr));
3128*8d67ca89SAndroid Build Coastguard Worker 
3129*8d67ca89SAndroid Build Coastguard Worker   for (int i = 0; i != 1000; ++i) {
3130*8d67ca89SAndroid Build Coastguard Worker     ASSERT_TRUE(android_run_on_all_threads([](void* arg) { return arg == nullptr; }, nullptr));
3131*8d67ca89SAndroid Build Coastguard Worker   }
3132*8d67ca89SAndroid Build Coastguard Worker 
3133*8d67ca89SAndroid Build Coastguard Worker   void *retval;
3134*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_join(t, &retval));
3135*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(nullptr, retval);
3136*8d67ca89SAndroid Build Coastguard Worker #else
3137*8d67ca89SAndroid Build Coastguard Worker   GTEST_SKIP() << "bionic-only test";
3138*8d67ca89SAndroid Build Coastguard Worker #endif
3139*8d67ca89SAndroid Build Coastguard Worker }
3140*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_getaffinity_np_failure)3141*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_getaffinity_np_failure) {
3142*8d67ca89SAndroid Build Coastguard Worker   // Trivial test of the errno-preserving/returning behavior.
3143*8d67ca89SAndroid Build Coastguard Worker #pragma clang diagnostic push
3144*8d67ca89SAndroid Build Coastguard Worker #pragma clang diagnostic ignored "-Wnonnull"
3145*8d67ca89SAndroid Build Coastguard Worker   errno = 0;
3146*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(EINVAL, pthread_getaffinity_np(pthread_self(), 0, nullptr));
3147*8d67ca89SAndroid Build Coastguard Worker   ASSERT_ERRNO(0);
3148*8d67ca89SAndroid Build Coastguard Worker #pragma clang diagnostic pop
3149*8d67ca89SAndroid Build Coastguard Worker }
3150*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_getaffinity)3151*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_getaffinity) {
3152*8d67ca89SAndroid Build Coastguard Worker   cpu_set_t set;
3153*8d67ca89SAndroid Build Coastguard Worker   CPU_ZERO(&set);
3154*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_getaffinity_np(pthread_self(), sizeof(set), &set));
3155*8d67ca89SAndroid Build Coastguard Worker   ASSERT_GT(CPU_COUNT(&set), 0);
3156*8d67ca89SAndroid Build Coastguard Worker }
3157*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_setaffinity_np_failure)3158*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_setaffinity_np_failure) {
3159*8d67ca89SAndroid Build Coastguard Worker   // Trivial test of the errno-preserving/returning behavior.
3160*8d67ca89SAndroid Build Coastguard Worker #pragma clang diagnostic push
3161*8d67ca89SAndroid Build Coastguard Worker #pragma clang diagnostic ignored "-Wnonnull"
3162*8d67ca89SAndroid Build Coastguard Worker   errno = 0;
3163*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(EINVAL, pthread_setaffinity_np(pthread_self(), 0, nullptr));
3164*8d67ca89SAndroid Build Coastguard Worker   ASSERT_ERRNO(0);
3165*8d67ca89SAndroid Build Coastguard Worker #pragma clang diagnostic pop
3166*8d67ca89SAndroid Build Coastguard Worker }
3167*8d67ca89SAndroid Build Coastguard Worker 
TEST(pthread,pthread_setaffinity)3168*8d67ca89SAndroid Build Coastguard Worker TEST(pthread, pthread_setaffinity) {
3169*8d67ca89SAndroid Build Coastguard Worker   cpu_set_t set;
3170*8d67ca89SAndroid Build Coastguard Worker   CPU_ZERO(&set);
3171*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_getaffinity_np(pthread_self(), sizeof(set), &set));
3172*8d67ca89SAndroid Build Coastguard Worker   // It's hard to make any more general claim than this,
3173*8d67ca89SAndroid Build Coastguard Worker   // but it ought to be safe to ask for the same affinity you already have.
3174*8d67ca89SAndroid Build Coastguard Worker   ASSERT_EQ(0, pthread_setaffinity_np(pthread_self(), sizeof(set), &set));
3175*8d67ca89SAndroid Build Coastguard Worker }
3176