112771Sqtt2@cornell.edu/* 212771Sqtt2@cornell.edu * Copyright (c) 2018, Cornell University 312771Sqtt2@cornell.edu * All rights reserved. 412771Sqtt2@cornell.edu * 512771Sqtt2@cornell.edu * Redistribution and use in source and binary forms, with or 612771Sqtt2@cornell.edu * without modification, are permitted provided that the following 712771Sqtt2@cornell.edu * conditions are met: 812771Sqtt2@cornell.edu * 912771Sqtt2@cornell.edu * Redistributions of source code must retain the above copyright 1012771Sqtt2@cornell.edu * notice, this list of conditions and the following disclaimer. 1112771Sqtt2@cornell.edu * 1212771Sqtt2@cornell.edu * Redistributions in binary form must reproduce the above 1312771Sqtt2@cornell.edu * copyright notice, this list of conditions and the following 1412771Sqtt2@cornell.edu * disclaimer in the documentation and/or other materials provided 1512771Sqtt2@cornell.edu * with the distribution. 1612771Sqtt2@cornell.edu * 1712771Sqtt2@cornell.edu * Neither the name of Cornell University nor the names of its 1812771Sqtt2@cornell.edu * contributors may be used to endorse or promote products derived 1912771Sqtt2@cornell.edu * from this software without specific prior written permission. 2012771Sqtt2@cornell.edu * 2112771Sqtt2@cornell.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 2212771Sqtt2@cornell.edu * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 2312771Sqtt2@cornell.edu * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 2412771Sqtt2@cornell.edu * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 2512771Sqtt2@cornell.edu * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 2612771Sqtt2@cornell.edu * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2712771Sqtt2@cornell.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2812771Sqtt2@cornell.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 2912771Sqtt2@cornell.edu * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 3012771Sqtt2@cornell.edu * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3112771Sqtt2@cornell.edu * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 3212771Sqtt2@cornell.edu * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 3312771Sqtt2@cornell.edu * POSSIBILITY OF SUCH DAMAGE. 3412771Sqtt2@cornell.edu * 3512771Sqtt2@cornell.edu * Authors: Tuan Ta, Moyang 3612771Sqtt2@cornell.edu */ 3712771Sqtt2@cornell.edu 3812771Sqtt2@cornell.edu//------------------------------------------------------------------------ 3912771Sqtt2@cornell.edu// sysfutex_d tests FUTEX_WAKE_OP functionalities of futex system call: 4012771Sqtt2@cornell.edu// - make a thread wait on a variable 4112771Sqtt2@cornell.edu// - atomically wake up a thread waiting on a variable and perform 4212771Sqtt2@cornell.edu// a operation on a value 4312771Sqtt2@cornell.edu//------------------------------------------------------------------------ 4412771Sqtt2@cornell.edu 4512771Sqtt2@cornell.edu#include "riscv_test.h" 4612771Sqtt2@cornell.edu#include "test_macros.h" 4712771Sqtt2@cornell.edu#include "test_macros_mt_ecall.h" 4812771Sqtt2@cornell.edu 4912771Sqtt2@cornell.edu RVTEST_RV64U 5012771Sqtt2@cornell.edu RVTEST_CODE_BEGIN 5112771Sqtt2@cornell.edu 5212771Sqtt2@cornell.edu#define NUM_THREADS 1 5312771Sqtt2@cornell.edu#define LOOP_COUNT 1000 5412771Sqtt2@cornell.edu 5512771Sqtt2@cornell.edu//------------------------------------------------------------------------ 5612771Sqtt2@cornell.edu// Master thread creates new threads, call _master function, waits for all 5712771Sqtt2@cornell.edu// threads to complete, deallocates threads and checks result 5812771Sqtt2@cornell.edu//------------------------------------------------------------------------ 5912771Sqtt2@cornell.edu li a0, NUM_THREADS 6012771Sqtt2@cornell.edu call _create_threads 6112771Sqtt2@cornell.edu 6212771Sqtt2@cornell.edu la t6, n_worker_threads 6312771Sqtt2@cornell.edu ld a0, (t6) 6412771Sqtt2@cornell.edu beqz a0, _fail // exit if there's no worker thread 6512771Sqtt2@cornell.edu 6612771Sqtt2@cornell.edu call _master_work 6712771Sqtt2@cornell.edu 6812771Sqtt2@cornell.edu la t6, n_worker_threads 6912771Sqtt2@cornell.edu ld a0, (t6) 7012771Sqtt2@cornell.edu call _join 7112771Sqtt2@cornell.edu 7212771Sqtt2@cornell.edu la t6, n_worker_threads 7312771Sqtt2@cornell.edu ld a0, (t6) 7412771Sqtt2@cornell.edu call _check 7512771Sqtt2@cornell.edu 7612771Sqtt2@cornell.edu la t6, n_worker_threads 7712771Sqtt2@cornell.edu ld a0, (t6) 7812771Sqtt2@cornell.edu call _delete_threads 7912771Sqtt2@cornell.edu 8012771Sqtt2@cornell.edu li a0, SUCCESS 8112771Sqtt2@cornell.edu 8212771Sqtt2@cornell.edu RVTEST_CODE_END 8312771Sqtt2@cornell.edu 8412771Sqtt2@cornell.edu//------------------------------------------------------------------------ 8512771Sqtt2@cornell.edu// master_work function executed by the parent/master thread 8612771Sqtt2@cornell.edu// 8712771Sqtt2@cornell.edu// Wake up thread(s) waiting on futex_X and then wait on futex_Y in a 8812771Sqtt2@cornell.edu// loop. Also atomically modify futex_Z during the wake-up. 8912771Sqtt2@cornell.edu//------------------------------------------------------------------------ 9012771Sqtt2@cornell.edu_master_work: 9112771Sqtt2@cornell.edu mv s0, ra // save return address 9212771Sqtt2@cornell.edu li t0, LOOP_COUNT 9312771Sqtt2@cornell.edu la t1, count_master 9412771Sqtt2@cornell.edu la t3, count_Z 9512771Sqtt2@cornell.edu 9612771Sqtt2@cornell.edu1: 9712771Sqtt2@cornell.edu // futex(futex_X, FUTEX_WAKE_OP, 1, val2, futex_Z, val3 ) 9812771Sqtt2@cornell.edu la a0, futex_X 9912771Sqtt2@cornell.edu li a1, FUTEX_WAKE_OP 10012771Sqtt2@cornell.edu li a2, 1 // wake up at most 1 thread 10112771Sqtt2@cornell.edu li a3, 0 // should not perform the second wake up 10212771Sqtt2@cornell.edu la a4, futex_Z // add 1 to futex_Z each time 10312771Sqtt2@cornell.edu li a5, FUTEX_OP(FUTEX_OP_ADD, 1, FUTEX_OP_CMP_LT, 0) 10412771Sqtt2@cornell.edu li a7, SYSCALL_FUTEX 10512771Sqtt2@cornell.edu ecall 10612771Sqtt2@cornell.edu 10712771Sqtt2@cornell.edu // increment count_Z (should equals to futex_Z) 10812771Sqtt2@cornell.edu ld t4, (t3) 10912771Sqtt2@cornell.edu addi t4, t4, 1 11012771Sqtt2@cornell.edu sd t4, (t3) 11112771Sqtt2@cornell.edu 11212771Sqtt2@cornell.edu // keep waking up until at least one thread is waken up 11312771Sqtt2@cornell.edu beqz a0, 1b 11412771Sqtt2@cornell.edu 11512771Sqtt2@cornell.edu // increment count_master 11612771Sqtt2@cornell.edu ld t2, (t1) 11712771Sqtt2@cornell.edu addi t2, t2, 1 11812771Sqtt2@cornell.edu sd t2, (t1) 11912771Sqtt2@cornell.edu 12012771Sqtt2@cornell.edu // futex(futex_Y, FUTEX_WAIT_PRIVATE, 0) 12112771Sqtt2@cornell.edu la a0, futex_Y 12212771Sqtt2@cornell.edu li a1, FUTEX_WAIT_PRIVATE 12312771Sqtt2@cornell.edu li a2, 0 // expected val of futex_Y 12412771Sqtt2@cornell.edu li a7, SYSCALL_FUTEX 12512771Sqtt2@cornell.edu ecall 12612771Sqtt2@cornell.edu 12712771Sqtt2@cornell.edu // decrement t0 12812771Sqtt2@cornell.edu addi t0, t0, -1 12912771Sqtt2@cornell.edu bnez t0, 1b 13012771Sqtt2@cornell.edu 13112771Sqtt2@cornell.edu // restore return address and return 13212771Sqtt2@cornell.edu mv ra, s0 13312771Sqtt2@cornell.edu ret 13412771Sqtt2@cornell.edu 13512771Sqtt2@cornell.edu//------------------------------------------------------------------------ 13612771Sqtt2@cornell.edu// mt_test function executed by child threads 13712771Sqtt2@cornell.edu// 13812771Sqtt2@cornell.edu// Wait on futex_X and then wake up threads waiting on futex_Y in a loop 13912771Sqtt2@cornell.edu//------------------------------------------------------------------------ 14012771Sqtt2@cornell.edu_mt_test: 14112771Sqtt2@cornell.edu li t0, LOOP_COUNT 14212771Sqtt2@cornell.edu la t1, count_child 14312771Sqtt2@cornell.edu 14412771Sqtt2@cornell.edu1: 14512771Sqtt2@cornell.edu // futex(futex_X, FUTEX_WAIT_PRIVATE, 1) 14612771Sqtt2@cornell.edu la a0, futex_X 14712771Sqtt2@cornell.edu li a1, FUTEX_WAIT_PRIVATE 14812771Sqtt2@cornell.edu li a2, 0 // expected val of futex_X 14912771Sqtt2@cornell.edu li a7, SYSCALL_FUTEX 15012771Sqtt2@cornell.edu ecall 15112771Sqtt2@cornell.edu 15212771Sqtt2@cornell.edu // increment count_child 15312771Sqtt2@cornell.edu ld t2, (t1) 15412771Sqtt2@cornell.edu addi t2, t2, 1 15512771Sqtt2@cornell.edu sd t2, (t1) 15612771Sqtt2@cornell.edu 15712771Sqtt2@cornell.edu2: 15812771Sqtt2@cornell.edu // futex(futex_Y, FUTEX_WAKE_PRIVATE, 0) 15912771Sqtt2@cornell.edu la a0, futex_Y 16012771Sqtt2@cornell.edu li a1, FUTEX_WAKE_PRIVATE 16112771Sqtt2@cornell.edu li a2, 1 // wake up at most 1 thread 16212771Sqtt2@cornell.edu li a7, SYSCALL_FUTEX 16312771Sqtt2@cornell.edu ecall 16412771Sqtt2@cornell.edu 16512771Sqtt2@cornell.edu // keep waking up until at least one thread is waken up 16612771Sqtt2@cornell.edu beqz a0, 2b 16712771Sqtt2@cornell.edu 16812771Sqtt2@cornell.edu // decrement t0 16912771Sqtt2@cornell.edu addi t0, t0, -1 17012771Sqtt2@cornell.edu bnez t0, 1b 17112771Sqtt2@cornell.edu 17212771Sqtt2@cornell.edu RVTEST_CODE_END 17312771Sqtt2@cornell.edu 17412771Sqtt2@cornell.edu//------------------------------------------------------------------------ 17512771Sqtt2@cornell.edu// _check: 17612771Sqtt2@cornell.edu// Each thread should do LOOP_COUNT iterations 17712771Sqtt2@cornell.edu//------------------------------------------------------------------------ 17812771Sqtt2@cornell.edu 17912771Sqtt2@cornell.edu_check: 18012771Sqtt2@cornell.edu la t0, count_master 18112771Sqtt2@cornell.edu la t1, count_child 18212771Sqtt2@cornell.edu li t2, LOOP_COUNT 18312771Sqtt2@cornell.edu la t3, count_Z 18412771Sqtt2@cornell.edu la t4, futex_Z 18512771Sqtt2@cornell.edu 18612771Sqtt2@cornell.edu ld t0, (t0) 18712771Sqtt2@cornell.edu bne t0, t2, _fail 18812771Sqtt2@cornell.edu 18912771Sqtt2@cornell.edu ld t1, (t1) 19012771Sqtt2@cornell.edu bne t1, t2, _fail 19112771Sqtt2@cornell.edu 19212771Sqtt2@cornell.edu ld t3, (t3) 19312771Sqtt2@cornell.edu ld t4, (t4) 19412771Sqtt2@cornell.edu bne t3, t4, _fail 19512771Sqtt2@cornell.edu 19612771Sqtt2@cornell.edu ret 19712771Sqtt2@cornell.edu 19812771Sqtt2@cornell.edu_fail: 19912771Sqtt2@cornell.edu li a0, FAILURE 20012771Sqtt2@cornell.edu RVTEST_CODE_END 20112771Sqtt2@cornell.edu 20212771Sqtt2@cornell.edu .data 20312771Sqtt2@cornell.edu 20412771Sqtt2@cornell.edufutex_X: .dword 0 20512771Sqtt2@cornell.edufutex_Y: .dword 0 20612771Sqtt2@cornell.edufutex_Z: .dword 0 20712771Sqtt2@cornell.edu 20812771Sqtt2@cornell.educount_master: .dword 0 20912771Sqtt2@cornell.educount_child: .dword 0 21012771Sqtt2@cornell.educount_Z: .dword 0 21112771Sqtt2@cornell.edu 21212771Sqtt2@cornell.eduMT_DATA 213