diff --git a/core/reactor_common.c b/core/reactor_common.c index 358480eb8..7257e5132 100644 --- a/core/reactor_common.c +++ b/core/reactor_common.c @@ -149,6 +149,38 @@ void lf_set_stop_tag(environment_t* env, tag_t tag) { } } +const char* lf_reactor_name(self_base_t* self) { return self->name; } + +const char* lf_reactor_full_name(self_base_t* self) { + if (self->full_name != NULL) { + return self->full_name; + } + // First find the length of the full name. + size_t name_len = strlen(self->name); + size_t len = name_len; + self_base_t* parent = self->parent; + while (parent != NULL) { + len++; // For the dot. + len += strlen(parent->name); + parent = parent->parent; + } + self->full_name = (char*)lf_allocate(len + 1, sizeof(char), &self->allocations); + self->full_name[len] = '\0'; // Null terminate the string. + + size_t location = len - name_len; + memcpy(&self->full_name[location], self->name, name_len); + parent = self->parent; + while (parent != NULL) { + location--; + self->full_name[location] = '.'; + size_t parent_len = strlen(parent->name); + location -= parent_len; + memcpy(&self->full_name[location], parent->name, parent_len); + parent = parent->parent; + } + return self->full_name; +} + #ifdef FEDERATED_DECENTRALIZED interval_t lf_get_stp_offset() { return lf_fed_STA_offset; } diff --git a/include/api/reaction_macros.h b/include/api/reaction_macros.h index 52c39e125..c73cde530 100644 --- a/include/api/reaction_macros.h +++ b/include/api/reaction_macros.h @@ -199,4 +199,25 @@ */ #define lf_time_logical_elapsed() lf_time_logical_elapsed(self->base.environment) +/** + * @brief Return the instance name of the reactor. + * + * The instance name is the name of given to the instance created by the `new` operator in LF. + * If the instance is in a bank, then the name will have a suffix of the form `[bank_index]`. + * + * @param reactor The reactor to get the name of. + */ +#define lf_reactor_name(reactor) lf_reactor_name(&reactor->base) + +/** + * @brief Return the fully qualified name of the reactor. + * + * The fully qualified name of a reactor is the instance name of the reactor concatenated with the names of all + * of its parents, separated by dots. If the reactor or any of its parents is a bank, then the name + * will have a suffix of the form `[bank_index]`. + * + * @param reactor The reactor to get the name of. + */ +#define lf_reactor_full_name(reactor) lf_reactor_full_name(&reactor->base) + #endif // REACTION_MACROS_H diff --git a/include/api/reaction_macros_undef.h b/include/api/reaction_macros_undef.h index 601ea34d3..26ab86b2e 100644 --- a/include/api/reaction_macros_undef.h +++ b/include/api/reaction_macros_undef.h @@ -26,4 +26,7 @@ #undef lf_time_logical #undef lf_time_logical_elapsed +#undef lf_reactor_name +#undef lf_reactor_full_name + #endif // REACTION_MACROS_H diff --git a/include/core/lf_types.h b/include/core/lf_types.h index b6d754ca2..385fc654e 100644 --- a/include/core/lf_types.h +++ b/include/core/lf_types.h @@ -251,8 +251,8 @@ struct trigger_t { * An allocation record that is used by a destructor for a reactor * to free memory that has been dynamically allocated for the particular * instance of the reactor. This will be an element of linked list. - * If the indirect field is true, then the allocated pointer points to - * pointer to allocated memory, rather than directly to the allocated memory. + * The `allocated` pointer points to the allocated memory, and the `next` + * pointer points to the next allocation record (or NULL if there are no more). */ typedef struct allocation_record_t { void* allocated; @@ -277,6 +277,9 @@ typedef struct self_base_t { struct allocation_record_t* allocations; struct reaction_t* executing_reaction; // The currently executing reaction of the reactor. environment_t* environment; + char* name; // The name of the reactor. If a bank, appended with [index]. + char* full_name; // The full name of the reactor or NULL if lf_reactor_full_name() is not called. + self_base_t* parent; // The parent of this reactor. #if !defined(LF_SINGLE_THREADED) void* reactor_mutex; // If not null, this is expected to point to an lf_mutex_t. // It is not declared as such to avoid a dependence on platform.h. diff --git a/include/core/reactor.h b/include/core/reactor.h index fffa9ba19..c98f2e93b 100644 --- a/include/core/reactor.h +++ b/include/core/reactor.h @@ -128,5 +128,26 @@ void lf_free_all_reactors(void); */ void lf_free_reactor(self_base_t* self); +/** + * @brief Return the instance name of the reactor. + * + * The instance name is the name of given to the instance created by the `new` operator in LF. + * If the instance is in a bank, then the name will have a suffix of the form `[bank_index]`. + * + * @param self The self struct of the reactor. + */ +const char* lf_reactor_name(self_base_t* self); + +/** + * @brief Return the full name of the reactor. + * + * The fully qualified name of a reactor is the instance name of the reactor concatenated with the names of all + * of its parents, separated by dots. If the reactor or any of its parents is a bank, then the name + * will have a suffix of the form `[bank_index]`. + * + * @param self The self struct of the reactor. + */ +const char* lf_reactor_full_name(self_base_t* self); + #endif /* REACTOR_H */ /** @} */