diff --git a/tools/testing/selftests/futex/functional/futex_wait.c b/tools/testing/selftests/futex/functional/futex_wait.c index 7b8879409007..5292f5d2c3b5 100644 --- a/tools/testing/selftests/futex/functional/futex_wait.c +++ b/tools/testing/selftests/futex/functional/futex_wait.c @@ -5,10 +5,11 @@ * futex cmp requeue test by André Almeida */ +#include #include +#include #include #include -#include #include "futextest.h" #include "kselftest_harness.h" @@ -19,125 +20,157 @@ void *futex; +struct waiter_args { + struct __test_metadata *_metadata; + unsigned int flags; +}; + static void *waiterfn(void *arg) { + struct waiter_args *args = (struct waiter_args *)arg; + struct __test_metadata *_metadata = args->_metadata; struct timespec to; - unsigned int flags = 0; - - if (arg) - flags = *((unsigned int *) arg); + int res; to.tv_sec = 0; to.tv_nsec = timeout_ns; - if (futex_wait(futex, 0, &to, flags)) - printf("waiter failed errno %d\n", errno); + res = futex_wait(futex, 0, &to, args->flags); + if (res) { + EXPECT_EQ(res, 0) + TH_LOG("waiter failed errno %d: %s", errno, strerror(errno)); + } + free(args); return NULL; } TEST(private_futex) { - unsigned int flags = FUTEX_PRIVATE_FLAG; + struct waiter_args *args = malloc(sizeof(*args)); u_int32_t f_private = 0; pthread_t waiter; int res; + args->_metadata = _metadata; + args->flags = FUTEX_PRIVATE_FLAG; futex = &f_private; /* Testing a private futex */ - ksft_print_dbg_msg("Calling private futex_wait on futex: %p\n", futex); - if (pthread_create(&waiter, NULL, waiterfn, (void *) &flags)) - ksft_exit_fail_msg("pthread_create failed\n"); + TH_LOG("Calling private futex_wait on futex: %p", futex); + ASSERT_EQ(pthread_create(&waiter, NULL, waiterfn, args), 0) + TH_LOG("pthread_create failed"); usleep(WAKE_WAIT_US); - ksft_print_dbg_msg("Calling private futex_wake on futex: %p\n", futex); + TH_LOG("Calling private futex_wake on futex: %p", futex); res = futex_wake(futex, 1, FUTEX_PRIVATE_FLAG); - if (res != 1) { - ksft_test_result_fail("futex_wake private returned: %d %s\n", - errno, strerror(errno)); - } else { - ksft_test_result_pass("futex_wake private succeeds\n"); - } + EXPECT_EQ(res, 1) + TH_LOG("futex_wake private returned: %d %s", res, res < 0 ? strerror(errno) : ""); + + pthread_join(waiter, NULL); } TEST(anon_page) { + struct waiter_args *args = malloc(sizeof(*args)); u_int32_t *shared_data; pthread_t waiter; int res, shm_id; + args->_metadata = _metadata; + args->flags = 0; + /* Testing an anon page shared memory */ shm_id = shmget(IPC_PRIVATE, 4096, IPC_CREAT | 0666); if (shm_id < 0) { - if (errno == ENOSYS) - ksft_exit_skip("shmget syscall not supported\n"); - perror("shmget"); - exit(1); + if (errno == ENOSYS) { + free(args); + SKIP(return, "shmget syscall not supported"); + } + ASSERT_GE(shm_id, 0) + TH_LOG("shmget failed: %s", strerror(errno)); } shared_data = shmat(shm_id, NULL, 0); + if (shared_data == (void *)-1) { + free(args); + ASSERT_NE(shared_data, (void *)-1) + TH_LOG("shmat failed: %s", strerror(errno)); + } *shared_data = 0; futex = shared_data; - ksft_print_dbg_msg("Calling shared (page anon) futex_wait on futex: %p\n", futex); - if (pthread_create(&waiter, NULL, waiterfn, NULL)) - ksft_exit_fail_msg("pthread_create failed\n"); + TH_LOG("Calling shared (page anon) futex_wait on futex: %p", futex); + ASSERT_EQ(pthread_create(&waiter, NULL, waiterfn, args), 0) + TH_LOG("pthread_create failed"); usleep(WAKE_WAIT_US); - ksft_print_dbg_msg("Calling shared (page anon) futex_wake on futex: %p\n", futex); + TH_LOG("Calling shared (page anon) futex_wake on futex: %p", futex); res = futex_wake(futex, 1, 0); - if (res != 1) { - ksft_test_result_fail("futex_wake shared (page anon) returned: %d %s\n", - errno, strerror(errno)); - } else { - ksft_test_result_pass("futex_wake shared (page anon) succeeds\n"); + EXPECT_EQ(res, 1) { + TH_LOG("futex_wake shared (page anon) returned: %d %s", + res, res < 0 ? strerror(errno) : ""); } + pthread_join(waiter, NULL); shmdt(shared_data); } TEST(file_backed) { + struct waiter_args *args = malloc(sizeof(*args)); u_int32_t f_private = 0; pthread_t waiter; int res, fd; void *shm; - /* Testing a file backed shared memory */ - fd = open(SHM_PATH, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); - if (fd < 0) - ksft_exit_fail_msg("open\n"); + args->_metadata = _metadata; + args->flags = 0; - if (ftruncate(fd, sizeof(f_private))) - ksft_exit_fail_msg("ftruncate\n"); + /* Testing a file backed shared memory */ + fd = open(SHM_PATH, O_RDWR | O_CREAT, 0600); + if (fd < 0) { + free(args); + ASSERT_GE(fd, 0) + TH_LOG("open failed: %s", strerror(errno)); + } + + if (ftruncate(fd, sizeof(f_private))) { + free(args); + close(fd); + ASSERT_TRUE(0) + TH_LOG("ftruncate failed: %s", strerror(errno)); + } shm = mmap(NULL, sizeof(f_private), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - if (shm == MAP_FAILED) - ksft_exit_fail_msg("mmap\n"); + if (shm == MAP_FAILED) { + free(args); + close(fd); + ASSERT_NE(shm, MAP_FAILED) + TH_LOG("mmap failed: %s", strerror(errno)); + } memcpy(shm, &f_private, sizeof(f_private)); futex = shm; - ksft_print_dbg_msg("Calling shared (file backed) futex_wait on futex: %p\n", futex); - if (pthread_create(&waiter, NULL, waiterfn, NULL)) - ksft_exit_fail_msg("pthread_create failed\n"); + TH_LOG("Calling shared (file backed) futex_wait on futex: %p", futex); + ASSERT_EQ(pthread_create(&waiter, NULL, waiterfn, args), 0) + TH_LOG("pthread_create failed"); usleep(WAKE_WAIT_US); - ksft_print_dbg_msg("Calling shared (file backed) futex_wake on futex: %p\n", futex); + TH_LOG("Calling shared (file backed) futex_wake on futex: %p", futex); res = futex_wake(shm, 1, 0); - if (res != 1) { - ksft_test_result_fail("futex_wake shared (file backed) returned: %d %s\n", - errno, strerror(errno)); - } else { - ksft_test_result_pass("futex_wake shared (file backed) succeeds\n"); + EXPECT_EQ(res, 1) { + TH_LOG("futex_wake shared (file backed) returned: %d %s", + res, res < 0 ? strerror(errno) : ""); } + pthread_join(waiter, NULL); munmap(shm, sizeof(f_private)); remove(SHM_PATH); close(fd);