Skip to content

Commit

Permalink
Merge branch 'main' into feature/distributed-erlang
Browse files Browse the repository at this point in the history
Merge a number of fixes and improvements from main branch.
  • Loading branch information
bettio committed Dec 27, 2024
2 parents a0a0a5b + 74258a1 commit efd440c
Show file tree
Hide file tree
Showing 72 changed files with 2,054 additions and 1,057 deletions.
28 changes: 28 additions & 0 deletions .github/workflows/esp32-build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,34 @@ jobs:
pytest-embedded-idf==1.10.3 \
pytest-embedded-qemu==1.10.3
- name: Build ESP32 tests using idf.py with memory checks
working-directory: ./src/platforms/esp32/test/
run: |
set -e
export PATH=${PATH}:${HOME}/.cache/rebar3/bin
cp sdkconfig.defaults sdkconfig.defaults.backup
echo "CONFIG_COMPILER_STACK_CHECK_MODE_ALL=y" >> sdkconfig.defaults
echo "CONFIG_COMPILER_STACK_CHECK=y" >> sdkconfig.defaults
echo "CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK=y" >> sdkconfig.defaults
echo "CONFIG_HEAP_POISONING_COMPREHENSIVE=y" >> sdkconfig.defaults
echo "CONFIG_ESP_WIFI_IRAM_OPT=n" >> sdkconfig.defaults
echo "CONFIG_ESP_WIFI_RX_IRAM_OPT=n" >> sdkconfig.defaults
. $IDF_PATH/export.sh
export IDF_TARGET=${{matrix.esp-idf-target}}
idf.py set-target ${{matrix.esp-idf-target}}
idf.py build
- name: Run ESP32 tests using qemu with memory checks build
working-directory: ./src/platforms/esp32/test/
timeout-minutes: 10
run: |
set -e
. $IDF_PATH/export.sh
export PATH=/opt/qemu/bin:${PATH}
pytest --target=${{matrix.esp-idf-target}} --embedded-services=idf,qemu -s
idf.py clean
cp sdkconfig.defaults.backup sdkconfig.defaults
- name: Build ESP32 tests using idf.py
working-directory: ./src/platforms/esp32/test/
run: |
Expand Down
118 changes: 118 additions & 0 deletions .github/workflows/esp32-simtest.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
#
# Copyright 2024 Davide Bettio <davide@uninstall.it>
# Copyright 2024 Peter Madsen-Mygdal <petermm@gmail.com>
#
# SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
#

name: ESP32 Sim test

on:
push:
paths:
- ".github/workflows/esp32-simtest.yaml"
- "CMakeLists.txt"
- "libs/**"
- "src/platforms/esp32/**"
- "src/platforms/esp32/**/**"
- "src/libAtomVM/**"
- "tools/packbeam/**"
pull_request:
paths:
- ".github/workflows/esp32-simtest.yaml"
- "src/platforms/esp32/**"
- "src/platforms/esp32/**/**"
- "src/libAtomVM/**"

concurrency:
group: ${{ github.workflow }}-${{ github.ref != 'refs/heads/main' && github.ref || github.run_id }}
cancel-in-progress: true

jobs:
cli_token:
name: WOKWI_CLI_TOKEN presence
runs-on: ubuntu-24.04
outputs:
token_check: ${{ steps.token_check.outputs.should-run }}

steps:
- name: Mark esp-sim-test job as 'to be run'
id: token_check
env:
wokwi_secret: ${{ secrets.WOKWI_CLI_TOKEN }}
run: |
if [${{ env.wokwi_secret }} == ''];
then
echo "WOKWI_CLI_TOKEN not found, please add it to your repository secrets"
else
echo "WOKWI_CLI_TOKEN found continuing..."
echo "should-run=true" >> $GITHUB_OUTPUT
fi
esp-sim-test:
needs: cli_token
runs-on: ubuntu-24.04
if: needs.cli_token.outputs.token_check == 'true'
container: espressif/idf:${{ matrix.idf-version }}
strategy:
fail-fast: false
# focus on device diversity.
matrix:
esp-idf-target: ["esp32", "esp32s2", "esp32s3", "esp32c3", "esp32c6"]
idf-version: ${{ ((contains(github.event.head_commit.message, 'full_sim_test')||contains(github.event.pull_request.title, 'full_sim_test')) && fromJSON('["v5.1.5", "v5.2.3", "v5.3.2", "v5.4-beta1"]')) || fromJSON('["v5.3.2"]') }}
include:
- esp-idf-target: "esp32p4"
idf-version: "v5.3.2"
- esp-idf-target: "esp32h2"
idf-version: "v5.3.2"

steps:
- name: Checkout repo
uses: actions/checkout@v4

- name: Install dependencies to build host AtomVM
run: |
set -eu
apt update
DEBIAN_FRONTEND=noninteractive apt install -y -q \
doxygen erlang-base erlang-dev erlang-dialyzer erlang-eunit \
erlang-asn1 erlang-common-test erlang-crypto erlang-edoc \
erlang-parsetools erlang-reltool erlang-syntax-tools erlang-tools \
libglib2.0-0 libpixman-1-0 \
gcc g++ zlib1g-dev libsdl2-2.0-0 libslirp0 libmbedtls-dev
wget --no-verbose https://github.com/erlang/rebar3/releases/download/3.18.0/rebar3
chmod +x rebar3
./rebar3 local install
- name: Install the Wokwi CLI
run: curl -L https://wokwi.com/ci/install.sh | sh

- name: Install pytest and pytest-embedded plugins
run: |
set -e
. $IDF_PATH/export.sh
pip install pytest==8.3.4 \
pytest-embedded==1.12.1 \
pytest-embedded-idf==1.12.1 \
pytest-embedded-qemu==1.12.1 \
pytest-embedded-wokwi==1.12.1
- name: Set SDKCONFIG_DEFAULTS and Build ESP32-sim tests using idf.py
working-directory: ./src/platforms/esp32/test/
run: |
set -e
export PATH=${PATH}:${HOME}/.cache/rebar3/bin
. $IDF_PATH/export.sh
idf.py -DSDKCONFIG_DEFAULTS='sdkconfig.ci.wokwi' set-target ${{matrix.esp-idf-target}}
idf.py build
- name: Run ESP32-sim tests using Wokwi CI
working-directory: ./src/platforms/esp32/test/
env:
WOKWI_CLI_TOKEN: ${{ secrets.WOKWI_CLI_TOKEN }}
timeout-minutes: 10
run: |
set -e
. $IDF_PATH/export.sh
pytest --embedded-services=idf,wokwi --wokwi-timeout=240000 --target=${{ matrix.esp-idf-target }} --wokwi-diagram=sim_boards/diagram.${{ matrix.esp-idf-target }}.json -s
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added support for external refs and encoded refs in external terms
- Introduce ports to represent native processes and added support for external ports and encoded ports in external terms
- Added `atomvm:get_creation/0`, equivalent to `erts_internal:get_creation/0`
- Added menuconfig option for enabling USE_USB_SERIAL, eg. serial over USB for certain ESP32-S2 boards etc.
- Partial support for `erlang:fun_info/2`
- Added support for `registered_name` in `erlang:process_info/2` and `Process.info/2`
- Added `net:gethostname/0` on platforms with gethostname(3).
- Added `socket:getopt/2`

### Fixed

- ESP32: improved sntp sync speed from a cold boot.
- Fixed `gen_server` internal messages to match OTP so it works across erlang distribution

## [0.6.6] - Unreleased

### Added

- Added the ability to run beams from the CLI for Generic Unix platform (it was already possible with nodejs and emscripten).
- Added support for 'erlang:--/2'.

### Fixed

Expand All @@ -39,6 +46,10 @@ might lead to a crash in certain situations.
- Fixed destruction of ssl-related resources
- Fix corruption when dealing with specific situations that involve more than 16 x registers when
certain VM instructions are used.
- Fixed ESP32 GPIO interrupt trigger `none`
- Fixed an issue where a timeout would occur immediately in a race condition
- Fixed SPI close command
- Added missing lock on socket structure

## [0.6.5] - 2024-10-15

Expand Down
4 changes: 4 additions & 0 deletions code-queries/non-term-to-term-func.ql
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ predicate isNotTermOrAtom(Expr expr) {
(mi.toString().matches("%_ATOM") or mi.toString().matches("TERM_%"))
)
) and
not (
expr instanceof EnumConstantAccess and
expr.(EnumConstantAccess).getTarget().toString().matches("%_ATOM")
) and
(
not expr instanceof ConditionalExpr
or
Expand Down
1 change: 1 addition & 0 deletions doc/src/apidocs/libatomvm/functions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ Functions
.. doxygenfunction:: globalcontext_get_process_nolock
.. doxygenfunction:: globalcontext_get_process_unlock
.. doxygenfunction:: globalcontext_get_registered_process
.. doxygenfunction:: globalcontext_get_registered_name_process
.. doxygenfunction:: globalcontext_init_process
.. doxygenfunction:: globalcontext_insert_atom
.. doxygenfunction:: globalcontext_insert_atom_maybe_copy
Expand Down
14 changes: 14 additions & 0 deletions libs/estdlib/src/erlang.erl
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
float_to_binary/2,
float_to_list/1,
float_to_list/2,
fun_info/2,
integer_to_binary/1,
integer_to_binary/2,
integer_to_list/1,
Expand Down Expand Up @@ -223,6 +224,7 @@ send_after(Time, Dest, Msg) ->
%% <ul>
%% <li><b>heap_size</b> the number of words used in the heap (integer), including the stack but excluding fragments</li>
%% <li><b>total_heap_size</b> the number of words used in the heap (integer) including fragments</li>
%% <li><b>registered_name</b> - returns `{registered_name, RegisteredName}' where `RegisteredName' is the registered name of the port or process. If the port/process has no registered name, `[]' is returned</li>
%% <li><b>stack_size</b> the number of words used in the stack (integer)</li>
%% <li><b>message_queue_len</b> the number of messages enqueued for the process (integer)</li>
%% <li><b>memory</b> the estimated total number of bytes in use by the process (integer)</li>
Expand All @@ -235,6 +237,7 @@ send_after(Time, Dest, Msg) ->
-spec process_info
(Pid :: pid(), heap_size) -> {heap_size, non_neg_integer()};
(Pid :: pid(), total_heap_size) -> {total_heap_size, non_neg_integer()};
(Pid :: pid(), registered_name) -> {registered_name, term()} | [];
(Pid :: pid(), stack_size) -> {stack_size, non_neg_integer()};
(Pid :: pid(), message_queue_len) -> {message_queue_len, non_neg_integer()};
(Pid :: pid(), memory) -> {memory, non_neg_integer()};
Expand Down Expand Up @@ -763,6 +766,17 @@ float_to_list(_Float) ->
float_to_list(_Float, _Options) ->
erlang:nif_error(undefined).

%%-----------------------------------------------------------------------------
%% @param Fun Function to get information about
%% @param Info A list of atoms specifying the information to return.
%% Available atoms are: module, name, arity, type
%% @returns Requested information about the function as a list of tuples.
%% @doc Returns information about the function `Fun' in unspecified order.
%% @end
%%-----------------------------------------------------------------------------
fun_info(_Fun, _Info) ->
erlang:nif_error(undefined).

%%-----------------------------------------------------------------------------
%% @param Integer integer to convert to a binary
%% @returns a binary with a text representation of the integer
Expand Down
11 changes: 10 additions & 1 deletion libs/estdlib/src/net.erl
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

-module(net).

-export([getaddrinfo/1, getaddrinfo/2]).
-export([getaddrinfo/1, getaddrinfo/2, gethostname/0]).

%% nif call (so we can use guards at the API)
-export([getaddrinfo_nif/2]).
Expand Down Expand Up @@ -78,3 +78,12 @@ getaddrinfo(Host, Service) when
%% @hidden
getaddrinfo_nif(_Host, _Service) ->
erlang:nif_error(undefined).

%%-----------------------------------------------------------------------------
%% @returns The (usually short) name of the host.
%% @doc Get the hostname
%% @end
%%-----------------------------------------------------------------------------
-spec gethostname() -> {ok, string()} | {error, any()}.
gethostname() ->
erlang:nif_error(undefined).
31 changes: 28 additions & 3 deletions libs/estdlib/src/socket.erl
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
send/2,
sendto/3,
setopt/3,
getopt/2,
connect/2,
shutdown/2
]).
Expand Down Expand Up @@ -66,7 +67,9 @@
-type in_addr() :: {0..255, 0..255, 0..255, 0..255}.
-type port_number() :: 0..65535.

-type socket_option() :: {socket, reuseaddr} | {socket, linger}.
-type socket_option() ::
{socket, reuseaddr | linger | type}
| {otp, recvbuf}.

-export_type([
socket/0,
Expand Down Expand Up @@ -443,11 +446,32 @@ sendto(Socket, Data, Dest) when is_binary(Data) ->
sendto(Socket, Data, Dest) ->
?MODULE:nif_sendto(Socket, erlang:iolist_to_binary(Data), Dest).

%%-----------------------------------------------------------------------------
%% @param Socket the socket
%% @param SocketOption the option
%% @returns `{ok, Value}' if successful; `{error, Reason}', otherwise.
%% @doc Get a socket option.
%%
%% Currently, the following options are supported:
%% <table>
%% <tr><td>`{socket, type}'</td><td>`type()'</td></tr>
%% </table>
%%
%% Example:
%%
%% `{ok, stream} = socket:getopt(ListeningSocket, {socket, type})'
%% @end
%%-----------------------------------------------------------------------------
-spec getopt(Socket :: socket(), SocketOption :: socket_option()) ->
{ok, Value :: term()} | {error, Reason :: term()}.
getopt(_Socket, _SocketOption) ->
erlang:nif_error(undefined).

%%-----------------------------------------------------------------------------
%% @param Socket the socket
%% @param SocketOption the option
%% @param Value the option value
%% @returns `{ok, Address}' if successful; `{error, Reason}', otherwise.
%% @returns `ok' if successful; `{error, Reason}', otherwise.
%% @doc Set a socket option.
%%
%% Set an option on a socket.
Expand All @@ -456,6 +480,7 @@ sendto(Socket, Data, Dest) ->
%% <table>
%% <tr><td>`{socket, reuseaddr}'</td><td>`boolean()'</td></tr>
%% <tr><td>`{socket, linger}'</td><td>`#{onoff => boolean(), linger => non_neg_integer()}'</td></tr>
%% <tr><td>`{otp, recvbuf}'</td><td>`non_neg_integer()'</td></tr>
%% </table>
%%
%% Example:
Expand All @@ -465,7 +490,7 @@ sendto(Socket, Data, Dest) ->
%% @end
%%-----------------------------------------------------------------------------
-spec setopt(Socket :: socket(), SocketOption :: socket_option(), Value :: term()) ->
ok | {error, Reason :: term()}.
ok | {error, any()}.
setopt(_Socket, _SocketOption, _Value) ->
erlang:nif_error(undefined).

Expand Down
1 change: 1 addition & 0 deletions src/libAtomVM/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ set(HEADER_FILES
bitstring.h
context.h
debug.h
defaultatoms.def
defaultatoms.h
dictionary.h
erl_nif.h
Expand Down
13 changes: 13 additions & 0 deletions src/libAtomVM/context.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ bool context_get_process_info(Context *ctx, term *out, term atom_key)
case TOTAL_HEAP_SIZE_ATOM:
case STACK_SIZE_ATOM:
case MESSAGE_QUEUE_LEN_ATOM:
case REGISTERED_NAME_ATOM:
case MEMORY_ATOM:
ret_size = TUPLE_SIZE(2);
break;
Expand Down Expand Up @@ -315,6 +316,18 @@ bool context_get_process_info(Context *ctx, term *out, term atom_key)
break;
}

// registered_name for process or port..
case REGISTERED_NAME_ATOM: {
term name = globalcontext_get_registered_name_process(ctx->global, ctx->process_id);
if (term_is_invalid_term((name))) {
ret = term_nil(); // Set ret to an empty list to match erlang behaviour
} else {
term_put_tuple_element(ret, 0, REGISTERED_NAME_ATOM);
term_put_tuple_element(ret, 1, name);
}
break;
}

// total_heap_size size in words of the heap of the process, including fragments
case TOTAL_HEAP_SIZE_ATOM: {
term_put_tuple_element(ret, 0, TOTAL_HEAP_SIZE_ATOM);
Expand Down
Loading

0 comments on commit efd440c

Please sign in to comment.