brintos

brintos / linux-shallow public Read only

0
0
Text · 2.9 KiB · 51485be Raw
137 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Copyright Collabora Ltd., 20214 *5 * futex cmp requeue test by André Almeida <andrealmeid@collabora.com>6 */7 8#include <pthread.h>9#include <limits.h>10#include "logging.h"11#include "futextest.h"12 13#define TEST_NAME "futex-requeue"14#define timeout_ns  3000000015#define WAKE_WAIT_US 1000016 17volatile futex_t *f1;18 19void usage(char *prog)20{21	printf("Usage: %s\n", prog);22	printf("  -c	Use color\n");23	printf("  -h	Display this help message\n");24	printf("  -v L	Verbosity level: %d=QUIET %d=CRITICAL %d=INFO\n",25	       VQUIET, VCRITICAL, VINFO);26}27 28void *waiterfn(void *arg)29{30	struct timespec to;31 32	to.tv_sec = 0;33	to.tv_nsec = timeout_ns;34 35	if (futex_wait(f1, *f1, &to, 0))36		printf("waiter failed errno %d\n", errno);37 38	return NULL;39}40 41int main(int argc, char *argv[])42{43	pthread_t waiter[10];44	int res, ret = RET_PASS;45	int c, i;46	volatile futex_t _f1 = 0;47	volatile futex_t f2 = 0;48 49	f1 = &_f1;50 51	while ((c = getopt(argc, argv, "cht:v:")) != -1) {52		switch (c) {53		case 'c':54			log_color(1);55			break;56		case 'h':57			usage(basename(argv[0]));58			exit(0);59		case 'v':60			log_verbosity(atoi(optarg));61			break;62		default:63			usage(basename(argv[0]));64			exit(1);65		}66	}67 68	ksft_print_header();69	ksft_set_plan(2);70	ksft_print_msg("%s: Test futex_requeue\n",71		       basename(argv[0]));72 73	/*74	 * Requeue a waiter from f1 to f2, and wake f2.75	 */76	if (pthread_create(&waiter[0], NULL, waiterfn, NULL))77		error("pthread_create failed\n", errno);78 79	usleep(WAKE_WAIT_US);80 81	info("Requeuing 1 futex from f1 to f2\n");82	res = futex_cmp_requeue(f1, 0, &f2, 0, 1, 0);83	if (res != 1) {84		ksft_test_result_fail("futex_requeue simple returned: %d %s\n",85				      res ? errno : res,86				      res ? strerror(errno) : "");87		ret = RET_FAIL;88	}89 90 91	info("Waking 1 futex at f2\n");92	res = futex_wake(&f2, 1, 0);93	if (res != 1) {94		ksft_test_result_fail("futex_requeue simple returned: %d %s\n",95				      res ? errno : res,96				      res ? strerror(errno) : "");97		ret = RET_FAIL;98	} else {99		ksft_test_result_pass("futex_requeue simple succeeds\n");100	}101 102 103	/*104	 * Create 10 waiters at f1. At futex_requeue, wake 3 and requeue 7.105	 * At futex_wake, wake INT_MAX (should be exactly 7).106	 */107	for (i = 0; i < 10; i++) {108		if (pthread_create(&waiter[i], NULL, waiterfn, NULL))109			error("pthread_create failed\n", errno);110	}111 112	usleep(WAKE_WAIT_US);113 114	info("Waking 3 futexes at f1 and requeuing 7 futexes from f1 to f2\n");115	res = futex_cmp_requeue(f1, 0, &f2, 3, 7, 0);116	if (res != 10) {117		ksft_test_result_fail("futex_requeue many returned: %d %s\n",118				      res ? errno : res,119				      res ? strerror(errno) : "");120		ret = RET_FAIL;121	}122 123	info("Waking INT_MAX futexes at f2\n");124	res = futex_wake(&f2, INT_MAX, 0);125	if (res != 7) {126		ksft_test_result_fail("futex_requeue many returned: %d %s\n",127				      res ? errno : res,128				      res ? strerror(errno) : "");129		ret = RET_FAIL;130	} else {131		ksft_test_result_pass("futex_requeue many succeeds\n");132	}133 134	ksft_print_cnts();135	return ret;136}137