Skip to content
Draft
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions RELEASENOTES-1.4.docu
Original file line number Diff line number Diff line change
Expand Up @@ -529,4 +529,9 @@
<build-id _6="next" _7="next"><add-note> Fixed a bug where executed callbacks
posted via immediate after statements would not trigger the device state
change notifier.</add-note></build-id>
<build-id _6="next" _7="next"><add-note> Added the `thread_aware` device
template to provide support for writing thread-aware device models.
For more information, see the Device templates subsection of the
Libraries and Built-ins section of the DML 1.4 Reference
Manual.</add-note></build-id>
</rn>
28 changes: 27 additions & 1 deletion include/simics/dmllib.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <simics/base/conf-object.h>
#include <simics/base/version.h>
#include <simics/util/swabber.h>
#include <simics/base/object-locks.h>
#include <simics/model-iface/bank-instrumentation.h>
#include <simics/simulator/conf-object.h>
#include <simics/util/alloc.h>
Expand Down Expand Up @@ -633,6 +634,22 @@ FOR_ENDIAN_VARIANTS(DEFINE_PRECHANGE);
#undef FOR_ALL_BITSIZES
#undef FOR_ENDIAN_VARIANTS


#define DML_THREAD_AWARE_IFACE_CALL(target_obj, call_expr) (({ \
domain_lock_t *__lock; \
SIM_ACQUIRE_TARGET(target_obj, &__lock); \
__auto_type __iface_ret = call_expr; \
SIM_RELEASE_TARGET(target_obj, &__lock); \
__iface_ret; \
}))

#define DML_THREAD_AWARE_IFACE_CALL_VOID(target_obj, call_expr) (({ \
domain_lock_t *__lock; \
SIM_ACQUIRE_TARGET(target_obj, &__lock); \
call_expr; \
SIM_RELEASE_TARGET(target_obj, &__lock); \
}))

UNUSED static attr_value_t
_serialize_identity(const _id_info_t *id_info_array, const _identity_t id) {
if (unlikely(id.id) == 0) {
Expand Down Expand Up @@ -1293,15 +1310,23 @@ _DML_execute_immediate_afters_now(conf_object_t *dev,
UNUSED static void
_DML_execute_immediate_afters(conf_object_t *dev, lang_void *aux) {
_dml_immediate_after_state_t *state = (_dml_immediate_after_state_t *)aux;
ASSERT(state->posted);
// Only acquire the device if it hasn't been deleted to avoid a
// use-after-free. There's no possibility of a data race on state->deleted
// (nor any other part of the state if state->deleted is true) as the
// device can only be deleted in global context.
if (unlikely(state->deleted)) {
ASSERT(state->posted);
ASSERT(QEMPTY(state->queue));
// No need to call QFREE, already done
MM_FREE(state);
return;
}
domain_lock_t *lock;
SIM_ACQUIRE_OBJECT(dev, &lock);
ASSERT(state->posted);
if (unlikely(QEMPTY(state->queue))) {
state->posted = false;
SIM_RELEASE_OBJECT(dev, &lock);
return;
}
_dml_immediate_after_queue_elem_t elem = QREMOVE(state->queue);
Expand All @@ -1314,6 +1339,7 @@ _DML_execute_immediate_afters(conf_object_t *dev, lang_void *aux) {
}
elem.callback(dev, elem.data.indices, elem.data.args);
_free_simple_event_data(elem.data);
SIM_RELEASE_OBJECT(dev, &lock);
}

UNUSED static void
Expand Down
Loading