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:
committed by
GitHub
parent
4dfdbbb5a5
commit
6e727dc18d
20
core/shared/platform/common/libc-util/SConscript
Normal file
20
core/shared/platform/common/libc-util/SConscript
Normal 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')
|
||||
20
core/shared/platform/common/posix/SConscript
Normal file
20
core/shared/platform/common/posix/SConscript
Normal 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')
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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 {
|
||||
|
||||
194
core/shared/platform/rt-thread/rtt_file.c
Normal file
194
core/shared/platform/rt-thread/rtt_file.c
Normal 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;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
||||
385
core/shared/platform/rt-thread/rtt_socket.c
Normal file
385
core/shared/platform/rt-thread/rtt_socket.c
Normal 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;
|
||||
}
|
||||
427
core/shared/platform/rt-thread/rtt_thread.c
Normal file
427
core/shared/platform/rt-thread/rtt_thread.c
Normal 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);
|
||||
}
|
||||
Reference in New Issue
Block a user