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