Support more features for rt-thread (#3661)

1, enable thread mgr
2, enable libc wasi
3, enable libc wasi threads
4, specify a function name of the module to run rather main
This commit is contained in:
dongsheng28849455 2024-07-26 10:34:15 +08:00 committed by GitHub
parent 4dfdbbb5a5
commit 6e727dc18d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 1283 additions and 95 deletions

1
.gitignore vendored
View File

@ -12,6 +12,7 @@
*.so
.clangd
.DS_Store
*.o
core/deps/**
core/shared/mem-alloc/tlsf

View File

@ -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'))

View File

@ -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']

View File

@ -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')

View File

@ -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')

View File

@ -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')

View File

@ -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')

View File

@ -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

View File

@ -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);

View File

@ -7,7 +7,16 @@
#ifndef RTTHREAD_PLATFORM_INTERNAL_H
#define RTTHREAD_PLATFORM_INTERNAL_H
#include <sys/ioctl.h>
#include <fcntl.h>
#include <limits.h>
#include <errno.h>
#include <poll.h>
#if defined(RT_USING_PTHREADS)
#include <pthread.h>
#else
#include <rtthread.h>
#endif
#include <stdbool.h>
#include <string.h>
#include <stdio.h>
@ -15,6 +24,8 @@
#include <math.h>
#include <stdint.h>
#include <ctype.h>
#include <dirent.h>
#include <assert.h>
#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 {

View File

@ -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 <errno.h>
#include <stdio.h>
#include <stddef.h>
#include <fcntl.h>
#include <stdint.h>
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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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 <errno.h>
#include <stdio.h>
#include <stddef.h>
#include <fcntl.h>
#include <stdint.h>
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);
}

View File

@ -11,6 +11,10 @@
#include <dfs_file.h>
#include <dfs_fs.h>
#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> <wasm_args ...>\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> <wasm_args ...>\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 */