diff --git a/Makefile b/Makefile index f00279f..c6633ba 100644 --- a/Makefile +++ b/Makefile @@ -16,6 +16,10 @@ check: -fsyntax-only -Iinclude test/ptoas_linx_type_compat.cpp $(CXX) -std=c++20 -D__linx -include test/linx_host_type_shim.hpp \ -fsyntax-only -Iinclude test/pto0583_contract.cpp + $(CXX) -std=c++20 -D__linx -fsyntax-only -Iinclude \ + test/linx_group_runtime_api.cpp + $(CC) -std=c11 -D__linx -fsyntax-only -Iinclude \ + test/linx_group_runtime_api.c bash -n test/tileop_api/compile.all test/tileop_api/run_negatives.sh \ test/tileop_api/verify_pto0583_asm.sh \ test/tileop_api/verify_target_cxx_frontend.sh diff --git a/README.md b/README.md index b605823..2c80f2f 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ canonical aliases. - [Comparison operations](docs/tileop-usage/cmp.md) - [Sorting operations](docs/tileop-usage/sort.md) - [Fixed-point matrix wrappers](docs/tileop-usage/tmatmul-fixp.md) +- [Hosted four-PE group runtime](docs/tileop-usage/group-runtime.md) ## Validation diff --git a/docs/tileop-usage/group-runtime.md b/docs/tileop-usage/group-runtime.md new file mode 100644 index 0000000..8e8e2eb --- /dev/null +++ b/docs/tileop-usage/group-runtime.md @@ -0,0 +1,41 @@ +# Hosted four-PE group runtime + +The first hosted SMT4 ABI keeps the process runtime on PE0 and uses a small +worker entry for PE1 through PE3. It is intentionally static-only, +single-shot, and independent of glibc or musl internals. + +## Required symbols + +Applications define one worker body: + +```cpp +extern "C" int __linx_group_worker_main(uint32_t peId, void *context); +``` + +PE0 calls: + +```cpp +int status = linx_group_run(context); +``` + +The linked compiler runtime provides `linx_group_run()` and the non-returning +`__linx_group_worker_start` entry consumed by gfrun. + +## Ownership + +- PE0 owns libc startup, TLS, file descriptors, input/output, and process + exit. +- PE1 through PE3 use independent stacks and do not call libc or issue + syscalls. +- `THREAD_ID` selects PE0 through PE3; `BLOCKID` remains the core work ID. +- The worker body publishes one completion status per PE and then parks until + PE0 terminates the process. + +## ELF boundary + +The first ABI supports static executable and static PIE carriers. A +`PT_INTERP` image is rejected. A static PIE may contain `PT_DYNAMIC` for +self-relocation without becoming a dynamically interpreted carrier. + +The executable must retain `__linx_group_worker_start` in its symbol table so +the functional model can assign PE1 through PE3 their initial PC. diff --git a/include/common/linx_group_runtime.h b/include/common/linx_group_runtime.h new file mode 100644 index 0000000..e54525d --- /dev/null +++ b/include/common/linx_group_runtime.h @@ -0,0 +1,28 @@ +#ifndef LINX_GROUP_RUNTIME_H +#define LINX_GROUP_RUNTIME_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* One static ELF provides one group worker body. A direct symbol avoids a + * function-pointer relocation in the first gfrun ABI. */ +int __linx_group_worker_main(uint32_t pe_id, void *context); + +/* Run the ELF's worker body on the fixed four-PE group. PE0 calls this after + * hosted libc and input initialization; PE1..PE3 are already parked in the + * entry exported below. The first non-zero PE status is returned. */ +int linx_group_run(void *context); + +/* Static hosted ELF ABI symbol consumed by gfrun. This entry never enters + * libc and never returns. */ +__attribute__((noreturn, used, visibility("default"))) void +__linx_group_worker_start(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/common/pto_tileop.hpp b/include/common/pto_tileop.hpp index 7ea24f3..892ed55 100644 --- a/include/common/pto_tileop.hpp +++ b/include/common/pto_tileop.hpp @@ -4,6 +4,7 @@ #include "common/pto_tile.hpp" #include "common/tileop_api.hpp" #include "common/global_iterator.hpp" +#include "common/linx_group_runtime.h" #include "common/tile_tensor_impl.hpp" #include "common/debug_utils.hpp" diff --git a/test/linx_group_runtime_api.c b/test/linx_group_runtime_api.c new file mode 100644 index 0000000..5806a75 --- /dev/null +++ b/test/linx_group_runtime_api.c @@ -0,0 +1,7 @@ +#include + +int __linx_group_worker_main(uint32_t pe_id, void *context) { + return context == 0 ? (int)pe_id : 0; +} + +int call_group_runtime_c(void *context) { return linx_group_run(context); } diff --git a/test/linx_group_runtime_api.cpp b/test/linx_group_runtime_api.cpp new file mode 100644 index 0000000..5e657a6 --- /dev/null +++ b/test/linx_group_runtime_api.cpp @@ -0,0 +1,7 @@ +#include + +extern "C" int __linx_group_worker_main(uint32_t peId, void *context) { + return context == nullptr ? static_cast(peId) : 0; +} + +int call_group_runtime(void *context) { return linx_group_run(context); }