Skip to content

Commit cd315f7

Browse files
authored
O1 heap, executor and main loop (#22)
- added `platform::O1HeapMemoryResource` - added platform executor and main loop
1 parent 8e49db2 commit cd315f7

File tree

12 files changed

+598
-7
lines changed

12 files changed

+598
-7
lines changed

.github/workflows/build.yml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,13 @@ name: build
22

33
on:
44
push:
5-
branches: [ "sshirokov/libcyphal" ]
5+
branches:
6+
- main
7+
- 'issue/*'
68
pull_request:
7-
branches: [ "sshirokov/libcyphal" ]
9+
branches:
10+
- main
11+
- 'issue/*'
812

913
env:
1014
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)

.vscode/settings.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"cSpell.words": [
33
"baremetal",
44
"Cyphal",
5+
"libcyphal",
56
"POSIX"
67
],
78
"cmake.sourceDirectory": "/home/sergei/Develop/git/OpenCyphal-Garage/demos/libcyphal_demo"

libcyphal_demo/.clang-tidy

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,4 @@ CheckOptions:
3333
- key: readability-magic-numbers.IgnoredIntegerValues
3434
value: '1;2;3;4;5;8;10;16;20;32;60;64;100;128;256;500;512;1000'
3535
WarningsAsErrors: '*'
36-
HeaderFilterRegex: 'include/libcyphal/.*\.hpp'
3736
FormatStyle: file

libcyphal_demo/src/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@ cmake_minimum_required(VERSION 3.20)
99
# Define the demo application build target and link it with the library.
1010
add_executable(
1111
demo
12+
${CMAKE_SOURCE_DIR}/src/application.cpp
1213
${CMAKE_SOURCE_DIR}/src/main.cpp
1314
${CMAKE_SOURCE_DIR}/src/no_cpp_heap.cpp
1415
)
15-
target_link_libraries(demo PRIVATE udpard)
1616
target_link_libraries(demo PRIVATE canard)
1717
target_link_libraries(demo PRIVATE o1heap)
18+
target_link_libraries(demo PRIVATE udpard)
1819
target_include_directories(demo PRIVATE ${submodules}/cetl/include)
1920
target_include_directories(demo PRIVATE ${submodules}/libcyphal/include)
2021
add_dependencies(demo dsdl_uavcan)

libcyphal_demo/src/application.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// This software is distributed under the terms of the MIT License.
2+
// Copyright (C) OpenCyphal Development Team <opencyphal.org>
3+
// Copyright Amazon.com Inc. or its affiliates.
4+
// SPDX-License-Identifier: MIT
5+
// Author: Sergei Shirokov <[email protected]>
6+
7+
#include "application.hpp"
8+
9+
#include <cetl/pf17/cetlpf.hpp>
10+
#include <o1heap.h>
11+
12+
#include <array>
13+
#include <cstddef>
14+
#include <iostream>
15+
16+
namespace
17+
{
18+
19+
constexpr std::size_t HeapSize = 16ULL * 1024ULL;
20+
alignas(O1HEAP_ALIGNMENT) std::array<cetl::byte, HeapSize> s_heap_arena{};
21+
22+
} // namespace
23+
24+
Application::Application()
25+
: o1_heap_mr_{s_heap_arena}
26+
{
27+
}
28+
29+
Application::~Application()
30+
{
31+
const auto mr_diag = o1_heap_mr_.queryDiagnostics();
32+
std::cout << "O(1) Heap diagnostics:" << "\n"
33+
<< " tcapacity=" << mr_diag.capacity << "\n"
34+
<< " tallocated=" << mr_diag.allocated << "\n"
35+
<< " tpeak_allocated=" << mr_diag.peak_allocated << "\n"
36+
<< " tpeak_request_size=" << mr_diag.peak_request_size << "\n"
37+
<< " toom_count=" << mr_diag.oom_count << "\n";
38+
}

libcyphal_demo/src/application.hpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// This software is distributed under the terms of the MIT License.
2+
// Copyright (C) OpenCyphal Development Team <opencyphal.org>
3+
// Copyright Amazon.com Inc. or its affiliates.
4+
// SPDX-License-Identifier: MIT
5+
// Author: Sergei Shirokov <[email protected]>
6+
7+
#ifndef APPLICATION_HPP
8+
#define APPLICATION_HPP
9+
10+
#include "platform/linux/epoll_single_threaded_executor.hpp"
11+
#include "platform/o1_heap_memory_resource.hpp"
12+
13+
#include <cetl/pf17/cetlpf.hpp>
14+
15+
/// The main application class.
16+
///
17+
/// Expected to be a singleton.
18+
///
19+
class Application final
20+
{
21+
public:
22+
Application();
23+
~Application();
24+
25+
Application(const Application&) = delete;
26+
Application& operator=(const Application&) = delete;
27+
Application(Application&&) = delete;
28+
Application& operator=(Application&&) = delete;
29+
30+
CETL_NODISCARD platform::Linux::EpollSingleThreadedExecutor& executor() noexcept
31+
{
32+
return executor_;
33+
}
34+
35+
CETL_NODISCARD cetl::pmr::memory_resource& memory() noexcept
36+
{
37+
return o1_heap_mr_;
38+
}
39+
40+
private:
41+
// MARK: Data members:
42+
43+
platform::Linux::EpollSingleThreadedExecutor executor_;
44+
platform::O1HeapMemoryResource o1_heap_mr_;
45+
46+
}; // Application
47+
48+
#endif // APPLICATION_HPP

libcyphal_demo/src/main.cpp

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,55 @@
44
// SPDX-License-Identifier: MIT
55
// Author: Sergei Shirokov <[email protected]>
66

7+
#include "application.hpp"
8+
9+
#include <cetl/pf17/cetlpf.hpp>
710
#include <libcyphal/application/node.hpp>
11+
#include <libcyphal/executor.hpp>
12+
#include <libcyphal/types.hpp>
813

14+
#include <algorithm>
15+
#include <chrono>
916
#include <iostream>
1017

18+
using namespace std::chrono_literals;
19+
20+
using Callback = libcyphal::IExecutor::Callback;
21+
1122
int main()
1223
{
13-
const std::string str{"LibCyphal demo."};
14-
std::cout << str << "\n";
24+
Application application;
25+
auto& executor = application.executor();
26+
27+
std::cout << "LibCyphal demo." << "\n";
28+
29+
auto cb = executor.registerCallback([](auto&) {
30+
//
31+
std::cout << "Callback fired." << "\n";
32+
});
33+
cb.schedule(Callback::Schedule::Repeat{executor.now(), libcyphal::Duration{1s}});
34+
35+
// Main loop.
36+
//
37+
libcyphal::Duration worst_lateness{0};
38+
const libcyphal::TimePoint deadline = executor.now() + 4s;
39+
std::cout << "-----------\nRunning..." << std::endl; // NOLINT
40+
//
41+
while (executor.now() < deadline)
42+
{
43+
const auto spin_result = executor.spinOnce();
44+
worst_lateness = std::max(worst_lateness, spin_result.worst_lateness);
45+
46+
libcyphal::Duration timeout{1s}; // awake at least once per second
47+
if (spin_result.next_exec_time.has_value())
48+
{
49+
timeout = std::min(timeout, spin_result.next_exec_time.value() - executor.now());
50+
}
51+
(void) executor.pollAwaitableResourcesFor(cetl::make_optional(timeout));
52+
}
53+
//
54+
std::cout << "Done.\n-----------\nRun Stats:\n";
55+
std::cout << " worst_callback_lateness=" << worst_lateness.count() << "us\n";
56+
1557
return 0;
1658
}

0 commit comments

Comments
 (0)