tests: Delete authors lists from test files.
[gem5.git] / tests / test-progs / asmtest / src / riscv / isa / rv64samt / sysfutex3_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 // sysfutex3_d tests FUTEX_CMP_REQUEUE functionalities of futex system
38 // call:
39 // - make worker threads waiting on futex 1
40 // - wake up 1 thread, requeue the rest of the threads to futex 2
41 // - wake all threads waiting on futex 1 and futex 2
42 //------------------------------------------------------------------------
43
44 #include "riscv_test.h"
45 #include "test_macros.h"
46 #include "test_macros_mt_ecall.h"
47
48 RVTEST_RV64U
49 RVTEST_CODE_BEGIN
50
51 #define NUM_THREADS 20
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 _master_work:
86 mv s0, ra // save return address
87 li t0, 0 // number of threads that have been waken
88 la t1, n_worker_threads
89 ld t1, (t1)
90
91 1:
92 // futex(futex_X, FUTEX_CMP_REQUEUE, 1, INT_MAX, futex_Y, *futex_X)
93 la a0, futex_X
94 li a1, FUTEX_CMP_REQUEUE
95 li a2, 1 // wake up at most 1 thread
96 li a3, 1000 // practically is INT_MAX
97 la a4, futex_Y // move all other waiter to futex_Y
98 li a5, 0
99 li a7, SYSCALL_FUTEX
100 ecall
101
102 // loop until wake up one thread, all other waiter are requeued to
103 // futex_Y
104 beqz a0, 1b
105
106 addi t0, t0, 1
107
108 2:
109 // alternating between futex_X and futex_Y
110 // because there could be new threads added to futex_X's queue
111 // after our futex_requeue
112
113 // futex(futex_Y, FUTEX_WAKE_PRIVATE, 0)
114 la a0, futex_Y
115 li a1, FUTEX_WAKE
116 li a2, 1 // wake up at most 1 thread
117 li a7, SYSCALL_FUTEX
118 ecall
119
120 add t0, t0, a0 // track the number of waken threads so far
121
122 // futex(futex_X, FUTEX_WAKE_PRIVATE, 0)
123 la a0, futex_X
124 li a1, FUTEX_WAKE
125 li a2, 1 // wake up at most 1 thread
126 li a7, SYSCALL_FUTEX
127 ecall
128
129 add t0, t0, a0 // track the number of waken threads so far
130
131 // keep waking up until all threads are waken up
132 blt t0, t1, 2b
133
134 // restore return address and return
135 mv ra, s0
136 ret
137
138 //------------------------------------------------------------------------
139 // mt_test function executed by child threads
140 //
141 // Wait on futex_X
142 //------------------------------------------------------------------------
143 _mt_test:
144 // futex(futex_X, FUTEX_WAIT_PRIVATE, 1)
145 la a0, futex_X
146 li a1, FUTEX_WAIT
147 li a2, 0 // expected val of futex_X
148 li a7, SYSCALL_FUTEX
149 ecall
150
151 RVTEST_CODE_END
152
153 //------------------------------------------------------------------------
154 // _check:
155 // counter should equals to number of child threads
156 //------------------------------------------------------------------------
157
158 _check:
159 ret
160
161 _fail:
162 li a0, FAILURE
163 RVTEST_CODE_END
164
165 .data
166
167 futex_X: .dword 0
168 futex_Y: .dword 0
169
170 MT_DATA