12aa8470fSDarren Hart /****************************************************************************** 22aa8470fSDarren Hart * 32aa8470fSDarren Hart * Copyright © International Business Machines Corp., 2006-2008 42aa8470fSDarren Hart * 52aa8470fSDarren Hart * This program is free software; you can redistribute it and/or modify 62aa8470fSDarren Hart * it under the terms of the GNU General Public License as published by 72aa8470fSDarren Hart * the Free Software Foundation; either version 2 of the License, or 82aa8470fSDarren Hart * (at your option) any later version. 92aa8470fSDarren Hart * 102aa8470fSDarren Hart * DESCRIPTION 112aa8470fSDarren Hart * This test excercises the futex syscall op codes needed for requeuing 122aa8470fSDarren Hart * priority inheritance aware POSIX condition variables and mutexes. 132aa8470fSDarren Hart * 142aa8470fSDarren Hart * AUTHORS 152aa8470fSDarren Hart * Sripathi Kodi <sripathik@in.ibm.com> 162aa8470fSDarren Hart * Darren Hart <dvhart@linux.intel.com> 172aa8470fSDarren Hart * 182aa8470fSDarren Hart * HISTORY 192aa8470fSDarren Hart * 2008-Jan-13: Initial version by Sripathi Kodi <sripathik@in.ibm.com> 202aa8470fSDarren Hart * 2009-Nov-6: futex test adaptation by Darren Hart <dvhart@linux.intel.com> 212aa8470fSDarren Hart * 222aa8470fSDarren Hart *****************************************************************************/ 232aa8470fSDarren Hart 242aa8470fSDarren Hart #include <errno.h> 252aa8470fSDarren Hart #include <limits.h> 262aa8470fSDarren Hart #include <pthread.h> 272aa8470fSDarren Hart #include <stdio.h> 282aa8470fSDarren Hart #include <stdlib.h> 292aa8470fSDarren Hart #include <signal.h> 302aa8470fSDarren Hart #include <string.h> 312aa8470fSDarren Hart #include "atomic.h" 322aa8470fSDarren Hart #include "futextest.h" 332aa8470fSDarren Hart #include "logging.h" 342aa8470fSDarren Hart 351f666e52SNaresh Kamboju #define TEST_NAME "futex-requeue-pi" 362aa8470fSDarren Hart #define MAX_WAKE_ITERS 1000 372aa8470fSDarren Hart #define THREAD_MAX 10 382aa8470fSDarren Hart #define SIGNAL_PERIOD_US 100 392aa8470fSDarren Hart 402aa8470fSDarren Hart atomic_t waiters_blocked = ATOMIC_INITIALIZER; 412aa8470fSDarren Hart atomic_t waiters_woken = ATOMIC_INITIALIZER; 422aa8470fSDarren Hart 432aa8470fSDarren Hart futex_t f1 = FUTEX_INITIALIZER; 442aa8470fSDarren Hart futex_t f2 = FUTEX_INITIALIZER; 452aa8470fSDarren Hart futex_t wake_complete = FUTEX_INITIALIZER; 462aa8470fSDarren Hart 472aa8470fSDarren Hart /* Test option defaults */ 482aa8470fSDarren Hart static long timeout_ns; 492aa8470fSDarren Hart static int broadcast; 502aa8470fSDarren Hart static int owner; 512aa8470fSDarren Hart static int locked; 522aa8470fSDarren Hart 532aa8470fSDarren Hart struct thread_arg { 542aa8470fSDarren Hart long id; 552aa8470fSDarren Hart struct timespec *timeout; 562aa8470fSDarren Hart int lock; 572aa8470fSDarren Hart int ret; 582aa8470fSDarren Hart }; 592aa8470fSDarren Hart #define THREAD_ARG_INITIALIZER { 0, NULL, 0, 0 } 602aa8470fSDarren Hart 612aa8470fSDarren Hart void usage(char *prog) 622aa8470fSDarren Hart { 632aa8470fSDarren Hart printf("Usage: %s\n", prog); 642aa8470fSDarren Hart printf(" -b Broadcast wakeup (all waiters)\n"); 652aa8470fSDarren Hart printf(" -c Use color\n"); 662aa8470fSDarren Hart printf(" -h Display this help message\n"); 672aa8470fSDarren Hart printf(" -l Lock the pi futex across requeue\n"); 682aa8470fSDarren Hart printf(" -o Use a third party pi futex owner during requeue (cancels -l)\n"); 692aa8470fSDarren Hart printf(" -t N Timeout in nanoseconds (default: 0)\n"); 702aa8470fSDarren Hart printf(" -v L Verbosity level: %d=QUIET %d=CRITICAL %d=INFO\n", 712aa8470fSDarren Hart VQUIET, VCRITICAL, VINFO); 722aa8470fSDarren Hart } 732aa8470fSDarren Hart 742aa8470fSDarren Hart int create_rt_thread(pthread_t *pth, void*(*func)(void *), void *arg, 752aa8470fSDarren Hart int policy, int prio) 762aa8470fSDarren Hart { 772aa8470fSDarren Hart int ret; 782aa8470fSDarren Hart struct sched_param schedp; 792aa8470fSDarren Hart pthread_attr_t attr; 802aa8470fSDarren Hart 812aa8470fSDarren Hart pthread_attr_init(&attr); 822aa8470fSDarren Hart memset(&schedp, 0, sizeof(schedp)); 832aa8470fSDarren Hart 842aa8470fSDarren Hart ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); 852aa8470fSDarren Hart if (ret) { 862aa8470fSDarren Hart error("pthread_attr_setinheritsched\n", ret); 872aa8470fSDarren Hart return -1; 882aa8470fSDarren Hart } 892aa8470fSDarren Hart 902aa8470fSDarren Hart ret = pthread_attr_setschedpolicy(&attr, policy); 912aa8470fSDarren Hart if (ret) { 922aa8470fSDarren Hart error("pthread_attr_setschedpolicy\n", ret); 932aa8470fSDarren Hart return -1; 942aa8470fSDarren Hart } 952aa8470fSDarren Hart 962aa8470fSDarren Hart schedp.sched_priority = prio; 972aa8470fSDarren Hart ret = pthread_attr_setschedparam(&attr, &schedp); 982aa8470fSDarren Hart if (ret) { 992aa8470fSDarren Hart error("pthread_attr_setschedparam\n", ret); 1002aa8470fSDarren Hart return -1; 1012aa8470fSDarren Hart } 1022aa8470fSDarren Hart 1032aa8470fSDarren Hart ret = pthread_create(pth, &attr, func, arg); 1042aa8470fSDarren Hart if (ret) { 1052aa8470fSDarren Hart error("pthread_create\n", ret); 1062aa8470fSDarren Hart return -1; 1072aa8470fSDarren Hart } 1082aa8470fSDarren Hart return 0; 1092aa8470fSDarren Hart } 1102aa8470fSDarren Hart 1112aa8470fSDarren Hart 1122aa8470fSDarren Hart void *waiterfn(void *arg) 1132aa8470fSDarren Hart { 1142aa8470fSDarren Hart struct thread_arg *args = (struct thread_arg *)arg; 1152aa8470fSDarren Hart futex_t old_val; 1162aa8470fSDarren Hart 1172aa8470fSDarren Hart info("Waiter %ld: running\n", args->id); 1182aa8470fSDarren Hart /* Each thread sleeps for a different amount of time 1192aa8470fSDarren Hart * This is to avoid races, because we don't lock the 1202aa8470fSDarren Hart * external mutex here */ 1212aa8470fSDarren Hart usleep(1000 * (long)args->id); 1222aa8470fSDarren Hart 1232aa8470fSDarren Hart old_val = f1; 1242aa8470fSDarren Hart atomic_inc(&waiters_blocked); 1252aa8470fSDarren Hart info("Calling futex_wait_requeue_pi: %p (%u) -> %p\n", 1262aa8470fSDarren Hart &f1, f1, &f2); 1272aa8470fSDarren Hart args->ret = futex_wait_requeue_pi(&f1, old_val, &f2, args->timeout, 1282aa8470fSDarren Hart FUTEX_PRIVATE_FLAG); 1292aa8470fSDarren Hart 1302aa8470fSDarren Hart info("waiter %ld woke with %d %s\n", args->id, args->ret, 1312aa8470fSDarren Hart args->ret < 0 ? strerror(errno) : ""); 1322aa8470fSDarren Hart atomic_inc(&waiters_woken); 1332aa8470fSDarren Hart if (args->ret < 0) { 1342aa8470fSDarren Hart if (args->timeout && errno == ETIMEDOUT) 1352aa8470fSDarren Hart args->ret = 0; 1362aa8470fSDarren Hart else { 1372aa8470fSDarren Hart args->ret = RET_ERROR; 1382aa8470fSDarren Hart error("futex_wait_requeue_pi\n", errno); 1392aa8470fSDarren Hart } 1402aa8470fSDarren Hart futex_lock_pi(&f2, NULL, 0, FUTEX_PRIVATE_FLAG); 1412aa8470fSDarren Hart } 1422aa8470fSDarren Hart futex_unlock_pi(&f2, FUTEX_PRIVATE_FLAG); 1432aa8470fSDarren Hart 1442aa8470fSDarren Hart info("Waiter %ld: exiting with %d\n", args->id, args->ret); 1452aa8470fSDarren Hart pthread_exit((void *)&args->ret); 1462aa8470fSDarren Hart } 1472aa8470fSDarren Hart 1482aa8470fSDarren Hart void *broadcast_wakerfn(void *arg) 1492aa8470fSDarren Hart { 1502aa8470fSDarren Hart struct thread_arg *args = (struct thread_arg *)arg; 1512aa8470fSDarren Hart int nr_requeue = INT_MAX; 1522aa8470fSDarren Hart int task_count = 0; 1532aa8470fSDarren Hart futex_t old_val; 1542aa8470fSDarren Hart int nr_wake = 1; 1552aa8470fSDarren Hart int i = 0; 1562aa8470fSDarren Hart 1572aa8470fSDarren Hart info("Waker: waiting for waiters to block\n"); 1582aa8470fSDarren Hart while (waiters_blocked.val < THREAD_MAX) 1592aa8470fSDarren Hart usleep(1000); 1602aa8470fSDarren Hart usleep(1000); 1612aa8470fSDarren Hart 1622aa8470fSDarren Hart info("Waker: Calling broadcast\n"); 1632aa8470fSDarren Hart if (args->lock) { 1642aa8470fSDarren Hart info("Calling FUTEX_LOCK_PI on mutex=%x @ %p\n", f2, &f2); 1652aa8470fSDarren Hart futex_lock_pi(&f2, NULL, 0, FUTEX_PRIVATE_FLAG); 1662aa8470fSDarren Hart } 1672aa8470fSDarren Hart continue_requeue: 1682aa8470fSDarren Hart old_val = f1; 1692aa8470fSDarren Hart args->ret = futex_cmp_requeue_pi(&f1, old_val, &f2, nr_wake, nr_requeue, 1702aa8470fSDarren Hart FUTEX_PRIVATE_FLAG); 1712aa8470fSDarren Hart if (args->ret < 0) { 1722aa8470fSDarren Hart args->ret = RET_ERROR; 1732aa8470fSDarren Hart error("FUTEX_CMP_REQUEUE_PI failed\n", errno); 1742aa8470fSDarren Hart } else if (++i < MAX_WAKE_ITERS) { 1752aa8470fSDarren Hart task_count += args->ret; 1762aa8470fSDarren Hart if (task_count < THREAD_MAX - waiters_woken.val) 1772aa8470fSDarren Hart goto continue_requeue; 1782aa8470fSDarren Hart } else { 1792aa8470fSDarren Hart error("max broadcast iterations (%d) reached with %d/%d tasks woken or requeued\n", 1802aa8470fSDarren Hart 0, MAX_WAKE_ITERS, task_count, THREAD_MAX); 1812aa8470fSDarren Hart args->ret = RET_ERROR; 1822aa8470fSDarren Hart } 1832aa8470fSDarren Hart 1842aa8470fSDarren Hart futex_wake(&wake_complete, 1, FUTEX_PRIVATE_FLAG); 1852aa8470fSDarren Hart 1862aa8470fSDarren Hart if (args->lock) 1872aa8470fSDarren Hart futex_unlock_pi(&f2, FUTEX_PRIVATE_FLAG); 1882aa8470fSDarren Hart 1892aa8470fSDarren Hart if (args->ret > 0) 1902aa8470fSDarren Hart args->ret = task_count; 1912aa8470fSDarren Hart 1922aa8470fSDarren Hart info("Waker: exiting with %d\n", args->ret); 1932aa8470fSDarren Hart pthread_exit((void *)&args->ret); 1942aa8470fSDarren Hart } 1952aa8470fSDarren Hart 1962aa8470fSDarren Hart void *signal_wakerfn(void *arg) 1972aa8470fSDarren Hart { 1982aa8470fSDarren Hart struct thread_arg *args = (struct thread_arg *)arg; 1992aa8470fSDarren Hart unsigned int old_val; 2002aa8470fSDarren Hart int nr_requeue = 0; 2012aa8470fSDarren Hart int task_count = 0; 2022aa8470fSDarren Hart int nr_wake = 1; 2032aa8470fSDarren Hart int i = 0; 2042aa8470fSDarren Hart 2052aa8470fSDarren Hart info("Waker: waiting for waiters to block\n"); 2062aa8470fSDarren Hart while (waiters_blocked.val < THREAD_MAX) 2072aa8470fSDarren Hart usleep(1000); 2082aa8470fSDarren Hart usleep(1000); 2092aa8470fSDarren Hart 2102aa8470fSDarren Hart while (task_count < THREAD_MAX && waiters_woken.val < THREAD_MAX) { 2112aa8470fSDarren Hart info("task_count: %d, waiters_woken: %d\n", 2122aa8470fSDarren Hart task_count, waiters_woken.val); 2132aa8470fSDarren Hart if (args->lock) { 2142aa8470fSDarren Hart info("Calling FUTEX_LOCK_PI on mutex=%x @ %p\n", 2152aa8470fSDarren Hart f2, &f2); 2162aa8470fSDarren Hart futex_lock_pi(&f2, NULL, 0, FUTEX_PRIVATE_FLAG); 2172aa8470fSDarren Hart } 2182aa8470fSDarren Hart info("Waker: Calling signal\n"); 2192aa8470fSDarren Hart /* cond_signal */ 2202aa8470fSDarren Hart old_val = f1; 2212aa8470fSDarren Hart args->ret = futex_cmp_requeue_pi(&f1, old_val, &f2, 2222aa8470fSDarren Hart nr_wake, nr_requeue, 2232aa8470fSDarren Hart FUTEX_PRIVATE_FLAG); 2242aa8470fSDarren Hart if (args->ret < 0) 2252aa8470fSDarren Hart args->ret = -errno; 2262aa8470fSDarren Hart info("futex: %x\n", f2); 2272aa8470fSDarren Hart if (args->lock) { 2282aa8470fSDarren Hart info("Calling FUTEX_UNLOCK_PI on mutex=%x @ %p\n", 2292aa8470fSDarren Hart f2, &f2); 2302aa8470fSDarren Hart futex_unlock_pi(&f2, FUTEX_PRIVATE_FLAG); 2312aa8470fSDarren Hart } 2322aa8470fSDarren Hart info("futex: %x\n", f2); 2332aa8470fSDarren Hart if (args->ret < 0) { 2342aa8470fSDarren Hart error("FUTEX_CMP_REQUEUE_PI failed\n", errno); 2352aa8470fSDarren Hart args->ret = RET_ERROR; 2362aa8470fSDarren Hart break; 2372aa8470fSDarren Hart } 2382aa8470fSDarren Hart 2392aa8470fSDarren Hart task_count += args->ret; 2402aa8470fSDarren Hart usleep(SIGNAL_PERIOD_US); 2412aa8470fSDarren Hart i++; 2422aa8470fSDarren Hart /* we have to loop at least THREAD_MAX times */ 2432aa8470fSDarren Hart if (i > MAX_WAKE_ITERS + THREAD_MAX) { 2442aa8470fSDarren Hart error("max signaling iterations (%d) reached, giving up on pending waiters.\n", 2452aa8470fSDarren Hart 0, MAX_WAKE_ITERS + THREAD_MAX); 2462aa8470fSDarren Hart args->ret = RET_ERROR; 2472aa8470fSDarren Hart break; 2482aa8470fSDarren Hart } 2492aa8470fSDarren Hart } 2502aa8470fSDarren Hart 2512aa8470fSDarren Hart futex_wake(&wake_complete, 1, FUTEX_PRIVATE_FLAG); 2522aa8470fSDarren Hart 2532aa8470fSDarren Hart if (args->ret >= 0) 2542aa8470fSDarren Hart args->ret = task_count; 2552aa8470fSDarren Hart 2562aa8470fSDarren Hart info("Waker: exiting with %d\n", args->ret); 2572aa8470fSDarren Hart info("Waker: waiters_woken: %d\n", waiters_woken.val); 2582aa8470fSDarren Hart pthread_exit((void *)&args->ret); 2592aa8470fSDarren Hart } 2602aa8470fSDarren Hart 2612aa8470fSDarren Hart void *third_party_blocker(void *arg) 2622aa8470fSDarren Hart { 2632aa8470fSDarren Hart struct thread_arg *args = (struct thread_arg *)arg; 2642aa8470fSDarren Hart int ret2 = 0; 2652aa8470fSDarren Hart 2662aa8470fSDarren Hart args->ret = futex_lock_pi(&f2, NULL, 0, FUTEX_PRIVATE_FLAG); 2672aa8470fSDarren Hart if (args->ret) 2682aa8470fSDarren Hart goto out; 2692aa8470fSDarren Hart args->ret = futex_wait(&wake_complete, wake_complete, NULL, 2702aa8470fSDarren Hart FUTEX_PRIVATE_FLAG); 2712aa8470fSDarren Hart ret2 = futex_unlock_pi(&f2, FUTEX_PRIVATE_FLAG); 2722aa8470fSDarren Hart 2732aa8470fSDarren Hart out: 2742aa8470fSDarren Hart if (args->ret || ret2) { 2752aa8470fSDarren Hart error("third_party_blocker() futex error", 0); 2762aa8470fSDarren Hart args->ret = RET_ERROR; 2772aa8470fSDarren Hart } 2782aa8470fSDarren Hart 2792aa8470fSDarren Hart pthread_exit((void *)&args->ret); 2802aa8470fSDarren Hart } 2812aa8470fSDarren Hart 2822aa8470fSDarren Hart int unit_test(int broadcast, long lock, int third_party_owner, long timeout_ns) 2832aa8470fSDarren Hart { 2842aa8470fSDarren Hart void *(*wakerfn)(void *) = signal_wakerfn; 2852aa8470fSDarren Hart struct thread_arg blocker_arg = THREAD_ARG_INITIALIZER; 2862aa8470fSDarren Hart struct thread_arg waker_arg = THREAD_ARG_INITIALIZER; 2872aa8470fSDarren Hart pthread_t waiter[THREAD_MAX], waker, blocker; 2882aa8470fSDarren Hart struct timespec ts, *tsp = NULL; 2892aa8470fSDarren Hart struct thread_arg args[THREAD_MAX]; 2902aa8470fSDarren Hart int *waiter_ret; 2912aa8470fSDarren Hart int i, ret = RET_PASS; 2922aa8470fSDarren Hart 2932aa8470fSDarren Hart if (timeout_ns) { 2942aa8470fSDarren Hart time_t secs; 2952aa8470fSDarren Hart 2962aa8470fSDarren Hart info("timeout_ns = %ld\n", timeout_ns); 2972aa8470fSDarren Hart ret = clock_gettime(CLOCK_MONOTONIC, &ts); 2982aa8470fSDarren Hart secs = (ts.tv_nsec + timeout_ns) / 1000000000; 2992aa8470fSDarren Hart ts.tv_nsec = ((int64_t)ts.tv_nsec + timeout_ns) % 1000000000; 3002aa8470fSDarren Hart ts.tv_sec += secs; 3012aa8470fSDarren Hart info("ts.tv_sec = %ld\n", ts.tv_sec); 3022aa8470fSDarren Hart info("ts.tv_nsec = %ld\n", ts.tv_nsec); 3032aa8470fSDarren Hart tsp = &ts; 3042aa8470fSDarren Hart } 3052aa8470fSDarren Hart 3062aa8470fSDarren Hart if (broadcast) 3072aa8470fSDarren Hart wakerfn = broadcast_wakerfn; 3082aa8470fSDarren Hart 3092aa8470fSDarren Hart if (third_party_owner) { 3102aa8470fSDarren Hart if (create_rt_thread(&blocker, third_party_blocker, 3112aa8470fSDarren Hart (void *)&blocker_arg, SCHED_FIFO, 1)) { 3122aa8470fSDarren Hart error("Creating third party blocker thread failed\n", 3132aa8470fSDarren Hart errno); 3142aa8470fSDarren Hart ret = RET_ERROR; 3152aa8470fSDarren Hart goto out; 3162aa8470fSDarren Hart } 3172aa8470fSDarren Hart } 3182aa8470fSDarren Hart 3192aa8470fSDarren Hart atomic_set(&waiters_woken, 0); 3202aa8470fSDarren Hart for (i = 0; i < THREAD_MAX; i++) { 3212aa8470fSDarren Hart args[i].id = i; 3222aa8470fSDarren Hart args[i].timeout = tsp; 3232aa8470fSDarren Hart info("Starting thread %d\n", i); 3242aa8470fSDarren Hart if (create_rt_thread(&waiter[i], waiterfn, (void *)&args[i], 3252aa8470fSDarren Hart SCHED_FIFO, 1)) { 3262aa8470fSDarren Hart error("Creating waiting thread failed\n", errno); 3272aa8470fSDarren Hart ret = RET_ERROR; 3282aa8470fSDarren Hart goto out; 3292aa8470fSDarren Hart } 3302aa8470fSDarren Hart } 3312aa8470fSDarren Hart waker_arg.lock = lock; 3322aa8470fSDarren Hart if (create_rt_thread(&waker, wakerfn, (void *)&waker_arg, 3332aa8470fSDarren Hart SCHED_FIFO, 1)) { 3342aa8470fSDarren Hart error("Creating waker thread failed\n", errno); 3352aa8470fSDarren Hart ret = RET_ERROR; 3362aa8470fSDarren Hart goto out; 3372aa8470fSDarren Hart } 3382aa8470fSDarren Hart 3392aa8470fSDarren Hart /* Wait for threads to finish */ 3402aa8470fSDarren Hart /* Store the first error or failure encountered in waiter_ret */ 3412aa8470fSDarren Hart waiter_ret = &args[0].ret; 3422aa8470fSDarren Hart for (i = 0; i < THREAD_MAX; i++) 3432aa8470fSDarren Hart pthread_join(waiter[i], 3442aa8470fSDarren Hart *waiter_ret ? NULL : (void **)&waiter_ret); 3452aa8470fSDarren Hart 3462aa8470fSDarren Hart if (third_party_owner) 3472aa8470fSDarren Hart pthread_join(blocker, NULL); 3482aa8470fSDarren Hart pthread_join(waker, NULL); 3492aa8470fSDarren Hart 3502aa8470fSDarren Hart out: 3512aa8470fSDarren Hart if (!ret) { 3522aa8470fSDarren Hart if (*waiter_ret) 3532aa8470fSDarren Hart ret = *waiter_ret; 3542aa8470fSDarren Hart else if (waker_arg.ret < 0) 3552aa8470fSDarren Hart ret = waker_arg.ret; 3562aa8470fSDarren Hart else if (blocker_arg.ret) 3572aa8470fSDarren Hart ret = blocker_arg.ret; 3582aa8470fSDarren Hart } 3592aa8470fSDarren Hart 3602aa8470fSDarren Hart return ret; 3612aa8470fSDarren Hart } 3622aa8470fSDarren Hart 3632aa8470fSDarren Hart int main(int argc, char *argv[]) 3642aa8470fSDarren Hart { 3652aa8470fSDarren Hart int c, ret; 3662aa8470fSDarren Hart 3672aa8470fSDarren Hart while ((c = getopt(argc, argv, "bchlot:v:")) != -1) { 3682aa8470fSDarren Hart switch (c) { 3692aa8470fSDarren Hart case 'b': 3702aa8470fSDarren Hart broadcast = 1; 3712aa8470fSDarren Hart break; 3722aa8470fSDarren Hart case 'c': 3732aa8470fSDarren Hart log_color(1); 3742aa8470fSDarren Hart break; 3752aa8470fSDarren Hart case 'h': 3762aa8470fSDarren Hart usage(basename(argv[0])); 3772aa8470fSDarren Hart exit(0); 3782aa8470fSDarren Hart case 'l': 3792aa8470fSDarren Hart locked = 1; 3802aa8470fSDarren Hart break; 3812aa8470fSDarren Hart case 'o': 3822aa8470fSDarren Hart owner = 1; 3832aa8470fSDarren Hart locked = 0; 3842aa8470fSDarren Hart break; 3852aa8470fSDarren Hart case 't': 3862aa8470fSDarren Hart timeout_ns = atoi(optarg); 3872aa8470fSDarren Hart break; 3882aa8470fSDarren Hart case 'v': 3892aa8470fSDarren Hart log_verbosity(atoi(optarg)); 3902aa8470fSDarren Hart break; 3912aa8470fSDarren Hart default: 3922aa8470fSDarren Hart usage(basename(argv[0])); 3932aa8470fSDarren Hart exit(1); 3942aa8470fSDarren Hart } 3952aa8470fSDarren Hart } 3962aa8470fSDarren Hart 397b274e75cSShuah Khan ksft_print_header(); 398b274e75cSShuah Khan ksft_print_msg("%s: Test requeue functionality\n", basename(argv[0])); 399b274e75cSShuah Khan ksft_print_msg( 400b274e75cSShuah Khan "\tArguments: broadcast=%d locked=%d owner=%d timeout=%ldns\n", 4012aa8470fSDarren Hart broadcast, locked, owner, timeout_ns); 4022aa8470fSDarren Hart 4032aa8470fSDarren Hart /* 4042aa8470fSDarren Hart * FIXME: unit_test is obsolete now that we parse options and the 4052aa8470fSDarren Hart * various style of runs are done by run.sh - simplify the code and move 4062aa8470fSDarren Hart * unit_test into main() 4072aa8470fSDarren Hart */ 4082aa8470fSDarren Hart ret = unit_test(broadcast, locked, owner, timeout_ns); 4092aa8470fSDarren Hart 4101f666e52SNaresh Kamboju print_result(TEST_NAME, ret); 4112aa8470fSDarren Hart return ret; 4122aa8470fSDarren Hart } 413