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.
36 //------------------------------------------------------------------------
37 // sysfutex3_d tests FUTEX_CMP_REQUEUE functionalities of futex system
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 //------------------------------------------------------------------------
44 #include "riscv_test.h"
45 #include "test_macros.h"
46 #include "test_macros_mt_ecall.h"
51 #define NUM_THREADS 20
53 //------------------------------------------------------------------------
54 // Master thread creates new threads, call _master function, waits for all
55 // threads to complete, deallocates threads and checks result
56 //------------------------------------------------------------------------
60 la t6, n_worker_threads
62 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
84 //------------------------------------------------------------------------
86 mv s0, ra // save return address
87 li t0, 0 // number of threads that have been waken
88 la t1, n_worker_threads
92 // futex(futex_X, FUTEX_CMP_REQUEUE, 1, INT_MAX, futex_Y, *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
102 // loop until wake up one thread, all other waiter are requeued to
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
113 // futex(futex_Y, FUTEX_WAKE_PRIVATE, 0)
116 li a2, 1 // wake up at most 1 thread
120 add t0, t0, a0 // track the number of waken threads so far
122 // futex(futex_X, FUTEX_WAKE_PRIVATE, 0)
125 li a2, 1 // wake up at most 1 thread
129 add t0, t0, a0 // track the number of waken threads so far
131 // keep waking up until all threads are waken up
134 // restore return address and return
138 //------------------------------------------------------------------------
139 // mt_test function executed by child threads
142 //------------------------------------------------------------------------
144 // futex(futex_X, FUTEX_WAIT_PRIVATE, 1)
147 li a2, 0 // expected val of futex_X
153 //------------------------------------------------------------------------
155 // counter should equals to number of child threads
156 //------------------------------------------------------------------------