sysfutex_d.S revision 12771
113819Sgabeblack@google.com/* 213819Sgabeblack@google.com * Copyright (c) 2018, Cornell University 313819Sgabeblack@google.com * All rights reserved. 413819Sgabeblack@google.com * 513819Sgabeblack@google.com * Redistribution and use in source and binary forms, with or 613819Sgabeblack@google.com * without modification, are permitted provided that the following 713819Sgabeblack@google.com * conditions are met: 813819Sgabeblack@google.com * 913819Sgabeblack@google.com * Redistributions of source code must retain the above copyright 1013819Sgabeblack@google.com * notice, this list of conditions and the following disclaimer. 1113819Sgabeblack@google.com * 1213819Sgabeblack@google.com * Redistributions in binary form must reproduce the above 1313819Sgabeblack@google.com * copyright notice, this list of conditions and the following 1413819Sgabeblack@google.com * disclaimer in the documentation and/or other materials provided 1513819Sgabeblack@google.com * with the distribution. 1613819Sgabeblack@google.com * 1713819Sgabeblack@google.com * Neither the name of Cornell University nor the names of its 1813819Sgabeblack@google.com * contributors may be used to endorse or promote products derived 1913819Sgabeblack@google.com * from this software without specific prior written permission. 2013819Sgabeblack@google.com * 2113819Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 2213819Sgabeblack@google.com * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 2313819Sgabeblack@google.com * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 2413819Sgabeblack@google.com * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 2513819Sgabeblack@google.com * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 2613819Sgabeblack@google.com * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2713819Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2813819Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 2913819Sgabeblack@google.com * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 3013819Sgabeblack@google.com * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3113819Sgabeblack@google.com * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 3213819Sgabeblack@google.com * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 3313819Sgabeblack@google.com * POSSIBILITY OF SUCH DAMAGE. 3413819Sgabeblack@google.com * 3513819Sgabeblack@google.com * Authors: Tuan Ta 3613819Sgabeblack@google.com */ 3713819Sgabeblack@google.com 3813819Sgabeblack@google.com//------------------------------------------------------------------------ 3913819Sgabeblack@google.com// sysfutex_d tests basic functionalities of futex system call: 4013819Sgabeblack@google.com// - make a thread wait on a variable 4113819Sgabeblack@google.com// - wake up a thread waiting on a variable 4213819Sgabeblack@google.com//------------------------------------------------------------------------ 4313819Sgabeblack@google.com 4413819Sgabeblack@google.com#include "riscv_test.h" 4513819Sgabeblack@google.com#include "test_macros.h" 4613819Sgabeblack@google.com#include "test_macros_mt_ecall.h" 4713819Sgabeblack@google.com 4813819Sgabeblack@google.com RVTEST_RV64U 4913819Sgabeblack@google.com RVTEST_CODE_BEGIN 5013819Sgabeblack@google.com 5113819Sgabeblack@google.com#define NUM_THREADS 1 5213819Sgabeblack@google.com#define LOOP_COUNT 1000 5313819Sgabeblack@google.com 5413819Sgabeblack@google.com//------------------------------------------------------------------------ 5513819Sgabeblack@google.com// Master thread creates new threads, call _master function, waits for all 5613819Sgabeblack@google.com// threads to complete, deallocates threads and checks result 5713819Sgabeblack@google.com//------------------------------------------------------------------------ 5813819Sgabeblack@google.com li a0, NUM_THREADS 5913819Sgabeblack@google.com call _create_threads 6013819Sgabeblack@google.com 6113819Sgabeblack@google.com la t6, n_worker_threads 6213819Sgabeblack@google.com ld a0, (t6) 6313819Sgabeblack@google.com beqz a0, _fail // exit if there's no worker thread 6413819Sgabeblack@google.com call _master_work 6513819Sgabeblack@google.com 6613819Sgabeblack@google.com la t6, n_worker_threads 6713819Sgabeblack@google.com ld a0, (t6) 6813819Sgabeblack@google.com call _join 6913819Sgabeblack@google.com 7013819Sgabeblack@google.com la t6, n_worker_threads 7113819Sgabeblack@google.com ld a0, (t6) 7213819Sgabeblack@google.com call _check 7313819Sgabeblack@google.com 7413819Sgabeblack@google.com la t6, n_worker_threads 7513819Sgabeblack@google.com ld a0, (t6) 7613819Sgabeblack@google.com call _delete_threads 7714189Sgabeblack@google.com 7813819Sgabeblack@google.com li a0, SUCCESS 7913819Sgabeblack@google.com 8013819Sgabeblack@google.com RVTEST_CODE_END 8113819Sgabeblack@google.com 8213819Sgabeblack@google.com//------------------------------------------------------------------------ 8313819Sgabeblack@google.com// master_work function executed by the parent/master thread 8413819Sgabeblack@google.com// 8513819Sgabeblack@google.com// Wake up thread(s) waiting on futex_X and then wait on futex_Y in a 8613819Sgabeblack@google.com// loop. 8713819Sgabeblack@google.com//------------------------------------------------------------------------ 8813819Sgabeblack@google.com_master_work: 8913819Sgabeblack@google.com mv s0, ra // save return address 9013819Sgabeblack@google.com li t0, LOOP_COUNT 9113819Sgabeblack@google.com la t1, count_master 9213819Sgabeblack@google.com 9313819Sgabeblack@google.com1: 9413819Sgabeblack@google.com // futex(futex_X, FUTEX_WAKE_PRIVATE, 1) 9513819Sgabeblack@google.com la a0, futex_X 9613819Sgabeblack@google.com li a1, FUTEX_WAKE_PRIVATE 9713819Sgabeblack@google.com li a2, 1 // wake up at most 1 thread 9813819Sgabeblack@google.com li a7, SYSCALL_FUTEX 9913819Sgabeblack@google.com ecall 10013819Sgabeblack@google.com 10113819Sgabeblack@google.com // keep waking up until at least one thread is waken up 10213819Sgabeblack@google.com beqz a0, 1b 10313819Sgabeblack@google.com 10413819Sgabeblack@google.com // increment count_master 10513819Sgabeblack@google.com ld t2, (t1) 10613819Sgabeblack@google.com addi t2, t2, 1 10713819Sgabeblack@google.com sd t2, (t1) 10813819Sgabeblack@google.com 10913819Sgabeblack@google.com // futex(futex_Y, FUTEX_WAIT_PRIVATE, 0) 11013819Sgabeblack@google.com la a0, futex_Y 11114189Sgabeblack@google.com li a1, FUTEX_WAIT_PRIVATE 11213819Sgabeblack@google.com li a2, 0 // expected val of futex_Y 11313819Sgabeblack@google.com li a7, SYSCALL_FUTEX 11413819Sgabeblack@google.com ecall 11513819Sgabeblack@google.com 11613819Sgabeblack@google.com // decrement t0 11713819Sgabeblack@google.com addi t0, t0, -1 11813819Sgabeblack@google.com bnez t0, 1b 11913819Sgabeblack@google.com 12013819Sgabeblack@google.com // restore return address and return 12113819Sgabeblack@google.com mv ra, s0 12213819Sgabeblack@google.com ret 12313819Sgabeblack@google.com 12413819Sgabeblack@google.com//------------------------------------------------------------------------ 12513819Sgabeblack@google.com// mt_test function executed by child threads 12613819Sgabeblack@google.com// 127// Wait on futex_X and then wake up threads waiting on futex_Y in a loop 128//------------------------------------------------------------------------ 129_mt_test: 130 li t0, LOOP_COUNT 131 la t1, count_child 132 1331: 134 // futex(futex_X, FUTEX_WAIT_PRIVATE, 1) 135 la a0, futex_X 136 li a1, FUTEX_WAIT_PRIVATE 137 li a2, 0 // expected val of futex_X 138 li a7, SYSCALL_FUTEX 139 ecall 140 141 // increment count_child 142 ld t2, (t1) 143 addi t2, t2, 1 144 sd t2, (t1) 145 1462: 147 // futex(futex_Y, FUTEX_WAKE_PRIVATE, 0) 148 la a0, futex_Y 149 li a1, FUTEX_WAKE_PRIVATE 150 li a2, 1 // wake up at most 1 thread 151 li a7, SYSCALL_FUTEX 152 ecall 153 154 // keep waking up until at least one thread is waken up 155 beqz a0, 2b 156 157 // decrement t0 158 addi t0, t0, -1 159 bnez t0, 1b 160 161 RVTEST_CODE_END 162 163//------------------------------------------------------------------------ 164// _check: 165// Each thread should do LOOP_COUNT iterations 166//------------------------------------------------------------------------ 167 168_check: 169 la t0, count_master 170 la t1, count_child 171 li t2, LOOP_COUNT 172 173 ld t0, (t0) 174 bne t0, t2, _fail 175 176 ld t1, (t1) 177 bne t1, t2, _fail 178 179 ret 180 181_fail: 182 li a0, FAILURE 183 RVTEST_CODE_END 184 185 .data 186 187futex_X: .dword 0 188futex_Y: .dword 0 189 190count_master: .dword 0 191count_child: .dword 0 192 193MT_DATA 194