112027Sjungma@eit.uni-kl.de/***************************************************************************** 212027Sjungma@eit.uni-kl.de 312027Sjungma@eit.uni-kl.de Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 412027Sjungma@eit.uni-kl.de more contributor license agreements. See the NOTICE file distributed 512027Sjungma@eit.uni-kl.de with this work for additional information regarding copyright ownership. 612027Sjungma@eit.uni-kl.de Accellera licenses this file to you under the Apache License, Version 2.0 712027Sjungma@eit.uni-kl.de (the "License"); you may not use this file except in compliance with the 812027Sjungma@eit.uni-kl.de License. You may obtain a copy of the License at 912027Sjungma@eit.uni-kl.de 1012027Sjungma@eit.uni-kl.de http://www.apache.org/licenses/LICENSE-2.0 1112027Sjungma@eit.uni-kl.de 1212027Sjungma@eit.uni-kl.de Unless required by applicable law or agreed to in writing, software 1312027Sjungma@eit.uni-kl.de distributed under the License is distributed on an "AS IS" BASIS, 1412027Sjungma@eit.uni-kl.de WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 1512027Sjungma@eit.uni-kl.de implied. See the License for the specific language governing 1612027Sjungma@eit.uni-kl.de permissions and limitations under the License. 1712027Sjungma@eit.uni-kl.de 1812027Sjungma@eit.uni-kl.de *****************************************************************************/ 1912027Sjungma@eit.uni-kl.de 2012027Sjungma@eit.uni-kl.de/***************************************************************************** 2112027Sjungma@eit.uni-kl.de 2212027Sjungma@eit.uni-kl.de sc_thread_process.cpp -- Thread process implementation 2312027Sjungma@eit.uni-kl.de 2412027Sjungma@eit.uni-kl.de Original Author: Andy Goodrich, Forte Design Systems, 4 August 2005 2512027Sjungma@eit.uni-kl.de 2612027Sjungma@eit.uni-kl.de CHANGE LOG AT THE END OF THE FILE 2712027Sjungma@eit.uni-kl.de *****************************************************************************/ 2812027Sjungma@eit.uni-kl.de 2912027Sjungma@eit.uni-kl.de#include "sysc/kernel/sc_cmnhdr.h" 3012027Sjungma@eit.uni-kl.de#include "sysc/kernel/sc_constants.h" 3112027Sjungma@eit.uni-kl.de#include "sysc/kernel/sc_thread_process.h" 3212027Sjungma@eit.uni-kl.de#include "sysc/kernel/sc_process_handle.h" 3312027Sjungma@eit.uni-kl.de#include "sysc/kernel/sc_simcontext_int.h" 3412027Sjungma@eit.uni-kl.de#include "sysc/kernel/sc_module.h" 3512027Sjungma@eit.uni-kl.de#include "sysc/utils/sc_machine.h" 3612027Sjungma@eit.uni-kl.de 3712027Sjungma@eit.uni-kl.de// DEBUGGING MACROS: 3812027Sjungma@eit.uni-kl.de// 3912027Sjungma@eit.uni-kl.de// DEBUG_MSG(NAME,P,MSG) 4012027Sjungma@eit.uni-kl.de// MSG = message to print 4112027Sjungma@eit.uni-kl.de// NAME = name that must match the process for the message to print, or 4212027Sjungma@eit.uni-kl.de// null if the message should be printed unconditionally. 4312027Sjungma@eit.uni-kl.de// P = pointer to process message is for, or NULL in which case the 4412027Sjungma@eit.uni-kl.de// message will not print. 4512027Sjungma@eit.uni-kl.de#if 0 4612027Sjungma@eit.uni-kl.de# define DEBUG_NAME "" 4712027Sjungma@eit.uni-kl.de# define DEBUG_MSG(NAME,P,MSG) \ 4812027Sjungma@eit.uni-kl.de { \ 4912027Sjungma@eit.uni-kl.de if ( P && ( (strlen(NAME)==0) || !strcmp(NAME,P->name())) ) \ 5012027Sjungma@eit.uni-kl.de std::cout << "**** " << sc_time_stamp() << " (" \ 5112027Sjungma@eit.uni-kl.de << sc_get_current_process_name() << "): " << MSG \ 5212027Sjungma@eit.uni-kl.de << " - " << P->name() << std::endl; \ 5312027Sjungma@eit.uni-kl.de } 5412027Sjungma@eit.uni-kl.de#else 5512027Sjungma@eit.uni-kl.de# define DEBUG_MSG(NAME,P,MSG) 5612027Sjungma@eit.uni-kl.de#endif 5712027Sjungma@eit.uni-kl.de 5812027Sjungma@eit.uni-kl.de 5912027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------ 6012027Sjungma@eit.uni-kl.de// user-defined default stack-size 6112027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------ 6212027Sjungma@eit.uni-kl.de#if defined(SC_OVERRIDE_DEFAULT_STACK_SIZE) 6312027Sjungma@eit.uni-kl.de# define SC_DEFAULT_STACK_SIZE_ SC_OVERRIDE_DEFAULT_STACK_SIZE 6412027Sjungma@eit.uni-kl.de 6512027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------ 6612027Sjungma@eit.uni-kl.de// architecture-specific default stack sizes 6712027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------ 6812027Sjungma@eit.uni-kl.de#elif !defined(SC_USE_PTHREADS) && (defined(__CYGWIN32__) || defined(__CYGWIN32)) 6912027Sjungma@eit.uni-kl.de# define SC_DEFAULT_STACK_SIZE_ 0x50000 7012027Sjungma@eit.uni-kl.de 7112027Sjungma@eit.uni-kl.de#elif defined(SC_LONG_64) || defined(__x86_64__) || defined(__LP64__) || \ 7212027Sjungma@eit.uni-kl.de defined(_M_X64) || defined(_M_AMD64) 7312027Sjungma@eit.uni-kl.de# define SC_DEFAULT_STACK_SIZE_ 0x40000 7412027Sjungma@eit.uni-kl.de 7512027Sjungma@eit.uni-kl.de#else 7612027Sjungma@eit.uni-kl.de# define SC_DEFAULT_STACK_SIZE_ 0x20000 7712027Sjungma@eit.uni-kl.de 7812027Sjungma@eit.uni-kl.de#endif // SC_DEFAULT_STACK_SIZE_ 7912027Sjungma@eit.uni-kl.de 8012027Sjungma@eit.uni-kl.de 8112027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------ 8212027Sjungma@eit.uni-kl.de// force 16-byte alignment on coroutine entry functions, needed for 8312027Sjungma@eit.uni-kl.de// QuickThreads (32-bit, see also fixes in qt/md/{i386,iX86_64}.[hs]), 8412027Sjungma@eit.uni-kl.de// and MinGW32 / Cygwin32 compilers on Windows platforms 8512027Sjungma@eit.uni-kl.de#if defined(__GNUC__) && !defined(__ICC) && !defined(__x86_64__) && \ 8612027Sjungma@eit.uni-kl.de (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ > 1 ) 8712027Sjungma@eit.uni-kl.de# define SC_ALIGNED_STACK_ \ 8812027Sjungma@eit.uni-kl.de __attribute__((force_align_arg_pointer)) 8912027Sjungma@eit.uni-kl.de#else 9012027Sjungma@eit.uni-kl.de# define SC_ALIGNED_STACK_ /* empty */ 9112027Sjungma@eit.uni-kl.de#endif 9212027Sjungma@eit.uni-kl.de 9312027Sjungma@eit.uni-kl.de 9412027Sjungma@eit.uni-kl.denamespace sc_core { 9512027Sjungma@eit.uni-kl.de 9612027Sjungma@eit.uni-kl.deconst int SC_DEFAULT_STACK_SIZE = SC_DEFAULT_STACK_SIZE_; 9712027Sjungma@eit.uni-kl.de#undef SC_DEFAULT_STACK_SIZE_ 9812027Sjungma@eit.uni-kl.de#undef SC_OVERRIDE_DEFAULT_STACK_SIZE 9912027Sjungma@eit.uni-kl.de 10012027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------ 10112027Sjungma@eit.uni-kl.de//"sc_thread_cor_fn" 10212027Sjungma@eit.uni-kl.de// 10312027Sjungma@eit.uni-kl.de// This function invokes the coroutine for the supplied object instance. 10412027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------ 10512027Sjungma@eit.uni-kl.deSC_ALIGNED_STACK_ 10612027Sjungma@eit.uni-kl.devoid sc_thread_cor_fn( void* arg ) 10712027Sjungma@eit.uni-kl.de{ 10812027Sjungma@eit.uni-kl.de sc_simcontext* simc_p = sc_get_curr_simcontext(); 10912027Sjungma@eit.uni-kl.de sc_thread_handle thread_h = RCAST<sc_thread_handle>( arg ); 11012027Sjungma@eit.uni-kl.de 11112027Sjungma@eit.uni-kl.de // PROCESS THE THREAD AND PROCESS ANY EXCEPTIONS THAT ARE THROWN: 11212027Sjungma@eit.uni-kl.de 11312027Sjungma@eit.uni-kl.de while( true ) { 11412027Sjungma@eit.uni-kl.de 11512027Sjungma@eit.uni-kl.de try { 11612027Sjungma@eit.uni-kl.de thread_h->semantics(); 11712027Sjungma@eit.uni-kl.de } 11812027Sjungma@eit.uni-kl.de catch( sc_user ) { 11912027Sjungma@eit.uni-kl.de continue; 12012027Sjungma@eit.uni-kl.de } 12112027Sjungma@eit.uni-kl.de catch( sc_halt ) { 12212027Sjungma@eit.uni-kl.de ::std::cout << "Terminating process " 12312027Sjungma@eit.uni-kl.de << thread_h->name() << ::std::endl; 12412027Sjungma@eit.uni-kl.de } 12512027Sjungma@eit.uni-kl.de catch( const sc_unwind_exception& ex ) { 12612027Sjungma@eit.uni-kl.de ex.clear(); 12712027Sjungma@eit.uni-kl.de if ( ex.is_reset() ) continue; 12812027Sjungma@eit.uni-kl.de } 12912027Sjungma@eit.uni-kl.de catch( ... ) { 13012027Sjungma@eit.uni-kl.de sc_report* err_p = sc_handle_exception(); 13112027Sjungma@eit.uni-kl.de thread_h->simcontext()->set_error( err_p ); 13212027Sjungma@eit.uni-kl.de } 13312027Sjungma@eit.uni-kl.de break; 13412027Sjungma@eit.uni-kl.de } 13512027Sjungma@eit.uni-kl.de 13612027Sjungma@eit.uni-kl.de sc_process_b* active_p = sc_get_current_process_b(); 13712027Sjungma@eit.uni-kl.de 13812027Sjungma@eit.uni-kl.de // REMOVE ALL TRACES OF OUR THREAD FROM THE SIMULATORS DATA STRUCTURES: 13912027Sjungma@eit.uni-kl.de 14012027Sjungma@eit.uni-kl.de thread_h->disconnect_process(); 14112027Sjungma@eit.uni-kl.de 14212027Sjungma@eit.uni-kl.de // IF WE AREN'T ACTIVE MAKE SURE WE WON'T EXECUTE: 14312027Sjungma@eit.uni-kl.de 14412027Sjungma@eit.uni-kl.de if ( thread_h->next_runnable() != 0 ) 14512027Sjungma@eit.uni-kl.de { 14612027Sjungma@eit.uni-kl.de simc_p->remove_runnable_thread(thread_h); 14712027Sjungma@eit.uni-kl.de } 14812027Sjungma@eit.uni-kl.de 14912027Sjungma@eit.uni-kl.de // IF WE ARE THE ACTIVE PROCESS ABORT OUR EXECUTION: 15012027Sjungma@eit.uni-kl.de 15112027Sjungma@eit.uni-kl.de 15212027Sjungma@eit.uni-kl.de if ( active_p == (sc_process_b*)thread_h ) 15312027Sjungma@eit.uni-kl.de { 15412027Sjungma@eit.uni-kl.de 15512027Sjungma@eit.uni-kl.de sc_core::sc_cor* x = simc_p->next_cor(); 15612027Sjungma@eit.uni-kl.de simc_p->cor_pkg()->abort( x ); 15712027Sjungma@eit.uni-kl.de } 15812027Sjungma@eit.uni-kl.de 15912027Sjungma@eit.uni-kl.de} 16012027Sjungma@eit.uni-kl.de 16112027Sjungma@eit.uni-kl.de 16212027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------ 16312027Sjungma@eit.uni-kl.de//"sc_thread_process::disable_process" 16412027Sjungma@eit.uni-kl.de// 16512027Sjungma@eit.uni-kl.de// This virtual method suspends this process and its children if requested to. 16612027Sjungma@eit.uni-kl.de// descendants = indicator of whether this process' children should also 16712027Sjungma@eit.uni-kl.de// be suspended 16812027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------ 16912027Sjungma@eit.uni-kl.devoid sc_thread_process::disable_process( 17012027Sjungma@eit.uni-kl.de sc_descendant_inclusion_info descendants ) 17112027Sjungma@eit.uni-kl.de{ 17212027Sjungma@eit.uni-kl.de 17312027Sjungma@eit.uni-kl.de // IF NEEDED PROPOGATE THE DISABLE REQUEST THROUGH OUR DESCENDANTS: 17412027Sjungma@eit.uni-kl.de 17512027Sjungma@eit.uni-kl.de if ( descendants == SC_INCLUDE_DESCENDANTS ) 17612027Sjungma@eit.uni-kl.de { 17712027Sjungma@eit.uni-kl.de const std::vector<sc_object*>& children = get_child_objects(); 17812027Sjungma@eit.uni-kl.de int child_n = children.size(); 17912027Sjungma@eit.uni-kl.de 18012027Sjungma@eit.uni-kl.de for ( int child_i = 0; child_i < child_n; child_i++ ) 18112027Sjungma@eit.uni-kl.de { 18212027Sjungma@eit.uni-kl.de sc_process_b* child_p = DCAST<sc_process_b*>(children[child_i]); 18312027Sjungma@eit.uni-kl.de if ( child_p ) child_p->disable_process(descendants); 18412027Sjungma@eit.uni-kl.de } 18512027Sjungma@eit.uni-kl.de } 18612027Sjungma@eit.uni-kl.de 18712027Sjungma@eit.uni-kl.de // DON'T ALLOW CORNER CASE BY DEFAULT: 18812027Sjungma@eit.uni-kl.de 18912027Sjungma@eit.uni-kl.de if ( !sc_allow_process_control_corners ) 19012027Sjungma@eit.uni-kl.de { 19112027Sjungma@eit.uni-kl.de switch( m_trigger_type ) 19212027Sjungma@eit.uni-kl.de { 19312027Sjungma@eit.uni-kl.de case AND_LIST_TIMEOUT: 19412027Sjungma@eit.uni-kl.de case EVENT_TIMEOUT: 19512027Sjungma@eit.uni-kl.de case OR_LIST_TIMEOUT: 19612027Sjungma@eit.uni-kl.de case TIMEOUT: 19712027Sjungma@eit.uni-kl.de report_error(SC_ID_PROCESS_CONTROL_CORNER_CASE_, 19812027Sjungma@eit.uni-kl.de "attempt to disable a thread with timeout wait"); 19912027Sjungma@eit.uni-kl.de break; 20012027Sjungma@eit.uni-kl.de default: 20112027Sjungma@eit.uni-kl.de break; 20212027Sjungma@eit.uni-kl.de } 20312027Sjungma@eit.uni-kl.de } 20412027Sjungma@eit.uni-kl.de 20512027Sjungma@eit.uni-kl.de // DISABLE OUR OBJECT INSTANCE: 20612027Sjungma@eit.uni-kl.de 20712027Sjungma@eit.uni-kl.de m_state = m_state | ps_bit_disabled; 20812027Sjungma@eit.uni-kl.de 20912027Sjungma@eit.uni-kl.de // IF THIS CALL IS BEFORE THE SIMULATION DON'T RUN THE THREAD: 21012027Sjungma@eit.uni-kl.de 21112027Sjungma@eit.uni-kl.de if ( !sc_is_running() ) 21212027Sjungma@eit.uni-kl.de { 21312027Sjungma@eit.uni-kl.de m_state = m_state | ps_bit_ready_to_run; 21412027Sjungma@eit.uni-kl.de simcontext()->remove_runnable_thread(this); 21512027Sjungma@eit.uni-kl.de } 21612027Sjungma@eit.uni-kl.de} 21712027Sjungma@eit.uni-kl.de 21812027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------ 21912027Sjungma@eit.uni-kl.de//"sc_thread_process::enable_process" 22012027Sjungma@eit.uni-kl.de// 22112027Sjungma@eit.uni-kl.de// This method resumes the execution of this process, and if requested, its 22212027Sjungma@eit.uni-kl.de// descendants. If the process was suspended and has a resumption pending it 22312027Sjungma@eit.uni-kl.de// will be dispatched in the next delta cycle. Otherwise the state will be 22412027Sjungma@eit.uni-kl.de// adjusted to indicate it is no longer suspended, but no immediate execution 22512027Sjungma@eit.uni-kl.de// will occur. 22612027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------ 22712027Sjungma@eit.uni-kl.devoid sc_thread_process::enable_process( 22812027Sjungma@eit.uni-kl.de sc_descendant_inclusion_info descendants ) 22912027Sjungma@eit.uni-kl.de{ 23012027Sjungma@eit.uni-kl.de 23112027Sjungma@eit.uni-kl.de // IF NEEDED PROPOGATE THE ENABLE REQUEST THROUGH OUR DESCENDANTS: 23212027Sjungma@eit.uni-kl.de 23312027Sjungma@eit.uni-kl.de if ( descendants == SC_INCLUDE_DESCENDANTS ) 23412027Sjungma@eit.uni-kl.de { 23512027Sjungma@eit.uni-kl.de const std::vector<sc_object*>& children = get_child_objects(); 23612027Sjungma@eit.uni-kl.de int child_n = children.size(); 23712027Sjungma@eit.uni-kl.de 23812027Sjungma@eit.uni-kl.de for ( int child_i = 0; child_i < child_n; child_i++ ) 23912027Sjungma@eit.uni-kl.de { 24012027Sjungma@eit.uni-kl.de sc_process_b* child_p = DCAST<sc_process_b*>(children[child_i]); 24112027Sjungma@eit.uni-kl.de if ( child_p ) child_p->enable_process(descendants); 24212027Sjungma@eit.uni-kl.de } 24312027Sjungma@eit.uni-kl.de } 24412027Sjungma@eit.uni-kl.de 24512027Sjungma@eit.uni-kl.de // ENABLE THIS OBJECT INSTANCE: 24612027Sjungma@eit.uni-kl.de // 24712027Sjungma@eit.uni-kl.de // If it was disabled and ready to run then put it on the run queue. 24812027Sjungma@eit.uni-kl.de 24912027Sjungma@eit.uni-kl.de m_state = m_state & ~ps_bit_disabled; 25012027Sjungma@eit.uni-kl.de if ( m_state == ps_bit_ready_to_run && sc_allow_process_control_corners ) 25112027Sjungma@eit.uni-kl.de { 25212027Sjungma@eit.uni-kl.de m_state = ps_normal; 25312027Sjungma@eit.uni-kl.de if ( next_runnable() == 0 ) 25412027Sjungma@eit.uni-kl.de simcontext()->push_runnable_thread(this); 25512027Sjungma@eit.uni-kl.de } 25612027Sjungma@eit.uni-kl.de} 25712027Sjungma@eit.uni-kl.de 25812027Sjungma@eit.uni-kl.de 25912027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------ 26012027Sjungma@eit.uni-kl.de//"sc_thread_process::kill_process" 26112027Sjungma@eit.uni-kl.de// 26212027Sjungma@eit.uni-kl.de// This method removes this object instance from use. It calls the 26312027Sjungma@eit.uni-kl.de// sc_process_b::kill_process() method to perform low level clean up. Then 26412027Sjungma@eit.uni-kl.de// it aborts this process if it is the active process. 26512027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------ 26612027Sjungma@eit.uni-kl.devoid sc_thread_process::kill_process(sc_descendant_inclusion_info descendants ) 26712027Sjungma@eit.uni-kl.de{ 26812027Sjungma@eit.uni-kl.de 26912027Sjungma@eit.uni-kl.de // IF THE SIMULATION HAS NOT BEEN INITIALIZED YET THAT IS AN ERROR: 27012027Sjungma@eit.uni-kl.de 27112027Sjungma@eit.uni-kl.de if ( !sc_is_running() ) 27212027Sjungma@eit.uni-kl.de { 27312027Sjungma@eit.uni-kl.de report_error( SC_ID_KILL_PROCESS_WHILE_UNITIALIZED_ ); 27412027Sjungma@eit.uni-kl.de } 27512027Sjungma@eit.uni-kl.de 27612027Sjungma@eit.uni-kl.de // IF NEEDED PROPOGATE THE KILL REQUEST THROUGH OUR DESCENDANTS: 27712027Sjungma@eit.uni-kl.de 27812027Sjungma@eit.uni-kl.de if ( descendants == SC_INCLUDE_DESCENDANTS ) 27912027Sjungma@eit.uni-kl.de { 28012027Sjungma@eit.uni-kl.de const std::vector<sc_object*> children = get_child_objects(); 28112027Sjungma@eit.uni-kl.de int child_n = children.size(); 28212027Sjungma@eit.uni-kl.de 28312027Sjungma@eit.uni-kl.de for ( int child_i = 0; child_i < child_n; child_i++ ) 28412027Sjungma@eit.uni-kl.de { 28512027Sjungma@eit.uni-kl.de sc_process_b* child_p = DCAST<sc_process_b*>(children[child_i]); 28612027Sjungma@eit.uni-kl.de if ( child_p ) child_p->kill_process(descendants); 28712027Sjungma@eit.uni-kl.de } 28812027Sjungma@eit.uni-kl.de } 28912027Sjungma@eit.uni-kl.de 29012027Sjungma@eit.uni-kl.de // IF THE PROCESS IS CURRENTLY UNWINDING OR IS ALREADY A ZOMBIE 29112027Sjungma@eit.uni-kl.de // IGNORE THE KILL: 29212027Sjungma@eit.uni-kl.de 29312027Sjungma@eit.uni-kl.de if ( m_unwinding ) 29412027Sjungma@eit.uni-kl.de { 29512027Sjungma@eit.uni-kl.de SC_REPORT_WARNING( SC_ID_PROCESS_ALREADY_UNWINDING_, name() ); 29612027Sjungma@eit.uni-kl.de return; 29712027Sjungma@eit.uni-kl.de } 29812027Sjungma@eit.uni-kl.de 29912027Sjungma@eit.uni-kl.de if ( m_state & ps_bit_zombie ) 30012027Sjungma@eit.uni-kl.de return; 30112027Sjungma@eit.uni-kl.de 30212027Sjungma@eit.uni-kl.de // SET UP TO KILL THE PROCESS IF SIMULATION HAS STARTED: 30312027Sjungma@eit.uni-kl.de // 30412027Sjungma@eit.uni-kl.de // If the thread does not have a stack don't try the throw! 30512027Sjungma@eit.uni-kl.de 30612027Sjungma@eit.uni-kl.de if ( sc_is_running() && m_has_stack ) 30712027Sjungma@eit.uni-kl.de { 30812027Sjungma@eit.uni-kl.de m_throw_status = THROW_KILL; 30912027Sjungma@eit.uni-kl.de m_wait_cycle_n = 0; 31012027Sjungma@eit.uni-kl.de simcontext()->preempt_with(this); 31112027Sjungma@eit.uni-kl.de } 31212027Sjungma@eit.uni-kl.de 31312027Sjungma@eit.uni-kl.de // IF THE SIMULATION HAS NOT STARTED REMOVE TRACES OF OUR PROCESS FROM 31412027Sjungma@eit.uni-kl.de // EVENT QUEUES, ETC.: 31512027Sjungma@eit.uni-kl.de 31612027Sjungma@eit.uni-kl.de else 31712027Sjungma@eit.uni-kl.de { 31812027Sjungma@eit.uni-kl.de disconnect_process(); 31912027Sjungma@eit.uni-kl.de } 32012027Sjungma@eit.uni-kl.de} 32112027Sjungma@eit.uni-kl.de 32212027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------ 32312027Sjungma@eit.uni-kl.de//"sc_thread_process::prepare_for_simulation" 32412027Sjungma@eit.uni-kl.de// 32512027Sjungma@eit.uni-kl.de// This method prepares this object instance for simulation. It calls the 32612027Sjungma@eit.uni-kl.de// coroutine package to create the actual thread. 32712027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------ 32812027Sjungma@eit.uni-kl.devoid sc_thread_process::prepare_for_simulation() 32912027Sjungma@eit.uni-kl.de{ 33012027Sjungma@eit.uni-kl.de m_cor_p = simcontext()->cor_pkg()->create( m_stack_size, 33112027Sjungma@eit.uni-kl.de sc_thread_cor_fn, this ); 33212027Sjungma@eit.uni-kl.de m_cor_p->stack_protect( true ); 33312027Sjungma@eit.uni-kl.de} 33412027Sjungma@eit.uni-kl.de 33512027Sjungma@eit.uni-kl.de 33612027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------ 33712027Sjungma@eit.uni-kl.de//"sc_thread_process::resume_process" 33812027Sjungma@eit.uni-kl.de// 33912027Sjungma@eit.uni-kl.de// This method resumes the execution of this process, and if requested, its 34012027Sjungma@eit.uni-kl.de// descendants. If the process was suspended and has a resumption pending it 34112027Sjungma@eit.uni-kl.de// will be dispatched in the next delta cycle. Otherwise the state will be 34212027Sjungma@eit.uni-kl.de// adjusted to indicate it is no longer suspended, but no immediate execution 34312027Sjungma@eit.uni-kl.de// will occur. 34412027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------ 34512027Sjungma@eit.uni-kl.devoid sc_thread_process::resume_process( 34612027Sjungma@eit.uni-kl.de sc_descendant_inclusion_info descendants ) 34712027Sjungma@eit.uni-kl.de{ 34812027Sjungma@eit.uni-kl.de 34912027Sjungma@eit.uni-kl.de // IF NEEDED PROPOGATE THE RESUME REQUEST THROUGH OUR DESCENDANTS: 35012027Sjungma@eit.uni-kl.de 35112027Sjungma@eit.uni-kl.de if ( descendants == SC_INCLUDE_DESCENDANTS ) 35212027Sjungma@eit.uni-kl.de { 35312027Sjungma@eit.uni-kl.de const std::vector<sc_object*>& children = get_child_objects(); 35412027Sjungma@eit.uni-kl.de int child_n = children.size(); 35512027Sjungma@eit.uni-kl.de 35612027Sjungma@eit.uni-kl.de for ( int child_i = 0; child_i < child_n; child_i++ ) 35712027Sjungma@eit.uni-kl.de { 35812027Sjungma@eit.uni-kl.de sc_process_b* child_p = DCAST<sc_process_b*>(children[child_i]); 35912027Sjungma@eit.uni-kl.de if ( child_p ) child_p->resume_process(descendants); 36012027Sjungma@eit.uni-kl.de } 36112027Sjungma@eit.uni-kl.de } 36212027Sjungma@eit.uni-kl.de 36312027Sjungma@eit.uni-kl.de // BY DEFAULT THE CORNER CASE IS AN ERROR: 36412027Sjungma@eit.uni-kl.de 36512027Sjungma@eit.uni-kl.de if ( !sc_allow_process_control_corners && (m_state & ps_bit_disabled) && 36612027Sjungma@eit.uni-kl.de (m_state & ps_bit_suspended) ) 36712027Sjungma@eit.uni-kl.de { 36812027Sjungma@eit.uni-kl.de m_state = m_state & ~ps_bit_suspended; 36912027Sjungma@eit.uni-kl.de report_error(SC_ID_PROCESS_CONTROL_CORNER_CASE_, 37012027Sjungma@eit.uni-kl.de "call to resume() on a disabled suspended thread"); 37112027Sjungma@eit.uni-kl.de } 37212027Sjungma@eit.uni-kl.de 37312027Sjungma@eit.uni-kl.de // CLEAR THE SUSPENDED BIT: 37412027Sjungma@eit.uni-kl.de 37512027Sjungma@eit.uni-kl.de m_state = m_state & ~ps_bit_suspended; 37612027Sjungma@eit.uni-kl.de 37712027Sjungma@eit.uni-kl.de // RESUME OBJECT INSTANCE IF IT IS READY TO RUN: 37812027Sjungma@eit.uni-kl.de 37912027Sjungma@eit.uni-kl.de if ( m_state & ps_bit_ready_to_run ) 38012027Sjungma@eit.uni-kl.de { 38112027Sjungma@eit.uni-kl.de m_state = m_state & ~ps_bit_ready_to_run; 38212027Sjungma@eit.uni-kl.de if ( next_runnable() == 0 ) 38312027Sjungma@eit.uni-kl.de simcontext()->push_runnable_thread(this); 38412027Sjungma@eit.uni-kl.de remove_dynamic_events(); // order important. 38512027Sjungma@eit.uni-kl.de } 38612027Sjungma@eit.uni-kl.de} 38712027Sjungma@eit.uni-kl.de 38812027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------ 38912027Sjungma@eit.uni-kl.de//"sc_thread_process::sc_thread_process" 39012027Sjungma@eit.uni-kl.de// 39112027Sjungma@eit.uni-kl.de// This is the object instance constructor for this class. 39212027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------ 39312027Sjungma@eit.uni-kl.desc_thread_process::sc_thread_process( const char* name_p, bool free_host, 39412027Sjungma@eit.uni-kl.de SC_ENTRY_FUNC method_p, sc_process_host* host_p, 39512027Sjungma@eit.uni-kl.de const sc_spawn_options* opt_p 39612027Sjungma@eit.uni-kl.de): 39712027Sjungma@eit.uni-kl.de sc_process_b( 39812027Sjungma@eit.uni-kl.de name_p ? name_p : sc_gen_unique_name("thread_p"), 39912027Sjungma@eit.uni-kl.de true, free_host, method_p, host_p, opt_p), 40012027Sjungma@eit.uni-kl.de m_cor_p(0), m_monitor_q(), m_stack_size(SC_DEFAULT_STACK_SIZE), 40112027Sjungma@eit.uni-kl.de m_wait_cycle_n(0) 40212027Sjungma@eit.uni-kl.de{ 40312027Sjungma@eit.uni-kl.de 40412027Sjungma@eit.uni-kl.de // CHECK IF THIS IS AN sc_module-BASED PROCESS AND SIMULATION HAS STARTED: 40512027Sjungma@eit.uni-kl.de 40612027Sjungma@eit.uni-kl.de if ( DCAST<sc_module*>(host_p) != 0 && sc_is_running() ) 40712027Sjungma@eit.uni-kl.de { 40812027Sjungma@eit.uni-kl.de report_error( SC_ID_MODULE_THREAD_AFTER_START_ ); 40912027Sjungma@eit.uni-kl.de } 41012027Sjungma@eit.uni-kl.de 41112027Sjungma@eit.uni-kl.de // INITIALIZE VALUES: 41212027Sjungma@eit.uni-kl.de // 41312027Sjungma@eit.uni-kl.de // If there are spawn options use them. 41412027Sjungma@eit.uni-kl.de 41512027Sjungma@eit.uni-kl.de m_process_kind = SC_THREAD_PROC_; 41612027Sjungma@eit.uni-kl.de 41712027Sjungma@eit.uni-kl.de if (opt_p) { 41812027Sjungma@eit.uni-kl.de m_dont_init = opt_p->m_dont_initialize; 41912027Sjungma@eit.uni-kl.de if ( opt_p->m_stack_size ) m_stack_size = opt_p->m_stack_size; 42012027Sjungma@eit.uni-kl.de 42112027Sjungma@eit.uni-kl.de // traverse event sensitivity list 42212027Sjungma@eit.uni-kl.de for (unsigned int i = 0; i < opt_p->m_sensitive_events.size(); i++) { 42312027Sjungma@eit.uni-kl.de sc_sensitive::make_static_sensitivity( 42412027Sjungma@eit.uni-kl.de this, *opt_p->m_sensitive_events[i]); 42512027Sjungma@eit.uni-kl.de } 42612027Sjungma@eit.uni-kl.de 42712027Sjungma@eit.uni-kl.de // traverse port base sensitivity list 42812027Sjungma@eit.uni-kl.de for ( unsigned int i = 0; i < opt_p->m_sensitive_port_bases.size(); i++) 42912027Sjungma@eit.uni-kl.de { 43012027Sjungma@eit.uni-kl.de sc_sensitive::make_static_sensitivity( 43112027Sjungma@eit.uni-kl.de this, *opt_p->m_sensitive_port_bases[i]); 43212027Sjungma@eit.uni-kl.de } 43312027Sjungma@eit.uni-kl.de 43412027Sjungma@eit.uni-kl.de // traverse interface sensitivity list 43512027Sjungma@eit.uni-kl.de for ( unsigned int i = 0; i < opt_p->m_sensitive_interfaces.size(); i++) 43612027Sjungma@eit.uni-kl.de { 43712027Sjungma@eit.uni-kl.de sc_sensitive::make_static_sensitivity( 43812027Sjungma@eit.uni-kl.de this, *opt_p->m_sensitive_interfaces[i]); 43912027Sjungma@eit.uni-kl.de } 44012027Sjungma@eit.uni-kl.de 44112027Sjungma@eit.uni-kl.de // traverse event finder sensitivity list 44212027Sjungma@eit.uni-kl.de for ( unsigned int i = 0; i < opt_p->m_sensitive_event_finders.size(); 44312027Sjungma@eit.uni-kl.de i++) 44412027Sjungma@eit.uni-kl.de { 44512027Sjungma@eit.uni-kl.de sc_sensitive::make_static_sensitivity( 44612027Sjungma@eit.uni-kl.de this, *opt_p->m_sensitive_event_finders[i]); 44712027Sjungma@eit.uni-kl.de } 44812027Sjungma@eit.uni-kl.de 44912027Sjungma@eit.uni-kl.de // process any reset signal specification: 45012027Sjungma@eit.uni-kl.de 45112027Sjungma@eit.uni-kl.de opt_p->specify_resets(); 45212027Sjungma@eit.uni-kl.de 45312027Sjungma@eit.uni-kl.de } 45412027Sjungma@eit.uni-kl.de 45512027Sjungma@eit.uni-kl.de else 45612027Sjungma@eit.uni-kl.de { 45712027Sjungma@eit.uni-kl.de m_dont_init = false; 45812027Sjungma@eit.uni-kl.de } 45912027Sjungma@eit.uni-kl.de 46012027Sjungma@eit.uni-kl.de} 46112027Sjungma@eit.uni-kl.de 46212027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------ 46312027Sjungma@eit.uni-kl.de//"sc_thread_process::~sc_thread_process" 46412027Sjungma@eit.uni-kl.de// 46512027Sjungma@eit.uni-kl.de// This is the object instance constructor for this class. 46612027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------ 46712027Sjungma@eit.uni-kl.desc_thread_process::~sc_thread_process() 46812027Sjungma@eit.uni-kl.de{ 46912027Sjungma@eit.uni-kl.de 47012027Sjungma@eit.uni-kl.de // DESTROY THE COROUTINE FOR THIS THREAD: 47112027Sjungma@eit.uni-kl.de 47212027Sjungma@eit.uni-kl.de if( m_cor_p != 0 ) { 47312027Sjungma@eit.uni-kl.de m_cor_p->stack_protect( false ); 47412027Sjungma@eit.uni-kl.de delete m_cor_p; 47512027Sjungma@eit.uni-kl.de m_cor_p = 0; 47612027Sjungma@eit.uni-kl.de } 47712027Sjungma@eit.uni-kl.de} 47812027Sjungma@eit.uni-kl.de 47912027Sjungma@eit.uni-kl.de 48012027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------ 48112027Sjungma@eit.uni-kl.de//"sc_thread_process::signal_monitors" 48212027Sjungma@eit.uni-kl.de// 48312027Sjungma@eit.uni-kl.de// This methods signals the list of monitors for this object instance. 48412027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------ 48512027Sjungma@eit.uni-kl.devoid sc_thread_process::signal_monitors(int type) 48612027Sjungma@eit.uni-kl.de{ 48712027Sjungma@eit.uni-kl.de int mon_n; // # of monitors present. 48812027Sjungma@eit.uni-kl.de 48912027Sjungma@eit.uni-kl.de mon_n = m_monitor_q.size(); 49012027Sjungma@eit.uni-kl.de for ( int mon_i = 0; mon_i < mon_n; mon_i++ ) 49112027Sjungma@eit.uni-kl.de m_monitor_q[mon_i]->signal(this, type); 49212027Sjungma@eit.uni-kl.de} 49312027Sjungma@eit.uni-kl.de 49412027Sjungma@eit.uni-kl.de 49512027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------ 49612027Sjungma@eit.uni-kl.de//"sc_thread_process::suspend_process" 49712027Sjungma@eit.uni-kl.de// 49812027Sjungma@eit.uni-kl.de// This virtual method suspends this process and its children if requested to. 49912027Sjungma@eit.uni-kl.de// descendants = indicator of whether this process' children should also 50012027Sjungma@eit.uni-kl.de// be suspended 50112027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------ 50212027Sjungma@eit.uni-kl.devoid sc_thread_process::suspend_process( 50312027Sjungma@eit.uni-kl.de sc_descendant_inclusion_info descendants ) 50412027Sjungma@eit.uni-kl.de{ 50512027Sjungma@eit.uni-kl.de 50612027Sjungma@eit.uni-kl.de // IF NEEDED PROPOGATE THE SUSPEND REQUEST THROUGH OUR DESCENDANTS: 50712027Sjungma@eit.uni-kl.de 50812027Sjungma@eit.uni-kl.de if ( descendants == SC_INCLUDE_DESCENDANTS ) 50912027Sjungma@eit.uni-kl.de { 51012027Sjungma@eit.uni-kl.de const std::vector<sc_object*>& children = get_child_objects(); 51112027Sjungma@eit.uni-kl.de int child_n = children.size(); 51212027Sjungma@eit.uni-kl.de 51312027Sjungma@eit.uni-kl.de for ( int child_i = 0; child_i < child_n; child_i++ ) 51412027Sjungma@eit.uni-kl.de { 51512027Sjungma@eit.uni-kl.de sc_process_b* child_p = DCAST<sc_process_b*>(children[child_i]); 51612027Sjungma@eit.uni-kl.de if ( child_p ) child_p->suspend_process(descendants); 51712027Sjungma@eit.uni-kl.de } 51812027Sjungma@eit.uni-kl.de } 51912027Sjungma@eit.uni-kl.de 52012027Sjungma@eit.uni-kl.de // CORNER CASE CHECKS, THE FOLLOWING ARE ERRORS: 52112027Sjungma@eit.uni-kl.de // (a) if this thread has a reset_signal_is specification 52212027Sjungma@eit.uni-kl.de // (b) if this thread is in synchronous reset 52312027Sjungma@eit.uni-kl.de 52412027Sjungma@eit.uni-kl.de if ( !sc_allow_process_control_corners && m_has_reset_signal ) 52512027Sjungma@eit.uni-kl.de { 52612027Sjungma@eit.uni-kl.de report_error(SC_ID_PROCESS_CONTROL_CORNER_CASE_, 52712027Sjungma@eit.uni-kl.de "attempt to suspend a thread that has a reset signal"); 52812027Sjungma@eit.uni-kl.de } 52912027Sjungma@eit.uni-kl.de else if ( !sc_allow_process_control_corners && m_sticky_reset ) 53012027Sjungma@eit.uni-kl.de { 53112027Sjungma@eit.uni-kl.de report_error(SC_ID_PROCESS_CONTROL_CORNER_CASE_, 53212027Sjungma@eit.uni-kl.de "attempt to suspend a thread in synchronous reset"); 53312027Sjungma@eit.uni-kl.de } 53412027Sjungma@eit.uni-kl.de 53512027Sjungma@eit.uni-kl.de // SUSPEND OUR OBJECT INSTANCE: 53612027Sjungma@eit.uni-kl.de // 53712027Sjungma@eit.uni-kl.de // (1) If we are on the runnable queue then set suspended and ready_to_run, 53812027Sjungma@eit.uni-kl.de // and remove ourselves from the run queue. 53912027Sjungma@eit.uni-kl.de // (2) If this is a self-suspension then a resume should cause immediate 54012027Sjungma@eit.uni-kl.de // scheduling of the process, and we need to call suspend_me() here. 54112027Sjungma@eit.uni-kl.de 54212027Sjungma@eit.uni-kl.de m_state = m_state | ps_bit_suspended; 54312027Sjungma@eit.uni-kl.de if ( next_runnable() != 0 ) 54412027Sjungma@eit.uni-kl.de { 54512027Sjungma@eit.uni-kl.de m_state = m_state | ps_bit_ready_to_run; 54612027Sjungma@eit.uni-kl.de simcontext()->remove_runnable_thread( this ); 54712027Sjungma@eit.uni-kl.de } 54812027Sjungma@eit.uni-kl.de if ( sc_get_current_process_b() == DCAST<sc_process_b*>(this) ) 54912027Sjungma@eit.uni-kl.de { 55012027Sjungma@eit.uni-kl.de m_state = m_state | ps_bit_ready_to_run; 55112027Sjungma@eit.uni-kl.de suspend_me(); 55212027Sjungma@eit.uni-kl.de } 55312027Sjungma@eit.uni-kl.de} 55412027Sjungma@eit.uni-kl.de 55512027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------ 55612027Sjungma@eit.uni-kl.de//"sc_thread_process::throw_reset" 55712027Sjungma@eit.uni-kl.de// 55812027Sjungma@eit.uni-kl.de// This virtual method is invoked when an reset is to be thrown. The 55912027Sjungma@eit.uni-kl.de// method will cancel any dynamic waits. If the reset is asynchronous it will 56012027Sjungma@eit.uni-kl.de// queue this object instance to be executed. 56112027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------ 56212027Sjungma@eit.uni-kl.devoid sc_thread_process::throw_reset( bool async ) 56312027Sjungma@eit.uni-kl.de{ 56412027Sjungma@eit.uni-kl.de // IF THE PROCESS IS CURRENTLY UNWINDING OR IS ALREADY A ZOMBIE 56512027Sjungma@eit.uni-kl.de // IGNORE THE RESET: 56612027Sjungma@eit.uni-kl.de 56712027Sjungma@eit.uni-kl.de if ( m_unwinding ) 56812027Sjungma@eit.uni-kl.de { 56912027Sjungma@eit.uni-kl.de SC_REPORT_WARNING( SC_ID_PROCESS_ALREADY_UNWINDING_, name() ); 57012027Sjungma@eit.uni-kl.de return; 57112027Sjungma@eit.uni-kl.de } 57212027Sjungma@eit.uni-kl.de 57312027Sjungma@eit.uni-kl.de if ( m_state & ps_bit_zombie ) 57412027Sjungma@eit.uni-kl.de return; 57512027Sjungma@eit.uni-kl.de 57612027Sjungma@eit.uni-kl.de 57712027Sjungma@eit.uni-kl.de // Set the throw type and clear any pending dynamic events: 57812027Sjungma@eit.uni-kl.de 57912027Sjungma@eit.uni-kl.de m_throw_status = async ? THROW_ASYNC_RESET : THROW_SYNC_RESET; 58012027Sjungma@eit.uni-kl.de m_wait_cycle_n = 0; 58112027Sjungma@eit.uni-kl.de 58212027Sjungma@eit.uni-kl.de // If this is an asynchronous reset: 58312027Sjungma@eit.uni-kl.de // 58412027Sjungma@eit.uni-kl.de // (a) Cancel any dynamic events 58512027Sjungma@eit.uni-kl.de // (b) Set the thread up for execution: 58612027Sjungma@eit.uni-kl.de // (i) If we are in the execution phase do it now. 58712027Sjungma@eit.uni-kl.de // (ii) If we are not queue it to execute next when we hit 58812027Sjungma@eit.uni-kl.de // the execution phase. 58912027Sjungma@eit.uni-kl.de 59012027Sjungma@eit.uni-kl.de if ( async ) 59112027Sjungma@eit.uni-kl.de { 59212027Sjungma@eit.uni-kl.de m_state = m_state & ~ps_bit_ready_to_run; 59312027Sjungma@eit.uni-kl.de remove_dynamic_events(); 59412027Sjungma@eit.uni-kl.de if ( simcontext()->evaluation_phase() ) 59512027Sjungma@eit.uni-kl.de { 59612027Sjungma@eit.uni-kl.de simcontext()->preempt_with( this ); 59712027Sjungma@eit.uni-kl.de } 59812027Sjungma@eit.uni-kl.de else 59912027Sjungma@eit.uni-kl.de { 60012027Sjungma@eit.uni-kl.de if ( is_runnable() ) 60112027Sjungma@eit.uni-kl.de simcontext()->remove_runnable_thread(this); 60212027Sjungma@eit.uni-kl.de simcontext()->execute_thread_next(this); 60312027Sjungma@eit.uni-kl.de } 60412027Sjungma@eit.uni-kl.de } 60512027Sjungma@eit.uni-kl.de} 60612027Sjungma@eit.uni-kl.de 60712027Sjungma@eit.uni-kl.de 60812027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------ 60912027Sjungma@eit.uni-kl.de//"sc_thread_process::throw_user" 61012027Sjungma@eit.uni-kl.de// 61112027Sjungma@eit.uni-kl.de// This virtual method is invoked when a user exception is to be thrown. 61212027Sjungma@eit.uni-kl.de// If requested it will also throw the exception to the children of this 61312027Sjungma@eit.uni-kl.de// object instance. The order of dispatch for the processes that are 61412027Sjungma@eit.uni-kl.de// thrown the exception is from youngest child to oldest child and then 61512027Sjungma@eit.uni-kl.de// this process instance. This means that this instance will be pushed onto 61612027Sjungma@eit.uni-kl.de// the front of the simulator's runnable queue and then the children will 61712027Sjungma@eit.uni-kl.de// be processed recursively. 61812027Sjungma@eit.uni-kl.de// helper_p = helper object to use to throw the exception. 61912027Sjungma@eit.uni-kl.de// descendants = indicator of whether this process' children should also 62012027Sjungma@eit.uni-kl.de// be suspended 62112027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------ 62212027Sjungma@eit.uni-kl.devoid sc_thread_process::throw_user( const sc_throw_it_helper& helper, 62312027Sjungma@eit.uni-kl.de sc_descendant_inclusion_info descendants ) 62412027Sjungma@eit.uni-kl.de{ 62512027Sjungma@eit.uni-kl.de 62612027Sjungma@eit.uni-kl.de // IF THE SIMULATION IS NOT ACTAULLY RUNNING THIS IS AN ERROR: 62712027Sjungma@eit.uni-kl.de 62812027Sjungma@eit.uni-kl.de if ( sc_get_status() != SC_RUNNING ) 62912027Sjungma@eit.uni-kl.de { 63012027Sjungma@eit.uni-kl.de report_error( SC_ID_THROW_IT_WHILE_NOT_RUNNING_ ); 63112027Sjungma@eit.uni-kl.de } 63212027Sjungma@eit.uni-kl.de 63312027Sjungma@eit.uni-kl.de // IF NEEDED PROPOGATE THE THROW REQUEST THROUGH OUR DESCENDANTS: 63412027Sjungma@eit.uni-kl.de 63512027Sjungma@eit.uni-kl.de if ( descendants == SC_INCLUDE_DESCENDANTS ) 63612027Sjungma@eit.uni-kl.de { 63712027Sjungma@eit.uni-kl.de const std::vector<sc_object*> children = get_child_objects(); 63812027Sjungma@eit.uni-kl.de int child_n = children.size(); 63912027Sjungma@eit.uni-kl.de 64012027Sjungma@eit.uni-kl.de for ( int child_i = 0; child_i < child_n; child_i++ ) 64112027Sjungma@eit.uni-kl.de { 64212027Sjungma@eit.uni-kl.de sc_process_b* child_p = DCAST<sc_process_b*>(children[child_i]); 64312027Sjungma@eit.uni-kl.de if ( child_p ) 64412027Sjungma@eit.uni-kl.de { 64512027Sjungma@eit.uni-kl.de DEBUG_MSG(DEBUG_NAME,child_p,"about to throw user on"); 64612027Sjungma@eit.uni-kl.de child_p->throw_user(helper, descendants); 64712027Sjungma@eit.uni-kl.de } 64812027Sjungma@eit.uni-kl.de } 64912027Sjungma@eit.uni-kl.de } 65012027Sjungma@eit.uni-kl.de 65112027Sjungma@eit.uni-kl.de // IF THE PROCESS IS CURRENTLY UNWINDING IGNORE THE THROW: 65212027Sjungma@eit.uni-kl.de 65312027Sjungma@eit.uni-kl.de if ( m_unwinding ) 65412027Sjungma@eit.uni-kl.de { 65512027Sjungma@eit.uni-kl.de SC_REPORT_WARNING( SC_ID_PROCESS_ALREADY_UNWINDING_, name() ); 65612027Sjungma@eit.uni-kl.de return; 65712027Sjungma@eit.uni-kl.de } 65812027Sjungma@eit.uni-kl.de 65912027Sjungma@eit.uni-kl.de // SET UP THE THROW REQUEST FOR THIS OBJECT INSTANCE AND QUEUE IT FOR 66012027Sjungma@eit.uni-kl.de // EXECUTION: 66112027Sjungma@eit.uni-kl.de 66212027Sjungma@eit.uni-kl.de if( m_has_stack ) 66312027Sjungma@eit.uni-kl.de { 66412027Sjungma@eit.uni-kl.de remove_dynamic_events(); 66512027Sjungma@eit.uni-kl.de DEBUG_MSG(DEBUG_NAME,this,"throwing user exception to"); 66612027Sjungma@eit.uni-kl.de m_throw_status = THROW_USER; 66712027Sjungma@eit.uni-kl.de if ( m_throw_helper_p != 0 ) delete m_throw_helper_p; 66812027Sjungma@eit.uni-kl.de m_throw_helper_p = helper.clone(); 66912027Sjungma@eit.uni-kl.de simcontext()->preempt_with( this ); 67012027Sjungma@eit.uni-kl.de } 67112027Sjungma@eit.uni-kl.de else 67212027Sjungma@eit.uni-kl.de { 67312027Sjungma@eit.uni-kl.de SC_REPORT_WARNING( SC_ID_THROW_IT_IGNORED_, name() ); 67412027Sjungma@eit.uni-kl.de } 67512027Sjungma@eit.uni-kl.de} 67612027Sjungma@eit.uni-kl.de 67712027Sjungma@eit.uni-kl.de 67812027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------ 67912027Sjungma@eit.uni-kl.de//"sc_thread_process::trigger_dynamic" 68012027Sjungma@eit.uni-kl.de// 68112027Sjungma@eit.uni-kl.de// This method sets up a dynamic trigger on an event. 68212027Sjungma@eit.uni-kl.de// 68312027Sjungma@eit.uni-kl.de// Notes: 68412027Sjungma@eit.uni-kl.de// (1) This method is identical to sc_method_process::trigger_dynamic(), 68512027Sjungma@eit.uni-kl.de// but they cannot be combined as sc_process_b::trigger_dynamic() 68612027Sjungma@eit.uni-kl.de// because the signatures things like sc_event::remove_dynamic() 68712027Sjungma@eit.uni-kl.de// have different overloads for sc_thread_process* and sc_method_process*. 68812027Sjungma@eit.uni-kl.de// So if you change code here you'll also need to change it in 68912027Sjungma@eit.uni-kl.de// sc_method_process.cpp. 69012027Sjungma@eit.uni-kl.de// 69112027Sjungma@eit.uni-kl.de// Result is true if this process should be removed from the event's list, 69212027Sjungma@eit.uni-kl.de// false if not. 69312027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------ 69412027Sjungma@eit.uni-kl.debool sc_thread_process::trigger_dynamic( sc_event* e ) 69512027Sjungma@eit.uni-kl.de{ 69612027Sjungma@eit.uni-kl.de // No time outs yet, and keep gcc happy. 69712027Sjungma@eit.uni-kl.de 69812027Sjungma@eit.uni-kl.de m_timed_out = false; 69912027Sjungma@eit.uni-kl.de 70012027Sjungma@eit.uni-kl.de // Escape cases: 70112027Sjungma@eit.uni-kl.de // (a) If this thread issued the notify() don't schedule it for 70212027Sjungma@eit.uni-kl.de // execution, but leave the sensitivity in place. 70312027Sjungma@eit.uni-kl.de // (b) If this thread is already runnable can't trigger an event. 70412027Sjungma@eit.uni-kl.de 70512027Sjungma@eit.uni-kl.de // not possible for thread processes! 70612027Sjungma@eit.uni-kl.de#if 0 // ! defined( SC_ENABLE_IMMEDIATE_SELF_NOTIFICATIONS ) 70712027Sjungma@eit.uni-kl.de if ( sc_get_current_process_b() == (sc_process_b*)this ) 70812027Sjungma@eit.uni-kl.de { 70912027Sjungma@eit.uni-kl.de report_immediate_self_notification(); 71012027Sjungma@eit.uni-kl.de return false; 71112027Sjungma@eit.uni-kl.de } 71212027Sjungma@eit.uni-kl.de#endif // SC_ENABLE_IMMEDIATE_SELF_NOTIFICATIONS 71312027Sjungma@eit.uni-kl.de 71412027Sjungma@eit.uni-kl.de if( is_runnable() ) 71512027Sjungma@eit.uni-kl.de return true; 71612027Sjungma@eit.uni-kl.de 71712027Sjungma@eit.uni-kl.de // If a process is disabled then we ignore any events, leaving them enabled: 71812027Sjungma@eit.uni-kl.de // 71912027Sjungma@eit.uni-kl.de // But if this is a time out event we need to remove both it and the 72012027Sjungma@eit.uni-kl.de // event that was being waited for. 72112027Sjungma@eit.uni-kl.de 72212027Sjungma@eit.uni-kl.de if ( m_state & ps_bit_disabled ) 72312027Sjungma@eit.uni-kl.de { 72412027Sjungma@eit.uni-kl.de if ( e == m_timeout_event_p ) 72512027Sjungma@eit.uni-kl.de { 72612027Sjungma@eit.uni-kl.de remove_dynamic_events( true ); 72712027Sjungma@eit.uni-kl.de return true; 72812027Sjungma@eit.uni-kl.de } 72912027Sjungma@eit.uni-kl.de else 73012027Sjungma@eit.uni-kl.de { 73112027Sjungma@eit.uni-kl.de return false; 73212027Sjungma@eit.uni-kl.de } 73312027Sjungma@eit.uni-kl.de } 73412027Sjungma@eit.uni-kl.de 73512027Sjungma@eit.uni-kl.de 73612027Sjungma@eit.uni-kl.de // Process based on the event type and current process state: 73712027Sjungma@eit.uni-kl.de // 73812027Sjungma@eit.uni-kl.de // Every case needs to set 'rc' and continue on to the end of 73912027Sjungma@eit.uni-kl.de // this method to allow suspend processing to work correctly. 74012027Sjungma@eit.uni-kl.de 74112027Sjungma@eit.uni-kl.de switch( m_trigger_type ) 74212027Sjungma@eit.uni-kl.de { 74312027Sjungma@eit.uni-kl.de case EVENT: 74412027Sjungma@eit.uni-kl.de m_event_p = 0; 74512027Sjungma@eit.uni-kl.de m_trigger_type = STATIC; 74612027Sjungma@eit.uni-kl.de break; 74712027Sjungma@eit.uni-kl.de 74812027Sjungma@eit.uni-kl.de case AND_LIST: 74912027Sjungma@eit.uni-kl.de -- m_event_count; 75012027Sjungma@eit.uni-kl.de if ( m_event_count == 0 ) 75112027Sjungma@eit.uni-kl.de { 75212027Sjungma@eit.uni-kl.de m_event_list_p->auto_delete(); 75312027Sjungma@eit.uni-kl.de m_event_list_p = 0; 75412027Sjungma@eit.uni-kl.de m_trigger_type = STATIC; 75512027Sjungma@eit.uni-kl.de } 75612027Sjungma@eit.uni-kl.de else 75712027Sjungma@eit.uni-kl.de { 75812027Sjungma@eit.uni-kl.de return true; 75912027Sjungma@eit.uni-kl.de } 76012027Sjungma@eit.uni-kl.de break; 76112027Sjungma@eit.uni-kl.de 76212027Sjungma@eit.uni-kl.de case OR_LIST: 76312027Sjungma@eit.uni-kl.de m_event_list_p->remove_dynamic( this, e ); 76412027Sjungma@eit.uni-kl.de m_event_list_p->auto_delete(); 76512027Sjungma@eit.uni-kl.de m_event_list_p = 0; 76612027Sjungma@eit.uni-kl.de m_trigger_type = STATIC; 76712027Sjungma@eit.uni-kl.de break; 76812027Sjungma@eit.uni-kl.de 76912027Sjungma@eit.uni-kl.de case TIMEOUT: 77012027Sjungma@eit.uni-kl.de m_trigger_type = STATIC; 77112027Sjungma@eit.uni-kl.de break; 77212027Sjungma@eit.uni-kl.de 77312027Sjungma@eit.uni-kl.de case EVENT_TIMEOUT: 77412027Sjungma@eit.uni-kl.de if ( e == m_timeout_event_p ) 77512027Sjungma@eit.uni-kl.de { 77612027Sjungma@eit.uni-kl.de m_timed_out = true; 77712027Sjungma@eit.uni-kl.de m_event_p->remove_dynamic( this ); 77812027Sjungma@eit.uni-kl.de m_event_p = 0; 77912027Sjungma@eit.uni-kl.de m_trigger_type = STATIC; 78012027Sjungma@eit.uni-kl.de } 78112027Sjungma@eit.uni-kl.de else 78212027Sjungma@eit.uni-kl.de { 78312027Sjungma@eit.uni-kl.de m_timeout_event_p->cancel(); 78412027Sjungma@eit.uni-kl.de m_timeout_event_p->reset(); 78512027Sjungma@eit.uni-kl.de m_event_p = 0; 78612027Sjungma@eit.uni-kl.de m_trigger_type = STATIC; 78712027Sjungma@eit.uni-kl.de } 78812027Sjungma@eit.uni-kl.de break; 78912027Sjungma@eit.uni-kl.de 79012027Sjungma@eit.uni-kl.de case OR_LIST_TIMEOUT: 79112027Sjungma@eit.uni-kl.de if ( e == m_timeout_event_p ) 79212027Sjungma@eit.uni-kl.de { 79312027Sjungma@eit.uni-kl.de m_timed_out = true; 79412027Sjungma@eit.uni-kl.de m_event_list_p->remove_dynamic( this, e ); 79512027Sjungma@eit.uni-kl.de m_event_list_p->auto_delete(); 79612027Sjungma@eit.uni-kl.de m_event_list_p = 0; 79712027Sjungma@eit.uni-kl.de m_trigger_type = STATIC; 79812027Sjungma@eit.uni-kl.de } 79912027Sjungma@eit.uni-kl.de 80012027Sjungma@eit.uni-kl.de else 80112027Sjungma@eit.uni-kl.de { 80212027Sjungma@eit.uni-kl.de m_timeout_event_p->cancel(); 80312027Sjungma@eit.uni-kl.de m_timeout_event_p->reset(); 80412027Sjungma@eit.uni-kl.de m_event_list_p->remove_dynamic( this, e ); 80512027Sjungma@eit.uni-kl.de m_event_list_p->auto_delete(); 80612027Sjungma@eit.uni-kl.de m_event_list_p = 0; 80712027Sjungma@eit.uni-kl.de m_trigger_type = STATIC; 80812027Sjungma@eit.uni-kl.de } 80912027Sjungma@eit.uni-kl.de break; 81012027Sjungma@eit.uni-kl.de 81112027Sjungma@eit.uni-kl.de case AND_LIST_TIMEOUT: 81212027Sjungma@eit.uni-kl.de if ( e == m_timeout_event_p ) 81312027Sjungma@eit.uni-kl.de { 81412027Sjungma@eit.uni-kl.de m_timed_out = true; 81512027Sjungma@eit.uni-kl.de m_event_list_p->remove_dynamic( this, e ); 81612027Sjungma@eit.uni-kl.de m_event_list_p->auto_delete(); 81712027Sjungma@eit.uni-kl.de m_event_list_p = 0; 81812027Sjungma@eit.uni-kl.de m_trigger_type = STATIC; 81912027Sjungma@eit.uni-kl.de } 82012027Sjungma@eit.uni-kl.de 82112027Sjungma@eit.uni-kl.de else 82212027Sjungma@eit.uni-kl.de { 82312027Sjungma@eit.uni-kl.de -- m_event_count; 82412027Sjungma@eit.uni-kl.de if ( m_event_count == 0 ) 82512027Sjungma@eit.uni-kl.de { 82612027Sjungma@eit.uni-kl.de m_timeout_event_p->cancel(); 82712027Sjungma@eit.uni-kl.de m_timeout_event_p->reset(); 82812027Sjungma@eit.uni-kl.de // no need to remove_dynamic 82912027Sjungma@eit.uni-kl.de m_event_list_p->auto_delete(); 83012027Sjungma@eit.uni-kl.de m_event_list_p = 0; 83112027Sjungma@eit.uni-kl.de m_trigger_type = STATIC; 83212027Sjungma@eit.uni-kl.de } 83312027Sjungma@eit.uni-kl.de else 83412027Sjungma@eit.uni-kl.de { 83512027Sjungma@eit.uni-kl.de return true; 83612027Sjungma@eit.uni-kl.de } 83712027Sjungma@eit.uni-kl.de } 83812027Sjungma@eit.uni-kl.de break; 83912027Sjungma@eit.uni-kl.de 84012027Sjungma@eit.uni-kl.de case STATIC: { 84112027Sjungma@eit.uni-kl.de // we should never get here, but throw_it() can make it happen. 84212027Sjungma@eit.uni-kl.de SC_REPORT_WARNING(SC_ID_NOT_EXPECTING_DYNAMIC_EVENT_NOTIFY_, name()); 84312027Sjungma@eit.uni-kl.de return true; 84412027Sjungma@eit.uni-kl.de } 84512027Sjungma@eit.uni-kl.de } 84612027Sjungma@eit.uni-kl.de 84712027Sjungma@eit.uni-kl.de // If we get here then the thread is has satisfied its wait criteria, if 84812027Sjungma@eit.uni-kl.de // its suspended mark its state as ready to run. If its not suspended then 84912027Sjungma@eit.uni-kl.de // push it onto the runnable queue. 85012027Sjungma@eit.uni-kl.de 85112027Sjungma@eit.uni-kl.de if ( (m_state & ps_bit_suspended) ) 85212027Sjungma@eit.uni-kl.de { 85312027Sjungma@eit.uni-kl.de m_state = m_state | ps_bit_ready_to_run; 85412027Sjungma@eit.uni-kl.de } 85512027Sjungma@eit.uni-kl.de else 85612027Sjungma@eit.uni-kl.de { 85712027Sjungma@eit.uni-kl.de simcontext()->push_runnable_thread(this); 85812027Sjungma@eit.uni-kl.de } 85912027Sjungma@eit.uni-kl.de 86012027Sjungma@eit.uni-kl.de return true; 86112027Sjungma@eit.uni-kl.de} 86212027Sjungma@eit.uni-kl.de 86312027Sjungma@eit.uni-kl.de 86412027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------ 86512027Sjungma@eit.uni-kl.de//"sc_set_stack_size" 86612027Sjungma@eit.uni-kl.de// 86712027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------ 86812027Sjungma@eit.uni-kl.devoid 86912027Sjungma@eit.uni-kl.desc_set_stack_size( sc_thread_handle thread_h, std::size_t size ) 87012027Sjungma@eit.uni-kl.de{ 87112027Sjungma@eit.uni-kl.de thread_h->set_stack_size( size ); 87212027Sjungma@eit.uni-kl.de} 87312027Sjungma@eit.uni-kl.de 87412027Sjungma@eit.uni-kl.de#undef DEBUG_MSG 87512027Sjungma@eit.uni-kl.de#undef DEBUG_NAME 87612027Sjungma@eit.uni-kl.de 87712027Sjungma@eit.uni-kl.de} // namespace sc_core 87812027Sjungma@eit.uni-kl.de 87912027Sjungma@eit.uni-kl.de 88012027Sjungma@eit.uni-kl.de/***************************************************************************** 88112027Sjungma@eit.uni-kl.de 88212027Sjungma@eit.uni-kl.de MODIFICATION LOG - modifiers, enter your name, affiliation, date and 88312027Sjungma@eit.uni-kl.de changes you are making here. 88412027Sjungma@eit.uni-kl.de 88512027Sjungma@eit.uni-kl.de Name, Affiliation, Date: 88612027Sjungma@eit.uni-kl.de Description of Modification: 88712027Sjungma@eit.uni-kl.de 88812027Sjungma@eit.uni-kl.de *****************************************************************************/ 88912027Sjungma@eit.uni-kl.de 89012027Sjungma@eit.uni-kl.de// $Log: sc_thread_process.cpp,v $ 89112027Sjungma@eit.uni-kl.de// Revision 1.57 2011/08/24 22:05:51 acg 89212027Sjungma@eit.uni-kl.de// Torsten Maehne: initialization changes to remove warnings. 89312027Sjungma@eit.uni-kl.de// 89412027Sjungma@eit.uni-kl.de// Revision 1.56 2011/08/07 19:08:04 acg 89512027Sjungma@eit.uni-kl.de// Andy Goodrich: moved logs to end of file so line number synching works 89612027Sjungma@eit.uni-kl.de// better between versions. 89712027Sjungma@eit.uni-kl.de// 89812027Sjungma@eit.uni-kl.de// Revision 1.55 2011/08/04 17:16:22 acg 89912027Sjungma@eit.uni-kl.de// Philipp A. Hartmann: fix handling of child objects in kill routine, need 90012027Sjungma@eit.uni-kl.de// to use a copy rather than a reference. 90112027Sjungma@eit.uni-kl.de// 90212027Sjungma@eit.uni-kl.de// Revision 1.53 2011/07/29 22:45:38 acg 90312027Sjungma@eit.uni-kl.de// Philipp A. Hartmann: changes to handle case where a process control 90412027Sjungma@eit.uni-kl.de// invocation on a child process causes the list of child processes to change. 90512027Sjungma@eit.uni-kl.de// 90612027Sjungma@eit.uni-kl.de// Revision 1.52 2011/07/24 11:27:04 acg 90712027Sjungma@eit.uni-kl.de// Andy Goodrich: moved the check for unwinding processes until after the 90812027Sjungma@eit.uni-kl.de// descendants have been processed in throw_user and kill. 90912027Sjungma@eit.uni-kl.de// 91012027Sjungma@eit.uni-kl.de// Revision 1.51 2011/07/24 11:20:03 acg 91112027Sjungma@eit.uni-kl.de// Philipp A. Hartmann: process control error message improvements: 91212027Sjungma@eit.uni-kl.de// (1) Downgrade error to warning for re-kills of processes. 91312027Sjungma@eit.uni-kl.de// (2) Add process name to process messages. 91412027Sjungma@eit.uni-kl.de// (3) drop some superfluous colons in messages. 91512027Sjungma@eit.uni-kl.de// 91612027Sjungma@eit.uni-kl.de// Revision 1.50 2011/05/09 04:07:49 acg 91712027Sjungma@eit.uni-kl.de// Philipp A. Hartmann: 91812027Sjungma@eit.uni-kl.de// (1) Restore hierarchy in all phase callbacks. 91912027Sjungma@eit.uni-kl.de// (2) Ensure calls to before_end_of_elaboration. 92012027Sjungma@eit.uni-kl.de// 92112027Sjungma@eit.uni-kl.de// Revision 1.49 2011/05/05 17:45:27 acg 92212027Sjungma@eit.uni-kl.de// Philip A. Hartmann: changes in WIN64 support. 92312027Sjungma@eit.uni-kl.de// Andy Goodrich: additional DEBUG_MSG instances to trace process handling. 92412027Sjungma@eit.uni-kl.de// 92512027Sjungma@eit.uni-kl.de// Revision 1.48 2011/04/19 15:04:27 acg 92612027Sjungma@eit.uni-kl.de// Philipp A. Hartmann: clean up SC_ID messages. 92712027Sjungma@eit.uni-kl.de// 92812027Sjungma@eit.uni-kl.de// Revision 1.47 2011/04/19 02:39:09 acg 92912027Sjungma@eit.uni-kl.de// Philipp A. Hartmann: added checks for additional throws during stack unwinds. 93012027Sjungma@eit.uni-kl.de// 93112027Sjungma@eit.uni-kl.de// Revision 1.46 2011/04/14 22:33:43 acg 93212027Sjungma@eit.uni-kl.de// Andy Goodrich: added missing checks for a process being a zombie. 93312027Sjungma@eit.uni-kl.de// 93412027Sjungma@eit.uni-kl.de// Revision 1.45 2011/04/13 02:45:11 acg 93512027Sjungma@eit.uni-kl.de// Andy Goodrich: eliminated warning message that occurred if the DEBUG_MSG 93612027Sjungma@eit.uni-kl.de// macro was used. 93712027Sjungma@eit.uni-kl.de// 93812027Sjungma@eit.uni-kl.de// Revision 1.44 2011/04/11 22:04:33 acg 93912027Sjungma@eit.uni-kl.de// Andy Goodrich: use the DEBUG_NAME macro for DEBUG_MSG messages. 94012027Sjungma@eit.uni-kl.de// 94112027Sjungma@eit.uni-kl.de// Revision 1.43 2011/04/10 22:12:32 acg 94212027Sjungma@eit.uni-kl.de// Andy Goodrich: adding debugging macros. 94312027Sjungma@eit.uni-kl.de// 94412027Sjungma@eit.uni-kl.de// Revision 1.42 2011/04/08 22:40:26 acg 94512027Sjungma@eit.uni-kl.de// Andy Goodrich: moved the reset event notification code out of throw_reset() 94612027Sjungma@eit.uni-kl.de// and into suspend_me. 94712027Sjungma@eit.uni-kl.de// 94812027Sjungma@eit.uni-kl.de// Revision 1.41 2011/04/08 18:24:07 acg 94912027Sjungma@eit.uni-kl.de// Andy Goodrich: fix asynchronous reset dispatch and when the reset_event() 95012027Sjungma@eit.uni-kl.de// is fired. 95112027Sjungma@eit.uni-kl.de// 95212027Sjungma@eit.uni-kl.de// Revision 1.40 2011/04/05 20:50:57 acg 95312027Sjungma@eit.uni-kl.de// Andy Goodrich: 95412027Sjungma@eit.uni-kl.de// (1) changes to make sure that event(), posedge() and negedge() only 95512027Sjungma@eit.uni-kl.de// return true if the clock has not moved. 95612027Sjungma@eit.uni-kl.de// (2) fixes for method self-resumes. 95712027Sjungma@eit.uni-kl.de// (3) added SC_PRERELEASE_VERSION 95812027Sjungma@eit.uni-kl.de// (4) removed kernel events from the object hierarchy, added 95912027Sjungma@eit.uni-kl.de// sc_hierarchy_name_exists(). 96012027Sjungma@eit.uni-kl.de// 96112027Sjungma@eit.uni-kl.de// Revision 1.39 2011/04/01 22:30:39 acg 96212027Sjungma@eit.uni-kl.de// Andy Goodrich: change hard assertion to warning for trigger_dynamic() 96312027Sjungma@eit.uni-kl.de// getting called when there is only STATIC sensitivity. This can result 96412027Sjungma@eit.uni-kl.de// because of sc_process_handle::throw_it(). 96512027Sjungma@eit.uni-kl.de// 96612027Sjungma@eit.uni-kl.de// Revision 1.38 2011/03/23 16:17:52 acg 96712027Sjungma@eit.uni-kl.de// Andy Goodrich: don't emit an error message for a resume on a disabled 96812027Sjungma@eit.uni-kl.de// process that is not suspended. 96912027Sjungma@eit.uni-kl.de// 97012027Sjungma@eit.uni-kl.de// Revision 1.37 2011/03/20 13:43:23 acg 97112027Sjungma@eit.uni-kl.de// Andy Goodrich: added async_signal_is() plus suspend() as a corner case. 97212027Sjungma@eit.uni-kl.de// 97312027Sjungma@eit.uni-kl.de// Revision 1.36 2011/03/08 20:49:31 acg 97412027Sjungma@eit.uni-kl.de// Andy Goodrich: implement coarse checking for synchronous reset - suspend 97512027Sjungma@eit.uni-kl.de// interaction. 97612027Sjungma@eit.uni-kl.de// 97712027Sjungma@eit.uni-kl.de// Revision 1.35 2011/03/08 20:32:28 acg 97812027Sjungma@eit.uni-kl.de// Andy Goodrich: implemented "coarse" checking for undefined process 97912027Sjungma@eit.uni-kl.de// control interactions. 98012027Sjungma@eit.uni-kl.de// 98112027Sjungma@eit.uni-kl.de// Revision 1.34 2011/03/07 18:25:19 acg 98212027Sjungma@eit.uni-kl.de// Andy Goodrich: tightening of check for resume on a disabled process to 98312027Sjungma@eit.uni-kl.de// only produce an error if it is ready to run. 98412027Sjungma@eit.uni-kl.de// 98512027Sjungma@eit.uni-kl.de// Revision 1.33 2011/03/07 17:38:44 acg 98612027Sjungma@eit.uni-kl.de// Andy Goodrich: tightening up of checks for undefined interaction between 98712027Sjungma@eit.uni-kl.de// synchronous reset and suspend. 98812027Sjungma@eit.uni-kl.de// 98912027Sjungma@eit.uni-kl.de// Revision 1.32 2011/03/06 23:30:13 acg 99012027Sjungma@eit.uni-kl.de// Andy Goodrich: refining suspend - sync reset corner case checking so that 99112027Sjungma@eit.uni-kl.de// the following are error situations: 99212027Sjungma@eit.uni-kl.de// (1) Calling suspend on a process with a reset_signal_is() specification 99312027Sjungma@eit.uni-kl.de// or sync_reset_on() is active. 99412027Sjungma@eit.uni-kl.de// (2) Calling sync_reset_on() on a suspended process. 99512027Sjungma@eit.uni-kl.de// 99612027Sjungma@eit.uni-kl.de// Revision 1.31 2011/03/06 19:57:11 acg 99712027Sjungma@eit.uni-kl.de// Andy Goodrich: refinements for the illegal suspend - synchronous reset 99812027Sjungma@eit.uni-kl.de// interaction. 99912027Sjungma@eit.uni-kl.de// 100012027Sjungma@eit.uni-kl.de// Revision 1.30 2011/03/06 16:47:09 acg 100112027Sjungma@eit.uni-kl.de// Andy Goodrich: changes for testing sync_reset - suspend corner cases. 100212027Sjungma@eit.uni-kl.de// 100312027Sjungma@eit.uni-kl.de// Revision 1.29 2011/03/06 15:59:23 acg 100412027Sjungma@eit.uni-kl.de// Andy Goodrich: added process control corner case checks. 100512027Sjungma@eit.uni-kl.de// 100612027Sjungma@eit.uni-kl.de// Revision 1.28 2011/03/05 19:44:20 acg 100712027Sjungma@eit.uni-kl.de// Andy Goodrich: changes for object and event naming and structures. 100812027Sjungma@eit.uni-kl.de// 100912027Sjungma@eit.uni-kl.de// Revision 1.27 2011/02/19 08:30:53 acg 101012027Sjungma@eit.uni-kl.de// Andy Goodrich: Moved process queueing into trigger_static from 101112027Sjungma@eit.uni-kl.de// sc_event::notify. 101212027Sjungma@eit.uni-kl.de// 101312027Sjungma@eit.uni-kl.de// Revision 1.26 2011/02/18 20:27:14 acg 101412027Sjungma@eit.uni-kl.de// Andy Goodrich: Updated Copyrights. 101512027Sjungma@eit.uni-kl.de// 101612027Sjungma@eit.uni-kl.de// Revision 1.25 2011/02/17 19:54:33 acg 101712027Sjungma@eit.uni-kl.de// Andy Goodrich: 101812027Sjungma@eit.uni-kl.de// (1) Changed signature of trigger_dynamic() back to bool, and moved 101912027Sjungma@eit.uni-kl.de// run queue processing into trigger_dynamic. 102012027Sjungma@eit.uni-kl.de// (2) Simplified process control usage. 102112027Sjungma@eit.uni-kl.de// 102212027Sjungma@eit.uni-kl.de// Revision 1.24 2011/02/16 22:37:31 acg 102312027Sjungma@eit.uni-kl.de// Andy Goodrich: clean up to remove need for ps_disable_pending. 102412027Sjungma@eit.uni-kl.de// 102512027Sjungma@eit.uni-kl.de// Revision 1.23 2011/02/14 17:51:40 acg 102612027Sjungma@eit.uni-kl.de// Andy Goodrich: proper pushing an poppping of the module hierarchy for 102712027Sjungma@eit.uni-kl.de// start_of_simulation() and end_of_simulation. 102812027Sjungma@eit.uni-kl.de// 102912027Sjungma@eit.uni-kl.de// Revision 1.22 2011/02/13 23:09:58 acg 103012027Sjungma@eit.uni-kl.de// Andy Goodrich: only remove dynamic events for asynchronous resets. 103112027Sjungma@eit.uni-kl.de// 103212027Sjungma@eit.uni-kl.de// Revision 1.21 2011/02/13 21:47:38 acg 103312027Sjungma@eit.uni-kl.de// Andy Goodrich: update copyright notice. 103412027Sjungma@eit.uni-kl.de// 103512027Sjungma@eit.uni-kl.de// Revision 1.20 2011/02/13 21:37:13 acg 103612027Sjungma@eit.uni-kl.de// Andy Goodrich: removed temporary diagnostic. Also there is 103712027Sjungma@eit.uni-kl.de// remove_dynamic_events() call in reset code. 103812027Sjungma@eit.uni-kl.de// 103912027Sjungma@eit.uni-kl.de// Revision 1.19 2011/02/13 21:35:09 acg 104012027Sjungma@eit.uni-kl.de// Andy Goodrich: added error messages for throws before the simulator is 104112027Sjungma@eit.uni-kl.de// initialized. 104212027Sjungma@eit.uni-kl.de// 104312027Sjungma@eit.uni-kl.de// Revision 1.18 2011/02/11 13:25:24 acg 104412027Sjungma@eit.uni-kl.de// Andy Goodrich: Philipp A. Hartmann's changes: 104512027Sjungma@eit.uni-kl.de// (1) Removal of SC_CTHREAD method overloads. 104612027Sjungma@eit.uni-kl.de// (2) New exception processing code. 104712027Sjungma@eit.uni-kl.de// 104812027Sjungma@eit.uni-kl.de// Revision 1.17 2011/02/08 08:18:16 acg 104912027Sjungma@eit.uni-kl.de// Andy Goodrich: removed obsolete code. 105012027Sjungma@eit.uni-kl.de// 105112027Sjungma@eit.uni-kl.de// Revision 1.16 2011/02/07 19:17:20 acg 105212027Sjungma@eit.uni-kl.de// Andy Goodrich: changes for IEEE 1666 compatibility. 105312027Sjungma@eit.uni-kl.de// 105412027Sjungma@eit.uni-kl.de// Revision 1.15 2011/02/04 15:27:36 acg 105512027Sjungma@eit.uni-kl.de// Andy Goodrich: changes for suspend-resume semantics. 105612027Sjungma@eit.uni-kl.de// 105712027Sjungma@eit.uni-kl.de// Revision 1.14 2011/02/01 23:01:53 acg 105812027Sjungma@eit.uni-kl.de// Andy Goodrich: removed dead code. 105912027Sjungma@eit.uni-kl.de// 106012027Sjungma@eit.uni-kl.de// Revision 1.13 2011/02/01 21:16:36 acg 106112027Sjungma@eit.uni-kl.de// Andy Goodrich: 106212027Sjungma@eit.uni-kl.de// (1) New version of trigger_dynamic() to implement new return codes and 106312027Sjungma@eit.uni-kl.de// proper processing of events with new dynamic process rules. 106412027Sjungma@eit.uni-kl.de// (2) Recoding of kill_process(), throw_user() and reset support to 106512027Sjungma@eit.uni-kl.de// consolidate preemptive thread execution in sc_simcontext::preempt_with(). 106612027Sjungma@eit.uni-kl.de// 106712027Sjungma@eit.uni-kl.de// Revision 1.12 2011/01/25 20:50:37 acg 106812027Sjungma@eit.uni-kl.de// Andy Goodrich: changes for IEEE 1666 2011. 106912027Sjungma@eit.uni-kl.de// 107012027Sjungma@eit.uni-kl.de// Revision 1.11 2011/01/20 16:52:20 acg 107112027Sjungma@eit.uni-kl.de// Andy Goodrich: changes for IEEE 1666 2011. 107212027Sjungma@eit.uni-kl.de// 107312027Sjungma@eit.uni-kl.de// Revision 1.10 2011/01/19 23:21:50 acg 107412027Sjungma@eit.uni-kl.de// Andy Goodrich: changes for IEEE 1666 2011 107512027Sjungma@eit.uni-kl.de// 107612027Sjungma@eit.uni-kl.de// Revision 1.9 2011/01/18 20:10:45 acg 107712027Sjungma@eit.uni-kl.de// Andy Goodrich: changes for IEEE1666_2011 semantics. 107812027Sjungma@eit.uni-kl.de// 107912027Sjungma@eit.uni-kl.de// Revision 1.8 2011/01/06 18:02:16 acg 108012027Sjungma@eit.uni-kl.de// Andy Goodrich: added check for disabled thread to trigger_dynamic(). 108112027Sjungma@eit.uni-kl.de// 108212027Sjungma@eit.uni-kl.de// Revision 1.7 2010/11/20 17:10:57 acg 108312027Sjungma@eit.uni-kl.de// Andy Goodrich: reset processing changes for new IEEE 1666 standard. 108412027Sjungma@eit.uni-kl.de// 108512027Sjungma@eit.uni-kl.de// Revision 1.6 2010/07/22 20:02:33 acg 108612027Sjungma@eit.uni-kl.de// Andy Goodrich: bug fixes. 108712027Sjungma@eit.uni-kl.de// 108812027Sjungma@eit.uni-kl.de// Revision 1.5 2009/07/28 01:10:53 acg 108912027Sjungma@eit.uni-kl.de// Andy Goodrich: updates for 2.3 release candidate. 109012027Sjungma@eit.uni-kl.de// 109112027Sjungma@eit.uni-kl.de// Revision 1.4 2009/05/22 16:06:29 acg 109212027Sjungma@eit.uni-kl.de// Andy Goodrich: process control updates. 109312027Sjungma@eit.uni-kl.de// 109412027Sjungma@eit.uni-kl.de// Revision 1.3 2008/05/22 17:06:06 acg 109512027Sjungma@eit.uni-kl.de// Andy Goodrich: formatting and comments. 109612027Sjungma@eit.uni-kl.de// 109712027Sjungma@eit.uni-kl.de// Revision 1.2 2007/09/20 20:32:35 acg 109812027Sjungma@eit.uni-kl.de// Andy Goodrich: changes to the semantics of throw_it() to match the 109912027Sjungma@eit.uni-kl.de// specification. A call to throw_it() will immediately suspend the calling 110012027Sjungma@eit.uni-kl.de// thread until all the throwees have executed. At that point the calling 110112027Sjungma@eit.uni-kl.de// thread will be restarted before the execution of any other threads. 110212027Sjungma@eit.uni-kl.de// 110312027Sjungma@eit.uni-kl.de// Revision 1.1.1.1 2006/12/15 20:20:05 acg 110412027Sjungma@eit.uni-kl.de// SystemC 2.3 110512027Sjungma@eit.uni-kl.de// 110612027Sjungma@eit.uni-kl.de// Revision 1.8 2006/04/20 17:08:17 acg 110712027Sjungma@eit.uni-kl.de// Andy Goodrich: 3.0 style process changes. 110812027Sjungma@eit.uni-kl.de// 110912027Sjungma@eit.uni-kl.de// Revision 1.7 2006/04/11 23:13:21 acg 111012027Sjungma@eit.uni-kl.de// Andy Goodrich: Changes for reduced reset support that only includes 111112027Sjungma@eit.uni-kl.de// sc_cthread, but has preliminary hooks for expanding to method and thread 111212027Sjungma@eit.uni-kl.de// processes also. 111312027Sjungma@eit.uni-kl.de// 111412027Sjungma@eit.uni-kl.de// Revision 1.6 2006/03/21 00:00:34 acg 111512027Sjungma@eit.uni-kl.de// Andy Goodrich: changed name of sc_get_current_process_base() to be 111612027Sjungma@eit.uni-kl.de// sc_get_current_process_b() since its returning an sc_process_b instance. 111712027Sjungma@eit.uni-kl.de// 111812027Sjungma@eit.uni-kl.de// Revision 1.5 2006/01/26 21:04:55 acg 111912027Sjungma@eit.uni-kl.de// Andy Goodrich: deprecation message changes and additional messages. 112012027Sjungma@eit.uni-kl.de// 112112027Sjungma@eit.uni-kl.de// Revision 1.4 2006/01/24 20:49:05 acg 112212027Sjungma@eit.uni-kl.de// Andy Goodrich: changes to remove the use of deprecated features within the 112312027Sjungma@eit.uni-kl.de// simulator, and to issue warning messages when deprecated features are used. 112412027Sjungma@eit.uni-kl.de// 112512027Sjungma@eit.uni-kl.de// Revision 1.3 2006/01/13 18:44:30 acg 112612027Sjungma@eit.uni-kl.de// Added $Log to record CVS changes into the source. 112712027Sjungma@eit.uni-kl.de// 1128