From 13d7c07404985ac53f69002ea2fd9bee33a72a5c Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Thu, 28 Mar 2024 15:10:16 +0000 Subject: [PATCH] Simplify disabling VHPI callbacks --- src/rt/model.c | 71 ++++--------------------------------------- src/rt/model.h | 7 +---- src/vhpi/vhpi-model.c | 68 +++++++++++------------------------------ 3 files changed, 24 insertions(+), 122 deletions(-) diff --git a/src/rt/model.c b/src/rt/model.c index 5ec9cc25..dda24dab 100644 --- a/src/rt/model.c +++ b/src/rt/model.c @@ -3486,84 +3486,25 @@ rt_watch_t *model_set_event_cb(rt_model_t *m, rt_signal_t *s, sig_event_fn_t fn, return w; } -bool model_clear_global_cb(rt_model_t *m, rt_event_t event, rt_event_fn_t fn, - void *user) -{ - assert(event < RT_LAST_EVENT); - - rt_callback_t **last = &m->global_cbs[event]; - if (!*last) - return false; - - for (rt_callback_t *it = *last; it; last = &(it->next), it = it->next) { - if (it->fn == fn && it->user == user) { - *last = it->next; - free(it); - return true; - } - } - - return false; -} - -typedef struct { - uint64_t when; - rt_event_fn_t fn; - void *user; -} timeout_params_t; - -static bool eventq_delete_fn(uint64_t key, void *e, void *context) -{ - timeout_params_t *params = context; - - if (key != params->when) - return false; - - if (pointer_tag(e) != EVENT_TIMEOUT) - return false; - - rt_callback_t *cb = untag_pointer(e, rt_callback_t); - if (cb->fn == params->fn && cb->user == params->user) { - free(cb); - return true; - } - - return false; -} - -bool model_clear_timeout_cb(rt_model_t *m, uint64_t when, rt_event_fn_t fn, - void *user) -{ - timeout_params_t params = { - .when = when, - .fn = fn, - .user = user, - }; - - return heap_delete(m->eventq_heap, eventq_delete_fn, ¶ms); -} - -bool model_clear_event_cb(rt_model_t *m, rt_watch_t *w) +void model_clear_event_cb(rt_model_t *m, rt_watch_t *w) { rt_nexus_t *n = &(w->signal->nexus); for (int i = 0; i < w->signal->n_nexus; i++, n = n->chain) clear_event(m, n, &(w->wakeable)); rt_watch_t **last = &m->watches; - for (rt_watch_t *it = *last; it; last = &(it->chain_all), it = it->chain_all) { + for (rt_watch_t *it = *last; it; + last = &(it->chain_all), it = it->chain_all) { if (it == w) { *last = it->chain_all; break; } } - if (w->wakeable.pending) { + if (w->wakeable.pending) w->wakeable.free_later = true; - return false; - } - - free(w); - return true; + else + free(w); } static void handle_interrupt_cb(jit_t *j, void *ctx) diff --git a/src/rt/model.h b/src/rt/model.h index 3c3f2cc3..fcf3c5b3 100644 --- a/src/rt/model.h +++ b/src/rt/model.h @@ -36,15 +36,10 @@ void model_set_global_cb(rt_model_t *m, rt_event_t event, rt_event_fn_t fn, void *user); rt_watch_t *model_set_event_cb(rt_model_t *m, rt_signal_t *s, sig_event_fn_t fn, void *user, bool postponed); +void model_clear_event_cb(rt_model_t *m, rt_watch_t *w); void model_set_timeout_cb(rt_model_t *m, uint64_t when, rt_event_fn_t fn, void *user); -bool model_clear_global_cb(rt_model_t *m, rt_event_t event, rt_event_fn_t fn, - void *user); -bool model_clear_event_cb(rt_model_t *m, rt_watch_t *w); -bool model_clear_timeout_cb(rt_model_t *m, uint64_t when, rt_event_fn_t fn, - void *user); - rt_model_t *get_model(void); rt_model_t *get_model_or_null(void); rt_proc_t *get_active_proc(void); diff --git a/src/vhpi/vhpi-model.c b/src/vhpi/vhpi-model.c index 610cde52..fede485f 100644 --- a/src/vhpi/vhpi-model.c +++ b/src/vhpi/vhpi-model.c @@ -394,15 +394,12 @@ typedef struct { DEF_CLASS(forGenerate, vhpiForGenerateK, region.object); typedef struct { - c_vhpiObject object; - vhpiHandleT pending; - vhpiStateT State; - vhpiEnumT Reason; - vhpiCbDataT data; - union { - uint64_t when; - rt_watch_t *watch; - }; + c_vhpiObject object; + vhpiHandleT pending; + vhpiStateT State; + vhpiEnumT Reason; + vhpiCbDataT data; + rt_watch_t *watch; } c_callback; DEF_CLASS(callback, vhpiCallbackK, object); @@ -535,10 +532,8 @@ static vhpiHandleT handle_for(c_vhpiObject *obj) return (obj->handle = (vhpiHandleT)bits); } -static void drop_handle(vhpiHandleT handle) +static void drop_handle(vhpi_context_t *c, vhpiHandleT handle) { - vhpi_context_t *c = vhpi_context(); - handle_slot_t *slot = decode_handle(c, handle); if (slot == NULL) return; @@ -1426,7 +1421,7 @@ static void vhpi_global_cb(rt_model_t *m, void *user) default: cb->State = vhpiMature; - drop_handle(handle); + drop_handle(c, handle); break; } } @@ -1683,7 +1678,7 @@ int vhpi_release_handle(vhpiHandleT handle) return 1; } - drop_handle(handle); + drop_handle(vhpi_context(), handle); return 0; } @@ -1737,9 +1732,9 @@ vhpiHandleT vhpi_register_cb(vhpiCbDataT *cb_data_p, int32_t flags) cb->pending = handle_for(&(cb->object)); const uint64_t now = model_now(m, NULL); - cb->when = vhpi_time_to_native(cb_data_p->time) + now; + const uint64_t when = vhpi_time_to_native(cb_data_p->time) + now; - model_set_timeout_cb(m, cb->when, vhpi_global_cb, cb->pending); + model_set_timeout_cb(m, when, vhpi_global_cb, cb->pending); return (flags & vhpiReturnCb) ? handle_for(&(cb->object)) : NULL; } @@ -1777,37 +1772,6 @@ vhpiHandleT vhpi_register_cb(vhpiCbDataT *cb_data_p, int32_t flags) } } -static bool disable_cb(c_callback *cb, vhpiHandleT handle) -{ - switch (cb->Reason) { - case vhpiCbRepEndOfProcesses: - case vhpiCbRepLastKnownDeltaCycle: - case vhpiCbRepNextTimeStep: - case vhpiCbEndOfProcesses: - case vhpiCbStartOfSimulation: - case vhpiCbEndOfSimulation: - case vhpiCbLastKnownDeltaCycle: - case vhpiCbNextTimeStep: - case vhpiCbEndOfTimeStep: - case vhpiCbRepEndOfTimeStep: - return model_clear_global_cb(vhpi_context()->model, - vhpi_get_rt_event(cb->Reason), - vhpi_global_cb, handle); - - case vhpiCbAfterDelay: - return model_clear_timeout_cb(vhpi_context()->model, cb->when, - vhpi_global_cb, handle); - - case vhpiCbValueChange: - return model_clear_event_cb(vhpi_context()->model, cb->watch); - - default: - vhpi_error(vhpiInternal, NULL, - "unsupported reason %d in vhpi_remove_cb", cb->Reason); - return 1; - } -} - DLLEXPORT int vhpi_remove_cb(vhpiHandleT handle) { @@ -1823,13 +1787,15 @@ int vhpi_remove_cb(vhpiHandleT handle) if (cb == NULL) return 1; - if (cb->State == vhpiEnable) - disable_cb(cb, cb->pending); + vhpi_context_t *c = vhpi_context(); + + if (cb->Reason == vhpiCbValueChange) + model_clear_event_cb(c->model, cb->watch); cb->State = vhpiMature; - drop_handle(cb->pending); - drop_handle(handle); + drop_handle(c, cb->pending); + drop_handle(c, handle); return 0; } -- 2.39.2