Skip to content

Commit

Permalink
Solve merge conflicts with main
Browse files Browse the repository at this point in the history
  • Loading branch information
magnmaeh committed Oct 16, 2024
2 parents 76cd531 + 4c3c0da commit 7ba372d
Show file tree
Hide file tree
Showing 57 changed files with 1,115 additions and 837 deletions.
31 changes: 31 additions & 0 deletions .github/actions/memory-report/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Fetch memory usage statistics
description: Fetch memory usage statistics from compiled tests for a specific branch

inputs:
branch:
required: true

outputs:
report:
description: "Memory usage statistics"
value: ${{ steps.make_report.outputs.report }}

runs:
using: "composite"
steps:
- name: Checkout
uses: actions/checkout@v3
with:
submodules: recursive
ref: ${{ inputs.branch }}
- name: Report
id: make_report
shell: bash
# For the multi line output
# https://stackoverflow.com/questions/74137120/how-to-fix-or-avoid-error-unable-to-process-file-command-output-successfully
run: |
make unit-test
EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
echo "report<<$EOF" >> $GITHUB_OUTPUT
echo "$(cat build/test/unit/*.size)" >> $GITHUB_OUTPUT
echo "$EOF" >> $GITHUB_OUTPUT
61 changes: 61 additions & 0 deletions .github/workflows/memory.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: Memory usage report

on:
pull_request:

permissions:
contents: write
pull-requests: write

jobs:
ci:
name: Report memory usage
runs-on: ubuntu-latest
steps:
# To get the potential changes to CI
- name: Checkout
uses: actions/checkout@v3
with:
submodules: recursive

- name: Generate memory usage report (base branch)
id: base
uses: ./.github/actions/memory-report
with:
branch: ${{ github.base_ref }}
- name: Generate memory usage report (head branch) # I.e. the PR branch
id: head
uses: ./.github/actions/memory-report
with:
branch: ${{ github.head_ref }}

- name: Compare
run: |
echo "$BASE_REPORT" > base_report.txt
echo "$HEAD_REPORT" > head_report.txt
python3 -m pip install -r scripts/ci/reports/requirements.txt
python3 scripts/ci/reports/parse-reports.py \
head_report.txt \
base_report.txt \
report
env:
BASE_REPORT: ${{ steps.base.outputs.report }}
HEAD_REPORT: ${{ steps.head.outputs.report }}

# This in conjunction with create-or-update-comment allows us to only
# comment once and update it after
- name: Find Comment
uses: peter-evans/find-comment@v3
id: fc
with:
issue-number: ${{ github.event.pull_request.number }}
comment-author: 'github-actions[bot]'
body-includes: Memory report

- name: Create or update comment
uses: peter-evans/create-or-update-comment@v4
with:
comment-id: ${{ steps.fc.outputs.comment-id }}
issue-number: ${{ github.event.pull_request.number }}
body-path: report.md
edit-mode: replace
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ elseif (PLATFORM STREQUAL "ZEPHYR")
zephyr_library_named(reactor-uc)
zephyr_library_sources(${SOURCES})
zephyr_library_link_libraries(kernel)
elseif (PLATFORM STREQUAL "PICO")
add_library(reactor-uc STATIC ${SOURCES})
target_link_libraries(reactor-uc PUBLIC pico_stdlib pico_sync)
else ()
message(FATAL_ERROR "No valid platform specified")
endif ()
Expand Down
24 changes: 24 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
BSD 2-Clause License

Copyright (c) 2024, The Lingua Franca Coordination Language

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.PHONY: clean test coverage asan format format-check ci lf-test lib proto
.PHONY: clean test coverage asan format format-check ci lf-test lib proto examples

test: unit-test lf-test
test: unit-test lf-test examples


# Generate protobuf code
Expand All @@ -14,7 +14,7 @@ lib:
make -C build


# Build and run examples
# Build examples
examples:
cmake -Bbuild -DBUILD_EXAMPLES=ON .
cmake --build build
Expand Down
17 changes: 9 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,10 @@ which enable distributed embedded systems.

## References
`reactor-uc` draws inspiration from the following existing open-source projects:
- reactor-cpp
- reactor-c
- qpc
- ssm-runtime
- [reactor-cpp](https://github.com/lf-lang/reactor-cpp)
- [reactor-c](https://github.com/lf-lang/reactor-c)
- [qpc](https://github.com/QuantumLeaps/qpc)
- [ssm-runtime](https://github.com/QuantumLeaps/qpc)

## TODO for the MVP:
- [x] Timers
Expand All @@ -98,12 +98,13 @@ which enable distributed embedded systems.
- [x] More platform abstractions (Riot, Zephyr and FlexPRET/InterPRET)
- [x] Reconsider where to buffer data (outputs vs inputs)
- [x] Consider if we should have FIFOs of pending events, not just a single for a trigger.
- [ ] Runtime errors
- [ ] Logging
- [x] Runtime errors
- [x] Logging
- [x] Delayed connections
- [x] Basic decentralized federations
- [ ] Multiports and banks
- [ ] Modal reactors
- [ ] Federated
- [ ] Delayed connections


## Troubleshooting

Expand Down
19 changes: 19 additions & 0 deletions examples/pico/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
cmake_minimum_required(VERSION 3.20.0)
set(PLATFORM "PICO" CACHE STRING "Platform to target")
set(BUILD_EXAMPLES OFF CAHCHE BOOL)

if (DEFINED ENV{PICO_SDK_PATH})
include("$ENV{PICO_SDK_PATH}/pico_sdk_init.cmake")
else()
message(FATAL_ERROR "PICO_SDK_PATH environment variable not set")
endif()

project(reactor-uc-pico)
pico_sdk_init()
add_subdirectory(../../ reactor-uc)

add_executable(hello_world
timer_ex.c
)

target_link_libraries(hello_world PRIVATE reactor-uc)
47 changes: 47 additions & 0 deletions examples/pico/timer_ex.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#include "reactor-uc/reactor-uc.h"

typedef struct {
Timer super;
Reaction *effects[0];
} MyTimer;

typedef struct {
Reaction super;
} MyReaction;

struct MyReactor {
Reactor super;
MyReaction my_reaction;
MyTimer timer;
Reaction *_reactions[1];
Trigger *_triggers[1];
};

void timer_handler(Reaction *_self) {
struct MyReactor *self = (struct MyReactor *)_self->parent;
printf("Hello World @ %lld\n", self->super.env->current_tag.time);
}

void MyReaction_ctor(MyReaction *self, Reactor *parent) {
Reaction_ctor(&self->super, parent, timer_handler, NULL, 0, 0);
}

void MyReactor_ctor(struct MyReactor *self, Environment *env) {
self->_reactions[0] = (Reaction *)&self->my_reaction;
self->_triggers[0] = (Trigger *)&self->timer;
Reactor_ctor(&self->super, "MyReactor", env, NULL, NULL, 0, self->_reactions, 1, self->_triggers, 1);
MyReaction_ctor(&self->my_reaction, &self->super);
Timer_ctor(&self->timer.super, &self->super, MSEC(0), MSEC(100), self->timer.effects, 1);
TIMER_REGISTER_EFFECT(self->timer, self->my_reaction);
}

struct MyReactor my_reactor;
Environment env;
int main() {
Environment_ctor(&env, (Reactor *)&my_reactor);
env.set_timeout(&env, SEC(1));
MyReactor_ctor(&my_reactor, &env);
env.assemble(&env);
env.start(&env);
return 0;
}
6 changes: 0 additions & 6 deletions examples/posix/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,3 @@ add_custom_target(examples
)

# Add each executable to the custom target
foreach(EXEC_NAME ${EXECUTABLES})
add_custom_command(TARGET examples
COMMAND ${EXEC_NAME}
COMMENT "Running ${EXEC_NAME}"
)
endforeach()
37 changes: 19 additions & 18 deletions examples/posix/testing_fed_conn.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,8 @@ typedef struct {
msg_t buffer[1];
} ConnSender;

void ConnSender_ctor(ConnSender *self, Reactor *parent, FederatedConnectionBundle *bundle, Port *upstream) {
FederatedOutputConnection_ctor(&self->super, parent, bundle, 0, upstream, &self->buffer[0], sizeof(self->buffer[0]));
void ConnSender_ctor(ConnSender *self, Reactor *parent, FederatedConnectionBundle *bundle) {
FederatedOutputConnection_ctor(&self->super, parent, bundle, 0, &self->buffer[0], sizeof(self->buffer[0]));
}

typedef struct {
Expand All @@ -133,20 +133,21 @@ typedef struct {

void SenderRecvConn_ctor(SenderRecvBundle *self, Sender *parent) {
TcpIpChannel_ctor(&self->channel, "127.0.0.1", PORT_NUM, AF_INET);
ConnSender_ctor(&self->conn, &parent->super, &self->super, &parent->out.super.super);
ConnSender_ctor(&self->conn, &parent->super, &self->super);
self->output[0] = &self->conn.super;
CONN_REGISTER_UPSTREAM(self->conn, parent->out);

TcpIpChannel *channel = &self->channel;
int ret = channel->super.bind(channel);
NetworkChannel *channel = (NetworkChannel *)&self->channel;
int ret = channel->bind(channel);
validate(ret == LF_OK);
printf("Sender: Bound\n");

// accept one connection
bool new_connection = channel->super.accept(channel);
bool new_connection = channel->accept(channel);
validate(new_connection);
printf("Sender: Accepted\n");

FederatedConnectionBundle_ctor(&self->super, &parent->super, &self->channel, NULL, 0,
FederatedConnectionBundle_ctor(&self->super, &parent->super, &self->channel.super, NULL, 0,
(FederatedOutputConnection **)&self->output, 1);
}

Expand All @@ -173,17 +174,17 @@ void RecvSenderBundle_ctor(RecvSenderBundle *self, Reactor *parent) {
TcpIpChannel_ctor(&self->channel, "127.0.0.1", PORT_NUM, AF_INET);
self->inputs[0] = &self->conn.super;

TcpIpChannel *channel = &self->channel;
NetworkChannel *channel = (NetworkChannel *)&self->channel;

lf_ret_t ret;
do {
ret = channel->super.connect(channel);
ret = channel->connect(channel);
} while (ret != LF_OK);
validate(ret == LF_OK);
printf("Recv: Connected\n");

FederatedConnectionBundle_ctor(&self->super, parent, &self->channel, (FederatedInputConnection **)&self->inputs, 1,
NULL, 0);
FederatedConnectionBundle_ctor(&self->super, parent, &self->channel.super, (FederatedInputConnection **)&self->inputs,
1, NULL, 0);
}

// Reactor main
Expand Down Expand Up @@ -233,9 +234,9 @@ void *main_sender(void *unused) {
(void)unused;
Environment_ctor(&env_send, (Reactor *)&sender);
MainSender_ctor(&sender, &env_send);
env_send.set_timeout(&env_send, SEC(1));
env_send.net_channel_size = 1;
env_send.net_channels = (TcpIpChannel **)&sender.net_channel;
env_send.scheduler.set_timeout(&env_send.scheduler, SEC(1));
env_send.net_bundles_size = 1;
env_send.net_bundles = (FederatedConnectionBundle **)&sender.bundle;
env_send.assemble(&env_send);
env_send.start(&env_send);
return NULL;
Expand All @@ -248,11 +249,11 @@ void *main_recv(void *unused) {
Environment_ctor(&env_recv, (Reactor *)&receiver);
env_recv.platform->enter_critical_section(env_recv.platform);
MainRecv_ctor(&receiver, &env_recv);
env_recv.set_timeout(&env_recv, SEC(1));
env_recv.keep_alive = true;
env_recv.scheduler.set_timeout(&env_recv.scheduler, SEC(1));
env_recv.scheduler.keep_alive = true;
env_recv.has_async_events = true;
env_recv.net_channel_size = 1;
env_recv.net_channels = (TcpIpChannel **)&receiver.net_channels;
env_recv.net_bundles_size = 1;
env_recv.net_bundles = (FederatedConnectionBundle **)&receiver.bundle;
env_recv.assemble(&env_recv);
env_recv.platform->leave_critical_section(env_recv.platform);
env_recv.start(&env_recv);
Expand Down
10 changes: 5 additions & 5 deletions examples/posix/testing_posix_tcp_ip_channel_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,19 @@ int main() {
TcpIpChannel_ctor(&channel, host, port, AF_INET);

// binding to that address
channel.super.connect(&channel);
channel.super.connect(&channel.super);

// change the super to non-blocking
channel.super.change_block_state(&channel, false);
channel.super.change_block_state(&channel.super, false);

for (int i = 0; i < NUM_ITER; i++) {
// sending message
channel.super.send(&channel, &port_message);
channel.super.send(&channel.super, &port_message);

// waiting for reply
TaggedMessage *received_message = NULL;
do {
received_message = channel.super.receive(&channel);
received_message = channel.super.receive(&channel.super);
} while (received_message == NULL);

printf("Received message with connection number %i and content %s\n", received_message->conn_id,
Expand All @@ -45,5 +45,5 @@ int main() {
sleep(i);
}

channel.super.close(&channel);
channel.super.close(&channel.super);
}
Loading

0 comments on commit 7ba372d

Please sign in to comment.