1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /****************************************************************************** 3 * 4 * Copyright FUJITSU LIMITED 2010 5 * Copyright KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> 6 * 7 * DESCRIPTION 8 * Internally, Futex has two handling mode, anon and file. The private file 9 * mapping is special. At first it behave as file, but after write anything 10 * it behave as anon. This test is intent to test such case. 11 * 12 * AUTHOR 13 * KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> 14 * 15 * HISTORY 16 * 2010-Jan-6: Initial version by KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> 17 * 18 *****************************************************************************/ 19 20 #include <stdio.h> 21 #include <stdlib.h> 22 #include <syscall.h> 23 #include <unistd.h> 24 #include <errno.h> 25 #include <linux/futex.h> 26 #include <pthread.h> 27 #include <libgen.h> 28 #include <signal.h> 29 #include <string.h> 30 31 #include "futextest.h" 32 #include "kselftest_harness.h" 33 34 #define PAGE_SZ 4096 35 36 char pad[PAGE_SZ] = {1}; 37 futex_t val = 1; 38 char pad2[PAGE_SZ] = {1}; 39 40 #define WAKE_WAIT_US 3000000 41 struct timespec wait_timeout = { .tv_sec = 5, .tv_nsec = 0}; 42 43 void *thr_futex_wait(void *arg) 44 { 45 struct __test_metadata *_metadata = (struct __test_metadata *)arg; 46 int ret; 47 48 TH_LOG("futex wait"); 49 ret = futex_wait(&val, 1, &wait_timeout, 0); 50 if (ret && errno != EWOULDBLOCK && errno != ETIMEDOUT) { 51 ASSERT_TRUE(0) 52 TH_LOG("futex error: %s", strerror(errno)); 53 } 54 55 if (ret && errno == ETIMEDOUT) { 56 ASSERT_TRUE(0) 57 TH_LOG("waiter timedout"); 58 } 59 60 TH_LOG("futex_wait: ret = %d, errno = %d", ret, errno); 61 62 return NULL; 63 } 64 65 TEST(wait_private_mapped_file) 66 { 67 pthread_t thr; 68 int res; 69 70 res = pthread_create(&thr, NULL, thr_futex_wait, _metadata); 71 ASSERT_EQ(res, 0) 72 TH_LOG("pthread_create error"); 73 74 TH_LOG("wait a while"); 75 usleep(WAKE_WAIT_US); 76 val = 2; 77 res = futex_wake(&val, 1, 0); 78 TH_LOG("futex_wake %d", res); 79 EXPECT_EQ(res, 1) 80 TH_LOG("FUTEX_WAKE didn't find the waiting thread"); 81 82 TH_LOG("join"); 83 pthread_join(thr, NULL); 84 } 85 86 TEST_HARNESS_MAIN 87