1616 *****************************************************************************/
1717
1818#include <pthread.h>
19+
1920#include "futextest.h"
2021#include "futex2test.h"
21- #include "logging.h"
22-
23- #define TEST_NAME "futex-wait-timeout"
22+ #include "../../kselftest_harness.h"
2423
2524static long timeout_ns = 100000 ; /* 100us default timeout */
2625static futex_t futex_pi ;
2726static pthread_barrier_t barrier ;
2827
29- void usage (char * prog )
30- {
31- printf ("Usage: %s\n" , prog );
32- printf (" -c Use color\n" );
33- printf (" -h Display this help message\n" );
34- printf (" -t N Timeout in nanoseconds (default: 100,000)\n" );
35- printf (" -v L Verbosity level: %d=QUIET %d=CRITICAL %d=INFO\n" ,
36- VQUIET , VCRITICAL , VINFO );
37- }
38-
3928/*
4029 * Get a PI lock and hold it forever, so the main thread lock_pi will block
4130 * and we can test the timeout
@@ -47,26 +36,25 @@ void *get_pi_lock(void *arg)
4736
4837 ret = futex_lock_pi (& futex_pi , NULL , 0 , 0 );
4938 if (ret != 0 )
50- error ("futex_lock_pi failed\n" , ret );
39+ ksft_exit_fail_msg ("futex_lock_pi failed\n" );
5140
5241 pthread_barrier_wait (& barrier );
5342
5443 /* Blocks forever */
5544 ret = futex_wait (& lock , 0 , NULL , 0 );
56- error ("futex_wait failed\n" , ret );
45+ ksft_exit_fail_msg ("futex_wait failed\n" );
5746
5847 return NULL ;
5948}
6049
6150/*
6251 * Check if the function returned the expected error
6352 */
64- static void test_timeout (int res , int * ret , char * test_name , int err )
53+ static void test_timeout (int res , char * test_name , int err )
6554{
6655 if (!res || errno != err ) {
6756 ksft_test_result_fail ("%s returned %d\n" , test_name ,
6857 res < 0 ? errno : res );
69- * ret = RET_FAIL ;
7058 } else {
7159 ksft_test_result_pass ("%s succeeds\n" , test_name );
7260 }
@@ -78,10 +66,8 @@ static void test_timeout(int res, int *ret, char *test_name, int err)
7866static int futex_get_abs_timeout (clockid_t clockid , struct timespec * to ,
7967 long timeout_ns )
8068{
81- if (clock_gettime (clockid , to )) {
82- error ("clock_gettime failed\n" , errno );
83- return errno ;
84- }
69+ if (clock_gettime (clockid , to ))
70+ ksft_exit_fail_msg ("clock_gettime failed\n" );
8571
8672 to -> tv_nsec += timeout_ns ;
8773
@@ -93,83 +79,66 @@ static int futex_get_abs_timeout(clockid_t clockid, struct timespec *to,
9379 return 0 ;
9480}
9581
96- int main ( int argc , char * argv [] )
82+ TEST ( wait_bitset )
9783{
9884 futex_t f1 = FUTEX_INITIALIZER ;
99- int res , ret = RET_PASS ;
10085 struct timespec to ;
101- pthread_t thread ;
102- int c ;
103- struct futex_waitv waitv = {
104- .uaddr = (uintptr_t )& f1 ,
105- .val = f1 ,
106- .flags = FUTEX_32 ,
107- .__reserved = 0
108- };
109-
110- while ((c = getopt (argc , argv , "cht:v:" )) != -1 ) {
111- switch (c ) {
112- case 'c' :
113- log_color (1 );
114- break ;
115- case 'h' :
116- usage (basename (argv [0 ]));
117- exit (0 );
118- case 't' :
119- timeout_ns = atoi (optarg );
120- break ;
121- case 'v' :
122- log_verbosity (atoi (optarg ));
123- break ;
124- default :
125- usage (basename (argv [0 ]));
126- exit (1 );
127- }
128- }
129-
130- ksft_print_header ();
131- ksft_set_plan (9 );
132- ksft_print_msg ("%s: Block on a futex and wait for timeout\n" ,
133- basename (argv [0 ]));
134- ksft_print_msg ("\tArguments: timeout=%ldns\n" , timeout_ns );
135-
136- pthread_barrier_init (& barrier , NULL , 2 );
137- pthread_create (& thread , NULL , get_pi_lock , NULL );
86+ int res ;
13887
13988 /* initialize relative timeout */
14089 to .tv_sec = 0 ;
14190 to .tv_nsec = timeout_ns ;
14291
14392 res = futex_wait (& f1 , f1 , & to , 0 );
144- test_timeout (res , & ret , "futex_wait relative" , ETIMEDOUT );
93+ test_timeout (res , "futex_wait relative" , ETIMEDOUT );
14594
14695 /* FUTEX_WAIT_BITSET with CLOCK_REALTIME */
14796 if (futex_get_abs_timeout (CLOCK_REALTIME , & to , timeout_ns ))
148- return RET_FAIL ;
97+ ksft_test_result_error ( "get_time error" ) ;
14998 res = futex_wait_bitset (& f1 , f1 , & to , 1 , FUTEX_CLOCK_REALTIME );
150- test_timeout (res , & ret , "futex_wait_bitset realtime" , ETIMEDOUT );
99+ test_timeout (res , "futex_wait_bitset realtime" , ETIMEDOUT );
151100
152101 /* FUTEX_WAIT_BITSET with CLOCK_MONOTONIC */
153102 if (futex_get_abs_timeout (CLOCK_MONOTONIC , & to , timeout_ns ))
154- return RET_FAIL ;
103+ ksft_test_result_error ( "get_time error" ) ;
155104 res = futex_wait_bitset (& f1 , f1 , & to , 1 , 0 );
156- test_timeout (res , & ret , "futex_wait_bitset monotonic" , ETIMEDOUT );
105+ test_timeout (res , "futex_wait_bitset monotonic" , ETIMEDOUT );
106+ }
107+
108+ TEST (requeue_pi )
109+ {
110+ futex_t f1 = FUTEX_INITIALIZER ;
111+ struct timespec to ;
112+ int res ;
157113
158114 /* FUTEX_WAIT_REQUEUE_PI with CLOCK_REALTIME */
159115 if (futex_get_abs_timeout (CLOCK_REALTIME , & to , timeout_ns ))
160- return RET_FAIL ;
116+ ksft_test_result_error ( "get_time error" ) ;
161117 res = futex_wait_requeue_pi (& f1 , f1 , & futex_pi , & to , FUTEX_CLOCK_REALTIME );
162- test_timeout (res , & ret , "futex_wait_requeue_pi realtime" , ETIMEDOUT );
118+ test_timeout (res , "futex_wait_requeue_pi realtime" , ETIMEDOUT );
163119
164120 /* FUTEX_WAIT_REQUEUE_PI with CLOCK_MONOTONIC */
165121 if (futex_get_abs_timeout (CLOCK_MONOTONIC , & to , timeout_ns ))
166- return RET_FAIL ;
122+ ksft_test_result_error ( "get_time error" ) ;
167123 res = futex_wait_requeue_pi (& f1 , f1 , & futex_pi , & to , 0 );
168- test_timeout (res , & ret , "futex_wait_requeue_pi monotonic" , ETIMEDOUT );
124+ test_timeout (res , "futex_wait_requeue_pi monotonic" , ETIMEDOUT );
125+
126+ }
127+
128+ TEST (lock_pi )
129+ {
130+ struct timespec to ;
131+ pthread_t thread ;
132+ int res ;
133+
134+ /* Create a thread that will lock forever so any waiter will timeout */
135+ pthread_barrier_init (& barrier , NULL , 2 );
136+ pthread_create (& thread , NULL , get_pi_lock , NULL );
169137
170138 /* Wait until the other thread calls futex_lock_pi() */
171139 pthread_barrier_wait (& barrier );
172140 pthread_barrier_destroy (& barrier );
141+
173142 /*
174143 * FUTEX_LOCK_PI with CLOCK_REALTIME
175144 * Due to historical reasons, FUTEX_LOCK_PI supports only realtime
@@ -181,26 +150,38 @@ int main(int argc, char *argv[])
181150 * smaller than realtime and the syscall will timeout immediately.
182151 */
183152 if (futex_get_abs_timeout (CLOCK_REALTIME , & to , timeout_ns ))
184- return RET_FAIL ;
153+ ksft_test_result_error ( "get_time error" ) ;
185154 res = futex_lock_pi (& futex_pi , & to , 0 , 0 );
186- test_timeout (res , & ret , "futex_lock_pi realtime" , ETIMEDOUT );
155+ test_timeout (res , "futex_lock_pi realtime" , ETIMEDOUT );
187156
188157 /* Test operations that don't support FUTEX_CLOCK_REALTIME */
189158 res = futex_lock_pi (& futex_pi , NULL , 0 , FUTEX_CLOCK_REALTIME );
190- test_timeout (res , & ret , "futex_lock_pi invalid timeout flag" , ENOSYS );
159+ test_timeout (res , "futex_lock_pi invalid timeout flag" , ENOSYS );
160+ }
161+
162+ TEST (waitv )
163+ {
164+ futex_t f1 = FUTEX_INITIALIZER ;
165+ struct futex_waitv waitv = {
166+ .uaddr = (uintptr_t )& f1 ,
167+ .val = f1 ,
168+ .flags = FUTEX_32 ,
169+ .__reserved = 0 ,
170+ };
171+ struct timespec to ;
172+ int res ;
191173
192174 /* futex_waitv with CLOCK_MONOTONIC */
193175 if (futex_get_abs_timeout (CLOCK_MONOTONIC , & to , timeout_ns ))
194- return RET_FAIL ;
176+ ksft_test_result_error ( "get_time error" ) ;
195177 res = futex_waitv (& waitv , 1 , 0 , & to , CLOCK_MONOTONIC );
196- test_timeout (res , & ret , "futex_waitv monotonic" , ETIMEDOUT );
178+ test_timeout (res , "futex_waitv monotonic" , ETIMEDOUT );
197179
198180 /* futex_waitv with CLOCK_REALTIME */
199181 if (futex_get_abs_timeout (CLOCK_REALTIME , & to , timeout_ns ))
200- return RET_FAIL ;
182+ ksft_test_result_error ( "get_time error" ) ;
201183 res = futex_waitv (& waitv , 1 , 0 , & to , CLOCK_REALTIME );
202- test_timeout (res , & ret , "futex_waitv realtime" , ETIMEDOUT );
203-
204- ksft_print_cnts ();
205- return ret ;
184+ test_timeout (res , "futex_waitv realtime" , ETIMEDOUT );
206185}
186+
187+ TEST_HARNESS_MAIN
0 commit comments