diff --git a/CHANGELOG.md b/CHANGELOG.md index d69a5e5d1..5b80039f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added support for external pids and encoded pids in external terms - 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` ## [0.6.6] - Unreleased diff --git a/libs/eavmlib/src/atomvm.erl b/libs/eavmlib/src/atomvm.erl index a5dd82645..a9a60df26 100644 --- a/libs/eavmlib/src/atomvm.erl +++ b/libs/eavmlib/src/atomvm.erl @@ -43,7 +43,8 @@ posix_clock_settime/2, posix_opendir/1, posix_closedir/1, - posix_readdir/1 + posix_readdir/1, + get_creation/0 ]). -export_type([ @@ -335,3 +336,8 @@ posix_closedir(_Dir) -> {ok, {dirent, Inode :: integer(), Name :: binary()}} | eof | {error, posix_error()}. posix_readdir(_Dir) -> erlang:nif_error(undefined). + +%% @hidden +-spec get_creation() -> non_neg_integer(). +get_creation() -> + erlang:nif_error(undefined). diff --git a/libs/estdlib/src/erlang.erl b/libs/estdlib/src/erlang.erl index a5834f2c5..a11ee7b03 100644 --- a/libs/estdlib/src/erlang.erl +++ b/libs/estdlib/src/erlang.erl @@ -1270,6 +1270,6 @@ localtime() -> erlang:nif_error(undefined). %% @hidden --spec setnode(atom(), pos_integer()) -> true. +-spec setnode(atom(), non_neg_integer()) -> true. setnode(_NodeName, _Creation) -> erlang:nif_error(undefined). diff --git a/src/libAtomVM/nifs.c b/src/libAtomVM/nifs.c index ea904958d..f0bf5c90b 100644 --- a/src/libAtomVM/nifs.c +++ b/src/libAtomVM/nifs.c @@ -167,7 +167,7 @@ static term nif_erlang_function_exported(Context *ctx, int argc, term argv[]); static term nif_erlang_garbage_collect(Context *ctx, int argc, term argv[]); static term nif_erlang_group_leader(Context *ctx, int argc, term argv[]); static term nif_erlang_get_module_info(Context *ctx, int argc, term argv[]); -static term nif_erlang_setnode(Context *ctx, int argc, term argv[]); +static term nif_erlang_setnode_2(Context *ctx, int argc, term argv[]); static term nif_erlang_memory(Context *ctx, int argc, term argv[]); static term nif_erlang_monitor(Context *ctx, int argc, term argv[]); static term nif_erlang_demonitor(Context *ctx, int argc, term argv[]); @@ -177,6 +177,7 @@ static term nif_atomvm_add_avm_pack_file(Context *ctx, int argc, term argv[]); static term nif_atomvm_close_avm_pack(Context *ctx, int argc, term argv[]); static term nif_atomvm_get_start_beam(Context *ctx, int argc, term argv[]); static term nif_atomvm_read_priv(Context *ctx, int argc, term argv[]); +static term nif_atomvm_get_creation(Context *ctx, int argc, term argv[]); static term nif_console_print(Context *ctx, int argc, term argv[]); static term nif_base64_encode(Context *ctx, int argc, term argv[]); static term nif_base64_decode(Context *ctx, int argc, term argv[]); @@ -669,10 +670,10 @@ static const struct Nif get_module_info_nif = .nif_ptr = nif_erlang_get_module_info }; -static const struct Nif setnode_nif = +static const struct Nif setnode_2_nif = { .base.type = NIFFunctionType, - .nif_ptr = nif_erlang_setnode + .nif_ptr = nif_erlang_setnode_2 }; static const struct Nif raise_nif = @@ -736,6 +737,11 @@ static const struct Nif atomvm_read_priv_nif = .base.type = NIFFunctionType, .nif_ptr = nif_atomvm_read_priv }; +static const struct Nif atomvm_get_creation_nif = +{ + .base.type = NIFFunctionType, + .nif_ptr = nif_atomvm_get_creation +}; static const struct Nif console_print_nif = { .base.type = NIFFunctionType, @@ -3975,7 +3981,7 @@ static term nif_erlang_get_module_info(Context *ctx, int argc, term argv[]) return result; } -static term nif_erlang_setnode(Context *ctx, int argc, term argv[]) +static term nif_erlang_setnode_2(Context *ctx, int argc, term argv[]) { UNUSED(argc); @@ -4343,6 +4349,19 @@ static term nif_atomvm_read_priv(Context *ctx, int argc, term argv[]) return result; } +// AtomVM extension, equivalent to erts_internal:get_creation/0 +static term nif_atomvm_get_creation(Context *ctx, int argc, term argv[]) +{ + UNUSED(argc); + UNUSED(argv); + + if (UNLIKELY(memory_ensure_free_opt(ctx, term_boxed_integer_size(ctx->global->creation), MEMORY_CAN_SHRINK) != MEMORY_GC_OK)) { + RAISE_ERROR(OUT_OF_MEMORY_ATOM); + } + + return term_make_maybe_boxed_int64(ctx->global->creation, &ctx->heap); +} + static term nif_console_print(Context *ctx, int argc, term argv[]) { UNUSED(argc); diff --git a/src/libAtomVM/nifs.gperf b/src/libAtomVM/nifs.gperf index 199aeb3d5..a4a3afe04 100644 --- a/src/libAtomVM/nifs.gperf +++ b/src/libAtomVM/nifs.gperf @@ -128,7 +128,7 @@ erlang:group_leader/0, &group_leader_nif erlang:group_leader/2, &group_leader_nif erlang:get_module_info/1, &get_module_info_nif erlang:get_module_info/2, &get_module_info_nif -erlang:setnode/2, &setnode_nif +erlang:setnode/2, &setnode_2_nif erts_debug:flat_size/1, &flat_size_nif ets:new/2, &ets_new_nif ets:insert/2, &ets_insert_nif @@ -154,6 +154,7 @@ atomvm:posix_clock_settime/2, IF_HAVE_CLOCK_SETTIME_OR_SETTIMEOFDAY(&atomvm_posi atomvm:posix_opendir/1, IF_HAVE_OPENDIR_READDIR_CLOSEDIR(&atomvm_posix_opendir_nif) atomvm:posix_closedir/1, IF_HAVE_OPENDIR_READDIR_CLOSEDIR(&atomvm_posix_closedir_nif) atomvm:posix_readdir/1, IF_HAVE_OPENDIR_READDIR_CLOSEDIR(&atomvm_posix_readdir_nif) +atomvm:get_creation/0, &atomvm_get_creation_nif code:load_abs/1, &code_load_abs_nif code:load_binary/3, &code_load_binary_nif code:all_available/0, &code_all_available_nif diff --git a/tests/erlang_tests/test_node.erl b/tests/erlang_tests/test_node.erl index da5fc52d0..751c21aef 100644 --- a/tests/erlang_tests/test_node.erl +++ b/tests/erlang_tests/test_node.erl @@ -47,6 +47,7 @@ test_node_distribution() -> ), register(net_kernel, NetKernelPid), true = erlang:setnode(test@test_node, 42), + 42 = get_creation(), test@test_node = node(), NetKernelPid ! quit, ok = @@ -74,6 +75,14 @@ has_setnode_creation() -> OTPRelease >= "23" end. +get_creation() -> + case erlang:system_info(machine) of + "ATOM" -> + atomvm:get_creation(); + "BEAM" -> + erts_internal:get_creation() + end. + sleep(Ms) -> receive after Ms -> ok