diff --git a/.gitignore b/.gitignore index 8a8d9ac2..355d391f 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ *.so .clangd .DS_Store +*.o core/deps/** core/shared/mem-alloc/tlsf @@ -37,4 +38,4 @@ tests/benchmarks/coremark/coremark* samples/workload/include/** !samples/workload/include/.gitkeep -# core/iwasm/libraries/wasi-threads \ No newline at end of file +# core/iwasm/libraries/wasi-threads diff --git a/build-scripts/SConscript b/build-scripts/SConscript index 648373b3..ccb1b19f 100644 --- a/build-scripts/SConscript +++ b/build-scripts/SConscript @@ -31,9 +31,11 @@ if GetDepend(['WAMR_BUILD_LIBC_BUILTIN']): if GetDepend(['WAMR_BUILD_LIBC_WASI']): objs += SConscript(os.path.join(IWASM_DIR, 'libraries', 'libc-wasi', 'SConscript')) + objs += SConscript(os.path.join(SHARED_DIR, 'platform', 'common', 'posix', 'SConscript')) + objs += SConscript(os.path.join(SHARED_DIR, 'platform', 'common', 'libc-util', 'SConscript')) if GetDepend(['WAMR_BUILD_LIB_PTHREAD']): - objs += SConscript(os.path.join(IWASM_DIR, 'libraries', 'libc-pthread', 'SConscript')) + objs += SConscript(os.path.join(IWASM_DIR, 'libraries', 'lib-pthread', 'SConscript')) if GetDepend(['WAMR_BUILD_THREAD_MGR']): objs += SConscript(os.path.join(IWASM_DIR, 'libraries', 'thread-mgr', 'SConscript')) @@ -41,6 +43,9 @@ if GetDepend(['WAMR_BUILD_THREAD_MGR']): if GetDepend(['WAMR_BUILD_LIBC_EMCC']): objs += SConscript(os.path.join(IWASM_DIR, 'libraries', 'libc-emmc', 'SConscript')) +if GetDepend(['WAMR_BUILD_LIB_WASI_THREADS']): + objs += SConscript(os.path.join(IWASM_DIR, 'libraries', 'lib-wasi-threads', 'SConscript')) + objs += SConscript(os.path.join(cwd, 'SConscript_config')); objs += SConscript(os.path.join(SHARED_DIR, 'platform', 'rt-thread', 'SConscript')) diff --git a/build-scripts/SConscript_config b/build-scripts/SConscript_config index 2401f3aa..246bd0aa 100644 --- a/build-scripts/SConscript_config +++ b/build-scripts/SConscript_config @@ -109,7 +109,27 @@ if GetDepend(['WAMR_BUILD_CUSTOM_NAME_SECTION']): if GetDepend(['WAMR_BUILD_TAIL_CALL']): CPPDEFINES += ['WASM_ENABLE_TAIL_CALL=1'] - print('[WAMR] Tail call enabledd') + print('[WAMR] Tail call enabled') + +if GetDepend(['WAMR_BUILD_THREAD_MGR']): + CPPDEFINES += ['WASM_ENABLE_THREAD_MGR=1'] + print('[WAMR] Thread manager enabled') + +if GetDepend(['WAMR_BUILD_LIBC_WASI']): + CPPDEFINES += ['WASM_ENABLE_LIBC_WASI=1'] + CPPDEFINES += ['WASM_ENABLE_MODULE_INST_CONTEXT=1'] + print('[WAMR] Libc wasi enabled') + +if GetDepend(['WAMR_BUILD_LIB_WASI_THREADS']): + CPPDEFINES += ['WASM_ENABLE_LIB_WASI_THREADS=1'] + print('[WAMR] Lib wasi threads enabled') + +if GetDepend(['WAMR_BUILD_REF_TYPES']): + CPPDEFINES += ['WASM_ENABLE_REF_TYPES=1'] + print('[WAMR] enable ref types') + +CPPDEFINES += ['BH_MALLOC=wasm_runtime_malloc'] +CPPDEFINES += ['BH_FREE=wasm_runtime_free'] LIBS = ['m'] diff --git a/core/iwasm/libraries/lib-pthread/SConscript b/core/iwasm/libraries/lib-pthread/SConscript index d03936c2..1eb1cc24 100644 --- a/core/iwasm/libraries/lib-pthread/SConscript +++ b/core/iwasm/libraries/lib-pthread/SConscript @@ -9,12 +9,12 @@ from building import * cwd = GetCurrentDir() src = Split(''' -libc_pthread_wrapper.c +lib_pthread_wrapper.c ''') CPPPATH = [cwd] -group = DefineGroup('iwasm_libc_pthread', src, depend = [''], CPPPATH = CPPPATH) +group = DefineGroup('iwasm_lib_pthread', src, depend = [''], CPPPATH = CPPPATH) Return('group') diff --git a/core/iwasm/libraries/lib-wasi-threads/SConscript b/core/iwasm/libraries/lib-wasi-threads/SConscript new file mode 100755 index 00000000..c4d62e3d --- /dev/null +++ b/core/iwasm/libraries/lib-wasi-threads/SConscript @@ -0,0 +1,15 @@ +# +# Copyright 2024 Sony Semiconductor Solutions Corporation. +# +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# + +from building import * + +cwd = GetCurrentDir() +src = Glob('*.c') +CPPPATH = [cwd] + +group = DefineGroup('iwasm_lib_wasi_threads', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/core/shared/platform/common/libc-util/SConscript b/core/shared/platform/common/libc-util/SConscript new file mode 100644 index 00000000..7180b26c --- /dev/null +++ b/core/shared/platform/common/libc-util/SConscript @@ -0,0 +1,20 @@ +# +# Copyright 2024 Sony Semiconductor Solutions Corporation. +# +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# + +from building import * +import re + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Split(''' +libc_errno.c +''') +CPPPATH = [cwd] + +group = DefineGroup('iwasm_libc_util', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/core/shared/platform/common/posix/SConscript b/core/shared/platform/common/posix/SConscript new file mode 100644 index 00000000..48cffda2 --- /dev/null +++ b/core/shared/platform/common/posix/SConscript @@ -0,0 +1,20 @@ +# +# Copyright 2024 Sony Semiconductor Solutions Corporation. +# +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# + +from building import * +import re + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Split(''' +posix_file.c +''') +CPPPATH = [cwd] + +group = DefineGroup('iwasm_common_posix', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/core/shared/platform/common/posix/posix_file.c b/core/shared/platform/common/posix/posix_file.c index ac7e5853..e3aec9f4 100644 --- a/core/shared/platform/common/posix/posix_file.c +++ b/core/shared/platform/common/posix/posix_file.c @@ -26,7 +26,7 @@ * (platform_internal.h) */ #if !defined(CONFIG_HAS_D_INO) -#if !defined(__NuttX__) +#if !defined(__NuttX__) && !defined(__RTTHREAD__) #define CONFIG_HAS_D_INO 1 #define CONFIG_HAS_ISATTY 1 #else diff --git a/core/shared/platform/common/posix/posix_thread.c b/core/shared/platform/common/posix/posix_thread.c index 189092e9..39baaa23 100644 --- a/core/shared/platform/common/posix/posix_thread.c +++ b/core/shared/platform/common/posix/posix_thread.c @@ -4,8 +4,10 @@ */ #ifndef _GNU_SOURCE +#if !defined(__RTTHREAD__) #define _GNU_SOURCE #endif +#endif #include "platform_api_vmcore.h" #include "platform_api_extension.h" @@ -448,7 +450,7 @@ os_thread_get_stack_boundary() addr += guard_size; } (void)stack_size; -#elif defined(__APPLE__) || defined(__NuttX__) +#elif defined(__APPLE__) || defined(__NuttX__) || defined(__RTTHREAD__) if ((addr = (uint8 *)pthread_get_stackaddr_np(self))) { stack_size = pthread_get_stacksize_np(self); diff --git a/core/shared/platform/rt-thread/platform_internal.h b/core/shared/platform/rt-thread/platform_internal.h index 4ebdabb1..69d6d558 100644 --- a/core/shared/platform/rt-thread/platform_internal.h +++ b/core/shared/platform/rt-thread/platform_internal.h @@ -7,7 +7,16 @@ #ifndef RTTHREAD_PLATFORM_INTERNAL_H #define RTTHREAD_PLATFORM_INTERNAL_H +#include +#include +#include +#include +#include +#if defined(RT_USING_PTHREADS) +#include +#else #include +#endif #include #include #include @@ -15,6 +24,8 @@ #include #include #include +#include +#include #if defined(WASM_ENABLE_AOT) #if defined(RTT_WAMR_BUILD_TARGET_THUMB) @@ -32,12 +43,67 @@ #endif #endif /* WASM_ENABLE_AOT */ +/* Use rt-thread's definition as default */ +#if 0 // defined(RT_USING_PTHREADS) +typedef pthread_t korp_tid; +typedef pthread_mutex_t korp_mutex; +typedef pthread_cond_t korp_cond; +typedef pthread_t korp_thread; +#else typedef rt_thread_t korp_tid; typedef struct rt_mutex korp_mutex; typedef struct rt_thread korp_cond; typedef struct rt_thread korp_thread; +#endif typedef unsigned int korp_sem; +#if !defined(socklen_t) && !defined(SOCKLEN_T_DEFINED) +typedef uint32_t socklen_t; +#endif + +#if !defined(SOL_SOCKET) +#define SOL_SOCKET 1 +#endif + +#if !defined(SO_TYPE) +#define SO_TYPE 3 +#endif + +#if !defined(SOCK_DGRAM) +#define SOCK_DGRAM 2 +#endif + +#if !defined(SOCK_STREAM) +#define SOCK_STREAM 1 +#endif + +#if !defined(UTIME_NOW) +#define UTIME_NOW -2L +#endif + +#if !defined(UTIME_OMIT) +#define UTIME_OMIT -1L +#endif + +#if !defined(AT_SYMLINK_NOFOLLOW) +#define AT_SYMLINK_NOFOLLOW 2 +#endif + +#if !defined(AT_SYMLINK_FOLLOW) +#define AT_SYMLINK_FOLLOW 4 +#endif + +#if !defined(AT_REMOVEDIR) +#define AT_REMOVEDIR 8 +#endif + +#define DT_BLK 0x06 +#define DT_CHR 0x02 +#define DT_LNK 0x0A + +#define PTHREAD_STACK_MIN 1024 +#define BH_THREAD_DEFAULT_PRIORITY 30 + /* korp_rwlock is used in platform_api_extension.h, we just define the type to make the compiler happy */ typedef struct { diff --git a/core/shared/platform/rt-thread/rtt_file.c b/core/shared/platform/rt-thread/rtt_file.c new file mode 100644 index 00000000..b9fd1f9f --- /dev/null +++ b/core/shared/platform/rt-thread/rtt_file.c @@ -0,0 +1,194 @@ +/* + * Copyright 2024 Sony Semiconductor Solutions Corporation. + * + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include "platform_api_vmcore.h" +#include "platform_api_extension.h" + +#include +#include +#include +#include +#include + +struct iovec { + void *iov_base; + size_t iov_len; +}; + +ssize_t +readv(int fd, const struct iovec *iov, int iovcnt) +{ + ssize_t ntotal; + ssize_t nread; + size_t remaining; + uint8_t *buffer; + int i; + + /* Process each entry in the struct iovec array */ + + for (i = 0, ntotal = 0; i < iovcnt; i++) { + /* Ignore zero-length reads */ + + if (iov[i].iov_len > 0) { + buffer = iov[i].iov_base; + remaining = iov[i].iov_len; + + /* Read repeatedly as necessary to fill buffer */ + + do { + /* NOTE: read() is a cancellation point */ + + nread = read(fd, buffer, remaining); + + /* Check for a read error */ + + if (nread < 0) { + return nread; + } + + /* Check for an end-of-file condition */ + + else if (nread == 0) { + return ntotal; + } + + /* Update pointers and counts in order to handle partial + * buffer reads. + */ + + buffer += nread; + remaining -= nread; + ntotal += nread; + } while (remaining > 0); + } + } + + return ntotal; +} + +ssize_t +writev(int fd, const struct iovec *iov, int iovcnt) +{ + uint16_t i, num; + int length; + + num = 0; + for (i = 0; i < iovcnt; i++) { + if (iov[i].iov_len > 0) { + length = write(fd, iov[i].iov_base, iov[i].iov_len); + if (length != iov[i].iov_len) + return errno; + + num += iov[i].iov_len; + } + } + return num; +} + +int +fstatat(int fd, const char *path, struct stat *buf, int flag) +{ + errno = ENOSYS; + return -1; +} + +int +mkdirat(int fd, const char *path, mode_t mode) +{ + errno = ENOSYS; + return -1; +} + +ssize_t +readlinkat(int fd, const char *path, char *buf, size_t bufsize) +{ + errno = EINVAL; + return -1; +} + +int +linkat(int fd1, const char *path1, int fd2, const char *path2, int flag) +{ + errno = ENOSYS; + return -1; +} + +int +renameat(int fromfd, const char *from, int tofd, const char *to) +{ + errno = ENOSYS; + return -1; +} + +int +symlinkat(const char *target, int fd, const char *path) +{ + errno = ENOSYS; + return -1; +} + +int +unlinkat(int fd, const char *path, int flag) +{ + errno = ENOSYS; + return -1; +} + +int +utimensat(int fd, const char *path, const struct timespec *ts, int flag) +{ + errno = ENOSYS; + return -1; +} + +DIR * +fdopendir(int fd) +{ + errno = ENOSYS; + return NULL; +} + +int +fdatasync(int fd) +{ + errno = ENOSYS; + return -1; +} + +ssize_t +preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset) +{ + errno = ENOSYS; + return 0; +} + +ssize_t +pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset) +{ + errno = ENOSYS; + return 0; +} + +char * +realpath(char *path, char *resolved_path) +{ + errno = ENOSYS; + return NULL; +} + +int +futimens(int fd, const struct timespec *times) +{ + errno = ENOSYS; + return -1; +} + +int +posix_fallocate(int __fd, off_t __offset, off_t __length) +{ + errno = ENOSYS; + return -1; +} diff --git a/core/shared/platform/rt-thread/rtt_platform.c b/core/shared/platform/rt-thread/rtt_platform.c index 10c59a7f..904bb52e 100644 --- a/core/shared/platform/rt-thread/rtt_platform.c +++ b/core/shared/platform/rt-thread/rtt_platform.c @@ -134,84 +134,41 @@ os_time_thread_cputime_us(void) return os_time_get_boot_us(); } -korp_tid -os_self_thread(void) -{ - return rt_thread_self(); -} - -uint8 * -os_thread_get_stack_boundary(void) -{ - rt_thread_t tid = rt_thread_self(); - return tid->stack_addr; -} - -void -os_thread_jit_write_protect_np(bool enabled) -{} - -int -os_mutex_init(korp_mutex *mutex) -{ - return rt_mutex_init(mutex, "wamr0", RT_IPC_FLAG_FIFO); -} - -int -os_mutex_destroy(korp_mutex *mutex) -{ - return rt_mutex_detach(mutex); -} - -int -os_mutex_lock(korp_mutex *mutex) -{ - return rt_mutex_take(mutex, RT_WAITING_FOREVER); -} - -int -os_mutex_unlock(korp_mutex *mutex) -{ - return rt_mutex_release(mutex); -} - -/* - * functions below was not implement - */ - -int -os_cond_init(korp_cond *cond) -{ - return 0; -} - -int -os_cond_destroy(korp_cond *cond) -{ - return 0; -} - -int -os_cond_wait(korp_cond *cond, korp_mutex *mutex) -{ - return 0; -} - void * os_mmap(void *hint, size_t size, int prot, int flags, os_file_handle file) { - void *addr; + void *buf_origin; + void *buf_fixed; + rt_ubase_t *addr_field; - if ((addr = rt_malloc(size))) - memset(addr, 0, size); + buf_origin = rt_malloc(size + 8 + sizeof(rt_ubase_t)); + if (!buf_origin) + return NULL; - return addr; + buf_fixed = buf_origin + sizeof(void *); + if ((rt_ubase_t)buf_fixed & 0x7) { + buf_fixed = (void *)((rt_ubase_t)(buf_fixed + 8) & (~7)); + } + + addr_field = buf_fixed - sizeof(rt_ubase_t); + *addr_field = (rt_ubase_t)buf_origin; + + memset(buf_origin, 0, size + 8 + sizeof(rt_ubase_t)); + return buf_fixed; } void os_munmap(void *addr, size_t size) { - rt_free(addr); + void *mem_origin; + rt_ubase_t *addr_field; + + if (addr) { + addr_field = addr - sizeof(rt_ubase_t); + mem_origin = (void *)(*addr_field); + + rt_free(mem_origin); + } } int @@ -227,3 +184,29 @@ os_dcache_flush(void) void os_icache_flush(void *start, size_t len) {} + +int +os_getpagesize(void) +{ + return 4096; +} + +void * +os_mremap(void *in, size_t old_size, size_t new_size) +{ + return os_realloc(in, new_size); +} + +__wasi_errno_t +os_clock_time_get(__wasi_clockid_t clock_id, __wasi_timestamp_t precision, + __wasi_timestamp_t *time) +{ + *time = rt_tick_get() * 1000ll * 1000ll; + return 0; +} + +__wasi_errno_t +os_clock_res_get(__wasi_clockid_t clock_id, __wasi_timestamp_t *resolution) +{ + return 0; +} diff --git a/core/shared/platform/rt-thread/rtt_socket.c b/core/shared/platform/rt-thread/rtt_socket.c new file mode 100644 index 00000000..ae1d9ed3 --- /dev/null +++ b/core/shared/platform/rt-thread/rtt_socket.c @@ -0,0 +1,385 @@ +/* + * Copyright 2024 Sony Semiconductor Solutions Corporation. + * + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include "platform_api_vmcore.h" +#include "platform_api_extension.h" + +int +os_socket_accept(bh_socket_t server_sock, bh_socket_t *sock, void *addr, + unsigned int *addrlen) +{ + return BHT_ERROR; +} + +int +os_socket_connect(bh_socket_t socket, const char *addr, int port) +{ + return BHT_ERROR; +} + +int +os_socket_recv_from(bh_socket_t socket, void *buf, unsigned int len, int flags, + bh_sockaddr_t *src_addr) +{ + return BHT_ERROR; +} + +int +os_socket_send_to(bh_socket_t socket, const void *buf, unsigned int len, + int flags, const bh_sockaddr_t *dest_addr) +{ + return BHT_ERROR; +} + +int +os_socket_addr_resolve(const char *host, const char *service, + uint8_t *hint_is_tcp, uint8_t *hint_is_ipv4, + bh_addr_info_t *addr_info, size_t addr_info_size, + size_t *max_info_size) +{ + return BHT_ERROR; +} + +int +os_socket_close(bh_socket_t socket) +{ + return BHT_ERROR; +} + +int +os_socket_addr_local(bh_socket_t socket, bh_sockaddr_t *sockaddr) +{ + return BHT_ERROR; +} + +int +os_socket_addr_remote(bh_socket_t socket, bh_sockaddr_t *sockaddr) +{ + return BHT_ERROR; +} + +int +os_socket_bind(bh_socket_t socket, const char *host, int *port) +{ + return BHT_ERROR; +} + +int +os_socket_listen(bh_socket_t socket, int max_client) +{ + return BHT_ERROR; +} + +int +os_socket_create(bh_socket_t *sock, bool is_ipv4, bool is_tcp) +{ + return BHT_ERROR; +} + +int +os_socket_send(bh_socket_t socket, const void *buf, unsigned int len) +{ + return BHT_ERROR; +} + +__wasi_errno_t +os_socket_shutdown(bh_socket_t socket) +{ + return __WASI_ENOSYS; +} + +int +os_socket_inet_network(bool is_ipv4, const char *cp, bh_ip_addr_buffer_t *out) +{ + return BHT_ERROR; +} + +int +os_socket_set_send_timeout(bh_socket_t socket, uint64 timeout_us) +{ + return BHT_ERROR; +} + +int +os_socket_get_recv_timeout(bh_socket_t socket, uint64 *timeout_us) +{ + return BHT_ERROR; +} + +int +os_socket_set_send_buf_size(bh_socket_t socket, size_t bufsiz) +{ + return BHT_ERROR; +} + +int +os_socket_get_send_buf_size(bh_socket_t socket, size_t *bufsiz) +{ + return BHT_ERROR; +} + +int +os_socket_set_recv_buf_size(bh_socket_t socket, size_t bufsiz) +{ + return BHT_ERROR; +} + +int +os_socket_get_recv_buf_size(bh_socket_t socket, size_t *bufsiz) +{ + return BHT_ERROR; +} + +int +os_socket_set_broadcast(bh_socket_t socket, bool is_enabled) +{ + return BHT_ERROR; +} + +int +os_socket_get_broadcast(bh_socket_t socket, bool *is_enabled) +{ + return BHT_ERROR; +} + +int +os_socket_get_send_timeout(bh_socket_t socket, uint64 *timeout_us) +{ + return BHT_ERROR; +} + +int +os_socket_set_recv_timeout(bh_socket_t socket, uint64 timeout_us) +{ + return BHT_ERROR; +} + +int +os_socket_set_keep_alive(bh_socket_t socket, bool is_enabled) +{ + return BHT_ERROR; +} + +int +os_socket_get_keep_alive(bh_socket_t socket, bool *is_enabled) +{ + return BHT_ERROR; +} + +int +os_socket_set_reuse_addr(bh_socket_t socket, bool is_enabled) +{ + return BHT_ERROR; +} + +int +os_socket_get_reuse_addr(bh_socket_t socket, bool *is_enabled) +{ + return BHT_ERROR; +} + +int +os_socket_set_reuse_port(bh_socket_t socket, bool is_enabled) +{ + return BHT_ERROR; +} + +int +os_socket_get_reuse_port(bh_socket_t socket, bool *is_enabled) +{ + return BHT_ERROR; +} + +int +os_socket_set_linger(bh_socket_t socket, bool is_enabled, int linger_s) +{ + return BHT_ERROR; +} + +int +os_socket_get_linger(bh_socket_t socket, bool *is_enabled, int *linger_s) +{ + return BHT_ERROR; +} + +int +os_socket_set_tcp_no_delay(bh_socket_t socket, bool is_enabled) +{ + return BHT_ERROR; +} + +int +os_socket_get_tcp_no_delay(bh_socket_t socket, bool *is_enabled) +{ + return BHT_ERROR; +} + +int +os_socket_set_tcp_quick_ack(bh_socket_t socket, bool is_enabled) +{ + return BHT_ERROR; +} + +int +os_socket_get_tcp_quick_ack(bh_socket_t socket, bool *is_enabled) +{ + return BHT_ERROR; +} + +int +os_socket_set_tcp_keep_idle(bh_socket_t socket, uint32 time_s) +{ + return BHT_ERROR; +} + +int +os_socket_get_tcp_keep_idle(bh_socket_t socket, uint32 *time_s) +{ + return BHT_ERROR; +} + +int +os_socket_set_tcp_keep_intvl(bh_socket_t socket, uint32 time_s) +{ + return BHT_ERROR; +} + +int +os_socket_get_tcp_keep_intvl(bh_socket_t socket, uint32 *time_s) +{ + return BHT_ERROR; +} + +int +os_socket_set_tcp_fastopen_connect(bh_socket_t socket, bool is_enabled) +{ + return BHT_ERROR; +} + +int +os_socket_get_tcp_fastopen_connect(bh_socket_t socket, bool *is_enabled) +{ + return BHT_ERROR; +} + +int +os_socket_set_ip_multicast_loop(bh_socket_t socket, bool ipv6, bool is_enabled) +{ + return BHT_ERROR; +} + +int +os_socket_get_ip_multicast_loop(bh_socket_t socket, bool ipv6, bool *is_enabled) +{ + return BHT_ERROR; +} + +int +os_socket_set_ip_add_membership(bh_socket_t socket, + bh_ip_addr_buffer_t *imr_multiaddr, + uint32_t imr_interface, bool is_ipv6) +{ + return BHT_ERROR; +} + +int +os_socket_set_ip_drop_membership(bh_socket_t socket, + bh_ip_addr_buffer_t *imr_multiaddr, + uint32_t imr_interface, bool is_ipv6) +{ + return BHT_ERROR; +} + +int +os_socket_set_ip_ttl(bh_socket_t socket, uint8_t ttl_s) +{ + return BHT_ERROR; +} + +int +os_socket_get_ip_ttl(bh_socket_t socket, uint8_t *ttl_s) +{ + return BHT_ERROR; +} + +int +os_socket_set_ip_multicast_ttl(bh_socket_t socket, uint8_t ttl_s) +{ + return BHT_ERROR; +} + +int +os_socket_get_ip_multicast_ttl(bh_socket_t socket, uint8_t *ttl_s) +{ + return BHT_ERROR; +} + +int +os_socket_set_ipv6_only(bh_socket_t socket, bool is_enabled) +{ + return BHT_ERROR; +} + +int +os_socket_get_ipv6_only(bh_socket_t socket, bool *is_enabled) +{ + return BHT_ERROR; +} + +static void +swap16(uint8 *pData) +{ + uint8 value = *pData; + *(pData) = *(pData + 1); + *(pData + 1) = value; +} + +static void +swap32(uint8 *pData) +{ + uint8 value = *pData; + *pData = *(pData + 3); + *(pData + 3) = value; + + value = *(pData + 1); + *(pData + 1) = *(pData + 2); + *(pData + 2) = value; +} + +/** In-enclave implementation of POSIX functions **/ +static bool +is_little_endian() +{ + long i = 0x01020304; + unsigned char *c = (unsigned char *)&i; + return (*c == 0x04) ? true : false; +} + +uint16 +htons(uint16 value) +{ + uint16 ret; + if (is_little_endian()) { + ret = value; + swap16((uint8 *)&ret); + return ret; + } + + return value; +} + +uint32 +htonl(uint32 value) +{ + uint32 ret; + if (is_little_endian()) { + ret = value; + swap32((uint8 *)&ret); + return ret; + } + + return value; +} diff --git a/core/shared/platform/rt-thread/rtt_thread.c b/core/shared/platform/rt-thread/rtt_thread.c new file mode 100644 index 00000000..5f988fad --- /dev/null +++ b/core/shared/platform/rt-thread/rtt_thread.c @@ -0,0 +1,427 @@ +/* + * Copyright 2024 Sony Semiconductor Solutions Corporation. + * + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include "platform_api_vmcore.h" +#include "platform_api_extension.h" + +#include +#include +#include +#include +#include + +struct os_thread_data; +typedef struct os_thread_wait_node *os_thread_wait_list; +typedef struct os_thread_wait_node { + /* Binary semaphore */ + rt_sem_t sem; + os_thread_wait_list next; +} os_thread_wait_node; + +typedef struct os_thread_data { + /* Next thread data */ + struct os_thread_data *next; + /* Thread handle */ + rt_thread_t handle; + /* Thread start routine */ + thread_start_routine_t start_routine; + /* Thread start routine argument */ + void *arg; + /* Wait node of current thread */ + os_thread_wait_node wait_node; + /* Lock for waiting list */ + rt_mutex_t wait_list_lock; + /* Waiting list of other threads who are joining this thread */ + os_thread_wait_list thread_wait_list; +} os_thread_data; + +/* Lock for thread data list */ +static rt_mutex_t thread_data_lock; + +static bool is_thread_sys_inited = false; + +/* Thread data list */ +static os_thread_data *thread_data_list = NULL; + +/* Thread data of supervisor thread */ +static os_thread_data supervisor_thread_data; + +/* Thread name index */ +static int thread_name_index = 0; + +static void +thread_data_list_add(os_thread_data *thread_data) +{ + rt_mutex_take(thread_data_lock, RT_WAITING_FOREVER); + if (!thread_data_list) + thread_data_list = thread_data; + else { + /* If already in list, just return */ + os_thread_data *p = thread_data_list; + while (p) { + if (p == thread_data) { + rt_mutex_release(thread_data_lock); + return; + } + p = p->next; + } + + /* Set as head of list */ + thread_data->next = thread_data_list; + thread_data_list = thread_data; + } + rt_mutex_release(thread_data_lock); +} + +static void +os_thread_wrapper(void *arg) +{ + os_thread_data *thread_data = arg; + + thread_data->handle = rt_thread_self(); + thread_data_list_add(thread_data); + + thread_data->start_routine(thread_data->arg); + rt_kprintf("start_routine quit\n"); + os_thread_exit(NULL); +} + +static void +thread_data_list_remove(os_thread_data *thread_data) +{ + rt_mutex_take(thread_data_lock, RT_WAITING_FOREVER); + if (thread_data_list) { + if (thread_data_list == thread_data) + thread_data_list = thread_data_list->next; + else { + /* Search and remove it from list */ + os_thread_data *p = thread_data_list; + while (p && p->next != thread_data) + p = p->next; + if (p && p->next == thread_data) + p->next = p->next->next; + } + } + rt_mutex_release(thread_data_lock); +} + +static os_thread_data * +thread_data_list_lookup(rt_thread_t handle) +{ + rt_mutex_take(thread_data_lock, RT_WAITING_FOREVER); + if (thread_data_list) { + os_thread_data *p = thread_data_list; + while (p) { + if (p->handle == handle) { + /* Found */ + rt_mutex_release(thread_data_lock); + return p; + } + p = p->next; + } + } + rt_mutex_release(thread_data_lock); + return NULL; +} + +static os_thread_data * +thread_data_current() +{ + rt_thread_t handle = rt_thread_self(); + return thread_data_list_lookup(handle); +} + +int +os_thread_sys_init() +{ + if (is_thread_sys_inited) + return BHT_OK; + + if (!(thread_data_lock = + rt_mutex_create("thread_data_lock_mutex", RT_IPC_FLAG_FIFO))) + return BHT_ERROR; + + /* Initialize supervisor thread data */ + memset(&supervisor_thread_data, 0, sizeof(supervisor_thread_data)); + + if (!(supervisor_thread_data.wait_node.sem = + rt_sem_create("spvr", 0, RT_IPC_FLAG_PRIO))) { + rt_mutex_delete(thread_data_lock); + return BHT_ERROR; + } + + supervisor_thread_data.handle = rt_thread_self(); + /* Set as head of thread data list */ + thread_data_list = &supervisor_thread_data; + + is_thread_sys_inited = true; + return BHT_OK; +} + +void +os_thread_sys_destroy() +{ + if (is_thread_sys_inited) { + rt_sem_release(supervisor_thread_data.wait_node.sem); + rt_mutex_delete(thread_data_lock); + is_thread_sys_inited = false; + } +} + +korp_tid +os_self_thread(void) +{ + return rt_thread_self(); +} + +uint8 * +os_thread_get_stack_boundary(void) +{ + rt_thread_t tid = rt_thread_self(); + return tid->stack_addr; +} + +void +os_thread_jit_write_protect_np(bool enabled) +{} + +int +os_mutex_init(korp_mutex *mutex) +{ + return rt_mutex_init(mutex, "wamr0", RT_IPC_FLAG_FIFO); +} + +int +os_mutex_destroy(korp_mutex *mutex) +{ + return rt_mutex_detach(mutex); +} + +int +os_mutex_lock(korp_mutex *mutex) +{ + return rt_mutex_take(mutex, RT_WAITING_FOREVER); +} + +int +os_mutex_unlock(korp_mutex *mutex) +{ + return rt_mutex_release(mutex); +} + +/* + * functions below was not implement + */ + +int +os_cond_init(korp_cond *cond) +{ + return 0; +} + +int +os_cond_destroy(korp_cond *cond) +{ + return 0; +} + +int +os_cond_wait(korp_cond *cond, korp_mutex *mutex) +{ + return 0; +} + +int +os_cond_signal(korp_cond *cond) +{ + return 0; +} + +int +os_cond_reltimedwait(korp_cond *cond, korp_mutex *mutex, uint64 useconds) +{ + return 0; +} + +int +os_rwlock_init(korp_rwlock *lock) +{ + return BHT_OK; +} + +int +os_rwlock_rdlock(korp_rwlock *lock) +{ + + return BHT_OK; +} + +int +os_rwlock_wrlock(korp_rwlock *lock) +{ + + return BHT_OK; +} + +int +os_rwlock_unlock(korp_rwlock *lock) +{ + return BHT_OK; +} + +int +os_rwlock_destroy(korp_rwlock *lock) +{ + return BHT_OK; +} + +int +os_thread_create_with_prio(korp_tid *p_tid, thread_start_routine_t start, + void *arg, unsigned int stack_size, int prio) +{ + os_thread_data *thread_data; + char thread_name[32]; + void *stack; + + if (!p_tid || !stack_size) + return BHT_ERROR; + + /* Create and initialize thread data */ + if (!(thread_data = rt_malloc(sizeof(os_thread_data)))) + return BHT_ERROR; + + memset(thread_data, 0, sizeof(os_thread_data)); + + thread_data->start_routine = start; + thread_data->arg = arg; + + if (!(thread_data->wait_node.sem = + rt_sem_create("sem", 0, RT_IPC_FLAG_PRIO))) + goto fail1; + + if (!(thread_data->wait_list_lock = + rt_mutex_create("wait_list_lock_mutex", RT_IPC_FLAG_FIFO))) + goto fail2; + + snprintf(thread_name, sizeof(thread_name), "%s%d", "wasm-thread-", + ++thread_name_index); + + thread_data->handle = rt_thread_create(thread_name, os_thread_wrapper, + thread_data, stack_size, 15, 5); + if (thread_data->handle == RT_NULL) { + rt_kprintf("os_thread_create_with_prio failed, tid=%d\n", + thread_data->handle); + goto fail3; + } + + thread_data_list_add(thread_data); + *p_tid = thread_data->handle; + rt_thread_startup(*p_tid); + return BHT_OK; + +fail3: + rt_mutex_delete(thread_data->wait_list_lock); +fail2: + rt_sem_delete(thread_data->wait_node.sem); +fail1: + rt_free(thread_data); + return BHT_ERROR; +} + +int +os_thread_create(korp_tid *p_tid, thread_start_routine_t start, void *arg, + unsigned int stack_size) +{ + return os_thread_create_with_prio(p_tid, start, arg, stack_size, + BH_THREAD_DEFAULT_PRIORITY); +} + +int +os_thread_detach(korp_tid thread) +{ + /* Do nothing */ + (void)thread; + return BHT_OK; +} + +int +os_thread_join(korp_tid thread, void **value_ptr) +{ + os_thread_data *thread_data, *curr_thread_data; + rt_thread_t handle = thread; + + (void)value_ptr; + + /* Get thread data of current thread */ + curr_thread_data = thread_data_current(); + curr_thread_data->wait_node.next = NULL; + + /* Get thread data */ + thread_data = thread_data_list_lookup(handle); + + rt_mutex_take(thread_data->wait_list_lock, RT_WAITING_FOREVER); + if (!thread_data->thread_wait_list) + thread_data->thread_wait_list = &curr_thread_data->wait_node; + else { + /* Add to end of waiting list */ + os_thread_wait_node *p = thread_data->thread_wait_list; + while (p->next) + p = p->next; + p->next = &curr_thread_data->wait_node; + } + rt_mutex_release(thread_data->wait_list_lock); + + /* Wait the sem */ + rt_sem_take(curr_thread_data->wait_node.sem, RT_WAITING_FOREVER); + return BHT_OK; +} + +static void +os_thread_cleanup(void) +{ + os_thread_data *thread_data = thread_data_current(); + os_thread_wait_list thread_wait_list; + rt_mutex_t wait_list_lock; + rt_sem_t wait_node_sem; + + // bh_assert(thread_data != NULL); + wait_list_lock = thread_data->wait_list_lock; + thread_wait_list = thread_data->thread_wait_list; + wait_node_sem = thread_data->wait_node.sem; + + rt_mutex_take(wait_list_lock, RT_WAITING_FOREVER); + if (thread_wait_list) { + /* Signal each joining thread */ + os_thread_wait_list head = thread_wait_list; + while (head) { + os_thread_wait_list next = head->next; + rt_sem_release(head->sem); + head = next; + } + } + rt_mutex_release(wait_list_lock); + + /* Free sem and lock */ + rt_sem_delete(wait_node_sem); + rt_mutex_delete(wait_list_lock); + + thread_data_list_remove(thread_data); + rt_free(thread_data); +} + +void +os_thread_exit(void *retval) +{ + (void)retval; + os_thread_cleanup(); + // vTaskDelete(NULL); +} + +int +os_thread_kill(korp_tid tid, int sig) +{ + return rt_thread_kill(tid, sig); +} diff --git a/product-mini/platforms/rt-thread/iwasm.c b/product-mini/platforms/rt-thread/iwasm.c index 9a21301d..7d15a041 100644 --- a/product-mini/platforms/rt-thread/iwasm.c +++ b/product-mini/platforms/rt-thread/iwasm.c @@ -11,6 +11,10 @@ #include #include +#if WASM_ENABLE_LIBC_WASI != 0 +#include "../common/libc_wasi.c" +#endif + #ifdef WAMR_ENABLE_RTT_EXPORT #ifdef WAMR_RTT_EXPORT_VPRINTF @@ -160,6 +164,15 @@ static NativeSymbol native_export_symbols[] = { #endif /* WAMR_ENABLE_RTT_EXPORT */ +static void * +app_instance_func(wasm_module_inst_t module_inst, const char *func_name, + int app_argc, char **app_argv) +{ + wasm_application_execute_func(module_inst, func_name, app_argc - 1, + app_argv + 1); + return wasm_runtime_get_exception(module_inst); +} + /** * run WASM module instance. * @param module_inst instance of wasm module @@ -170,12 +183,8 @@ static NativeSymbol native_export_symbols[] = { static void * app_instance_main(wasm_module_inst_t module_inst, int app_argc, char **app_argv) { - const char *exception; - wasm_application_execute_main(module_inst, app_argc, app_argv); - if ((exception = wasm_runtime_get_exception(module_inst))) - rt_kprintf("%s\n", exception); - return NULL; + return wasm_runtime_get_exception(module_inst); } rt_uint8_t * @@ -214,28 +223,36 @@ void iwasm_help(void) { #ifdef WAMR_ENABLE_IWASM_PARAMS - rt_kputs("wrong input: iwasm [-t] [-m] [-s] <*.wasm> \n" - " iwasm [-h]\n"); - rt_kputs("\t -h: show this tips.\n"); - rt_kputs("\t -t: show time taking to run this app.\n"); - rt_kputs("\t -m: show memory taking to run this app\n"); - rt_kputs("\t wasm file name and exec params must behind of all vm-param\n"); + rt_kputs("Usage: iwasm [-options] wasm_file [args...]\n"); + rt_kputs("options:\n"); + rt_kputs(" -t Show time taking to run this app.\n"); + rt_kputs(" -m Show memory taking to run this app\n"); + rt_kputs(" -f|--function name Specify a function name of the module " + "to run rather than main\n"); + rt_kputs(" --max-threads=n Set maximum thread number per " + "cluster, default is 4\n"); #else - rt_kputs("wrong input: iwasm <*.wasm> \n"); + rt_kputs("Usage: iwasm wasm_file [args...]\n"); #endif /* WAMR_ENABLE_PARAMS */ } int iwasm(int argc, char **argv) { + const char *exception = NULL; + const char *func_name = NULL; rt_uint8_t *wasm_file_buf = NULL; rt_uint32_t wasm_file_size; - rt_uint32_t stack_size = 4 * 1024, heap_size = 4 * 1024; + rt_uint32_t stack_size = 64 * 1024, heap_size = 256 * 1024; wasm_module_t wasm_module = NULL; wasm_module_inst_t wasm_module_inst = NULL; RuntimeInitArgs init_args; static char error_buf[128] = { 0 }; /* avoid stack overflow */ +#if WASM_ENABLE_LIBC_WASI != 0 + libc_wasi_parse_context_t wasi_parse_ctx; + memset(&wasi_parse_ctx, 0, sizeof(wasi_parse_ctx)); +#endif #ifdef WAMR_ENABLE_IWASM_PARAMS int i_arg_begin; @@ -260,6 +277,17 @@ iwasm(int argc, char **argv) iwasm_help(); return 0; } + else if (argv[i_arg_begin][1] == 'f') { + func_name = argv[++i_arg_begin]; + } + else if (!strncmp(argv[i_arg_begin], "--max-threads=", 14)) { + if (argv[0][14] != '\0') + wasm_runtime_set_max_thread_num(atoi(argv[0] + 14)); + else { + iwasm_help(); + return 0; + } + } else if (argv[i_arg_begin][1] == 0x00) { continue; } @@ -303,8 +331,8 @@ iwasm(int argc, char **argv) rt_thread_t tid; if (show_stack) { tid = rt_thread_self(); - printf("thread stack addr: %p, size: %u, sp: %p\n", tid->stack_addr, - tid->stack_size, tid->sp); + rt_kprintf("thread stack addr: %p, size: %u, sp: %p\n", tid->stack_addr, + tid->stack_size, tid->sp); } #endif /* WAMR_ENABLE_PARAMS */ @@ -326,6 +354,10 @@ iwasm(int argc, char **argv) rt_kprintf("%s\n", error_buf); goto fail2; } +#if WASM_ENABLE_LIBC_WASI != 0 + libc_wasi_init(wasm_module, argc, argv, &wasi_parse_ctx); +#endif + rt_memset(error_buf, 0x00, sizeof(error_buf)); wasm_module_inst = wasm_runtime_instantiate( wasm_module, stack_size, heap_size, error_buf, sizeof(error_buf)); @@ -341,13 +373,31 @@ iwasm(int argc, char **argv) } #endif /* WAMR_ENABLE_PARAMS */ - app_instance_main(wasm_module_inst, argc - i_arg_begin, &argv[i_arg_begin]); + if (func_name) { + exception = app_instance_func(wasm_module_inst, func_name, + argc - i_arg_begin, &argv[i_arg_begin]); + } + else { + exception = app_instance_main(wasm_module_inst, argc - i_arg_begin, + &argv[i_arg_begin]); + rt_kprintf("finshed run app_instance_main\n"); + } + + if (exception) + rt_kprintf("%s\n", exception); + +#if WASM_ENABLE_LIBC_WASI != 0 + if (!exception) { + /* propagate wasi exit code. */ + wasm_runtime_get_wasi_exit_code(wasm_module_inst); + } +#endif #ifdef WAMR_ENABLE_IWASM_PARAMS if (show_time_exec) { ticks_exec = rt_tick_get() - ticks_exec; - printf("[iwasm] execute ticks took: %u [ticks/s = %u]\n", ticks_exec, - RT_TICK_PER_SECOND); + rt_kprintf("[iwasm] execute ticks took: %u [ticks/s = %u]\n", + ticks_exec, RT_TICK_PER_SECOND); } #if defined(RT_USING_HEAP) && defined(RT_USING_MEMHEAP_AS_HEAP) if (show_mem) { @@ -361,8 +411,8 @@ iwasm(int argc, char **argv) } #endif if (show_stack) { - printf("[iwasm] thread stack addr: %p, size: %u, sp: %p\n", - tid->stack_addr, tid->stack_size, tid->sp); + rt_kprintf("[iwasm] thread stack addr: %p, size: %u, sp: %p\n", + tid->stack_addr, tid->stack_size, tid->sp); } #endif /* WAMR_ENABLE_PARAMS */