104303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes/*
204303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes * Copyright (C) 2014 The Android Open Source Project
304303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes *
404303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
504303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes * you may not use this file except in compliance with the License.
604303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes * You may obtain a copy of the License at
704303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes *
804303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
904303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes *
1004303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes * Unless required by applicable law or agreed to in writing, software
1104303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
1204303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1304303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes * See the License for the specific language governing permissions and
1404303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes * limitations under the License.
1504303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes */
1604303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes
1704303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes#include <semaphore.h>
1804303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes
1904303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes#include <errno.h>
2004303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes#include <gtest/gtest.h>
2104303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes#include <limits.h>
2204303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes#include <pthread.h>
2304303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes#include <time.h>
2404303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes#include <unistd.h>
2504303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes
2604303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes#include "private/bionic_constants.h"
27ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui#include "ScopedSignalHandler.h"
2804303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes
2904303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott HughesTEST(semaphore, sem_init) {
3004303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  sem_t s;
3104303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes
3204303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  // Perfectly fine initial values.
3304303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ASSERT_EQ(0, sem_init(&s, 0, 0));
3404303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ASSERT_EQ(0, sem_init(&s, 0, 1));
3504303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ASSERT_EQ(0, sem_init(&s, 0, 123));
3604303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes
3704303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  // Too small an initial value.
3804303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  errno = 0;
3904303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ASSERT_EQ(-1, sem_init(&s, 0, -1));
4004303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ASSERT_EQ(EINVAL, errno);
4104303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes
4204303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ASSERT_EQ(SEM_VALUE_MAX, sysconf(_SC_SEM_VALUE_MAX));
4304303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes
4404303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  // The largest initial value.
4504303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ASSERT_EQ(0, sem_init(&s, 0, SEM_VALUE_MAX));
4604303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes
4704303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  // Too large an initial value.
4804303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  errno = 0;
4904303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ASSERT_EQ(-1, sem_init(&s, 0, SEM_VALUE_MAX + 1));
5004303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ASSERT_EQ(EINVAL, errno);
5104303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes
5204303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ASSERT_EQ(0, sem_destroy(&s));
5304303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes}
5404303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes
5504303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott HughesTEST(semaphore, sem_trywait) {
5604303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  sem_t s;
5704303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ASSERT_EQ(0, sem_init(&s, 0, 3));
5804303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ASSERT_EQ(0, sem_trywait(&s));
5904303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ASSERT_EQ(0, sem_trywait(&s));
6004303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ASSERT_EQ(0, sem_trywait(&s));
6104303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  errno = 0;
6204303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ASSERT_EQ(-1, sem_trywait(&s));
6304303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ASSERT_EQ(EAGAIN, errno);
6404303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ASSERT_EQ(0, sem_destroy(&s));
6504303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes}
6604303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes
6704303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughesstatic void SemWaitThreadTestFn(sem_t& sem) {
6804303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ASSERT_EQ(0, sem_wait(&sem));
6904303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes}
7004303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes
7104303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughesstatic void* SemWaitThreadFn(void* arg) {
7204303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  SemWaitThreadTestFn(*reinterpret_cast<sem_t*>(arg));
7304303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  return nullptr;
7404303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes}
7504303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes
7604303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott HughesTEST(semaphore, sem_wait__sem_post) {
7704303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  sem_t s;
7804303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ASSERT_EQ(0, sem_init(&s, 0, 0));
7904303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes
8004303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  pthread_t t1, t2, t3;
8104303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ASSERT_EQ(0, pthread_create(&t1, NULL, SemWaitThreadFn, &s));
8204303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ASSERT_EQ(0, pthread_create(&t2, NULL, SemWaitThreadFn, &s));
8304303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ASSERT_EQ(0, pthread_create(&t3, NULL, SemWaitThreadFn, &s));
8404303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes
8504303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ASSERT_EQ(0, sem_post(&s));
8604303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ASSERT_EQ(0, sem_post(&s));
8704303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ASSERT_EQ(0, sem_post(&s));
8804303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes
8904303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  void* result;
9004303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ASSERT_EQ(0, pthread_join(t1, &result));
9104303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ASSERT_EQ(0, pthread_join(t2, &result));
9204303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ASSERT_EQ(0, pthread_join(t3, &result));
9304303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes}
9404303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes
9504303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughesstatic inline void timespec_add_ms(timespec& ts, size_t ms) {
9604303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ts.tv_sec  += ms / 1000;
9704303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ts.tv_nsec += (ms % 1000) * 1000000;
9804303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  if (ts.tv_nsec >= NS_PER_S) {
9904303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes    ts.tv_sec++;
10004303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes    ts.tv_nsec -= NS_PER_S;
10104303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  }
10204303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes}
10304303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes
10404303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott HughesTEST(semaphore, sem_timedwait) {
10504303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  sem_t s;
10604303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ASSERT_EQ(0, sem_init(&s, 0, 0));
10704303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes
10804303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  timespec ts;
10904303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ASSERT_EQ(0, clock_gettime(CLOCK_REALTIME, &ts));
11004303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  timespec_add_ms(ts, 100);
11104303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes
11204303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  errno = 0;
11304303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ASSERT_EQ(-1, sem_timedwait(&s, &ts));
11404303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ASSERT_EQ(ETIMEDOUT, errno);
11504303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes
11604303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  // A negative timeout is an error.
11704303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  errno = 0;
11804303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ts.tv_nsec = -1;
11904303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ASSERT_EQ(-1, sem_timedwait(&s, &ts));
12004303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ASSERT_EQ(EINVAL, errno);
121c9a659c57b256001fd63f9825bde69e660c2655bYabin Cui  errno = 0;
122c9a659c57b256001fd63f9825bde69e660c2655bYabin Cui  ts.tv_nsec = NS_PER_S;
123c9a659c57b256001fd63f9825bde69e660c2655bYabin Cui  ASSERT_EQ(-1, sem_timedwait(&s, &ts));
124c9a659c57b256001fd63f9825bde69e660c2655bYabin Cui  ASSERT_EQ(EINVAL, errno);
125c9a659c57b256001fd63f9825bde69e660c2655bYabin Cui
126c9a659c57b256001fd63f9825bde69e660c2655bYabin Cui  errno = 0;
127c9a659c57b256001fd63f9825bde69e660c2655bYabin Cui  ts.tv_nsec = NS_PER_S - 1;
128c9a659c57b256001fd63f9825bde69e660c2655bYabin Cui  ts.tv_sec = -1;
129c9a659c57b256001fd63f9825bde69e660c2655bYabin Cui  ASSERT_EQ(-1, sem_timedwait(&s, &ts));
130c9a659c57b256001fd63f9825bde69e660c2655bYabin Cui  ASSERT_EQ(ETIMEDOUT, errno);
13104303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes
13204303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ASSERT_EQ(0, sem_destroy(&s));
13304303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes}
13404303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes
135dd586f2ebd0c42904e699f3634568a38c97d4da7Elliott HughesTEST(semaphore_DeathTest, sem_timedwait_null_timeout) {
136dd586f2ebd0c42904e699f3634568a38c97d4da7Elliott Hughes  sem_t s;
137dd586f2ebd0c42904e699f3634568a38c97d4da7Elliott Hughes  ASSERT_EQ(0, sem_init(&s, 0, 0));
138dd586f2ebd0c42904e699f3634568a38c97d4da7Elliott Hughes
139dd586f2ebd0c42904e699f3634568a38c97d4da7Elliott Hughes  ASSERT_EXIT(sem_timedwait(&s, nullptr), testing::KilledBySignal(SIGSEGV), "");
140dd586f2ebd0c42904e699f3634568a38c97d4da7Elliott Hughes}
141dd586f2ebd0c42904e699f3634568a38c97d4da7Elliott Hughes
14204303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott HughesTEST(semaphore, sem_getvalue) {
14304303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  sem_t s;
14404303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ASSERT_EQ(0, sem_init(&s, 0, 0));
14504303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes
14604303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  int i;
14704303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ASSERT_EQ(0, sem_getvalue(&s, &i));
14804303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ASSERT_EQ(0, i);
14904303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes
15004303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ASSERT_EQ(0, sem_post(&s));
15104303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ASSERT_EQ(0, sem_getvalue(&s, &i));
15204303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ASSERT_EQ(1, i);
15304303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes
15404303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ASSERT_EQ(0, sem_post(&s));
15504303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ASSERT_EQ(0, sem_getvalue(&s, &i));
15604303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ASSERT_EQ(2, i);
15704303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes
15804303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ASSERT_EQ(0, sem_wait(&s));
15904303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ASSERT_EQ(0, sem_getvalue(&s, &i));
16004303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes  ASSERT_EQ(1, i);
16104303f5a8ab9a992f3671d46b6ee2171582cbd61Elliott Hughes}
162ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui
163ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cuiextern "C" void android_set_application_target_sdk_version(uint32_t target);
164ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui
165ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cuistatic void sem_wait_test_signal_handler(int) {
166ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui}
167ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui
168ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cuistatic void* SemWaitEINTRThreadFn(void* arg) {
169ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui  sem_t* sem = reinterpret_cast<sem_t*>(arg);
170ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui  uintptr_t have_eintr = 0;
171ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui  uintptr_t have_error = 0;
172ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui  while (true) {
173ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui    int result = sem_wait(sem);
174ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui    if (result == 0) {
175ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui      break;
176ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui    }
177ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui    if (result == -1) {
178ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui      if (errno == EINTR) {
179ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui        have_eintr = 1;
180ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui      } else {
181ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui        have_error = 1;
182ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui        break;
183ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui      }
184ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui    }
185ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui  }
186ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui  return reinterpret_cast<void*>((have_eintr << 1) | have_error);
187ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui}
188ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui
189ca482742985a22dbf5ee4a0afdf8525300f7785dYabin CuiTEST(semaphore, sem_wait_no_EINTR_in_sdk_less_equal_than_23) {
190ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui#if defined(__BIONIC__)
191ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui  android_set_application_target_sdk_version(23U);
192ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui  sem_t s;
193ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui  ASSERT_EQ(0, sem_init(&s, 0, 0));
194ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui  ScopedSignalHandler handler(SIGUSR1, sem_wait_test_signal_handler);
195ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui  pthread_t thread;
196ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui  ASSERT_EQ(0, pthread_create(&thread, nullptr, SemWaitEINTRThreadFn, &s));
197ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui  // Give some time for the thread to run sem_wait.
198ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui  usleep(500000);
199ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui  ASSERT_EQ(0, pthread_kill(thread, SIGUSR1));
200ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui  // Give some time for the thread to handle signal.
201ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui  usleep(500000);
202ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui  ASSERT_EQ(0, sem_post(&s));
203ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui  void* result;
204ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui  ASSERT_EQ(0, pthread_join(thread, &result));
205ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui  ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(result));
206ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui#else
207ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui  GTEST_LOG_(INFO) << "This test tests sem_wait's compatibility for old sdk versions";
208ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui#endif
209ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui}
210ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui
211ca482742985a22dbf5ee4a0afdf8525300f7785dYabin CuiTEST(semaphore, sem_wait_EINTR_in_sdk_greater_than_23) {
212ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui#if defined(__BIONIC__)
213ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui  android_set_application_target_sdk_version(24U);
214ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui#endif
215ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui  sem_t s;
216ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui  ASSERT_EQ(0, sem_init(&s, 0, 0));
217ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui  ScopedSignalHandler handler(SIGUSR1, sem_wait_test_signal_handler);
218ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui  pthread_t thread;
219ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui  ASSERT_EQ(0, pthread_create(&thread, nullptr, SemWaitEINTRThreadFn, &s));
220ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui  // Give some time for the thread to run sem_wait.
221ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui  usleep(500000);
222ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui  ASSERT_EQ(0, pthread_kill(thread, SIGUSR1));
223ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui  // Give some time for the thread to handle signal.
224ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui  usleep(500000);
225ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui  ASSERT_EQ(0, sem_post(&s));
226ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui  void* result;
227ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui  ASSERT_EQ(0, pthread_join(thread, &result));
228ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui  ASSERT_EQ(2U, reinterpret_cast<uintptr_t>(result));
229ca482742985a22dbf5ee4a0afdf8525300f7785dYabin Cui}
230