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 21 test07.cpp -- Test handling of process objects with living descendants 22 23 Original Author: Philipp A. Hartmann, OFFIS 24 25 *****************************************************************************/ 26/***************************************************************************** 27 MODIFICATION LOG - modifiers, enter your name, affiliation, date and 28 changes you are making here. 29 30 Name, Affiliation, Date: 31 Description of Modification: 32 33 *****************************************************************************/ 34// $Log: test07.cpp,v $ 35// Revision 1.2 2011/02/14 17:00:00 acg 36// Andy Goodrich: updated copyright and added cvs logging information inline. 37// 38 39#define SC_INCLUDE_DYNAMIC_PROCESSES 40#include <systemc.h> 41 42void 43dump_hierarchy( 44 std::vector< sc_object* > const & objs = sc_get_top_level_objects() 45 , unsigned level = 0 46) 47{ 48 if (!level) 49 std::cout << "------ " << "(" << sc_time_stamp() << ")" << " ------" 50 << std::endl; 51 52 std::vector<sc_object*>::const_iterator it = objs.begin(); 53 for( ; it != objs.end(); it++ ) 54 { 55 std::cout << std::string( level + 1, ' ' ) 56 << (*it)->name() << " (" << (*it)->kind() << ")"; 57 58 sc_process_handle h(*it); 59 60 std::cout << ( h.valid() // is it a process? -> print state 61 ? (! h.terminated() ? " (running)" : " (terminated)" ) 62 : "" ) 63 << std::endl; 64 65 dump_hierarchy( (*it)->get_child_objects(), level+1 ); 66 } 67 68 if (!level) 69 std::cout << "---------------------- " << std::endl; 70} 71 72struct my_object : sc_object { 73 my_object( const char* name ) : sc_object( name ) {} 74 ~my_object() 75 { 76 std::cout << "+++ " << this->name() << " deleted" << std::endl; 77 } 78}; 79 80SC_MODULE(DUT) 81{ 82 SC_CTOR(DUT) 83 : leaf_(0) 84 { 85 SC_THREAD(parent); 86 } 87 88 enum start_options 89 { 90 no_children = 0, 91 start_child_proc = 1, 92 create_child_obj = 2, 93 both_children = 3 94 }; 95 96 void child( start_options opt ){ 97 start(); 98 99 my_object local( "local" ); 100 101 if( opt & create_child_obj ) 102 leaf_=new my_object("dyn_obj"); 103 104 wait( 100, SC_NS ); 105 106 if( opt & start_child_proc ) 107 sc_spawn( sc_bind( &DUT::child, this, no_children ) 108 , "grandchild" ); 109 110 wait( 100, SC_NS ); 111 end(); 112 } 113 114 void parent() 115 { 116 // only parent alive 117 wait( 50, SC_NS ); 118 dump_hierarchy(); 119 120 sc_spawn( sc_bind( &DUT::child, this, start_child_proc ), "child0" ); 121 sc_spawn( sc_bind( &DUT::child, this, both_children ), "child1" ); 122 123 // direct children up and running 124 wait( 50, SC_NS ); 125 dump_hierarchy(); 126 127 // grandchildren started, child object created 128 wait( 100, SC_NS ); 129 dump_hierarchy(); 130 131 // direct children ended (zombies kept) 132 wait( 100, SC_NS ); 133 dump_hierarchy(); 134 135 // grandhildren ended (zombie with child object kept) 136 wait( 100, SC_NS ); 137 dump_hierarchy(); 138 139 // child object removed, zombies deleted 140 delete leaf_; leaf_ = 0; 141 wait( 100, SC_NS ); 142 dump_hierarchy(); 143 144 { 145 // create another pair of children 146 sc_process_handle 147 h0 = sc_spawn( sc_bind( &DUT::child, this, start_child_proc ), "child0" ), 148 h1 = sc_spawn( sc_bind( &DUT::child, this, start_child_proc ), "child1" ); 149 150 wait( 100, SC_NS ); 151 dump_hierarchy(); 152 153 // and kill them, after it has spawned its grandchild 154 wait( 50, SC_NS ); 155 h0.kill(); 156 h1.kill( SC_INCLUDE_DESCENDANTS ); 157 158 std::cout << "+++ kills sent ... " 159 << "(" << sc_time_stamp() << ")" 160 << std::endl; 161 162 // needed to avoid segfault 163 //wait(SC_ZERO_TIME); 164 165 } // drop handles 166 167 wait( 50, SC_NS ); 168 dump_hierarchy(); 169 170 end(); 171 } 172 173 void start() 174 { 175 std::cout 176 << "+++ " 177 << sc_get_current_process_handle().name() 178 << " starting " 179 << "(" << sc_time_stamp() << ")" 180 << std::endl; 181 } 182 void end() 183 { 184 std::cout 185 << "+++ " 186 << sc_get_current_process_handle().name() 187 << " exiting " 188 << "(" << sc_time_stamp() << ")" 189 << std::endl; 190 } 191 192 my_object* leaf_; 193}; 194 195 196int sc_main( int, char*[] ) 197{ 198 DUT dut("dut"); 199 sc_start(900, SC_NS ); 200 // everything cleaned up (only module still alive) 201 dump_hierarchy(); 202 203 return 0; 204} 205