From 26dcecebdb2622147c5ff0488c0dde1e41414eaf Mon Sep 17 00:00:00 2001 From: steve Date: Fri, 31 Mar 2000 07:08:39 +0000 Subject: [PATCH] allow cancelling of cbValueChange events. --- vpi/sys_display.c | 15 ++++++++++-- vvm/vpi_callback.c | 58 ++++++++++++++++++++++++++++++++-------------- vvm/vpi_priv.h | 12 ++++++++-- vvm/vpi_signal.c | 11 ++++++--- 4 files changed, 72 insertions(+), 24 deletions(-) diff --git a/vpi/sys_display.c b/vpi/sys_display.c index 24de467ca..243d25b41 100644 --- a/vpi/sys_display.c +++ b/vpi/sys_display.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: sys_display.c,v 1.11 2000/02/23 02:56:56 steve Exp $" +#ident "$Id: sys_display.c,v 1.12 2000/03/31 07:08:39 steve Exp $" #endif # include "vpi_user.h" @@ -300,11 +300,14 @@ static int monitor_cb_1(p_cb_data cause) { struct t_cb_data cb; struct t_vpi_time time; + /* The user_data of the callback is a pointer to the callback + handle. I use this to reschedule the callback if needed. */ + vpiHandle*cbh = (vpiHandle*) (cause->user_data); /* Reschedule this event so that it happens for the next trigger on this variable. */ cb = *cause; - vpi_register_cb(&cb); + *cbh = vpi_register_cb(&cb); if (monitor_scheduled) return 0; @@ -363,6 +366,11 @@ static int sys_monitor_calltf(char*name) switch (vpi_get(vpiType, monitor_info.items[idx])) { case vpiNet: case vpiReg: + /* Monitoring reg and net values involves setting + a collback for value changes. pass the storage + pointer for the callback itself as user_data so + that the callback can refresh itself. */ + cb.user_data = (char*)(monitor_callbacks+idx); cb.obj = monitor_info.items[idx]; monitor_callbacks[idx] = vpi_register_cb(&cb); break; @@ -413,6 +421,9 @@ void sys_display_register() /* * $Log: sys_display.c,v $ + * Revision 1.12 2000/03/31 07:08:39 steve + * allow cancelling of cbValueChange events. + * * Revision 1.11 2000/02/23 02:56:56 steve * Macintosh compilers do not support ident. * diff --git a/vvm/vpi_callback.c b/vvm/vpi_callback.c index befbd7a55..1b47a5778 100644 --- a/vvm/vpi_callback.c +++ b/vvm/vpi_callback.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: vpi_callback.c,v 1.6 2000/02/23 02:56:56 steve Exp $" +#ident "$Id: vpi_callback.c,v 1.7 2000/03/31 07:08:39 steve Exp $" #endif # include "vpi_priv.h" @@ -69,20 +69,15 @@ static void vpip_call_callback(void*cp) void vpip_run_value_changes(struct __vpiSignal*sig) { struct __vpiCallback*cur; - if (sig->monitor == 0) return; - - while (sig->monitor->next != sig->monitor) { - cur = sig->monitor->next; - sig->monitor->next = cur->next; + while (sig->mfirst) { + cur = sig->mfirst; + sig->mfirst = cur->next; + if (sig->mfirst == 0) + sig->mlast = 0; cur->next = 0; cur->ev = vpip_sim_insert_event(0, cur, vpip_call_callback, 0); } - - cur = sig->monitor; - sig->monitor = 0; - cur->next = 0; - cur->ev = vpip_sim_insert_event(0, cur, vpip_call_callback, 0); } /* @@ -110,18 +105,21 @@ static void go_value_change(struct __vpiCallback*rfp) assert((sig->base.vpi_type->type_code == vpiReg) || (sig->base.vpi_type->type_code == vpiNet)); + /* If there are no monitor events, start the list. */ - if (sig->monitor == 0) { - rfp->next = rfp; - sig->monitor = rfp; + if (sig->mfirst == 0) { + rfp->sig = sig; + rfp->next = 0; + sig->mfirst = rfp; + sig->mlast = rfp; return; } /* Put me at the end of the list. Remember that the monitor points to the *last* item in the list. */ - rfp->next = sig->monitor->next; - sig->monitor->next = rfp; - sig->monitor = rfp; + rfp->sig = sig; + rfp->next = 0; + sig->mlast->next = rfp; } /* @@ -157,9 +155,32 @@ int vpi_remove_cb(vpiHandle ref) assert(ref->vpi_type->type_code == vpiCallback); if (rfp->ev) { + /* callbacks attached to events are easy. */ vpip_sim_cancel_event(rfp->ev); + } else if (rfp->sig) { + + /* callbacks to signals need to be removed from the + signal's list of monitor callbacks. */ + struct __vpiSignal*sig = rfp->sig; + + if (sig->mfirst == rfp) { + sig->mfirst = rfp->next; + if (sig->mfirst == 0) + sig->mlast = 0; + rfp->next = 0; + rfp->sig = 0; + } else { + struct __vpiCallback*cur = sig->mfirst; + while (cur->next != rfp) { + assert(cur->next); + cur = cur->next; + } + cur->next = rfp->next; + if (cur->next == 0) + sig->mlast = cur; + } } else { assert(0); } @@ -170,6 +191,9 @@ int vpi_remove_cb(vpiHandle ref) /* * $Log: vpi_callback.c,v $ + * Revision 1.7 2000/03/31 07:08:39 steve + * allow cancelling of cbValueChange events. + * * Revision 1.6 2000/02/23 02:56:56 steve * Macintosh compilers do not support ident. * diff --git a/vvm/vpi_priv.h b/vvm/vpi_priv.h index f766d4910..70dd8b8bc 100644 --- a/vvm/vpi_priv.h +++ b/vvm/vpi_priv.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: vpi_priv.h,v 1.13 2000/03/25 05:02:24 steve Exp $" +#ident "$Id: vpi_priv.h,v 1.14 2000/03/31 07:08:39 steve Exp $" #endif /* @@ -127,7 +127,11 @@ struct __vpiCallback { struct __vpiHandle base; struct t_cb_data cb_data; + /* Set this value if I'm pending in the event queue. */ struct vpip_event*ev; + /* Set this value if I'm waiting for a value change on a signal*/ + struct __vpiSignal*sig; + struct __vpiCallback*next; }; @@ -205,7 +209,8 @@ struct __vpiSignal { vpip_bit_t*bits; unsigned nbits; /* monitors are added here. */ - struct __vpiCallback*monitor; + struct __vpiCallback*mfirst; + struct __vpiCallback*mlast; }; @@ -337,6 +342,9 @@ extern int vpip_finished(); /* * $Log: vpi_priv.h,v $ + * Revision 1.14 2000/03/31 07:08:39 steve + * allow cancelling of cbValueChange events. + * * Revision 1.13 2000/03/25 05:02:24 steve * signal bits are referenced at run time by the vpiSignal struct. * diff --git a/vvm/vpi_signal.c b/vvm/vpi_signal.c index c9a95e20a..c52a83634 100644 --- a/vvm/vpi_signal.c +++ b/vvm/vpi_signal.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: vpi_signal.c,v 1.8 2000/03/25 05:02:25 steve Exp $" +#ident "$Id: vpi_signal.c,v 1.9 2000/03/31 07:08:39 steve Exp $" #endif # include "vpi_priv.h" @@ -82,7 +82,8 @@ vpiHandle vpip_make_net(struct __vpiSignal*ref, const char*name, ref->name = name; ref->bits = b; ref->nbits = nb; - ref->monitor = 0; + ref->mfirst = 0; + ref->mlast = 0; return &(ref->base); } @@ -103,12 +104,16 @@ vpiHandle vpip_make_reg(struct __vpiSignal*ref, const char*name, ref->name = name; ref->bits = b; ref->nbits = nb; - ref->monitor = 0; + ref->mfirst = 0; + ref->mlast = 0; return &(ref->base); } /* * $Log: vpi_signal.c,v $ + * Revision 1.9 2000/03/31 07:08:39 steve + * allow cancelling of cbValueChange events. + * * Revision 1.8 2000/03/25 05:02:25 steve * signal bits are referenced at run time by the vpiSignal struct. *