1/***************************************************************************** 2 3 Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 4 more contributor license agreements. See the NOTICE file distributed 5 with this work for additional information regarding copyright ownership. 6 Accellera licenses this file to you under the Apache License, Version 2.0 7 (the "License"); you may not use this file except in compliance with the 8 License. You may obtain a copy of the License at 9 10 http://www.apache.org/licenses/LICENSE-2.0 11 12 Unless required by applicable law or agreed to in writing, software 13 distributed under the License is distributed on an "AS IS" BASIS, 14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 implied. See the License for the specific language governing 16 permissions and limitations under the License. 17 18 *****************************************************************************/ 19 20// kill_reset.cpp -- test for 21// 22// Original Author: John Aynsley, Doulos, Inc. 23// 24// MODIFICATION LOG - modifiers, enter your name, affiliation, date and 25// 26// $Log: kill_reset.cpp,v $ 27// Revision 1.2 2011/05/08 19:18:46 acg 28// Andy Goodrich: remove extraneous + prefixes from git diff. 29// 30 31// Reset and kill a thread process, including nested kills and resets 32 33#include <systemc> 34 35using namespace sc_core; 36using std::cout; 37using std::endl; 38 39struct M3: sc_module 40{ 41 M3(sc_module_name _name) 42 { 43 SC_THREAD(ticker); 44 k = sc_get_current_process_handle(); 45 46 SC_THREAD(calling); 47 48 SC_THREAD(target); 49 t = sc_get_current_process_handle(); 50 51 SC_THREAD(victim); 52 v = sc_get_current_process_handle(); 53 54 SC_THREAD(bystander); 55 b = sc_get_current_process_handle(); 56 57 SC_THREAD(second_bystander); 58 b2 = sc_get_current_process_handle(); 59 60 SC_THREAD(third_bystander); 61 b3 = sc_get_current_process_handle(); 62 63 killing_over = false; 64 third_bystander_knocked_over = false; 65 } 66 67 sc_process_handle t, k, v, b, b2, b3; 68 sc_event ev; 69 int count; 70 bool killing_over; 71 bool third_bystander_knocked_over; 72 73 void ticker() 74 { 75 for (;;) 76 { 77 try { 78 wait(10, SC_NS); 79 ev.notify(); 80 sc_assert( !sc_is_unwinding() ); 81 } 82 catch (const sc_unwind_exception& ex) 83 { 84 // ticker process killed by target 85 cout << "sc_unwind_exception caught by ticker" << endl; 86 sc_assert( !ex.is_reset() ); 87 sc_assert( count == 1 ); 88 sc_assert( !killing_over ); 89 sc_assert( t.is_unwinding() ); 90 sc_assert( sc_is_unwinding() ); 91 92 v.kill(); 93 throw ex; 94 } 95 } 96 } 97 98 void calling() 99 { 100 wait(15, SC_NS); 101 // Target runs at time 10 NS due to notification 102 sc_assert( count == 1 ); 103 // The victim awakes every 1ns 104 sc_assert( sc_time_to_pending_activity() <= sc_time(1, SC_NS) ); 105 106 wait(10, SC_NS); 107 // Target runs again at time 20 NS due to notification 108 sc_assert( count == 2 ); 109 110 t.reset(); 111 // Target reset immediately at time 25 NS 112 sc_assert( count == 0 ); 113 114 wait(10, SC_NS); 115 // Target runs again at time 30 NS due to notification 116 sc_assert( count == 1 ); 117 118 t.kill(); 119 sc_assert( !killing_over ); 120 killing_over = true; 121 122 // Target killed immediately at time 35 NS 123 if (t.valid()) 124 sc_assert( t.terminated() ); 125 if (k.valid()) 126 sc_assert( k.terminated() ); 127 if (v.valid()) 128 sc_assert( v.terminated() ); 129 sc_assert( b.valid() && !b.terminated() ); 130 sc_assert( b2.valid() && !b2.terminated() ); 131 if (b3.valid()) 132 sc_assert( b3.terminated() ); 133 134 sc_stop(); 135 } 136 137 void target() 138 { 139 cout << "Target called/reset at " << sc_time_stamp() << endl; 140 count = 0; 141 for (;;) 142 { 143 try { 144 wait(ev); 145 cout << "Target awoke at " << sc_time_stamp() << endl; 146 ++count; 147 } 148 catch (const sc_unwind_exception& ex) 149 { 150 cout << "sc_unwind_exception caught by target" << endl; 151 if (count == 2) 152 sc_assert( ex.is_reset() ); 153 else if (count == 1) 154 { 155 sc_assert( !ex.is_reset() ); 156 sc_assert( !killing_over ); 157 k.kill(); 158 } 159 else 160 sc_assert( false ); 161 throw ex; 162 } 163 } 164 } 165 166 void victim() 167 { 168 try { 169 while (true) 170 { 171 wait(1, SC_NS); 172 sc_assert( !sc_is_unwinding() ); 173 } 174 } 175 catch (const sc_unwind_exception& ex) 176 { 177 cout << "sc_unwind_exception caught by victim" << endl; 178 sc_assert( sc_time_stamp() == sc_time(35, SC_NS) ); 179 sc_assert( ex.is_reset() == false ); 180 sc_assert( !killing_over ); 181 sc_assert( v.is_unwinding() ); 182 sc_assert( sc_is_unwinding() ); 183 184 b.reset(); 185 throw ex; 186 } 187 } 188 189 void bystander() // Gets reset by victim 190 { 191 for (;;) 192 { 193 try { 194 wait(ev); 195 } 196 catch (const sc_unwind_exception& ex) { 197 cout << "sc_unwind_exception caught by bystander" << endl; 198 sc_assert( sc_time_stamp() == sc_time(35, SC_NS) ); 199 sc_assert( ex.is_reset() == true ); 200 sc_assert( !killing_over ); 201 sc_assert( v.is_unwinding() ); // sic 202 sc_assert( sc_is_unwinding() ); 203 204 b2.reset(); 205 throw ex; 206 } 207 } 208 } 209 210 void second_bystander() // Gets reset by bystander 211 { 212 for (;;) 213 { 214 try { 215 wait(ev); 216 } 217 catch (const sc_unwind_exception& ex) { 218 cout << "sc_unwind_exception caught by second_bystander" << endl; 219 sc_assert( sc_time_stamp() == sc_time(35, SC_NS) ); 220 sc_assert( ex.is_reset() == true ); 221 sc_assert( !killing_over ); 222 sc_assert( v.is_unwinding() ); // sic 223 sc_assert( b.is_unwinding() ); // sic 224 sc_assert( sc_is_unwinding() ); 225 226 b3.kill(); 227 throw ex; 228 } 229 } 230 } 231 232 void third_bystander() // Gets killed by second bystander 233 { 234 for (;;) 235 { 236 try { 237 wait(ev); 238 } 239 catch (const sc_unwind_exception& ex) { 240 cout << "sc_unwind_exception caught by third_bystander" << endl; 241 sc_assert( sc_time_stamp() == sc_time(35, SC_NS) ); 242 sc_assert( !ex.is_reset() == true ); 243 sc_assert( !killing_over ); 244 sc_assert( v.is_unwinding() ); // sic 245 sc_assert( b.is_unwinding() ); // sic 246 sc_assert( b2.is_unwinding() ); // sic 247 sc_assert( sc_is_unwinding() ); 248 249 third_bystander_knocked_over = true; 250 throw ex; 251 } 252 } 253 } 254 255 SC_HAS_PROCESS(M3); 256}; 257 258int sc_main(int argc, char* argv[]) 259{ 260 M3 m("m"); 261 sc_assert( sc_pending_activity() == false ); 262 sc_assert( sc_time_to_pending_activity() == sc_max_time() ); 263 264 sc_start(); 265 sc_assert( m.third_bystander_knocked_over ); 266 267 cout << endl << "Success" << endl; 268 return 0; 269} 270 271