Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
4 changes: 2 additions & 2 deletions conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def _min_cppstd(self):
def _compilers_minimum_version(self):
# We may reduce these in the future.
return {
"gcc": ("14", "GCC 14+ required for async_context"),
"gcc": ("15", "GCC 15+ required for async_context"),
"clang": (
"19",
"Clang 19+ required for async_context"
Expand Down Expand Up @@ -100,7 +100,7 @@ def validate(self):
def build_requirements(self):
self.tool_requires("cmake/[^4.0.0]")
self.tool_requires("ninja/[^1.3.0]")
self.requires("libhal-cmake-util/[^5.0.3]")
self.requires("libhal-cmake-util/[^5.0.6]")
if str(self.settings.os) != "baremetal":
self.test_requires("boost-ext-ut/2.3.1",
options={'disable_module': False})
Expand Down
3 changes: 2 additions & 1 deletion cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@
"doxygenenum",
"alignof",
"inplace",
"interruptible"
"interruptible",
"riscv"
],
"ignorePaths": [
"build/",
Expand Down
2 changes: 1 addition & 1 deletion modules/coroutine.cppm
Original file line number Diff line number Diff line change
Expand Up @@ -1622,7 +1622,7 @@ public:
requires std::is_constructible_v<T, U&&>
{
m_state.template emplace<T>(std::forward<U>(p_value));
};
}

/**
* @brief Move constructor for future
Expand Down
3 changes: 2 additions & 1 deletion modules/sync.cppm
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ module;
#include <cstddef>

#include <coroutine>
#include <new>
#include <utility>

export module async_context:sync;

Expand Down Expand Up @@ -154,7 +156,6 @@ public:

private:
friend class mutex;

guard(mutex* p_access, context* p_context)
: m_access(p_access)
, m_context(p_context)
Expand Down
37 changes: 25 additions & 12 deletions test_package/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,45 +29,58 @@ import async_context;

using namespace std::chrono_literals;

// linking println doesn't work on embedded systems generally
template<typename... Args>
void test_package_print([[maybe_unused]] std::format_string<Args...> p_fmt,
[[maybe_unused]] Args&&... p_args)
{
// If we are on a system with a real OS (Linux, Windows, macOS), use println.
// If we are in an embedded toolchain (arm-none-eabi, riscv64-unknown-elf),
// the following macro will NOT be defined.
#if defined(__GLIBC__) || defined(_WIN32) || defined(__APPLE__)
std::println(stdout, p_fmt, p_args...);
#endif
}

// Simulates reading sensor data with I/O delay
async::future<int> read_sensor(async::context& ctx, std::string_view p_name)
async::future<int> read_sensor(async::context&, std::string_view p_name)
{
std::println("['{}': Sensor] Read complete: 42", p_name);
test_package_print("['{}': Sensor] Read complete: 42", p_name);
co_return 42;
}

// Processes data with computation delay
async::future<int> process_data(async::context& p_ctx,
async::future<int> process_data(async::context&,
std::string_view p_name,
int value)
{
std::println("['{}': Process] Processing {}...", p_name, value);
test_package_print("['{}': Process] Processing {}...", p_name, value);
co_await 10ms; // Simulate processing time
int result = value * 2;
std::println("['{}': Process] Result: {}", p_name, result);
test_package_print("['{}': Process] Result: {}", p_name, result);
co_return result;
}

async::future<void> write_actuator(async::context& p_ctx,
std::string_view p_name,
int value)
{
std::println("['{}': Actuator] Writing {}...", p_name, value);
test_package_print("['{}': Actuator] Writing {}...", p_name, value);
co_await p_ctx.block_by_signal();
std::println("['{}': Actuator] Write complete!", p_name);
test_package_print("['{}': Actuator] Write complete!", p_name);
}

// Coordinates the full pipeline
async::future<void> sensor_pipeline(async::context& ctx,
std::string_view p_name)
{
std::println("Pipeline '{}' starting...", p_name);
test_package_print("Pipeline '{}' starting...", p_name);

int sensor_value = co_await read_sensor(ctx, p_name);
int processed = co_await process_data(ctx, p_name, sensor_value);
co_await write_actuator(ctx, p_name, processed);

std::println("Pipeline '{}' complete!\n", p_name);
test_package_print("Pipeline '{}' complete!\n", p_name);
}

// Stub implementation for ARM M Cortex targets without
Expand Down Expand Up @@ -103,8 +116,8 @@ int main()
auto pipeline2_future = sensor_pipeline(ctx1, "🔥 System 2");
// This is needed to simulate the context being unblocked by an external
// callback.
auto unblock_function =
[&ctx0, &ctx1](async::context& p_ctx) -> async::future<void> {
auto unblock_function = [&ctx0,
&ctx1](async::context&) -> async::future<void> {
while (true) {
if (ctx0.done() and ctx1.done()) {
break;
Expand Down Expand Up @@ -132,6 +145,6 @@ int main()
// Run ctx0, ctx1 and unblock_context to completion
async::run_until_done(clk, stub_sleep_function, ctx0, ctx1, unblock_context);

std::println("Both pipelines completed successfully!");
test_package_print("Both pipelines completed successfully!");
return 0;
}
2 changes: 1 addition & 1 deletion tests/mutex.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ void guards_tests()
auto guard = co_await mutex.lock(p_context);

// setup dma transaction...
std::println("Waiting on io complete flag, blocking by I/O");
std::println("Waiting on io complete flag, blocking by signal");

// Would normally wrap this in a while loop to check if the resource is
// fread.
Expand Down
Loading