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