File: futex.c

package info (click to toggle)
systemtap 4.4-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 38,260 kB
  • sloc: cpp: 77,147; ansic: 61,828; xml: 49,277; exp: 42,244; sh: 11,046; python: 2,772; perl: 2,252; tcl: 1,305; makefile: 1,086; lisp: 105; java: 102; awk: 101; asm: 91; sed: 16
file content (131 lines) | stat: -rw-r--r-- 3,872 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/* COVERAGE: futex */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <linux/futex.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/mman.h>

static int *futex_addr;

static inline int
__futex(int *uaddr, int op, int val, const struct timespec *timeout,
	int *uaddr2, int val3)
{
    return syscall(SYS_futex, uaddr, op, val, timeout, uaddr2, val3);
}

void do_child()
{
    *futex_addr = 0;
    __futex(futex_addr, FUTEX_WAIT, 0, NULL, NULL, 0);
}

int main()
{
    pid_t pid;
    int status;
    struct timespec t = {0,789};

    // Create a mmapped area that both the parent and child processes
    // can access.
    futex_addr = mmap(NULL, sizeof(int), PROT_READ|PROT_WRITE,
		      MAP_SHARED|MAP_ANONYMOUS, -1, 0);

    pid = fork();
    if (pid == 0) {		/* child */
	do_child();
	exit(0);
    }

    // Wait for the child to run and wait on the futex.
    sleep(1);

    // Wake the child (which should immediately exit).
    __futex(futex_addr, FUTEX_WAKE, 1, NULL, NULL, 0);
    //staptest// futex (XXXX, FUTEX_WAKE, 1) = 1

    // Clean up the child process and the mmapped area.
    waitpid(pid, &status, 0);
    munmap(futex_addr, sizeof(int));

    /* Limit testing. */

    __futex((int *)-1, FUTEX_WAKE, 1, NULL, NULL, 0);
#ifdef __s390__
    //staptest// futex (0x[7]?[f]+, FUTEX_WAKE, 1) = NNNN
#else
    //staptest// futex (0x[f]+, FUTEX_WAKE, 1) = NNNN
#endif
    __futex(NULL, -1, 1, NULL, NULL, 0);
#ifdef __s390__
    //staptest// futex (0x0, 0x[7]?[f]+, 1) = NNNN
#else
    //staptest// futex (0x0, 0x[f]+, 1) = NNNN
#endif

    __futex(NULL, FUTEX_CMP_REQUEUE, -1, NULL, NULL, 0);
    //staptest// futex (0x0, FUTEX_CMP_REQUEUE, -1, 0, 0x0, 0) = NNNN

    __futex(NULL, FUTEX_CMP_REQUEUE, 1, (struct timespec *)-1, NULL, 0);
#if __WORDSIZE == 64
    //staptest// futex (0x0, FUTEX_CMP_REQUEUE, 1, 18446744073709551615, 0x0, 0) = NNNN
#else
#ifdef __s390__
    //staptest// futex (0x0, FUTEX_CMP_REQUEUE, 1, [[[[2147483647!!!!4294967295]]]], 0x0, 0) = NNNN
#else
    //staptest// futex (0x0, FUTEX_CMP_REQUEUE, 1, 4294967295, 0x0, 0) = NNNN
#endif
#endif

    __futex(NULL, FUTEX_CMP_REQUEUE, 1, NULL, (int *)-1, 0);
#ifdef __s390__
    //staptest// futex (0x0, FUTEX_CMP_REQUEUE, 1, 0, 0x[7]?[f]+, 0) = NNNN
#else
    //staptest// futex (0x0, FUTEX_CMP_REQUEUE, 1, 0, 0x[f]+, 0) = NNNN
#endif

    __futex(NULL, FUTEX_CMP_REQUEUE, 1, NULL, NULL, -1);
    //staptest// futex (0x0, FUTEX_CMP_REQUEUE, 1, 0, 0x0, -1) = NNNN

    /* Since the futex argstr is different based on the operation,
     * test several variants. */

#ifdef FUTEX_WAKE_BITSET
    __futex(NULL, FUTEX_WAKE_BITSET, 1, NULL, NULL, -1);
#ifdef __s390__
    //staptest// futex (0x0, FUTEX_WAKE_BITSET, 1, 0x[7]?[f]+) = NNNN
#else
    //staptest// futex (0x0, FUTEX_WAKE_BITSET, 1, 0x[f]+) = NNNN
#endif
#endif

    __futex(NULL, FUTEX_WAIT, 1, &t, NULL, 0);
    //staptest// futex (0x0, FUTEX_WAIT, 1, \[0.000000789\]) = NNNN

#ifdef FUTEX_WAIT_BITSET
    __futex(NULL, FUTEX_WAIT_BITSET, 1, &t, NULL, 0xbeef);
    //staptest// futex (0x0, FUTEX_WAIT_BITSET, 1, \[0.000000789\], 0xbeef) = NNNN
#endif

    __futex(NULL, FUTEX_REQUEUE, 1, (struct timespec *)2, NULL, -1);
    //staptest// futex (0x0, FUTEX_REQUEUE, 1, 2, 0x0) = NNNN

    __futex(NULL, FUTEX_CMP_REQUEUE, 1, (struct timespec *)2, (int *)3, -1);
    //staptest// futex (0x0, FUTEX_CMP_REQUEUE, 1, 2, 0x3, -1) = NNNN

    __futex(NULL, FUTEX_WAKE_OP, 1, (struct timespec *)2, (int *)3,
	    FUTEX_OP(FUTEX_OP_SET, 2, FUTEX_OP_CMP_EQ, 1));
    //staptest// futex (0x0, FUTEX_WAKE_OP, 1, 2, 0x3, {FUTEX_OP_SET, 2, FUTEX_OP_CMP_EQ, 1}) = NNNN

#ifdef FUTEX_WAIT_REQUEUE_PI
    __futex(NULL, FUTEX_WAIT_REQUEUE_PI, 1, &t, NULL, 0);
    //staptest// futex (0x0, FUTEX_WAIT_REQUEUE_PI, 1, \[0.000000789\], 0x0) = NNNN
#endif

    return 0;
}