cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

futex_requeue.c (3020B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Copyright Collabora Ltd., 2021
      4 *
      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  30000000
     15#define WAKE_WAIT_US 10000
     16
     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}