futex-tests.uir 3.85 KB
Newer Older
1 2 3 4 5 6 7 8
// require "primitives.uir"

.global @shared_value1 <@i64>
.global @shared_value2 <@i64>
.global @the_futex <@i32>

.const @I64_42 <@i64> = 42

9
.funcdef @futex_waiter VERSION @futex_waiter_v1 <@v_v> {
Kunshan Wang's avatar
Kunshan Wang committed
10
    %entry():
11 12 13
        %rv = COMMINST @uvm.futex.wait <@i32> (@the_futex @I32_0)
        %sv = LOAD <@i64> @shared_value1

14
        [%trap_waiter] TRAP <> KEEPALIVE(%rv %sv)
15 16 17
        COMMINST @uvm.thread_exit
}

18
.funcdef @futex_setter VERSION @futex_setter_v1 <@v_v> {
Kunshan Wang's avatar
Kunshan Wang committed
19
    %entry():
20 21 22 23
        STORE <@i64> @shared_value1 @I64_0
        STORE <@i64> @shared_value2 @I64_0
        STORE <@i32> @the_futex @I32_0

24 25
        %ns = COMMINST @uvm.new_stack <[@v_v]> (@futex_waiter)
        %nt = NEWTHREAD %ns PASS_VALUES <> ()
26 27 28

        STORE <@i64> @shared_value1 @I64_42

Kunshan Wang's avatar
Kunshan Wang committed
29
        BRANCH %wait_body()
30

Kunshan Wang's avatar
Kunshan Wang committed
31
    %wait_body():
32 33
        %nwakes = COMMINST @uvm.futex.wake <@i32> (@the_futex @I32_1)
        %is_1 = EQ <@i32> %nwakes @I32_1
Kunshan Wang's avatar
Kunshan Wang committed
34
        BRANCH2 %is_1 %wait_exit() %wait_body()
35

Kunshan Wang's avatar
Kunshan Wang committed
36
    %wait_exit():
37
        [%trap_setter] TRAP <>
38 39 40 41 42
        COMMINST @uvm.thread_exit
}

.const @I64_ONE_SECOND <@i64> = 1000000000

43
.funcdef @futex_delayer VERSION @futex_delayer_v1 <@v_v> {
Kunshan Wang's avatar
Kunshan Wang committed
44
    %entry():
45 46
        STORE <@i32> @the_futex @I32_0
        %rv = COMMINST @uvm.futex.wait_timeout <@i32> (@the_futex @I32_0 @I64_ONE_SECOND)
47
        [%trap_delayer] TRAP <> KEEPALIVE(%rv)
48 49 50
        COMMINST @uvm.thread_exit
}

51
.funcdef @futex_no_sleep VERSION @futex_no_sleep_v1 <@v_v> {
Kunshan Wang's avatar
Kunshan Wang committed
52
    %entry():
53 54
        STORE <@i32> @the_futex @I32_0
        %rv = COMMINST @uvm.futex.wait <@i32> (@the_futex @I32_1)
55
        [%trap_no_sleep] TRAP <> KEEPALIVE(%rv)
56 57 58 59 60
        COMMINST @uvm.thread_exit
}

.global @the_other_futex <@i32>

61
.funcdef @futex_requeue_waiter VERSION @futex_requeue_waiter_v1 <@v_v> {
Kunshan Wang's avatar
Kunshan Wang committed
62
    %entry():
63
        %rv = COMMINST @uvm.futex.wait <@i32> (@the_futex @I32_0)
64
        [%trap_requeue_waiter] TRAP <> KEEPALIVE(%rv)
65 66 67
        COMMINST @uvm.thread_exit
}

68
.funcdef @futex_requeue_test VERSION @futex_requeue_test_v1 <@v_v> {
Kunshan Wang's avatar
Kunshan Wang committed
69
    %entry():
70 71 72
        STORE <@i32> @the_futex @I32_0
        STORE <@i32> @the_other_futex @I32_0

73 74
        %ns = COMMINST @uvm.new_stack <[@v_v]> (@futex_requeue_waiter)
        %nt = NEWTHREAD %ns PASS_VALUES <> ()
75

76 77
        %ns2 = COMMINST @uvm.new_stack <[@v_v]> (@futex_requeue_waiter)
        %nt2 = NEWTHREAD %ns2 PASS_VALUES <> ()
78

Kunshan Wang's avatar
Kunshan Wang committed
79
        BRANCH %wait_body(%nt %nt2)
80

Kunshan Wang's avatar
Kunshan Wang committed
81
    %wait_body(<@thread> %nt <@thread> %nt2):
82 83
        %rv = [%trap_wait] TRAP <@i32> KEEPALIVE (%nt %nt2)
        %is_1 = EQ <@i32> %rv @I32_1
84
        BRANCH2 %is_1 %wait_exit() %wait_body(%nt %nt2)
85

Kunshan Wang's avatar
Kunshan Wang committed
86
    %wait_exit():
87 88
        %nwakes = COMMINST @uvm.futex.cmp_requeue <@i32> (@the_futex @the_other_futex @I32_0 @I32_1)
        %nwakes2 = COMMINST @uvm.futex.wake <@i32> (@the_other_futex @I32_1)
89
        [%trap_setter] TRAP <> KEEPALIVE (%nwakes %nwakes2)
90 91 92
        COMMINST @uvm.thread_exit
}

93
.funcsig @futex_gc_waiter_sig = (@refi32) -> ()
Kunshan Wang's avatar
Kunshan Wang committed
94 95
.funcdef @futex_gc_waiter VERSION @futex_gc_waiter_v1 <@futex_gc_waiter_sig> {
    %entry(<@refi32> %ref):
96 97
        %ir = GETIREF <@i32> %ref
        %rv = COMMINST @uvm.futex.wait <@i32> (%ir @I32_0)
98
        [%trap_gc_waiter] TRAP <> KEEPALIVE(%rv)
99 100 101
        COMMINST @uvm.thread_exit
}

102
.funcdef @futex_with_gc VERSION @futex_with_gc_v1 <@v_v> {
Kunshan Wang's avatar
Kunshan Wang committed
103
    %entry():
104 105 106 107
        %obj = NEW <@i64>
        %ir = GETIREF <@i64> %obj
        STORE <@i32> %ir @I32_0

108 109
        %ns = COMMINST @uvm.new_stack <[@futex_gc_waiter_sig]> (@futex_gc_waiter)
        %nt = NEWTHREAD %ns PASS_VALUES <@refi32> (%obj)
110

Kunshan Wang's avatar
Kunshan Wang committed
111
        BRANCH %wait_body(%ir %nt)
112

Kunshan Wang's avatar
Kunshan Wang committed
113
    %wait_body(<@irefi64> %ir <@thread> %nt):
114 115
        %rv = [%trap_wait] TRAP <@i32> KEEPALIVE (%nt)
        %is_1 = EQ <@i32> %rv @I32_1
Kunshan Wang's avatar
Kunshan Wang committed
116
        BRANCH2 %is_1 %wait_exit(%ir) %wait_body(%ir %nt)
117

Kunshan Wang's avatar
Kunshan Wang committed
118
    %wait_exit(<@irefi64> %ir):
119
        [%trap_gc] TRAP <>
120 121

        %nwakes = COMMINST @uvm.futex.wake <@i32> (%ir @I32_1)
122
        [%trap_exit] TRAP <> KEEPALIVE (%nwakes)
123 124
        COMMINST @uvm.thread_exit
}