1/* 2 * Some or all of this work - Copyright (c) 2006 - 2021, Intel Corp. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without modification, 6 * are permitted provided that the following conditions are met: 7 * 8 * Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * Neither the name of Intel Corporation nor the names of its contributors 14 * may be used to endorse or promote products derived from this software 15 * without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 25 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 26 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29/* 30 * Multi access to different type data 31 * 32 * Types: 33 * - Buffer 34 * - Package 35 * 36 * Notations: 37 * 38 * Leading thread - the worker thread #1 which plays in the relevant test 39 * some control role. 40 */ 41 42 43/* Leading thread (thread #1) put there commands for other threads */ 44Name(b900, Buffer(){0,0,0,0,0,0,0,0}) 45 46/* 47 * This buffer is zeroed by the leading thread and then to 48 * be filled by other worker threads, some non-zero respond to 49 * the leading thread. 50 */ 51Name(b901, Buffer(){0,0,0,0,0,0,0,0}) 52 53/* 54 * This buffer is zeroed by the leading thread and then to be 55 * filled by other worker threads when they see that i900 is zero. 56 * 57 * The leading thread uses it to check that all the worker threads 58 * saw zero i900 before to start the next command. 59 */ 60Name(b902, Buffer(){0,0,0,0,0,0,0,0}) 61 62Name(i900, 0) // signal start fulfilling command 63Name(i901, 0x30) // to do command 0x30 once only 64Name(c900, 0x31) // 65 66/* 67 * Test #. 68 * 69 * Leading thread (thread #1) is a controlling thread other are worker threads here. 70 * 71 * arg0 - number of threads 72 * arg1 - ID of current thread 73 * arg2 - Index of current thread 74 */ 75Method(m900, 1) 76{ 77 if (LGreater(arg0, 8)) { 78 se00(arg2, er06) 79 return 80 } 81 if (LGreaterEqual(arg2, arg0)) { 82 se00(arg2, er06) 83 } 84 85 if (LEqual(arg2, 1)) { 86 87 /* Leading thread */ 88 89 While (1) { 90 91 if (i901) { 92 Store(0, i901) 93 m200(b900, arg0, 0x30) 94 m200(b901, arg0, 0) 95 Store(1, i900) 96 } 97 98 m206(arg2, sl01) 99 } 100 } else { 101 While (1) { 102 103 /* Determine the command for particular thread */ 104 105 Store(c900, Local0) 106 107 /* Control thread allows for worker threads to fulfill their commands */ 108 if (i900) { 109 Store(DerefOf(Index(b901, arg2)), Local1) 110 /* This thread doesn't yet fulfill its command */ 111 if (LNot(Local1)) { 112 /* Command to be fulfilled */ 113 Store(DerefOf(Index(b900, arg2)), Local0) 114 } 115 /* Unnecessary */ 116 if (LNot(i900)) { 117 Store(c900, Local0) 118 } 119 } 120 121 if (LNot(i900)) { 122 Store(DerefOf(Index(b902, arg2)), Local0) 123 if (LNot(Local0)) { 124 /* Any non-zero value */ 125 Store(rs00, Index(b902, arg2)) 126 } 127 } 128 m206(arg2, sl01) 129 } 130 } 131} 132 133/* 134 * Thread 1 waits for all the worker threads to 135 * fulfill the specified for them the buffer of commands. 136 * 137 * arg0 - number of threads 138 * arg1 - flag if to check that all the worker threads saw my zero do00 139 */ 140Method(m9ff, 2) 141{ 142 Name(lpN0, 0) 143 Name(lpC0, 0) 144 Name(find, 0) 145 146 /* 147 * Check that all the worker threads saw my 148 * non-zero do00 and fulfilled the proper command. 149 */ 150 While (1) { 151 Store(0, find) 152 Store(arg0, lpN0) 153 Store(0, lpC0) 154 While (lpN0) { 155 156 /* For not a Control thread only */ 157 if (LNotEqual(lpC0, 0)) { 158 Store(DerefOf(Index(b900, lpC0)), Local0) 159 Store(DerefOf(Index(b901, lpC0)), Local1) 160 if (LNotEqual(Local0, Local1)) { 161 Store(1, find) 162 break 163 } 164 } 165 166 Decrement(lpN0) 167 Increment(lpC0) 168 } 169 170 if (LNot(find)) { 171 break 172 } 173 174 /* 175 * Don't report about Control thread sleeping - 176 * don't use m206(0, sl00). 177 */ 178 Sleep(sl00) 179 } 180 181 /* 182 * Check that all the worker threads saw my zero do00 183 * (if only it is not the EXIT command). 184 * Note: assumed that EXIT command is specified for all 185 * the threads simultaneously, so only. 186 */ 187 if (arg1) { 188 if (fl01) { 189 m109() 190 } else { 191 m200(b902, arg0, 0) 192 } 193 Store(0, do00) 194 While (1) { 195 Store(0, find) 196 if (fl01) { 197 Store(m10a(), find) 198 } else { 199 Store(arg0, lpN0) 200 Store(0, lpC0) 201 While (lpN0) { 202 203 /* For not a Control thread only */ 204 if (LNotEqual(lpC0, 0)) { 205 Store(DerefOf(Index(b902, lpC0)), Local0) 206 if (LNot(Local0)) { 207 Store(1, find) 208 break 209 } 210 } 211 212 Decrement(lpN0) 213 Increment(lpC0) 214 } 215 } 216 217 if (LNot(find)) { 218 break 219 } 220 221 /* 222 * Don't report about Control thread sleeping - 223 * don't use m206(0, sl00). 224 */ 225 Sleep(sl00) 226 } 227 228 /* All the worker threads are ready for any next command */ 229 } 230} 231