2 * Copyright (c) 2018, Cornell University
5 * Redistribution and use in source and binary forms, with or
6 * without modification, are permitted provided that the following
9 * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
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.
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.
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.
38 //------------------------------------------------------------------------
39 // sysfutex_d tests basic functionalities of futex system call:
40 // - make a thread wait on a variable
41 // - wake up a thread waiting on a variable
42 //------------------------------------------------------------------------
44 #include "riscv_test.h"
45 #include "test_macros.h"
46 #include "test_macros_mt_ecall.h"
52 #define LOOP_COUNT 1000
54 //------------------------------------------------------------------------
55 // Master thread creates new threads, call _master function, waits for all
56 // threads to complete, deallocates threads and checks result
57 //------------------------------------------------------------------------
61 la t6, n_worker_threads
63 beqz a0, _fail // exit if there's no worker thread
66 la t6, n_worker_threads
70 la t6, n_worker_threads
74 la t6, n_worker_threads
82 //------------------------------------------------------------------------
83 // master_work function executed by the parent/master thread
85 // Wake up thread(s) waiting on futex_X and then wait on futex_Y in a
87 //------------------------------------------------------------------------
89 mv s0, ra // save return address
94 // futex(futex_X, FUTEX_WAKE_PRIVATE, 1)
96 li a1, FUTEX_WAKE_PRIVATE
97 li a2, 1 // wake up at most 1 thread
101 // keep waking up until at least one thread is waken up
104 // increment count_master
109 // futex(futex_Y, FUTEX_WAIT_PRIVATE, 0)
111 li a1, FUTEX_WAIT_PRIVATE
112 li a2, 0 // expected val of futex_Y
120 // restore return address and return
124 //------------------------------------------------------------------------
125 // mt_test function executed by child threads
127 // Wait on futex_X and then wake up threads waiting on futex_Y in a loop
128 //------------------------------------------------------------------------
134 // futex(futex_X, FUTEX_WAIT_PRIVATE, 1)
136 li a1, FUTEX_WAIT_PRIVATE
137 li a2, 0 // expected val of futex_X
141 // increment count_child
147 // futex(futex_Y, FUTEX_WAKE_PRIVATE, 0)
149 li a1, FUTEX_WAKE_PRIVATE
150 li a2, 1 // wake up at most 1 thread
154 // keep waking up until at least one thread is waken up
163 //------------------------------------------------------------------------
165 // Each thread should do LOOP_COUNT iterations
166 //------------------------------------------------------------------------
190 count_master: .dword 0
191 count_child: .dword 0