diff --git a/vvp/schedule.cc b/vvp/schedule.cc index 78920dee9..961aa36e6 100644 --- a/vvp/schedule.cc +++ b/vvp/schedule.cc @@ -855,6 +855,7 @@ void schedule_final_vthread(vthread_t thr) struct vthread_event_s*cur = new vthread_event_s; cur->thr = thr; + vthread_mark_final(thr); vthread_mark_scheduled(thr); schedule_final_event(cur); diff --git a/vvp/vthread.cc b/vvp/vthread.cc index 2b35315b0..02c7c179d 100644 --- a/vvp/vthread.cc +++ b/vvp/vthread.cc @@ -833,6 +833,19 @@ void vthread_mark_scheduled(vthread_t thr) } } +void vthread_mark_final(vthread_t thr) +{ + /* + * The behavior in a final thread is the same as in a function. Any + * child thread will be executed immediately rather than being + * scheduled. + */ + while (thr != 0) { + thr->i_am_in_function = 1; + thr = thr->wait_next; + } +} + void vthread_delay_delete() { if (running_thread) diff --git a/vvp/vthread.h b/vvp/vthread.h index 75d7929c8..1658c6839 100644 --- a/vvp/vthread.h +++ b/vvp/vthread.h @@ -51,6 +51,11 @@ extern vthread_t vthread_new(vvp_code_t sa, __vpiScope*scope); */ extern void vthread_mark_scheduled(vthread_t thr); +/* + * This function marks the thread as being a final procedure. + */ +extern void vthread_mark_final(vthread_t thr); + /* * This function causes deletion of the currently running thread to * be delayed until after all sync events have been processed for the