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// This test_macros includes necessary functions and macros to create 40// and exit threads. They're used in multi-threaded assembly tests. 41// This assumes the target system can concurrently support 4 different 42// threads (i.e., 1 master thread and 3 child threads) 43//------------------------------------------------------------------------ 44 45#ifndef __TEST_MACROS_MT_H 46#define __TEST_MACROS_MT_H 47 48#define SYSCALL_MMAP 222 49#define SYSCALL_MUNMAP 215 50#define SYSCALL_CLONE 220 51 52#define STACK_SIZE (4096 * 1024) 53 54#define PROT_READ 0x1 55#define PROT_WRITE 0x2 56#define MMAP_PROT_FLAGS (PROT_READ | PROT_WRITE) 57 58#define MAP_PRIVATE 0x02 59#define MAP_ANONYMOUS 0x20 60#define MAP_STACK 0x20000 61#define MMAP_MAP_FLAGS (MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK) 62 63#define CLONE_VM 0x00000100 64#define CLONE_FS 0x00000200 65#define CLONE_FILES 0x00000400 66#define CLONE_SIGHAND 0x00000800 67#define CLONE_PARENT 0x00008000 68#define CLONE_THREAD 0x00010000 69#define CLONE_IO 0x80000000 70#define CLONE_FLAGS (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND\ 71 | CLONE_PARENT | CLONE_THREAD | CLONE_IO) 72 73#define NUM_THREADS 3 74 75#define FAILURE 1 76#define SUCCESS 0 77 78#define HARTID 0xF14 79 80//------------------------------------------------------------------------ 81// create NUM_THREADS child threads 82//------------------------------------------------------------------------ 83_create_threads: 84 li t0, NUM_THREADS 85 mv s0, ra // save return register 861: 87 jal ra, _alloc_stack 88 addi sp, sp, -8 89 sd a0, (sp) // save pointer to the new stack 90 jal ra, _clone_thread // clone a new thread 91 addi t0, t0, -1 92 bnez t0, 1b 93 mv ra, s0 // restore return register 94 ret 95 96_alloc_stack: 97 li a0, 0 98 li a1, STACK_SIZE 99 li a2, MMAP_PROT_FLAGS 100 li a3, MMAP_MAP_FLAGS 101 li a4, -1 102 li a5, 0 103 li a7, SYSCALL_MMAP 104 ecall 105 ret 106 107_clone_thread: 108 li a1, STACK_SIZE 109 add a1, a1, a0 110 li a0, CLONE_FLAGS 111 li a7, SYSCALL_CLONE 112 ecall 113 beqz a0, _mt_test 114 ret 115 116//------------------------------------------------------------------------ 117// wait for all child threads to exit 118//------------------------------------------------------------------------ 119_join: 120 la t0, barrier 121 li t1, NUM_THREADS 1221: 123 ld t2, (t0) 124 bne t1, t2, 1b 125 ret 126 127//------------------------------------------------------------------------ 128// deallocate NUM_THREADS child threads 129//------------------------------------------------------------------------ 130_delete_threads: 131 li t0, NUM_THREADS 132 mv s0, ra // save return register 1331: 134 ld a0, (sp) // pop the new stack's pointer 135 addi sp, sp, 8 136 jal ra, _dealloc_stack 137 addi t0, t0, -1 138 bnez t0, 1b 139 mv ra, s0 // restore return register 140 ret 141 142_dealloc_stack: 143 li a1, STACK_SIZE 144 li a7, SYSCALL_MUNMAP 145 ecall 146 ret 147 148#define MT_DATA \ 149 shared_var: .dword 0; \ 150 barrier: .dword 0; \ 151 array: .dword 0x00000000deadbeef, \ 152 0xdeadbeefdeadbeef, \ 153 0x12343eeaaf423451; \ 154 155#endif 156