1 /*****************************************************************************
2 
3   Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
4   more contributor license agreements.  See the NOTICE file distributed
5   with this work for additional information regarding copyright ownership.
6   Accellera licenses this file to you under the Apache License, Version 2.0
7   (the "License"); you may not use this file except in compliance with the
8   License.  You may obtain a copy of the License at
9 
10     http://www.apache.org/licenses/LICENSE-2.0
11 
12   Unless required by applicable law or agreed to in writing, software
13   distributed under the License is distributed on an "AS IS" BASIS,
14   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
15   implied.  See the License for the specific language governing
16   permissions and limitations under the License.
17 
18  *****************************************************************************/
19 
20 /*****************************************************************************
21 
22   sc_event.cpp --
23 
24   Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
25 
26  CHANGE LOG APPEARS AT THE END OF THE FILE
27  *****************************************************************************/
28 
29 #include <cstdlib>
30 #include <cstring>
31 
32 #include "sysc/kernel/sc_event.h"
33 #include "sysc/kernel/sc_kernel_ids.h"
34 #include "sysc/kernel/sc_phase_callback_registry.h"
35 #include "sysc/kernel/sc_process.h"
36 #include "sysc/kernel/sc_process_handle.h"
37 #include "sysc/kernel/sc_simcontext_int.h"
38 #include "sysc/kernel/sc_object_manager.h"
39 #include "sysc/utils/sc_utils_ids.h"
40 
41 #include <sstream>
42 
43 namespace sc_core {
44 
45 using std::malloc;
46 using std::strrchr;
47 using std::strncmp;
48 
49 // ----------------------------------------------------------------------------
50 //  CLASS : sc_event
51 //
52 //  The event class.
53 // ----------------------------------------------------------------------------
54 
55 // kernel-internal event, that is never notified
56 const sc_event sc_event::none( kernel_event, "none" );
57 
58 const char*
basename() const59 sc_event::basename() const
60 {
61     const char* p = strrchr( m_name.c_str(), SC_HIERARCHY_CHAR );
62     return p ? (p + 1) : m_name.c_str();
63 }
64 
65 void
cancel()66 sc_event::cancel()
67 {
68     // cancel a delta or timed notification
69     switch( m_notify_type ) {
70     case DELTA: {
71         // remove this event from the delta events set
72         m_simc->remove_delta_event( this );
73         m_notify_type = NONE;
74         break;
75     }
76     case TIMED: {
77         // remove this event from the timed events set
78         sc_assert( m_timed != 0 );
79         m_timed->m_event = 0;
80         m_timed = 0;
81         m_notify_type = NONE;
82         break;
83     }
84     default:
85         ;
86     }
87 }
88 
89 
90 void
notify()91 sc_event::notify()
92 {
93     // immediate notification
94     if( !m_simc->evaluation_phase() )
95         // coming from
96         //  * elaboration
97         //  * sc_prim_channel::update
98         //  * phase callbacks
99     {
100         SC_REPORT_ERROR( SC_ID_IMMEDIATE_NOTIFICATION_, "" );
101         return;
102     }
103     cancel();
104     trigger();
105 }
106 
107 void
notify(const sc_time & t)108 sc_event::notify( const sc_time& t )
109 {
110     if( m_notify_type == DELTA ) {
111         return;
112     }
113     if( t == SC_ZERO_TIME ) {
114 #       if SC_HAS_PHASE_CALLBACKS_
115             if( SC_UNLIKELY_( m_simc->get_status()
116                               & (SC_END_OF_UPDATE|SC_BEFORE_TIMESTEP) ) )
117             {
118                 std::stringstream msg;
119                 msg << m_simc->get_status()
120                     << ":\n\t delta notification of `"
121                     << name() << "' ignored";
122                 SC_REPORT_WARNING( SC_ID_PHASE_CALLBACK_FORBIDDEN_
123                                  , msg.str().c_str() );
124                 return;
125             }
126 #       endif
127         if( m_notify_type == TIMED ) {
128             // remove this event from the timed events set
129             sc_assert( m_timed != 0 );
130             m_timed->m_event = 0;
131             m_timed = 0;
132         }
133         // add this event to the delta events set
134         m_delta_event_index = m_simc->add_delta_event( this );
135         m_notify_type = DELTA;
136         return;
137     }
138 #   if SC_HAS_PHASE_CALLBACKS_
139         if( SC_UNLIKELY_( m_simc->get_status()
140                         & (SC_END_OF_UPDATE|SC_BEFORE_TIMESTEP) ) )
141         {
142             std::stringstream msg;
143             msg << m_simc->get_status()
144                 << ":\n\t timed notification of `"
145                 << name() << "' ignored";
146             SC_REPORT_WARNING( SC_ID_PHASE_CALLBACK_FORBIDDEN_
147                              , msg.str().c_str() );
148             return;
149         }
150 #   endif
151     if( m_notify_type == TIMED ) {
152         sc_assert( m_timed != 0 );
153         if( m_timed->m_notify_time <= m_simc->time_stamp() + t ) {
154             return;
155         }
156         // remove this event from the timed events set
157         m_timed->m_event = 0;
158         m_timed = 0;
159     }
160     // add this event to the timed events set
161     sc_event_timed* et = new sc_event_timed( this, m_simc->time_stamp() + t );
162     m_simc->add_timed_event( et );
163     m_timed = et;
164     m_notify_type = TIMED;
165 }
166 
sc_warn_notify_delayed()167 static void sc_warn_notify_delayed()
168 {
169     static bool warn_notify_delayed=true;
170     if ( warn_notify_delayed )
171     {
172         warn_notify_delayed = false;
173         SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
174       "notify_delayed(...) is deprecated, use notify(sc_time) instead" );
175     }
176 }
177 
178 void
notify_delayed()179 sc_event::notify_delayed()
180 {
181     sc_warn_notify_delayed();
182     if( m_notify_type != NONE ) {
183         SC_REPORT_ERROR( SC_ID_NOTIFY_DELAYED_, 0 );
184     }
185     // add this event to the delta events set
186     m_delta_event_index = m_simc->add_delta_event( this );
187     m_notify_type = DELTA;
188 }
189 
190 void
notify_delayed(const sc_time & t)191 sc_event::notify_delayed( const sc_time& t )
192 {
193     sc_warn_notify_delayed();
194     if( m_notify_type != NONE ) {
195         SC_REPORT_ERROR( SC_ID_NOTIFY_DELAYED_, 0 );
196     }
197     if( t == SC_ZERO_TIME ) {
198         // add this event to the delta events set
199         m_delta_event_index = m_simc->add_delta_event( this );
200         m_notify_type = DELTA;
201     } else {
202         // add this event to the timed events set
203         sc_event_timed* et = new sc_event_timed( this,
204                                                  m_simc->time_stamp() + t );
205         m_simc->add_timed_event( et );
206         m_timed = et;
207         m_notify_type = TIMED;
208     }
209 }
210 
211 #define SC_KERNEL_EVENT_PREFIX "$$$$kernel_event$$$$_"
212 sc_event::kernel_tag sc_event::kernel_event;
213 
214 // +----------------------------------------------------------------------------
215 // |"sc_event::register_event"
216 // |
217 // | This method sets the name of this object instance and optionally adds
218 // | it to the object manager's hierarchy. The object instance will be
219 // | inserted into the object manager's hierarchy if one of the following is
220 // | true:
221 // |   (a) the leaf name is non-null and is_kernel_event == false
222 // |   (b) the event is being created before the start of simulation.
223 // |
224 // | Arguments:
225 // |     leaf_name = leaf name of the object or NULL.
226 // +----------------------------------------------------------------------------
227 void
register_event(const char * leaf_name,bool is_kernel_event)228 sc_event::register_event( const char* leaf_name, bool is_kernel_event /* = false */ )
229 {
230     sc_object_manager* object_manager = m_simc->get_object_manager();
231     m_parent_p = m_simc->active_object();
232 
233     // No name provided, if we are not executing then create a name:
234 
235     if( !leaf_name || !leaf_name[0] )
236     {
237         if ( sc_is_running( m_simc ) ) return;
238         leaf_name = sc_gen_unique_name
239             ( is_kernel_event ? SC_KERNEL_EVENT_PREFIX : "event" );
240     }
241 
242     // prepend kernel events with internal prefix
243     else if ( is_kernel_event )
244     {
245         m_name = SC_KERNEL_EVENT_PREFIX;
246         m_name.append( leaf_name );
247         leaf_name = m_name.c_str();
248     }
249 
250     // Create a hierarchichal name and place it into the object manager if
251     // its not a kernel event:
252 
253     object_manager->create_name( leaf_name ).swap( m_name );
254 
255     if ( !is_kernel_event )
256     {
257 	object_manager->insert_event(m_name, this);
258 	if ( m_parent_p )
259 	    m_parent_p->add_child_event( this );
260 	else
261 	    m_simc->add_child_event( this );
262     }
263 }
264 
265 void
reset()266 sc_event::reset()
267 {
268     m_notify_type = NONE;
269     m_delta_event_index = -1;
270     m_timed = 0;
271     // clear the dynamic sensitive methods
272     m_methods_dynamic.resize(0);
273     // clear the dynamic sensitive threads
274     m_threads_dynamic.resize(0);
275 }
276 
277 // +----------------------------------------------------------------------------
278 // |"sc_event::sc_event(name)"
279 // |
280 // | This is the object instance constructor for named sc_event instances.
281 // | If the name is non-null or this is during elaboration add the
282 // | event to the object hierarchy.
283 // |
284 // | Arguments:
285 // |     name = name of the event.
286 // +----------------------------------------------------------------------------
sc_event(const char * name)287 sc_event::sc_event( const char* name ) :
288     m_name(),
289     m_parent_p(NULL),
290     m_simc( sc_get_curr_simcontext() ),
291     m_trigger_stamp( ~sc_dt::UINT64_ZERO ),
292     m_notify_type( NONE ),
293     m_delta_event_index( -1 ),
294     m_timed( 0 ),
295     m_methods_static(),
296     m_methods_dynamic(),
297     m_threads_static(),
298     m_threads_dynamic()
299 {
300     register_event( name );
301 }
302 
303 // +----------------------------------------------------------------------------
304 // |"sc_event::sc_event()"
305 // |
306 // | This is the object instance constructor for non-named sc_event instances.
307 // | If this is during elaboration create a name and add it to the object
308 // | hierarchy.
309 // +----------------------------------------------------------------------------
sc_event()310 sc_event::sc_event() :
311     m_name(),
312     m_parent_p(NULL),
313     m_simc( sc_get_curr_simcontext() ),
314     m_trigger_stamp( ~sc_dt::UINT64_ZERO ),
315     m_notify_type( NONE ),
316     m_delta_event_index( -1 ),
317     m_timed( 0 ),
318     m_methods_static(),
319     m_methods_dynamic(),
320     m_threads_static(),
321     m_threads_dynamic()
322 {
323     register_event( NULL );
324 }
325 
326 // +----------------------------------------------------------------------------
327 // |"sc_event::sc_event(kernel_event, name)"
328 // |
329 // | This is the object instance constructor for kernel sc_event instances.
330 // | If this is during elaboration create an implementation-defined name and
331 // | do NOT add it to the object hierarchy.
332 // +----------------------------------------------------------------------------
sc_event(kernel_tag,const char * name)333 sc_event::sc_event( kernel_tag, const char* name ) :
334     m_name(),
335     m_parent_p(NULL),
336     m_simc( sc_get_curr_simcontext() ),
337     m_trigger_stamp( ~sc_dt::UINT64_ZERO ),
338     m_notify_type( NONE ),
339     m_delta_event_index( -1 ),
340     m_timed( 0 ),
341     m_methods_static(),
342     m_methods_dynamic(),
343     m_threads_static(),
344     m_threads_dynamic()
345 {
346     register_event( name, /* is_kernel_event = */ true );
347 }
348 
349 // +----------------------------------------------------------------------------
350 // |"sc_event::~sc_event"
351 // |
352 // | This is the object instance destructor for this class. It cancels any
353 // | outstanding waits and removes the event from the object manager's
354 // | instance table if it has a name.
355 // +----------------------------------------------------------------------------
~sc_event()356 sc_event::~sc_event()
357 {
358     cancel();
359     if ( m_name.length() != 0 )
360     {
361 	sc_object_manager* object_manager_p = m_simc->get_object_manager();
362 	object_manager_p->remove_event( m_name );
363     }
364 
365     for(size_t i = 0; i < m_threads_dynamic.size(); ++i ) {
366         if( m_threads_dynamic[i]->m_event_p == this )
367             m_threads_dynamic[i]->m_event_p = 0;
368     }
369     for(size_t i = 0; i < m_methods_dynamic.size(); ++i ) {
370         if( m_methods_dynamic[i]->m_event_p == this )
371             m_methods_dynamic[i]->m_event_p = 0;
372     }
373 }
374 
375 // +----------------------------------------------------------------------------
376 // |"sc_event::trigger"
377 // |
378 // | This method "triggers" this object instance. This consists of scheduling
379 // | for execution all the processes that are schedulable and waiting on this
380 // | event.
381 // +----------------------------------------------------------------------------
382 void
trigger()383 sc_event::trigger()
384 {
385     m_trigger_stamp = m_simc->change_stamp();
386     m_notify_type = NONE;
387     m_delta_event_index = -1;
388     m_timed = 0;
389 
390     int       last_i; // index of last element in vector now accessing.
391     int       size;   // size of vector now accessing.
392 
393 
394     // trigger the static sensitive methods
395 
396     if( ( size = m_methods_static.size() ) != 0 )
397     {
398         sc_method_handle* l_methods_static = &m_methods_static[0];
399         int i = size - 1;
400         do {
401             sc_method_handle method_h = l_methods_static[i];
402             method_h->trigger_static();
403         } while( -- i >= 0 );
404     }
405 
406     // trigger the dynamic sensitive methods
407 
408 
409     if( ( size = m_methods_dynamic.size() ) != 0 )
410     {
411 	last_i = size - 1;
412 	sc_method_handle* l_methods_dynamic = &m_methods_dynamic[0];
413 	for ( int i = 0; i <= last_i; i++ )
414 	{
415 	    sc_method_handle method_h = l_methods_dynamic[i];
416 	    if ( method_h->trigger_dynamic( this ) )
417 	    {
418 		l_methods_dynamic[i] = l_methods_dynamic[last_i];
419 		last_i--;
420 		i--;
421 	    }
422 	}
423         m_methods_dynamic.resize(last_i+1);
424     }
425 
426 
427     // trigger the static sensitive threads
428 
429     if( ( size = m_threads_static.size() ) != 0 )
430     {
431         sc_thread_handle* l_threads_static = &m_threads_static[0];
432         int i = size - 1;
433         do {
434             sc_thread_handle thread_h = l_threads_static[i];
435             thread_h->trigger_static();
436         } while( -- i >= 0 );
437     }
438 
439     // trigger the dynamic sensitive threads
440 
441     if( ( size = m_threads_dynamic.size() ) != 0 )
442     {
443 	last_i = size - 1;
444 	sc_thread_handle* l_threads_dynamic = &m_threads_dynamic[0];
445 	for ( int i = 0; i <= last_i; i++ )
446 	{
447 	    sc_thread_handle thread_h = l_threads_dynamic[i];
448 	    if ( thread_h->trigger_dynamic( this ) )
449 	    {
450 		l_threads_dynamic[i] = l_threads_dynamic[last_i];
451 		i--;
452 		last_i--;
453 	    }
454 	}
455         m_threads_dynamic.resize(last_i+1);
456     }
457 }
458 
triggered() const459 bool sc_event::triggered() const
460 {
461     return m_trigger_stamp == m_simc->change_stamp();
462 }
463 
464 bool
remove_static(sc_method_handle method_h_) const465 sc_event::remove_static( sc_method_handle method_h_ ) const
466 {
467     int size;
468     if ( ( size = m_methods_static.size() ) != 0 ) {
469       sc_method_handle* l_methods_static = &m_methods_static[0];
470       for( int i = size - 1; i >= 0; -- i ) {
471           if( l_methods_static[i] == method_h_ ) {
472               l_methods_static[i] = l_methods_static[size - 1];
473               m_methods_static.resize(size-1);
474               return true;
475           }
476       }
477     }
478     return false;
479 }
480 
481 bool
remove_static(sc_thread_handle thread_h_) const482 sc_event::remove_static( sc_thread_handle thread_h_ ) const
483 {
484     int size;
485     if ( ( size = m_threads_static.size() ) != 0 ) {
486       sc_thread_handle* l_threads_static = &m_threads_static[0];
487       for( int i = size - 1; i >= 0; -- i ) {
488           if( l_threads_static[i] == thread_h_ ) {
489               l_threads_static[i] = l_threads_static[size - 1];
490               m_threads_static.resize(size-1);
491               return true;
492           }
493       }
494     }
495     return false;
496 }
497 
498 bool
remove_dynamic(sc_method_handle method_h_) const499 sc_event::remove_dynamic( sc_method_handle method_h_ ) const
500 {
501     int size;
502     if ( ( size = m_methods_dynamic.size() ) != 0 ) {
503       sc_method_handle* l_methods_dynamic = &m_methods_dynamic[0];
504       for( int i = size - 1; i >= 0; -- i ) {
505           if( l_methods_dynamic[i] == method_h_ ) {
506               l_methods_dynamic[i] = l_methods_dynamic[size - 1];
507               m_methods_dynamic.resize(size-1);
508               return true;
509           }
510       }
511     }
512     return false;
513 }
514 
515 bool
remove_dynamic(sc_thread_handle thread_h_) const516 sc_event::remove_dynamic( sc_thread_handle thread_h_ ) const
517 {
518     int size;
519     if ( ( size= m_threads_dynamic.size() ) != 0 ) {
520       sc_thread_handle* l_threads_dynamic = &m_threads_dynamic[0];
521       for( int i = size - 1; i >= 0; -- i ) {
522           if( l_threads_dynamic[i] == thread_h_ ) {
523               l_threads_dynamic[i] = l_threads_dynamic[size - 1];
524               m_threads_dynamic.resize(size-1);
525               return true;
526           }
527       }
528     }
529     return false;
530 }
531 
532 
533 // ----------------------------------------------------------------------------
534 //  CLASS : sc_event_timed
535 //
536 //  Class for storing the time to notify a timed event.
537 // ----------------------------------------------------------------------------
538 
539 // dedicated memory management; not MT-Safe
540 
541 union sc_event_timed_u
542 {
543     sc_event_timed_u* next;
544     char              dummy[sizeof( sc_event_timed )];
545 };
546 
547 static
548 sc_event_timed_u* free_list = 0;
549 
550 void*
allocate()551 sc_event_timed::allocate()
552 {
553     const int ALLOC_SIZE = 64;
554 
555     if( free_list == 0 ) {
556         free_list = (sc_event_timed_u*) malloc( ALLOC_SIZE *
557                                                 sizeof( sc_event_timed_u ) );
558         int i = 0;
559         for( ; i < ALLOC_SIZE - 1; ++ i ) {
560             free_list[i].next = &free_list[i + 1];
561         }
562         free_list[i].next = 0;
563     }
564 
565     sc_event_timed_u* q = free_list;
566     free_list = free_list->next;
567     return q;
568 }
569 
570 void
deallocate(void * p)571 sc_event_timed::deallocate( void* p )
572 {
573     if( p != 0 ) {
574         sc_event_timed_u* q = reinterpret_cast<sc_event_timed_u*>( p );
575         q->next = free_list;
576         free_list = q;
577     }
578 }
579 
580 
581 // ----------------------------------------------------------------------------
582 //  CLASS : sc_event_list
583 //
584 //  Base class for lists of events.
585 // ----------------------------------------------------------------------------
586 
587 void
push_back(const sc_event & e)588 sc_event_list::push_back( const sc_event& e )
589 {
590     // make sure e is not already in the list
591     if ( m_events.size() != 0 ) {
592       const sc_event** l_events = &m_events[0];
593       for( int i = m_events.size() - 1; i >= 0; -- i ) {
594           if( &e == l_events[i] ) {
595               // event already in the list; ignore
596               return;
597           }
598       }
599     }
600     m_events.push_back( &e );
601 }
602 
603 void
push_back(const sc_event_list & el)604 sc_event_list::push_back( const sc_event_list& el )
605 {
606     m_events.reserve( size() + el.size() );
607     for ( int i = el.m_events.size() - 1; i >= 0; --i )
608     {
609         push_back( *el.m_events[i] );
610     }
611     el.auto_delete();
612 }
613 
614 void
add_dynamic(sc_method_handle method_h) const615 sc_event_list::add_dynamic( sc_method_handle method_h ) const
616 {
617     m_busy++;
618     if ( m_events.size() != 0 ) {
619       const sc_event* const * l_events = &m_events[0];
620       for( int i = m_events.size() - 1; i >= 0; -- i ) {
621           l_events[i]->add_dynamic( method_h );
622       }
623   }
624 }
625 
626 void
add_dynamic(sc_thread_handle thread_h) const627 sc_event_list::add_dynamic( sc_thread_handle thread_h ) const
628 {
629     m_busy++;
630     if ( m_events.size() != 0 ) {
631       const sc_event* const* l_events = &m_events[0];
632       for( int i = m_events.size() - 1; i >= 0; -- i ) {
633           l_events[i]->add_dynamic( thread_h );
634       }
635   }
636 }
637 
638 void
remove_dynamic(sc_method_handle method_h,const sc_event * e_not) const639 sc_event_list::remove_dynamic( sc_method_handle method_h,
640                                const sc_event* e_not ) const
641 {
642     if ( m_events.size() != 0 ) {
643       const sc_event* const* l_events = &m_events[0];
644       for( int i = m_events.size() - 1; i >= 0; -- i ) {
645           const sc_event* e = l_events[i];
646           if( e != e_not ) {
647               e->remove_dynamic( method_h );
648           }
649       }
650   }
651 }
652 
653 void
remove_dynamic(sc_thread_handle thread_h,const sc_event * e_not) const654 sc_event_list::remove_dynamic( sc_thread_handle thread_h,
655                                const sc_event* e_not ) const
656 {
657     if ( m_events.size() != 0 ) {
658       const sc_event* const* l_events = &m_events[0];
659       for( int i = m_events.size() - 1; i >= 0; -- i ) {
660           const sc_event* e = l_events[i];
661           if( e != e_not ) {
662               e->remove_dynamic( thread_h );
663           }
664       }
665   }
666 }
667 
668 void
report_premature_destruction() const669 sc_event_list::report_premature_destruction() const
670 {
671     // TDB: reliably detect premature destruction
672     //
673     // If an event list is used as a member of a module,
674     // its lifetime may (correctly) end, although there
675     // are processes currently waiting for it.
676     //
677     // Detecting (and ignoring) this corner-case is quite
678     // difficult for similar reasons to the sc_is_running()
679     // return value during the destruction of the module
680     // hierarchy.
681     //
682     // Ignoring the lifetime checks for now, if no process
683     // is currently running (which is only part of the story):
684 
685     if( sc_get_current_process_handle().valid() ) {
686         // called from a destructor, can't throw
687         SC_REPORT_FATAL( SC_ID_EVENT_LIST_FAILED_
688                        , "list prematurely destroyed" );
689         sc_abort();
690     }
691 }
692 
693 void
report_invalid_modification() const694 sc_event_list::report_invalid_modification() const
695 {
696     SC_REPORT_ERROR( SC_ID_EVENT_LIST_FAILED_
697                    , "list modified while being waited on" );
698     // may continue, if suppressed
699 }
700 
701 // ----------------------------------------------------------------------------
702 //  Deprecated functional notation for notifying events.
703 // ----------------------------------------------------------------------------
704 
sc_warn_notify()705 static void sc_warn_notify()
706 {
707     static bool warn_notify=true;
708     if ( warn_notify )
709     {
710   SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
711       "the notify() function is deprecated use sc_event::notify()" );
712   warn_notify = false;
713     }
714 }
715 
716 void
notify(sc_event & e)717 notify( sc_event& e )
718 {
719     sc_warn_notify();
720     e.notify();
721 }
722 
723 void
notify(const sc_time & t,sc_event & e)724 notify( const sc_time& t, sc_event& e )
725 {
726     sc_warn_notify();
727     e.notify( t );
728 }
729 
730 void
notify(double v,sc_time_unit tu,sc_event & e)731 notify( double v, sc_time_unit tu, sc_event& e )
732 {
733     sc_warn_notify();
734     e.notify( v, tu );
735 }
736 
737 } // namespace sc_core
738 
739 // $Log: sc_event.cpp,v $
740 // Revision 1.17  2011/08/26 20:46:09  acg
741 //  Andy Goodrich: moved the modification log to the end of the file to
742 //  eliminate source line number skew when check-ins are done.
743 //
744 // Revision 1.16  2011/08/24 22:05:50  acg
745 //  Torsten Maehne: initialization changes to remove warnings.
746 //
747 // Revision 1.15  2011/03/12 21:07:51  acg
748 //  Andy Goodrich: changes to kernel generated event support.
749 //
750 // Revision 1.14  2011/03/06 15:55:52  acg
751 //  Andy Goodrich: changes for named events.
752 //
753 // Revision 1.13  2011/03/05 01:39:21  acg
754 //  Andy Goodrich: changes for named events.
755 //
756 // Revision 1.12  2011/02/19 08:33:25  acg
757 //  Andy Goodrich: remove }'s that should have been removed before.
758 //
759 // Revision 1.11  2011/02/19 08:30:53  acg
760 //  Andy Goodrich: Moved process queueing into trigger_static from
761 //  sc_event::notify.
762 //
763 // Revision 1.10  2011/02/18 20:27:14  acg
764 //  Andy Goodrich: Updated Copyrights.
765 //
766 // Revision 1.9  2011/02/17 19:49:51  acg
767 //  Andy Goodrich:
768 //    (1) Changed signature of trigger_dynamic() to return a bool again.
769 //    (2) Moved process run queue processing into trigger_dynamic().
770 //
771 // Revision 1.8  2011/02/16 22:37:30  acg
772 //  Andy Goodrich: clean up to remove need for ps_disable_pending.
773 //
774 // Revision 1.7  2011/02/13 21:47:37  acg
775 //  Andy Goodrich: update copyright notice.
776 //
777 // Revision 1.6  2011/02/01 21:02:28  acg
778 //  Andy Goodrich: new return code for trigger_dynamic() calls.
779 //
780 // Revision 1.5  2011/01/18 20:10:44  acg
781 //  Andy Goodrich: changes for IEEE1666_2011 semantics.
782 //
783 // Revision 1.4  2011/01/06 18:04:05  acg
784 //  Andy Goodrich: added code to leave disabled processes on the dynamic
785 //  method and thread queues.
786 //
787 // Revision 1.3  2008/05/22 17:06:25  acg
788 //  Andy Goodrich: updated copyright notice to include 2008.
789 //
790 // Revision 1.2  2007/01/17 22:44:30  acg
791 //  Andy Goodrich: fix for Microsoft compiler.
792 //
793 // Revision 1.7  2006/04/11 23:13:20  acg
794 //   Andy Goodrich: Changes for reduced reset support that only includes
795 //   sc_cthread, but has preliminary hooks for expanding to method and thread
796 //   processes also.
797 //
798 // Revision 1.6  2006/01/25 00:31:19  acg
799 //  Andy Goodrich: Changed over to use a standard message id of
800 //  SC_ID_IEEE_1666_DEPRECATION for all deprecation messages.
801 //
802 // Revision 1.5  2006/01/24 20:59:11  acg
803 //  Andy Goodrich: fix up of CVS comments, new version roll.
804 //
805 // Revision 1.4  2006/01/24 20:48:14  acg
806 // Andy Goodrich: added deprecation warnings for notify_delayed(). Added two
807 // new implementation-dependent methods, notify_next_delta() & notify_internal()
808 // to replace calls to notify_delayed() from within the simulator. These two
809 // new methods are simpler than notify_delayed() and should speed up simulations
810 //
811 // Revision 1.3  2006/01/13 18:44:29  acg
812 // Added $Log to record CVS changes into the source.
813 
814 // Taf!
815