tests: Delete authors lists from test files.
[gem5.git] / tests / test-progs / asmtest / src / riscv / isa / rv64samt / sysfutex2_d.S
1 /*
2 * Copyright (c) 2018, Cornell University
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or
6 * without modification, are permitted provided that the following
7 * conditions are met:
8 *
9 * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following
14 * disclaimer in the documentation and/or other materials provided
15 * with the distribution.
16 *
17 * Neither the name of Cornell University nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
22 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
23 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
26 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
29 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
30 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
34 */
35
36 //------------------------------------------------------------------------
37 // sysfutex_d tests FUTEX_WAKE_OP functionalities of futex system call:
38 // - make a thread wait on a variable
39 // - atomically wake up a thread waiting on a variable and perform
40 // a operation on a value
41 //------------------------------------------------------------------------
42
43 #include "riscv_test.h"
44 #include "test_macros.h"
45 #include "test_macros_mt_ecall.h"
46
47 RVTEST_RV64U
48 RVTEST_CODE_BEGIN
49
50 #define NUM_THREADS 1
51 #define LOOP_COUNT 1000
52
53 //------------------------------------------------------------------------
54 // Master thread creates new threads, call _master function, waits for all
55 // threads to complete, deallocates threads and checks result
56 //------------------------------------------------------------------------
57 li a0, NUM_THREADS
58 call _create_threads
59
60 la t6, n_worker_threads
61 ld a0, (t6)
62 beqz a0, _fail // exit if there's no worker thread
63
64 call _master_work
65
66 la t6, n_worker_threads
67 ld a0, (t6)
68 call _join
69
70 la t6, n_worker_threads
71 ld a0, (t6)
72 call _check
73
74 la t6, n_worker_threads
75 ld a0, (t6)
76 call _delete_threads
77
78 li a0, SUCCESS
79
80 RVTEST_CODE_END
81
82 //------------------------------------------------------------------------
83 // master_work function executed by the parent/master thread
84 //
85 // Wake up thread(s) waiting on futex_X and then wait on futex_Y in a
86 // loop. Also atomically modify futex_Z during the wake-up.
87 //------------------------------------------------------------------------
88 _master_work:
89 mv s0, ra // save return address
90 li t0, LOOP_COUNT
91 la t1, count_master
92 la t3, count_Z
93
94 1:
95 // futex(futex_X, FUTEX_WAKE_OP, 1, val2, futex_Z, val3 )
96 la a0, futex_X
97 li a1, FUTEX_WAKE_OP
98 li a2, 1 // wake up at most 1 thread
99 li a3, 0 // should not perform the second wake up
100 la a4, futex_Z // add 1 to futex_Z each time
101 li a5, FUTEX_OP(FUTEX_OP_ADD, 1, FUTEX_OP_CMP_LT, 0)
102 li a7, SYSCALL_FUTEX
103 ecall
104
105 // increment count_Z (should equals to futex_Z)
106 ld t4, (t3)
107 addi t4, t4, 1
108 sd t4, (t3)
109
110 // keep waking up until at least one thread is waken up
111 beqz a0, 1b
112
113 // increment count_master
114 ld t2, (t1)
115 addi t2, t2, 1
116 sd t2, (t1)
117
118 // futex(futex_Y, FUTEX_WAIT_PRIVATE, 0)
119 la a0, futex_Y
120 li a1, FUTEX_WAIT_PRIVATE
121 li a2, 0 // expected val of futex_Y
122 li a7, SYSCALL_FUTEX
123 ecall
124
125 // decrement t0
126 addi t0, t0, -1
127 bnez t0, 1b
128
129 // restore return address and return
130 mv ra, s0
131 ret
132
133 //------------------------------------------------------------------------
134 // mt_test function executed by child threads
135 //
136 // Wait on futex_X and then wake up threads waiting on futex_Y in a loop
137 //------------------------------------------------------------------------
138 _mt_test:
139 li t0, LOOP_COUNT
140 la t1, count_child
141
142 1:
143 // futex(futex_X, FUTEX_WAIT_PRIVATE, 1)
144 la a0, futex_X
145 li a1, FUTEX_WAIT_PRIVATE
146 li a2, 0 // expected val of futex_X
147 li a7, SYSCALL_FUTEX
148 ecall
149
150 // increment count_child
151 ld t2, (t1)
152 addi t2, t2, 1
153 sd t2, (t1)
154
155 2:
156 // futex(futex_Y, FUTEX_WAKE_PRIVATE, 0)
157 la a0, futex_Y
158 li a1, FUTEX_WAKE_PRIVATE
159 li a2, 1 // wake up at most 1 thread
160 li a7, SYSCALL_FUTEX
161 ecall
162
163 // keep waking up until at least one thread is waken up
164 beqz a0, 2b
165
166 // decrement t0
167 addi t0, t0, -1
168 bnez t0, 1b
169
170 RVTEST_CODE_END
171
172 //------------------------------------------------------------------------
173 // _check:
174 // Each thread should do LOOP_COUNT iterations
175 //------------------------------------------------------------------------
176
177 _check:
178 la t0, count_master
179 la t1, count_child
180 li t2, LOOP_COUNT
181 la t3, count_Z
182 la t4, futex_Z
183
184 ld t0, (t0)
185 bne t0, t2, _fail
186
187 ld t1, (t1)
188 bne t1, t2, _fail
189
190 ld t3, (t3)
191 ld t4, (t4)
192 bne t3, t4, _fail
193
194 ret
195
196 _fail:
197 li a0, FAILURE
198 RVTEST_CODE_END
199
200 .data
201
202 futex_X: .dword 0
203 futex_Y: .dword 0
204 futex_Z: .dword 0
205
206 count_master: .dword 0
207 count_child: .dword 0
208 count_Z: .dword 0
209
210 MT_DATA