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 3612771Sqtt2@cornell.edu */ 3712771Sqtt2@cornell.edu 3812771Sqtt2@cornell.edu//------------------------------------------------------------------------ 3912771Sqtt2@cornell.edu// This code tests lr.d and sc.d instructions in multi-threading system. 4012771Sqtt2@cornell.edu// All threads execute a critical section LOOP_COUNT times. A thread 4112771Sqtt2@cornell.edu// gets into a critical section by acquiring a lock variable (i.e., 4212771Sqtt2@cornell.edu// shared_var) and checking return value. 4312771Sqtt2@cornell.edu// 0 means the lock is not being locked. Each thread increments 4412771Sqtt2@cornell.edu// a variable (i.e., var) inside the critical section and releases the 4512771Sqtt2@cornell.edu// lock by swapping back 0 to the lock variable. 4612771Sqtt2@cornell.edu// The master thread (i.e., thread 0) waits for all threads to complete 4712771Sqtt2@cornell.edu// and compare the var's value to the expected result. 4812771Sqtt2@cornell.edu//------------------------------------------------------------------------ 4912771Sqtt2@cornell.edu 5012771Sqtt2@cornell.edu#include "riscv_test.h" 5112771Sqtt2@cornell.edu#include "test_macros.h" 5212771Sqtt2@cornell.edu#include "test_macros_mt.h" 5312771Sqtt2@cornell.edu 5412771Sqtt2@cornell.edu RVTEST_RV64U 5512771Sqtt2@cornell.edu RVTEST_CODE_BEGIN 5612771Sqtt2@cornell.edu 5712771Sqtt2@cornell.edu#define LOOP_COUNT 1000 5812771Sqtt2@cornell.edu#define RESULT NUM_THREADS * LOOP_COUNT 5912771Sqtt2@cornell.edu 6012771Sqtt2@cornell.edu//------------------------------------------------------------------------ 6112771Sqtt2@cornell.edu// Master thread creates new threads, waits for all threads to complete, 6212771Sqtt2@cornell.edu// deallocates threads and checks result 6312771Sqtt2@cornell.edu//------------------------------------------------------------------------ 6412771Sqtt2@cornell.edu call _create_threads 6512771Sqtt2@cornell.edu call _join 6612771Sqtt2@cornell.edu call _delete_threads 6712771Sqtt2@cornell.edu call _check 6812771Sqtt2@cornell.edu 6912771Sqtt2@cornell.edu RVTEST_CODE_END 7012771Sqtt2@cornell.edu 7112771Sqtt2@cornell.edu//------------------------------------------------------------------------ 7212771Sqtt2@cornell.edu// mt_test function executed in child threads 7312771Sqtt2@cornell.edu// A child thread signals its completion by atomicaly adding 1 to barrier 7412771Sqtt2@cornell.edu//------------------------------------------------------------------------ 7512771Sqtt2@cornell.edu_mt_test: 7612771Sqtt2@cornell.edu li t0, 1 // initialize the swap value (1-locked) 7712771Sqtt2@cornell.edu li t1, LOOP_COUNT 7812771Sqtt2@cornell.edu la t2, var // load the var's address 7912771Sqtt2@cornell.edu la a0, shared_var 8012771Sqtt2@cornell.edu 8112771Sqtt2@cornell.edu1: 8212771Sqtt2@cornell.edu lr.d.aq s2, (a0) // load and reserve a0 8312771Sqtt2@cornell.edu bnez s2, 1b // retry lr if the lock is being held 8412771Sqtt2@cornell.edu sc.d.rl s2, t0, (a0) // try to lock a0 8512771Sqtt2@cornell.edu bnez s2, 1b // retry if sc failed 8612771Sqtt2@cornell.edu 8712771Sqtt2@cornell.edu lw t3, (t2) // load the var's value 8812771Sqtt2@cornell.edu addi t3, t3, 1 // add 1 to the value 8912771Sqtt2@cornell.edu sw t3, (t2) // store the new value to var 9012771Sqtt2@cornell.edu 9112771Sqtt2@cornell.edu sd zero, (a0) // release the lock by storing 0 to a0 9212771Sqtt2@cornell.edu 9312771Sqtt2@cornell.edu addi t1, t1, -1 // decrement the loop_count 9412771Sqtt2@cornell.edu bnez t1, 1b // repeat if not done yet 9512771Sqtt2@cornell.edu 9612771Sqtt2@cornell.edu la a0, barrier 9712771Sqtt2@cornell.edu amoadd.d zero, t0, (a0) // signal this thread's completion 9812771Sqtt2@cornell.edu 9912771Sqtt2@cornell.edu RVTEST_CODE_END 10012771Sqtt2@cornell.edu 10112771Sqtt2@cornell.edu//------------------------------------------------------------------------ 10212771Sqtt2@cornell.edu// Master thread checks result 10312771Sqtt2@cornell.edu//------------------------------------------------------------------------ 10412771Sqtt2@cornell.edu_check: 10512771Sqtt2@cornell.edu la a0, var 10612771Sqtt2@cornell.edu li a1, RESULT 10712771Sqtt2@cornell.edu ld a0, (a0) 10812771Sqtt2@cornell.edu bne a0, a1, _fail 10912771Sqtt2@cornell.edu li a0, SUCCESS 11012771Sqtt2@cornell.edu ret 11112771Sqtt2@cornell.edu 11212771Sqtt2@cornell.edu_fail: 11312771Sqtt2@cornell.edu li a0, FAILURE 11412771Sqtt2@cornell.edu ret 11512771Sqtt2@cornell.edu 11612771Sqtt2@cornell.edu .data 11712771Sqtt2@cornell.edu 11812771Sqtt2@cornell.eduMT_DATA 11912771Sqtt2@cornell.eduvar: .dword 0 120