Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into houliston/tracer
Browse files Browse the repository at this point in the history
  • Loading branch information
TrentHouliston committed Aug 30, 2024
2 parents 393bfd6 + 5ff730b commit b93d331
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 34 deletions.
4 changes: 2 additions & 2 deletions docs/dsl.rst
Original file line number Diff line number Diff line change
Expand Up @@ -207,9 +207,9 @@ Scope::LOCAL
````````````
.. doxygenstruct:: NUClear::dsl::word::emit::Local

Scope::DIRECT
Scope::INLINE
`````````````
.. doxygenstruct:: NUClear::dsl::word::emit::Direct
.. doxygenstruct:: NUClear::dsl::word::emit::Inline

Scope::Initialise
``````````````````
Expand Down
6 changes: 3 additions & 3 deletions docs/extension.rst
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ passed in. It is important to note that the type will only be considered by NUCl
attributes need to be stored in the DSL word type template it and use static variables, see `Sync`.

There are DSL words that are not meant to be used directly but as a part of other words, see `CacheGet` and `TypeBind`.
`TypeBind` adds the reaction to the list of reactions to be run when a `Local` or `Direct` emit is called for the data
`TypeBind` adds the reaction to the list of reactions to be run when a `Local` or `Inline` emit is called for the data
type. `CacheGet` gets the last value from a thread-local cache (see `ThreadSore` below) this cache is usually populated
in the last a `Local` or `Direct` emit call for the data type.
in the last a `Local` or `Inline` emit call for the data type.

If the type you want to become a DSL extension word is not defined within your control specialise `DSLProxy<>` with the
type. Provide the template methods to the specialisation of `DSLProxy<>` as if it were the type.
Expand All @@ -56,7 +56,7 @@ destructor.
e.g. for the `IO` word we have
.. codeblock:: c++
reaction->unbinders.push_back([](const threading::Reaction& r) {
r.reactor.emit<emit::Direct>(std::make_unique<operation::Unbind<IO>>(r.id));
r.reactor.emit<emit::Inline>(std::make_unique<operation::Unbind<IO>>(r.id));
});

which will tell the extension reactor that this reaction no longer exists.
Expand Down
10 changes: 5 additions & 5 deletions docs/startup.rst
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,10 @@ Data Emission Statements

As the system is single threaded at this time, the order in which reactors are installed can be significantly important.
This is pertinent when dealing with any data emissions during reactor construction which are NOT emitted under
:ref:`Scope::Initialise`. For example; data emission during the construction of a reactor using :ref:`Scope::DIRECT`,
:ref:`Scope::Initialise`. For example; data emission during the construction of a reactor using :ref:`Scope::INLINE`,
:ref:`Scope::UDP`, or :ref:`Scope::Network` will trigger any necessary activity to run inline. Should any reactions be
defined to run as a result of the emission, the task will be generated and also run inline. It is here where the order
in which reactors are installed becomes important. Suppose Reactor1 were to emit under :ref:`Scope::DIRECT`, and
in which reactors are installed becomes important. Suppose Reactor1 were to emit under :ref:`Scope::INLINE`, and
Reactor2 had a reaction defined to run on the associated datatype. In this case, the reaction defined by Reactor2 would
not run, as it was not yet defined at the time of data emission. However, should the roles be reserved, then the
reaction would run.
Expand Down Expand Up @@ -95,7 +95,7 @@ reaction would run.
to use :ref:`Scope::Initialise`. This will put a hold on the data emission, until the next step in the process
:ref:`Initialise Scope Tasks`, ensuring that any reactions subscribed to the emission will run.

Anything else?** Emissions during the construction of reactors using :ref:`Scope::DIRECT`, :ref:`Scope::UDP` and
Anything else?** Emissions during the construction of reactors using :ref:`Scope::INLINE`, :ref:`Scope::UDP` and
:ref:`Scope::Network` will trigger any reactions (which have already been defined - before the data emission) and
force any associated tasks to run inline.

Expand Down Expand Up @@ -164,7 +164,7 @@ Any on<:ref:`Shutdown`>() reaction requests will then be queued (in the order in
:ref:`Priority`::IDLE.

Note that during this phase, any other task which would normally be scheduled as a result of a non-direct emission will
be silently dropped, while any tasks which would occur as a result of a :ref:`Scope::DIRECT` emission will interrupt the
be silently dropped, while any tasks which would occur as a result of a :ref:`Scope::INLINE` emission will interrupt the
shutdown process and run as normal.

.. todo::
Expand All @@ -184,7 +184,7 @@ Emissions Scope Table
+==========================+=============================================================================================================================================================================================================================================================================================================================================+======================================================================================================================================================================================================================+=====================================================================================================================================================================================================================+
| :ref:`Scope::LOCAL` | Schedules any tasks for reactions which are currently loaded and bound to the emission data. Adds to the queue of tasks to start running when the system shifts to the :ref:`Execution Phase (multithreaded)` | Schedules any tasks for reactions which are bound to the emission data. Adds to the queue of tasks based on the desired :ref:`Priority` level | Any emissions under this scope while the system is in the shutdown phase are ignored. |
+--------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| :ref:`Scope::DIRECT` | Schedules any tasks for reactions which are currently loaded and bound to the emission data. Pauses the initialization phase, and runs the task in-line. The initialization phase continues upon task completion. | Schedules any tasks for reactions which are currently loaded and bound to the emission data. Pauses the task currently executing and runs the new task in-line. The execution phase continues upon task completion. | Schedules any tasks for reactions which are currently loaded and bound to the emission data. Pauses the task currently executing and runs the new task in-line. The shutdown phase continues upon task completion. |
| :ref:`Scope::INLINE` | Schedules any tasks for reactions which are currently loaded and bound to the emission data. Pauses the initialization phase, and runs the task in-line. The initialization phase continues upon task completion. | Schedules any tasks for reactions which are currently loaded and bound to the emission data. Pauses the task currently executing and runs the new task in-line. The execution phase continues upon task completion. | Schedules any tasks for reactions which are currently loaded and bound to the emission data. Pauses the task currently executing and runs the new task in-line. The shutdown phase continues upon task completion. |
+--------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| :ref:`Scope::Initialise` | Data emitted under this scope during this phase will wait until all reactors have been installed into the powerPlant before triggering any reactions. Any tasks generated as a result of this emission type are the first tasks to run when the powerPlant starts. This is the recommended emission type for this phase of system startup. | Any emissions under this scope while the system is in the execution phase are ignored. | Any emissions under this scope while the system is in the shutdown phase are ignored. |
+--------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
Expand Down
6 changes: 3 additions & 3 deletions src/dsl/fusion/has_run_inline.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#ifndef NUCLEAR_DSL_FUSION_HAS_INLINABLE_HPP
#define NUCLEAR_DSL_FUSION_HAS_INLINABLE_HPP
#ifndef NUCLEAR_DSL_FUSION_HAS_RUN_INLINE_HPP
#define NUCLEAR_DSL_FUSION_HAS_RUN_INLINE_HPP

#include "../../threading/ReactionTask.hpp"
#include "NoOp.hpp"
Expand Down Expand Up @@ -55,4 +55,4 @@ namespace dsl {
} // namespace dsl
} // namespace NUClear

#endif // NUCLEAR_DSL_FUSION_HAS_INLINABLE_HPP
#endif // NUCLEAR_DSL_FUSION_HAS_RUN_INLINE_HPP
10 changes: 5 additions & 5 deletions src/util/CallbackGenerator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ namespace util {

// Set the created status as rejected and emit it
if (task->stats != nullptr) {
PowerPlant::powerplant->emit<dsl::word::emit::Inline>(
PowerPlant::powerplant->emit(
std::make_unique<message::ReactionEvent>(message::ReactionEvent::BLOCKED, task->stats));
}

Expand All @@ -104,7 +104,7 @@ namespace util {

// Set the created status as no data and emit it
if (task->stats != nullptr) {
PowerPlant::powerplant->emit<dsl::word::emit::Local>(
PowerPlant::powerplant->emit(
std::make_unique<message::ReactionEvent>(message::ReactionEvent::MISSING_DATA, task->stats));
}

Expand All @@ -114,7 +114,7 @@ namespace util {

// Set the created status as no data and emit it
if (task->stats != nullptr) {
PowerPlant::powerplant->emit<dsl::word::emit::Local>(
PowerPlant::powerplant->emit(
std::make_unique<message::ReactionEvent>(message::ReactionEvent::CREATED, task->stats));
}

Expand All @@ -126,7 +126,7 @@ namespace util {

if (task.stats != nullptr) {
task.stats->started = message::ReactionStatistics::Event::now();
PowerPlant::powerplant->emit<dsl::word::emit::Local>(
PowerPlant::powerplant->emit(
std::make_unique<message::ReactionEvent>(message::ReactionEvent::STARTED, task.stats));
}

Expand All @@ -147,7 +147,7 @@ namespace util {

if (task.stats != nullptr) {
task.stats->finished = message::ReactionStatistics::Event::now();
PowerPlant::powerplant->emit<dsl::word::emit::Local>(
PowerPlant::powerplant->emit(
std::make_unique<message::ReactionEvent>(message::ReactionEvent::FINISHED, task.stats));
}
};
Expand Down
43 changes: 27 additions & 16 deletions tests/tests/dsl/Inline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,11 @@ class TestReactor : public test_util::TestBase<TestReactor> {
}

void log_interaction(const SimpleMessage& source, const std::string& target) {
std::lock_guard<std::mutex> lock(mutex);
const std::lock_guard<std::mutex> lock(mutex);
const auto& pool = NUClear::threading::scheduler::Pool::current();
events[source.data][target] =
pool->descriptor->name + " " + std::to_string(source.emitter == std::this_thread::get_id());
pool->descriptor->name + " "
+ (source.emitter == std::this_thread::get_id() ? "same thread" : "different thread");
}

/// A vector of events that have happened
Expand All @@ -91,24 +92,34 @@ TEST_CASE("Test the interactions between inline emits and the Inline dsl keyword
NUClear::Configuration config;
config.thread_count = 4;
NUClear::PowerPlant plant(config);
plant.install<NUClear::extension::TraceController>();
plant.emit<NUClear::dsl::word::emit::Inline>(std::make_unique<NUClear::message::BeginTrace>());
const auto& reactor = plant.install<TestReactor>();
plant.start();

const std::vector<std::string> expected = {
"Default Inline -> Default Always on Default 1", "Default Inline -> Default Neutral on Default 1",
"Default Inline -> Default Never on Default 0", "Default Inline -> Main Always on Default 1",
"Default Inline -> Main Neutral on Default 1", "Default Inline -> Main Never on Main 0",
"Default Local -> Default Always on Default 1", "Default Local -> Default Neutral on Default 0",
"Default Local -> Default Never on Default 0", "Default Local -> Main Always on Default 1",
"Default Local -> Main Neutral on Main 0", "Default Local -> Main Never on Main 0",
"Main Inline -> Default Always on Main 1", "Main Inline -> Default Neutral on Main 1",
"Main Inline -> Default Never on Default 0", "Main Inline -> Main Always on Main 1",
"Main Inline -> Main Neutral on Main 1", "Main Inline -> Main Never on Main 1",
"Main Local -> Default Always on Main 1", "Main Local -> Default Neutral on Default 0",
"Main Local -> Default Never on Default 0", "Main Local -> Main Always on Main 1",
"Main Local -> Main Neutral on Main 1", "Main Local -> Main Never on Main 1",
"Default Inline -> Default Always on Default same thread",
"Default Inline -> Default Neutral on Default same thread",
"Default Inline -> Default Never on Default different thread",
"Default Inline -> Main Always on Default same thread",
"Default Inline -> Main Neutral on Default same thread",
"Default Inline -> Main Never on Main different thread",
"Default Local -> Default Always on Default same thread",
"Default Local -> Default Neutral on Default different thread",
"Default Local -> Default Never on Default different thread",
"Default Local -> Main Always on Default same thread",
"Default Local -> Main Neutral on Main different thread",
"Default Local -> Main Never on Main different thread",
"Main Inline -> Default Always on Main same thread",
"Main Inline -> Default Neutral on Main same thread",
"Main Inline -> Default Never on Default different thread",
"Main Inline -> Main Always on Main same thread",
"Main Inline -> Main Neutral on Main same thread",
"Main Inline -> Main Never on Main same thread",
"Main Local -> Default Always on Main same thread",
"Main Local -> Default Neutral on Default different thread",
"Main Local -> Default Never on Default different thread",
"Main Local -> Main Always on Main same thread",
"Main Local -> Main Neutral on Main same thread",
"Main Local -> Main Never on Main same thread",
};

std::vector<std::string> actual;
Expand Down

0 comments on commit b93d331

Please sign in to comment.