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 * Authors: Tuan Ta 36 */ 37 38//------------------------------------------------------------------------ 39// sysfutex1_d tests basic functionalities of futex system call: 40// - make some threads wait on a variable 41// - wake up all threads waiting on a variable 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 MAX_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, MAX_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 all threads waiting on futex_X 86//------------------------------------------------------------------------ 87_master_work: 88 mv s0, ra // save return address 89 li t0, 0 // number of threads that have been waken 90 la t1, n_worker_threads 91 ld t1, (t1) 92 931: 94 // futex(futex_X, FUTEX_WAKE_PRIVATE, n_worker_threads) 95 la a0, futex_X 96 li a1, FUTEX_WAKE_PRIVATE 97 li a2, 1 // wake up at most 1 thread 98 li a7, SYSCALL_FUTEX 99 ecall 100 101 add t0, t0, a0 // track the number of waken threads so far 102 103 // keep waking up until all threads are waken up 104 blt t0, t1, 1b 105 106 // restore return address and return 107 mv ra, s0 108 ret 109 110//------------------------------------------------------------------------ 111// mt_test function executed by child threads 112// 113// Wait on futex_X 114//------------------------------------------------------------------------ 115_mt_test: 116 // futex(futex_X, FUTEX_WAIT_PRIVATE, 1) 117 la a0, futex_X 118 li a1, FUTEX_WAIT_PRIVATE 119 li a2, 0 // expected val of futex_X 120 li a7, SYSCALL_FUTEX 121 ecall 122 123 RVTEST_CODE_END 124 125//------------------------------------------------------------------------ 126// _check: 127// Each thread should do LOOP_COUNT iterations 128//------------------------------------------------------------------------ 129 130_check: 131 ret 132 133_fail: 134 li a0, FAILURE 135 RVTEST_CODE_END 136 137 .data 138 139futex_X: .dword 0 140futex_Y: .dword 0 141 142count_master: .dword 0 143count_child: .dword 0 144 145MT_DATA 146