blob: b06efa29e0d8491b69d5544e0230f2a133a7f34e [file] [log] [blame]
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <errno.h>
#include <linux/futex.h>
#include <pthread.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>
#include "gtest/gtest.h"
extern "C" int __wrap_syscall(int number, ...); // testee
TEST(SyscallWrapTest, TestGettid) {
EXPECT_LE(0, __wrap_syscall(__NR_gettid));
EXPECT_EQ(gettid(), __wrap_syscall(__NR_gettid));
}
TEST(SyscallWrapTest, TestFutexTimedWait) {
int ftx = 0;
const struct timespec timeout = {0, 1};
errno = 0;
EXPECT_EQ(-1, __wrap_syscall(
__NR_futex, &ftx, FUTEX_WAIT, 0, &timeout, NULL, 0));
EXPECT_EQ(ETIMEDOUT, errno);
ftx = 0;
errno = 0;
EXPECT_EQ(-1, __wrap_syscall(
__NR_futex, &ftx, FUTEX_WAIT_PRIVATE, 0, &timeout, NULL, 0));
EXPECT_EQ(ETIMEDOUT, errno);
}
TEST(SyscallWrapTest, TestFutexWait) {
int ftx = 1;
errno = 0;
EXPECT_EQ(-1, __wrap_syscall(
__NR_futex, &ftx, FUTEX_WAIT, 0, NULL, NULL, 0));
EXPECT_EQ(EWOULDBLOCK, errno);
ftx = 1;
errno = 0;
EXPECT_EQ(-1, __wrap_syscall(
__NR_futex, &ftx, FUTEX_WAIT_PRIVATE, 0, NULL, NULL, 0));
EXPECT_EQ(EWOULDBLOCK, errno);
}
static void* Signal(void* ftx) {
int woken;
do {
woken = __wrap_syscall(__NR_futex, ftx, FUTEX_WAKE, 1, NULL, NULL, 0);
// Check that woken is 0 or 1.
EXPECT_LE(0, woken);
EXPECT_GE(1, woken);
} while (woken == 0);
return NULL;
}
TEST(SyscallWrapTest, TestFutexWake) {
int ftx = 0;
pthread_t th;
pthread_create(&th, NULL, Signal, &ftx);
errno = 0;
EXPECT_EQ(0, __wrap_syscall(__NR_futex, &ftx, FUTEX_WAIT, 0, NULL, NULL, 0));
EXPECT_EQ(0, errno);
EXPECT_EQ(0, pthread_join(th, NULL));
}
static void* SignalAll(void* ftx) {
int woken;
do {
woken = __wrap_syscall(
__NR_futex, ftx, FUTEX_WAKE_PRIVATE, INT_MAX, NULL, NULL, 0);
// Check that woken is 0 or 1.
EXPECT_LE(0, woken);
EXPECT_GE(1, woken);
} while (woken == 0);
return NULL;
}
TEST(SyscallWrapTest, QEMU_DISABLED_TestFutexWakePrivate) {
int ftx = 0;
pthread_t th;
pthread_create(&th, NULL, SignalAll, &ftx);
errno = 0;
EXPECT_EQ(0, __wrap_syscall(
__NR_futex, &ftx, FUTEX_WAIT_PRIVATE, 0, NULL, NULL, 0));
EXPECT_EQ(0, errno);
EXPECT_EQ(0, pthread_join(th, NULL));
}
TEST(SyscallWrapTest, TestFutexFd) {
errno = 0;
EXPECT_EQ(-1, __wrap_syscall(__NR_futex, NULL, FUTEX_FD, 0, NULL, NULL, 0));
EXPECT_EQ(ENOSYS, errno);
}
TEST(SyscallWrapTest, TestEnosys) {
// As of today, all syscalls other than gettid and futex are unsupported.
errno = 0;
EXPECT_EQ(-1, __wrap_syscall(__NR_access, "/", R_OK));
EXPECT_EQ(ENOSYS, errno);
}