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.h (4397B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2/*
      3 * Glibc independent futex library for testing kernel functionality.
      4 * Shamelessly stolen from Darren Hart <dvhltc@us.ibm.com>
      5 *    http://git.kernel.org/cgit/linux/kernel/git/dvhart/futextest.git/
      6 */
      7
      8#ifndef _FUTEX_H
      9#define _FUTEX_H
     10
     11#include <unistd.h>
     12#include <sys/syscall.h>
     13#include <sys/types.h>
     14#include <linux/futex.h>
     15
     16struct bench_futex_parameters {
     17	bool silent;
     18	bool fshared;
     19	bool mlockall;
     20	bool multi; /* lock-pi */
     21	bool pi; /* requeue-pi */
     22	bool broadcast; /* requeue */
     23	unsigned int runtime; /* seconds*/
     24	unsigned int nthreads;
     25	unsigned int nfutexes;
     26	unsigned int nwakes;
     27	unsigned int nrequeue;
     28};
     29
     30/**
     31 * futex_syscall() - SYS_futex syscall wrapper
     32 * @uaddr:	address of first futex
     33 * @op:		futex op code
     34 * @val:	typically expected value of uaddr, but varies by op
     35 * @timeout:	typically an absolute struct timespec (except where noted
     36 *		otherwise). Overloaded by some ops
     37 * @uaddr2:	address of second futex for some ops
     38 * @val3:	varies by op
     39 * @opflags:	flags to be bitwise OR'd with op, such as FUTEX_PRIVATE_FLAG
     40 *
     41 * futex_syscall() is used by all the following futex op wrappers. It can also be
     42 * used for misuse and abuse testing. Generally, the specific op wrappers
     43 * should be used instead.
     44 *
     45 * These argument descriptions are the defaults for all
     46 * like-named arguments in the following wrappers except where noted below.
     47 */
     48static inline int
     49futex_syscall(volatile u_int32_t *uaddr, int op, u_int32_t val, struct timespec *timeout,
     50	      volatile u_int32_t *uaddr2, int val3, int opflags)
     51{
     52	return syscall(SYS_futex, uaddr, op | opflags, val, timeout, uaddr2, val3);
     53}
     54
     55static inline int
     56futex_syscall_nr_requeue(volatile u_int32_t *uaddr, int op, u_int32_t val, int nr_requeue,
     57			 volatile u_int32_t *uaddr2, int val3, int opflags)
     58{
     59	return syscall(SYS_futex, uaddr, op | opflags, val, nr_requeue, uaddr2, val3);
     60}
     61
     62/**
     63 * futex_wait() - block on uaddr with optional timeout
     64 * @timeout:	relative timeout
     65 */
     66static inline int
     67futex_wait(u_int32_t *uaddr, u_int32_t val, struct timespec *timeout, int opflags)
     68{
     69	return futex_syscall(uaddr, FUTEX_WAIT, val, timeout, NULL, 0, opflags);
     70}
     71
     72/**
     73 * futex_wake() - wake one or more tasks blocked on uaddr
     74 * @nr_wake:	wake up to this many tasks
     75 */
     76static inline int
     77futex_wake(u_int32_t *uaddr, int nr_wake, int opflags)
     78{
     79	return futex_syscall(uaddr, FUTEX_WAKE, nr_wake, NULL, NULL, 0, opflags);
     80}
     81
     82/**
     83 * futex_lock_pi() - block on uaddr as a PI mutex
     84 */
     85static inline int
     86futex_lock_pi(u_int32_t *uaddr, struct timespec *timeout, int opflags)
     87{
     88	return futex_syscall(uaddr, FUTEX_LOCK_PI, 0, timeout, NULL, 0, opflags);
     89}
     90
     91/**
     92 * futex_unlock_pi() - release uaddr as a PI mutex, waking the top waiter
     93 */
     94static inline int
     95futex_unlock_pi(u_int32_t *uaddr, int opflags)
     96{
     97	return futex_syscall(uaddr, FUTEX_UNLOCK_PI, 0, NULL, NULL, 0, opflags);
     98}
     99
    100/**
    101* futex_cmp_requeue() - requeue tasks from uaddr to uaddr2
    102* @nr_wake:        wake up to this many tasks
    103* @nr_requeue:     requeue up to this many tasks
    104*/
    105static inline int
    106futex_cmp_requeue(u_int32_t *uaddr, u_int32_t val, u_int32_t *uaddr2, int nr_wake,
    107		 int nr_requeue, int opflags)
    108{
    109	return futex_syscall_nr_requeue(uaddr, FUTEX_CMP_REQUEUE, nr_wake, nr_requeue, uaddr2,
    110					val, opflags);
    111}
    112
    113/**
    114 * futex_wait_requeue_pi() - block on uaddr and prepare to requeue to uaddr2
    115 * @uaddr:	non-PI futex source
    116 * @uaddr2:	PI futex target
    117 *
    118 * This is the first half of the requeue_pi mechanism. It shall always be
    119 * paired with futex_cmp_requeue_pi().
    120 */
    121static inline int
    122futex_wait_requeue_pi(u_int32_t *uaddr, u_int32_t val, u_int32_t *uaddr2,
    123		      struct timespec *timeout, int opflags)
    124{
    125	return futex_syscall(uaddr, FUTEX_WAIT_REQUEUE_PI, val, timeout, uaddr2, 0,
    126			     opflags);
    127}
    128
    129/**
    130 * futex_cmp_requeue_pi() - requeue tasks from uaddr to uaddr2
    131 * @uaddr:	non-PI futex source
    132 * @uaddr2:	PI futex target
    133 * @nr_requeue:	requeue up to this many tasks
    134 *
    135 * This is the second half of the requeue_pi mechanism. It shall always be
    136 * paired with futex_wait_requeue_pi(). The first waker is always awoken.
    137 */
    138static inline int
    139futex_cmp_requeue_pi(u_int32_t *uaddr, u_int32_t val, u_int32_t *uaddr2,
    140		     int nr_requeue, int opflags)
    141{
    142	return futex_syscall_nr_requeue(uaddr, FUTEX_CMP_REQUEUE_PI, 1, nr_requeue, uaddr2,
    143					val, opflags);
    144}
    145
    146#endif /* _FUTEX_H */