re-org platform APIs, simplify porting process (#201)

Co-authored-by: Xu Jun <jun1.xu@intel.com>
This commit is contained in:
Xu Jun 2020-03-16 16:43:57 +08:00 committed by GitHub
parent ef5ceffe71
commit f1a0e75ab7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
177 changed files with 2954 additions and 7904 deletions

View File

@ -3,24 +3,6 @@
string(TOUPPER ${WAMR_BUILD_TARGET} WAMR_BUILD_TARGET)
# Add definitions for the build platform
if (WAMR_BUILD_PLATFORM STREQUAL "linux")
add_definitions(-DBH_PLATFORM_LINUX)
elseif (WAMR_BUILD_PLATFORM STREQUAL "linux-sgx")
add_definitions(-DBH_PLATFORM_LINUX_SGX)
elseif (WAMR_BUILD_PLATFORM STREQUAL "zephyr")
add_definitions(-DBH_PLATFORM_ZEPHYR)
elseif (WAMR_BUILD_PLATFORM STREQUAL "vxworks")
add_definitions(-DBH_PLATFORM_VXWORKS)
elseif (WAMR_BUILD_PLATFORM STREQUAL "darwin")
add_definitions(-DBH_PLATFORM_DARWIN)
elseif (WAMR_BUILD_PLATFORM STREQUAL "alios-things")
add_definitions(-DBH_PLATFORM_ALIOS_THINGS)
elseif (WAMR_BUILD_PLATFORM STREQUAL "android")
add_definitions(-DBH_PLATFORM_ANDROID)
else ()
message (WARNING "-- WAMR build platform isn't set")
endif ()
# Add definitions for the build target
if (WAMR_BUILD_TARGET STREQUAL "X86_64")
@ -53,6 +35,10 @@ else ()
message (FATAL_ERROR "-- WAMR build target isn't set")
endif ()
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
add_definitions(-DBH_DEBUG=1)
endif ()
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
if (WAMR_BUILD_TARGET STREQUAL "X86_64" OR WAMR_BUILD_TARGET STREQUAL "AMD_64")
# Add -fPIC flag if build as 64-bit

View File

@ -16,14 +16,7 @@ typedef union jvalue {
double d;
} jvalue;
#ifndef bh_memcpy_s
int b_memcpy_s(void * s1, unsigned int s1max,
const void * s2, unsigned int n);
#define bh_memcpy_s(dest, dlen, src, slen) do { \
int _ret = slen == 0 ? 0 : b_memcpy_s (dest, dlen, src, slen); \
(void)_ret; \
} while (0)
#endif
static inline int16_t get_int16(const char *buf)
{

View File

@ -9,30 +9,6 @@
/* Note: the bh_plaform.h is the only head file separately
implemented by both [app] and [native] worlds */
#include "bh_platform.h"
#include "wasm_export.h"
#define get_module_inst(exec_env) \
wasm_runtime_get_module_inst(exec_env)
#define validate_app_addr(offset, size) \
wasm_runtime_validate_app_addr(module_inst, offset, size)
#define validate_app_str_addr(offset) \
wasm_runtime_validate_app_str_addr(module_inst, offset)
#define addr_app_to_native(offset) \
wasm_runtime_addr_app_to_native(module_inst, offset)
#define addr_native_to_app(ptr) \
wasm_runtime_addr_native_to_app(module_inst, ptr)
#define module_malloc(size, p_native_addr) \
wasm_runtime_module_malloc(module_inst, size, p_native_addr)
#define module_free(offset) \
wasm_runtime_module_free(module_inst, offset)
/*char *wa_strdup(const char *);*/
#endif /* end of _NATIVE_INTERFACE_H */

View File

@ -79,23 +79,3 @@ char *wa_strdup(const char *s)
memcpy(s1, s, strlen(s) + 1);
return s1;
}
#define RSIZE_MAX 0x7FFFFFFF
int b_memcpy_s(void * s1, unsigned int s1max, const void * s2, unsigned int n)
{
char *dest = (char*) s1;
char *src = (char*) s2;
if (n == 0) {
return 0;
}
if (s1 == NULL || s1max > RSIZE_MAX) {
return -1;
}
if (s2 == NULL || n > s1max) {
memset(dest, 0, s1max);
return -1;
}
memcpy(dest, src, n);
return 0;
}

View File

@ -35,14 +35,14 @@ typedef int int32;
#define WA_FREE free
#endif
char *wa_strdup(const char *s);
uint32 htonl(uint32 value);
uint32 ntohl(uint32 value);
uint16 htons(uint16 value);
uint16 ntohs(uint16 value);
int
b_memcpy_s(void * s1, unsigned int s1max, const void * s2, unsigned int n);
// We are not worried for the WASM world since the sandbox will catch it.
#define bh_memcpy_s(dst, dst_len, src, src_len) memcpy(dst, src, src_len)
#endif /* DEPS_IWASM_APP_LIBS_BASE_BH_PLATFORM_H_ */

View File

@ -3,12 +3,9 @@
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "runtime_timer.h"
#include "bh_platform.h"
#include "app_manager_export.h"
#include "module_wasm_app.h"
#include "bh_list.h"
#include "bh_thread.h"
#include "bh_time.h"
#include "timer_native_api.h"
static bool timer_thread_run = true;
@ -46,7 +43,7 @@ void * thread_modulers_timer_check(void * arg)
while (timer_thread_run) {
ms_to_expiry = -1;
vm_mutex_lock(&g_timer_ctx_list_mutex);
os_mutex_lock(&g_timer_ctx_list_mutex);
timer_ctx_node_t* elem = (timer_ctx_node_t*)
bh_list_first_elem(&g_timer_ctx_list);
while (elem) {
@ -58,14 +55,14 @@ void * thread_modulers_timer_check(void * arg)
elem = (timer_ctx_node_t*) bh_list_elem_next(elem);
}
vm_mutex_unlock(&g_timer_ctx_list_mutex);
os_mutex_unlock(&g_timer_ctx_list_mutex);
if (ms_to_expiry == -1)
ms_to_expiry = 60 * 1000;
vm_mutex_lock(&g_timer_ctx_list_mutex);
vm_cond_reltimedwait(&g_timer_ctx_list_cond, &g_timer_ctx_list_mutex,
ms_to_expiry);
vm_mutex_unlock(&g_timer_ctx_list_mutex);
os_mutex_lock(&g_timer_ctx_list_mutex);
os_cond_reltimedwait(&g_timer_ctx_list_cond, &g_timer_ctx_list_mutex,
ms_to_expiry * 1000);
os_mutex_unlock(&g_timer_ctx_list_mutex);
}
return NULL;
@ -73,9 +70,9 @@ void * thread_modulers_timer_check(void * arg)
void wakeup_modules_timer_thread(timer_ctx_t ctx)
{
vm_mutex_lock(&g_timer_ctx_list_mutex);
vm_cond_signal(&g_timer_ctx_list_cond);
vm_mutex_unlock(&g_timer_ctx_list_mutex);
os_mutex_lock(&g_timer_ctx_list_mutex);
os_cond_signal(&g_timer_ctx_list_cond);
os_mutex_unlock(&g_timer_ctx_list_mutex);
}
void init_wasm_timer()
@ -83,11 +80,11 @@ void init_wasm_timer()
korp_tid tm_tid;
bh_list_init(&g_timer_ctx_list);
vm_cond_init(&g_timer_ctx_list_cond);
os_cond_init(&g_timer_ctx_list_cond);
/* temp solution for: thread_modulers_timer_check thread would recursive lock the mutex */
vm_recursive_mutex_init(&g_timer_ctx_list_mutex);
os_recursive_mutex_init(&g_timer_ctx_list_mutex);
vm_thread_create(&tm_tid, thread_modulers_timer_check,
os_thread_create(&tm_tid, thread_modulers_timer_check,
NULL, BH_APPLET_PRESERVED_STACK_SIZE);
}
@ -115,16 +112,16 @@ timer_ctx_t create_wasm_timer_ctx(unsigned int module_id, int prealloc_num)
memset(node, 0, sizeof(*node));
node->timer_ctx = ctx;
vm_mutex_lock(&g_timer_ctx_list_mutex);
os_mutex_lock(&g_timer_ctx_list_mutex);
bh_list_insert(&g_timer_ctx_list, node);
vm_mutex_unlock(&g_timer_ctx_list_mutex);
os_mutex_unlock(&g_timer_ctx_list_mutex);
return ctx;
}
void destroy_module_timer_ctx(unsigned int module_id)
{
vm_mutex_lock(&g_timer_ctx_list_mutex);
os_mutex_lock(&g_timer_ctx_list_mutex);
timer_ctx_node_t* elem = (timer_ctx_node_t*)
bh_list_first_elem(&g_timer_ctx_list);
while (elem) {
@ -137,7 +134,7 @@ void destroy_module_timer_ctx(unsigned int module_id)
elem = (timer_ctx_node_t*) bh_list_elem_next(elem);
}
vm_mutex_unlock(&g_timer_ctx_list_mutex);
os_mutex_unlock(&g_timer_ctx_list_mutex);
}
timer_ctx_t get_wasm_timer_ctx(wasm_module_inst_t module_inst)
@ -192,6 +189,6 @@ extern uint32 get_sys_tick_ms();
uint32
wasm_get_sys_tick_ms(wasm_exec_env_t exec_env)
{
return (uint32) bh_get_tick_ms();
return (uint32)bh_get_tick_ms();
}

View File

@ -11,14 +11,12 @@
*/
#include "connection_lib.h"
#include "bh_thread.h"
#include "bh_platform.h"
#include "app_manager_export.h"
#include "module_wasm_app.h"
#include "conn_tcp.h"
#include "conn_udp.h"
#include "conn_uart.h"
#include "bh_common.h"
#include "bh_assert.h"
#include <unistd.h>
#include <sys/epoll.h>
@ -96,7 +94,7 @@ connection_interface_t connection_impl = {
static void add_connection(sys_connection_t *conn)
{
vm_mutex_lock(&g_lock);
os_mutex_lock(&g_lock);
g_handle_max++;
if (g_handle_max == -1)
@ -110,7 +108,7 @@ static void add_connection(sys_connection_t *conn)
g_connections = conn;
}
vm_mutex_unlock(&g_lock);
os_mutex_unlock(&g_lock);
}
#define FREE_CONNECTION(conn) do { \
@ -124,7 +122,7 @@ static int get_app_conns_num(uint32 module_id)
sys_connection_t *conn;
int num = 0;
vm_mutex_lock(&g_lock);
os_mutex_lock(&g_lock);
conn = g_connections;
while (conn) {
@ -133,7 +131,7 @@ static int get_app_conns_num(uint32 module_id)
conn = conn->next;
}
vm_mutex_unlock(&g_lock);
os_mutex_unlock(&g_lock);
return num;
}
@ -142,7 +140,7 @@ static sys_connection_t *find_connection(uint32 handle, bool remove_found)
{
sys_connection_t *conn, *prev = NULL;
vm_mutex_lock(&g_lock);
os_mutex_lock(&g_lock);
conn = g_connections;
while (conn) {
@ -154,7 +152,7 @@ static sys_connection_t *find_connection(uint32 handle, bool remove_found)
g_connections = conn->next;
}
}
vm_mutex_unlock(&g_lock);
os_mutex_unlock(&g_lock);
return conn;
} else {
prev = conn;
@ -162,7 +160,7 @@ static sys_connection_t *find_connection(uint32 handle, bool remove_found)
}
}
vm_mutex_unlock(&g_lock);
os_mutex_unlock(&g_lock);
return NULL;
}
@ -171,7 +169,7 @@ static void cleanup_connections(uint32 module_id)
{
sys_connection_t *conn, *prev = NULL;
vm_mutex_lock(&g_lock);
os_mutex_lock(&g_lock);
conn = g_connections;
while (conn) {
@ -194,7 +192,7 @@ static void cleanup_connections(uint32 module_id)
}
}
vm_mutex_unlock(&g_lock);
os_mutex_unlock(&g_lock);
}
static conn_type_t get_conn_type(const char *name)
@ -546,13 +544,13 @@ void app_mgr_connection_event_callback(module_data *m_data, bh_message_t msg)
bool init_connection_framework()
{
korp_thread tid;
korp_tid tid;
epollfd = epoll_create(MAX_EVENTS);
if (epollfd == -1)
return false;
if (vm_mutex_init(&g_lock) != 0) {
if (os_mutex_init(&g_lock) != 0) {
close(epollfd);
return false;
}
@ -566,7 +564,7 @@ bool init_connection_framework()
goto fail;
}
if (vm_thread_create(&tid,
if (os_thread_create(&tid,
polling_thread_routine,
NULL,
BH_APPLET_PRESERVED_STACK_SIZE) != 0) {
@ -576,7 +574,7 @@ bool init_connection_framework()
return true;
fail:
vm_mutex_destroy(&g_lock);
os_mutex_destroy(&g_lock);
close(epollfd);
return false;
}

View File

@ -6,10 +6,7 @@
#include "runtime_sensor.h"
#include "app_manager_export.h"
#include "module_wasm_app.h"
#include "bh_thread.h"
#include "bh_time.h"
#include "bh_common.h"
#include "bh_assert.h"
#include "bh_platform.h"
static sys_sensor_t * g_sys_sensors = NULL;
static int g_sensor_id_max = 0;
@ -103,11 +100,11 @@ wasm_sensor_config(wasm_exec_env_t exec_env,
module_inst);
bh_assert(mod_id != ID_NONE);
vm_mutex_lock(&s->lock);
os_mutex_lock(&s->lock);
c = find_sensor_client(s, mod_id, false);
if (c == NULL) {
vm_mutex_unlock(&s->lock);
os_mutex_unlock(&s->lock);
return false;
}
@ -115,7 +112,7 @@ wasm_sensor_config(wasm_exec_env_t exec_env,
c->bit_cfg = bit_cfg;
c->delay = delay;
vm_mutex_unlock(&s->lock);
os_mutex_unlock(&s->lock);
if (s->config != NULL) {
attr_cont = attr_container_create("config sensor");
@ -149,19 +146,19 @@ wasm_sensor_open(wasm_exec_env_t exec_env,
module_inst);
bh_assert(mod_id != ID_NONE);
vm_mutex_lock(&s->lock);
os_mutex_lock(&s->lock);
c = find_sensor_client(s, mod_id, false);
if (c) {
// the app already opened this sensor
vm_mutex_unlock(&s->lock);
os_mutex_unlock(&s->lock);
return -1;
}
sensor_client_t * client = (sensor_client_t*) wasm_runtime_malloc(
sizeof(sensor_client_t));
if (client == NULL) {
vm_mutex_unlock(&s->lock);
os_mutex_unlock(&s->lock);
return -1;
}
@ -172,7 +169,7 @@ wasm_sensor_open(wasm_exec_env_t exec_env,
client->next = s->clients;
s->clients = client;
vm_mutex_unlock(&s->lock);
os_mutex_unlock(&s->lock);
refresh_read_interval(s);
@ -218,10 +215,10 @@ wasm_sensor_close(wasm_exec_env_t exec_env, uint32 sensor)
if (s == NULL)
return false;
vm_mutex_lock(&s->lock);
os_mutex_lock(&s->lock);
if ((c = find_sensor_client(s, client_id, true)) != NULL)
wasm_runtime_free(c);
vm_mutex_unlock(&s->lock);
os_mutex_unlock(&s->lock);
refresh_read_interval(s);
@ -251,7 +248,7 @@ void refresh_read_interval(sensor_obj_t sensor)
{
sensor_client_t *c;
uint32 interval = sensor->default_interval;
vm_mutex_lock(&sensor->lock);
os_mutex_lock(&sensor->lock);
c = sensor->clients;
if (c)
@ -263,7 +260,7 @@ void refresh_read_interval(sensor_obj_t sensor)
c = c->next;
}
vm_mutex_unlock(&sensor->lock);
os_mutex_unlock(&sensor->lock);
sensor->read_interval = interval;
}
@ -310,7 +307,7 @@ add_sys_sensor(char * name, char * description, int instance,
g_sys_sensors = s;
}
vm_mutex_init(&s->lock);
os_mutex_init(&s->lock);
return s;
}
@ -366,7 +363,7 @@ sensor_client_t *find_sensor_client(sys_sensor_t * sensor,
int check_sensor_timers()
{
int ms_to_next_check = -1;
uint32 now = (uint32) bh_get_tick_ms();
uint32 now = (uint32)bh_get_tick_ms();
sys_sensor_t * s = g_sys_sensors;
while (s) {
@ -412,11 +409,11 @@ void sensor_cleanup_callback(uint32 module_id)
while (s) {
sensor_client_t *c;
vm_mutex_lock(&s->lock);
os_mutex_lock(&s->lock);
if ((c = find_sensor_client(s, module_id, true)) != NULL) {
wasm_runtime_free(c);
}
vm_mutex_unlock(&s->lock);
os_mutex_unlock(&s->lock);
s = s->next;
}
}

View File

@ -3,9 +3,7 @@
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "bh_common.h"
#include "bh_queue.h"
#include "bh_thread.h"
#include "bh_platform.h"
#include "runtime_sensor.h"
#include "bi-inc/attr_container.h"
#include "module_wasm_app.h"
@ -91,15 +89,15 @@ static void thread_sensor_check(void * arg)
int ms_to_expiry = check_sensor_timers();
if (ms_to_expiry == -1)
ms_to_expiry = 5000;
vm_mutex_lock(&mutex);
vm_cond_reltimedwait(&cond, &mutex, ms_to_expiry);
vm_mutex_unlock(&mutex);
os_mutex_lock(&mutex);
os_cond_reltimedwait(&cond, &mutex, ms_to_expiry * 1000);
os_mutex_unlock(&mutex);
}
}
static void cb_wakeup_thread()
{
vm_cond_signal(&cond);
os_cond_signal(&cond);
}
void set_sensor_reshceduler(void (*callback)());
@ -107,8 +105,8 @@ void set_sensor_reshceduler(void (*callback)());
void init_sensor_framework()
{
// init the mutext and conditions
vm_cond_init(&cond);
vm_mutex_init(&mutex);
os_cond_init(&cond);
os_mutex_init(&mutex);
set_sensor_reshceduler(cb_wakeup_thread);
@ -123,9 +121,9 @@ void init_sensor_framework()
void start_sensor_framework()
{
korp_thread tid;
korp_tid tid;
vm_thread_create(&tid,
os_thread_create(&tid,
(void *)thread_sensor_check,
NULL,
BH_APPLET_PRESERVED_STACK_SIZE);

View File

@ -6,8 +6,7 @@
#include "lvgl.h"
#include "app_manager_export.h"
#include "module_wasm_app.h"
#include "bh_list.h"
#include "bh_thread.h"
#include "bh_platform.h"
#include "wgl_native_utils.h"
#include "wgl.h"
@ -39,6 +38,10 @@ static korp_mutex g_object_list_mutex;
static bool lv_task_handler_thread_run = true;
static korp_mutex task_handler_lock;
static korp_cond task_handler_cond;
static void app_mgr_object_event_callback(module_data *m_data, bh_message_t msg)
{
uint32 argv[2];
@ -79,7 +82,7 @@ static void cleanup_object_list(uint32 module_id)
{
object_node_t *elem;
vm_mutex_lock(&g_object_list_mutex);
os_mutex_lock(&g_object_list_mutex);
while (true) {
bool found = false;
@ -104,7 +107,7 @@ static void cleanup_object_list(uint32 module_id)
break;
}
vm_mutex_unlock(&g_object_list_mutex);
os_mutex_unlock(&g_object_list_mutex);
}
static bool init_object_event_callback_framework()
@ -128,20 +131,20 @@ bool wgl_native_validate_object(int32 obj_id, lv_obj_t **obj)
{
object_node_t *elem;
vm_mutex_lock(&g_object_list_mutex);
os_mutex_lock(&g_object_list_mutex);
elem = (object_node_t *)bh_list_first_elem(&g_object_list);
while (elem) {
if (obj_id == elem->obj_id) {
if (obj != NULL)
*obj = elem->obj;
vm_mutex_unlock(&g_object_list_mutex);
os_mutex_unlock(&g_object_list_mutex);
return true;
}
elem = (object_node_t *) bh_list_elem_next(elem);
}
vm_mutex_unlock(&g_object_list_mutex);
os_mutex_unlock(&g_object_list_mutex);
return false;
}
@ -165,9 +168,9 @@ bool wgl_native_add_object(lv_obj_t *obj, uint32 module_id, uint32 *obj_id)
node->obj_id = g_obj_id_max;
node->module_id = module_id;
vm_mutex_lock(&g_object_list_mutex);
os_mutex_lock(&g_object_list_mutex);
bh_list_insert(&g_object_list, node);
vm_mutex_unlock(&g_object_list_mutex);
os_mutex_unlock(&g_object_list_mutex);
if (obj_id != NULL)
*obj_id = node->obj_id;
@ -194,20 +197,20 @@ static void _obj_del_recursive(lv_obj_t *obj)
i = i_next;
}
vm_mutex_lock(&g_object_list_mutex);
os_mutex_lock(&g_object_list_mutex);
elem = (object_node_t *)bh_list_first_elem(&g_object_list);
while (elem) {
if (obj == elem->obj) {
bh_list_remove(&g_object_list, elem);
wasm_runtime_free(elem);
vm_mutex_unlock(&g_object_list_mutex);
os_mutex_unlock(&g_object_list_mutex);
return;
}
elem = (object_node_t *) bh_list_elem_next(elem);
}
vm_mutex_unlock(&g_object_list_mutex);
os_mutex_unlock(&g_object_list_mutex);
}
static void _obj_clean_recursive(lv_obj_t *obj)
@ -255,52 +258,55 @@ static void internal_lv_obj_event_cb(lv_obj_t *obj, lv_event_t event)
{
object_node_t *elem;
vm_mutex_lock(&g_object_list_mutex);
os_mutex_lock(&g_object_list_mutex);
elem = (object_node_t *)bh_list_first_elem(&g_object_list);
while (elem) {
if (obj == elem->obj) {
post_widget_msg_to_module(elem, event);
vm_mutex_unlock(&g_object_list_mutex);
os_mutex_unlock(&g_object_list_mutex);
return;
}
elem = (object_node_t *) bh_list_elem_next(elem);
}
vm_mutex_unlock(&g_object_list_mutex);
os_mutex_unlock(&g_object_list_mutex);
}
static void* lv_task_handler_thread_routine (void *arg)
{
korp_sem sem;
if (vm_sem_init(&sem, 1) != 0) {
printf("Init semaphore for lvgl task handler thread fail!\n");
return NULL;
}
os_mutex_lock(&task_handler_lock);
while (lv_task_handler_thread_run) {
vm_sem_reltimedwait(&sem, 100);
os_cond_reltimedwait(&task_handler_cond, &task_handler_lock,
100 * 1000);
lv_task_handler();
}
vm_sem_destroy(&sem);
os_mutex_unlock(&task_handler_lock);
return NULL;
}
void wgl_init(void)
{
korp_thread tid;
korp_tid tid;
if (os_mutex_init(&task_handler_lock) != 0)
return;
if (os_cond_init(&task_handler_cond) != 0) {
os_mutex_destroy(&task_handler_lock);
return;
}
lv_init();
bh_list_init(&g_object_list);
vm_recursive_mutex_init(&g_object_list_mutex);
os_recursive_mutex_init(&g_object_list_mutex);
init_object_event_callback_framework();
/* new a thread, call lv_task_handler periodically */
vm_thread_create(&tid,
os_thread_create(&tid,
lv_task_handler_thread_routine,
NULL,
BH_APPLET_PRESERVED_STACK_SIZE);
@ -309,6 +315,8 @@ void wgl_init(void)
void wgl_exit(void)
{
lv_task_handler_thread_run = false;
os_cond_destroy(&task_handler_cond);
os_mutex_destroy(&task_handler_lock);
}
/* -------------------------------------------------------------------------

View File

@ -5,8 +5,7 @@
#include "app_manager.h"
#include "app_manager_host.h"
#include "bh_queue.h"
#include "bh_thread.h"
#include "bh_platform.h"
#include "bi-inc/attr_container.h"
#include "event.h"
#include "watchdog.h"
@ -38,7 +37,7 @@ void app_manager_post_applets_update_event()
return;
}
vm_mutex_lock(&module_data_list_lock);
os_mutex_lock(&module_data_list_lock);
m_data = module_data_list;
while (m_data) {
@ -80,7 +79,8 @@ void app_manager_post_applets_update_event()
app_manager_printf("Post applets update event success!\n");
attr_container_dump(attr_cont);
fail: vm_mutex_unlock(&module_data_list_lock);
fail:
os_mutex_unlock(&module_data_list_lock);
attr_container_destroy(attr_cont);
}
@ -89,7 +89,7 @@ static int get_applets_count()
module_data *m_data;
int num = 0;
vm_mutex_lock(&module_data_list_lock);
os_mutex_lock(&module_data_list_lock);
m_data = module_data_list;
while (m_data) {
@ -97,7 +97,7 @@ static int get_applets_count()
m_data = m_data->next;
}
vm_mutex_unlock(&module_data_list_lock);
os_mutex_unlock(&module_data_list_lock);
return num;
}
@ -118,7 +118,7 @@ static bool app_manager_query_applets(request_t *msg, const char *name)
return false;
}
vm_mutex_lock(&module_data_list_lock);
os_mutex_lock(&module_data_list_lock);
m_data = module_data_list;
while (m_data) {
@ -186,7 +186,8 @@ static bool app_manager_query_applets(request_t *msg, const char *name)
app_manager_printf("Query Applets success!\n");
attr_container_dump(attr_cont);
fail: vm_mutex_unlock(&module_data_list_lock);
fail:
os_mutex_unlock(&module_data_list_lock);
attr_container_destroy(attr_cont);
return ret;
}
@ -368,9 +369,11 @@ void app_manager_startup(host_interface *interface)
/* Enter loop run */
bh_queue_enter_loop_run(g_app_mgr_queue, app_manager_queue_callback, NULL);
fail2: module_data_list_destroy();
fail2:
module_data_list_destroy();
fail1: bh_queue_destroy(g_app_mgr_queue);
fail1:
bh_queue_destroy(g_app_mgr_queue);
}
#include "module_config.h"

View File

@ -7,9 +7,6 @@
#define APP_MANAGER_H
#include "bh_platform.h"
#include "bh_common.h"
#include "bh_queue.h"
#include "bh_types.h"
#include "app_manager_export.h"
#include "native_interface.h"
#include "bi-inc/shared_utils.h"
@ -21,8 +18,8 @@ extern "C" {
#define APP_MGR_MALLOC wasm_runtime_malloc
#define APP_MGR_FREE wasm_runtime_free
/* bh_printf is defined in each platform */
#define app_manager_printf bh_printf
/* os_printf is defined in each platform */
#define app_manager_printf os_printf
#define SEND_ERR_RESPONSE(mid, err_msg) do { \
app_manager_printf("%s\n", err_msg); \

View File

@ -3,13 +3,11 @@
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "bh_common.h"
#include "bh_types.h"
#include "bh_platform.h"
#include "app_manager_host.h"
#include "app_manager.h"
#include "app_manager_export.h"
#include "coap_ext.h"
#include "bh_thread.h"
/* host communication interface */
static host_interface host_commu;
@ -235,7 +233,7 @@ int aee_host_msg_callback(void *msg, uint16_t msg_len)
bool app_manager_host_init(host_interface *interface)
{
vm_mutex_init(&host_lock);
os_mutex_init(&host_lock);
memset(&recv_ctx, 0, sizeof(recv_ctx));
host_commu.init = interface->init;
@ -255,7 +253,7 @@ int app_manager_host_send_msg(int msg_type, const unsigned char *buf, int size)
int size_s = size, n;
char header[16];
vm_mutex_lock(&host_lock);
os_mutex_lock(&host_lock);
/* leading bytes */
bh_memcpy_s(header, 2, leadings, 2);
@ -270,13 +268,13 @@ int app_manager_host_send_msg(int msg_type, const unsigned char *buf, int size)
bh_memcpy_s(header + 4, 4, &size_s, 4);
n = host_commu.send(NULL, header, 8);
if (n != 8) {
vm_mutex_unlock(&host_lock);
os_mutex_unlock(&host_lock);
return 0;
}
/* payload */
n = host_commu.send(NULL, buf, size);
vm_mutex_unlock(&host_lock);
os_mutex_unlock(&host_lock);
printf("sent %d bytes to host\n", n);
return n;

View File

@ -269,12 +269,12 @@ check_exception()
jeff_runtime_call_java(method, argc, argv, argt);
if (is_wd_started) {
vm_mutex_lock(&wd_timer->lock);
os_mutex_lock(&wd_timer->lock);
if (!wd_timer->is_interrupting) {
wd_timer->is_stopped = true;
watchdog_timer_stop(wd_timer);
}
vm_mutex_unlock(&wd_timer->lock);
os_mutex_unlock(&wd_timer->lock);
}
return !check_exception();
@ -1395,7 +1395,7 @@ check_exception()
if (applet_data->vm_instance->main_file) {
app_manager_printf("Watchdog cancel applet main thread.\n");
vm_thread_cancel(applet_data->vm_instance->main_tlr.handle);
os_thread_cancel(applet_data->vm_instance->main_tlr.handle);
/* k_thread_abort(applet_data->vm_instance->main_tlr.handle); */
}

View File

@ -5,8 +5,7 @@
#include "app_manager.h"
#include "app_manager_host.h"
#include "bh_queue.h"
#include "bh_thread.h"
#include "bh_platform.h"
#include "bi-inc/attr_container.h"
#include "event.h"
#include "watchdog.h"
@ -21,13 +20,13 @@ module_data *module_data_list;
bool module_data_list_init()
{
module_data_list = NULL;
return !vm_mutex_init(&module_data_list_lock) ? true : false;
return !os_mutex_init(&module_data_list_lock) ? true : false;
}
void module_data_list_destroy()
{
vm_mutex_lock(&module_data_list_lock);
os_mutex_lock(&module_data_list_lock);
if (module_data_list) {
while (module_data_list) {
module_data *p = module_data_list->next;
@ -35,14 +34,14 @@ void module_data_list_destroy()
module_data_list = p;
}
}
vm_mutex_unlock(&module_data_list_lock);
vm_mutex_destroy(&module_data_list_lock);
os_mutex_unlock(&module_data_list_lock);
os_mutex_destroy(&module_data_list_lock);
}
static void module_data_list_add(module_data *m_data)
{
static uint32 module_id_max = 1;
vm_mutex_lock(&module_data_list_lock);
os_mutex_lock(&module_data_list_lock);
// reserve some special ID
// TODO: check the new id is not already occupied!
if (module_id_max == 0xFFFFFFF0)
@ -55,12 +54,12 @@ static void module_data_list_add(module_data *m_data)
m_data->next = module_data_list;
module_data_list = m_data;
}
vm_mutex_unlock(&module_data_list_lock);
os_mutex_unlock(&module_data_list_lock);
}
void module_data_list_remove(module_data *m_data)
{
vm_mutex_lock(&module_data_list_lock);
os_mutex_lock(&module_data_list_lock);
if (module_data_list) {
if (module_data_list == m_data)
module_data_list = module_data_list->next;
@ -74,46 +73,46 @@ void module_data_list_remove(module_data *m_data)
p->next = p->next->next;
}
}
vm_mutex_unlock(&module_data_list_lock);
os_mutex_unlock(&module_data_list_lock);
}
module_data*
module_data_list_lookup(const char *module_name)
{
vm_mutex_lock(&module_data_list_lock);
os_mutex_lock(&module_data_list_lock);
if (module_data_list) {
module_data *p = module_data_list;
while (p) {
/* Search by module name */
if (!strcmp(module_name, p->module_name)) {
vm_mutex_unlock(&module_data_list_lock);
os_mutex_unlock(&module_data_list_lock);
return p;
}
p = p->next;
}
}
vm_mutex_unlock(&module_data_list_lock);
os_mutex_unlock(&module_data_list_lock);
return NULL;
}
module_data*
module_data_list_lookup_id(unsigned int module_id)
{
vm_mutex_lock(&module_data_list_lock);
os_mutex_lock(&module_data_list_lock);
if (module_data_list) {
module_data *p = module_data_list;
while (p) {
/* Search by module name */
if (module_id == p->id) {
vm_mutex_unlock(&module_data_list_lock);
os_mutex_unlock(&module_data_list_lock);
return p;
}
p = p->next;
}
}
vm_mutex_unlock(&module_data_list_lock);
os_mutex_unlock(&module_data_list_lock);
return NULL;
}
@ -201,7 +200,7 @@ void release_module(module_data *m_data)
int check_modules_timer_expiry()
{
vm_mutex_lock(&module_data_list_lock);
os_mutex_lock(&module_data_list_lock);
module_data *p = module_data_list;
int ms_to_expiry = -1;
@ -215,7 +214,7 @@ int check_modules_timer_expiry()
p = p->next;
}
vm_mutex_unlock(&module_data_list_lock);
os_mutex_unlock(&module_data_list_lock);
return ms_to_expiry;
}

View File

@ -7,9 +7,8 @@
#include "native_interface.h" /* for request_t type */
#include "app_manager_host.h"
#include "bh_queue.h"
#include "bh_platform.h"
#include "bi-inc/attr_container.h"
#include "bh_thread.h"
#include "coap_ext.h"
#include "event.h"
#include "watchdog.h"
@ -429,7 +428,6 @@ wasm_app_routine(void *arg)
module_data *m_data = (module_data *) arg;
wasm_data *wasm_app_data = (wasm_data*) m_data->internal_data;
wasm_module_inst_t inst = wasm_app_data->wasm_module_inst;
korp_tid thread = wasm_app_data->thread_id;
/* Set m_data to the VM managed instance's custom data */
wasm_runtime_set_custom_data(inst, m_data);
@ -489,8 +487,6 @@ fail2:
wasm_runtime_call_wasm(wasm_app_data->exec_env, func_onDestroy, 0, NULL);
fail1:
vm_thread_detach(thread);
vm_thread_exit(NULL);
return NULL;
}
@ -847,7 +843,7 @@ wasm_app_module_install(request_t * msg)
}
/* Create WASM app thread. */
if (vm_thread_create(&wasm_app_data->thread_id, wasm_app_routine,
if (os_thread_create(&wasm_app_data->thread_id, wasm_app_routine,
(void*) m_data, APP_THREAD_STACK_SIZE_DEFAULT) != 0) {
module_data_list_remove(m_data);
SEND_ERR_RESPONSE(msg->mid,
@ -941,7 +937,7 @@ wasm_app_module_uninstall(request_t *msg)
/* Wait for wasm app thread to exit */
wasm_app_data = (wasm_data*) m_data->internal_data;
vm_thread_join(wasm_app_data->thread_id, NULL, -1);
os_thread_join(wasm_app_data->thread_id, NULL);
cleanup_app_resource(m_data);
@ -1358,7 +1354,7 @@ wasm_app_module_on_install_request_byte_arrive(uint8 ch,
total_size = (total_size + 3) & ~((uint64)3);
if (total_size >= UINT32_MAX
|| !(section->section_body =
bh_mmap(NULL, (uint32)total_size,
os_mmap(NULL, (uint32)total_size,
map_prot, map_flags))) {
app_manager_printf("Allocate executable memory failed!\n");
goto fail;
@ -1553,7 +1549,7 @@ destroy_all_aot_sections(aot_section_list_t sections)
aot_section_t *next = cur->next;
if (cur->section_body != NULL) {
if (cur->section_type == AOT_SECTION_TYPE_TEXT)
bh_munmap(cur->section_body, cur->section_body_size);
os_munmap(cur->section_body, cur->section_body_size);
else
APP_MGR_FREE(cur->section_body);
}
@ -1583,7 +1579,7 @@ destroy_part_aot_sections(aot_section_list_t *p_sections,
if (cur->section_body != NULL) {
if (cur->section_type == AOT_SECTION_TYPE_TEXT)
bh_munmap(cur->section_body, cur->section_body_size);
os_munmap(cur->section_body, cur->section_body_size);
else
APP_MGR_FREE(cur->section_body);
}

View File

@ -4,8 +4,7 @@
*/
#include "watchdog.h"
#include "bh_queue.h"
#include "bh_thread.h"
#include "bh_platform.h"
#define WATCHDOG_THREAD_PRIORITY 5
@ -20,7 +19,7 @@ static void watchdog_timer_callback(void *timer)
watchdog_timer_stop(wd_timer);
vm_mutex_lock(&wd_timer->lock);
os_mutex_lock(&wd_timer->lock);
if (!wd_timer->is_stopped) {
@ -30,7 +29,7 @@ static void watchdog_timer_callback(void *timer)
sizeof(module_data));
}
vm_mutex_unlock(&wd_timer->lock);
os_mutex_unlock(&wd_timer->lock);
}
#endif
@ -39,12 +38,12 @@ bool watchdog_timer_init(module_data *m_data)
#ifdef WATCHDOG_ENABLED /* TODO */
watchdog_timer *wd_timer = &m_data->wd_timer;
if (0 != vm_mutex_init(&wd_timer->lock))
if (0 != os_mutex_init(&wd_timer->lock))
return false;
if (!(wd_timer->timer_handle =
app_manager_timer_create(watchdog_timer_callback, wd_timer))) {
vm_mutex_destroy(&wd_timer->lock);
os_mutex_destroy(&wd_timer->lock);
return false;
}
@ -59,20 +58,20 @@ void watchdog_timer_destroy(watchdog_timer *wd_timer)
{
#ifdef WATCHDOG_ENABLED /* TODO */
app_manager_timer_destroy(wd_timer->timer_handle);
vm_mutex_destroy(&wd_timer->lock);
os_mutex_destroy(&wd_timer->lock);
#endif
}
void watchdog_timer_start(watchdog_timer *wd_timer)
{
vm_mutex_lock(&wd_timer->lock);
os_mutex_lock(&wd_timer->lock);
wd_timer->is_interrupting = false;
wd_timer->is_stopped = false;
app_manager_timer_start(wd_timer->timer_handle,
wd_timer->module_data->timeout);
vm_mutex_unlock(&wd_timer->lock);
os_mutex_unlock(&wd_timer->lock);
}
void watchdog_timer_stop(watchdog_timer *wd_timer)

View File

@ -36,6 +36,10 @@
#endif
#endif
#ifndef BH_DEBUG
#define BH_DEBUG 0
#endif
enum {
/* Memory allocator ems */
MEM_ALLOCATOR_EMS = 0,
@ -144,7 +148,7 @@ enum {
/* Default min/max heap size of each app */
#define APP_HEAP_SIZE_DEFAULT (8 * 1024)
#define APP_HEAP_SIZE_MIN (2 * 1024)
#define APP_HEAP_SIZE_MAX (1024 * 1024)
#define APP_HEAP_SIZE_MAX (512 * 1024 * 1024)
/* Default wasm stack size of each app */
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)

View File

@ -829,7 +829,7 @@ destroy_object_data_sections(AOTObjectDataSection *data_sections,
AOTObjectDataSection *data_section = data_sections;
for (i = 0; i < data_section_count; i++, data_section++)
if (data_section->data)
bh_munmap(data_section->data, data_section->size);
os_munmap(data_section->data, data_section->size);
wasm_runtime_free(data_sections);
}
@ -872,7 +872,7 @@ load_object_data_sections(const uint8 **p_buf, const uint8 *buf_end,
/* Allocate memory for data */
if (!(data_sections[i].data =
bh_mmap(NULL, data_sections[i].size, map_prot, map_flags))) {
os_mmap(NULL, data_sections[i].size, map_prot, map_flags))) {
set_error_buf(error_buf, error_buf_size,
"AOT module load failed: "
"allocate memory failed.");
@ -1594,7 +1594,7 @@ load_from_sections(AOTModule *module, AOTSection *sections,
/* Flush data cache before executing AOT code,
* otherwise unpredictable behavior can occur. */
bh_dcache_flush();
os_dcache_flush();
return true;
}
@ -1668,7 +1668,7 @@ destroy_sections(AOTSection *section_list, bool destroy_aot_text)
if (destroy_aot_text
&& section->section_type == AOT_SECTION_TYPE_TEXT
&& section->section_body)
bh_munmap((uint8*)section->section_body, section->section_body_size);
os_munmap((uint8*)section->section_body, section->section_body_size);
wasm_runtime_free(section);
section = next;
}
@ -1719,7 +1719,7 @@ create_sections(const uint8 *buf, uint32 size,
total_size = (uint64)section_size + aot_get_plt_table_size();
total_size = (total_size + 3) & ~((uint64)3);
if (total_size >= UINT32_MAX
|| !(aot_text = bh_mmap(NULL, (uint32)total_size,
|| !(aot_text = os_mmap(NULL, (uint32)total_size,
map_prot, map_flags))) {
wasm_runtime_free(section);
set_error_buf(error_buf, error_buf_size,
@ -2075,7 +2075,7 @@ aot_unload(AOTModule *module)
bh_hash_map_destroy(module->const_str_set);
if (module->code)
bh_munmap(module->code, module->code_size);
os_munmap(module->code, module->code_size);
if (module->data_sections)
destroy_object_data_sections(module->data_sections,

View File

@ -751,7 +751,7 @@ aot_enlarge_memory(AOTModuleInstance *module_inst, uint32 inc_page_count)
uint32 max_page_count = module_inst->mem_max_page_count;
uint32 total_page_count = cur_page_count + inc_page_count;
uint64 total_size = (uint64)num_bytes_per_page * total_page_count;
uint32 total_size_old;
uint32 total_size_old = module_inst->memory_data_size;
if (inc_page_count <= 0)
/* No need to enlarge memory */
@ -773,14 +773,14 @@ aot_enlarge_memory(AOTModuleInstance *module_inst, uint32 inc_page_count)
aot_set_exception(module_inst, "fail to enlarge memory.");
return false;
}
total_size_old = module_inst->memory_data_size;
bh_memcpy_s(mem_data_new, (uint32)total_size,
mem_data_old, total_size_old);
memset(mem_data_new + total_size_old,
0, (uint32)total_size - total_size_old);
wasm_runtime_free(mem_data_old);
}
memset(mem_data_new + total_size_old,
0, (uint32)total_size - total_size_old);
module_inst->mem_cur_page_count = total_page_count;
module_inst->memory_data_size = (uint32)total_size;
module_inst->memory_data.ptr = mem_data_new;

View File

@ -6,7 +6,6 @@
#ifndef _WASM_EXEC_ENV_H
#define _WASM_EXEC_ENV_H
#include "bh_thread.h"
#include "bh_assert.h"
#if WASM_ENABLE_INTERP != 0
#include "../interpreter/wasm.h"

View File

@ -6,7 +6,6 @@
#include "wasm_runtime_common.h"
#include "bh_platform.h"
#include "mem_alloc.h"
#include "bh_thread.h"
#if BEIHAI_ENABLE_MEMORY_PROFILING != 0
@ -60,12 +59,12 @@ wasm_memory_init_with_pool(void *mem, unsigned int bytes)
memory_mode = MEMORY_MODE_POOL;
pool_allocator = _allocator;
#if BEIHAI_ENABLE_MEMORY_PROFILING != 0
vm_mutex_init(&profile_lock);
os_mutex_init(&profile_lock);
#endif
global_pool_size = bytes;
return true;
}
bh_printf("Init memory with pool (%p, %u) failed.\n", mem, bytes);
LOG_ERROR("Init memory with pool (%p, %u) failed.\n", mem, bytes);
return false;
}
@ -80,11 +79,11 @@ wasm_memory_init_with_allocator(void *_malloc_func,
realloc_func = _realloc_func;
free_func = _free_func;
#if BEIHAI_ENABLE_MEMORY_PROFILING != 0
vm_mutex_init(&profile_lock);
os_mutex_init(&profile_lock);
#endif
return true;
}
bh_printf("Init memory with allocator (%p, %p, %p) failed.\n",
LOG_ERROR("Init memory with allocator (%p, %p, %p) failed.\n",
_malloc_func, _realloc_func, _free_func);
return false;
}
@ -110,7 +109,7 @@ void
wasm_runtime_memory_destroy()
{
#if BEIHAI_ENABLE_MEMORY_PROFILING != 0
vm_mutex_destroy(&profile_lock);
os_mutex_destroy(&profile_lock);
#endif
if (memory_mode == MEMORY_MODE_POOL)
mem_allocator_destroy(pool_allocator);
@ -130,7 +129,7 @@ void *
wasm_runtime_malloc(unsigned int size)
{
if (memory_mode == MEMORY_MODE_UNKNOWN) {
bh_printf("wasm_runtime_malloc failed: memory hasn't been initialize.\n");
LOG_WARNING("wasm_runtime_malloc failed: memory hasn't been initialize.\n");
return NULL;
} else if (memory_mode == MEMORY_MODE_POOL) {
return mem_allocator_malloc(pool_allocator, size);
@ -143,7 +142,7 @@ void *
wasm_runtime_realloc(void *ptr, unsigned int size)
{
if (memory_mode == MEMORY_MODE_UNKNOWN) {
bh_printf("wasm_runtime_realloc failed: memory hasn't been initialize.\n");
LOG_WARNING("wasm_runtime_realloc failed: memory hasn't been initialize.\n");
return NULL;
} else if (memory_mode == MEMORY_MODE_POOL) {
return mem_allocator_realloc(pool_allocator, ptr, size);
@ -159,7 +158,7 @@ void
wasm_runtime_free(void *ptr)
{
if (memory_mode == MEMORY_MODE_UNKNOWN) {
bh_printf("wasm_runtime_free failed: memory hasn't been initialize.\n");
LOG_WARNING("wasm_runtime_free failed: memory hasn't been initialize.\n");
} else if (memory_mode == MEMORY_MODE_POOL) {
mem_allocator_free(pool_allocator, ptr);
} else {
@ -177,7 +176,7 @@ wasm_runtime_malloc_profile(const char *file, int line,
if (p) {
memory_profile_t *profile;
vm_mutex_lock(&profile_lock);
os_mutex_lock(&profile_lock);
profile = memory_profiles_list;
while (profile) {
@ -194,7 +193,7 @@ wasm_runtime_malloc_profile(const char *file, int line,
} else {
profile = wasm_runtime_malloc(sizeof(memory_profile_t));
if (!profile) {
vm_mutex_unlock(&profile_lock);
os_mutex_unlock(&profile_lock);
bh_memcpy_s(p, size + 8, &size, sizeof(size));
return (char *)p + 8;
}
@ -209,7 +208,7 @@ wasm_runtime_malloc_profile(const char *file, int line,
memory_profiles_list = profile;
}
vm_mutex_unlock(&profile_lock);
os_mutex_unlock(&profile_lock);
bh_memcpy_s(p, size + 8, &size, sizeof(size));
memory_in_use += size;
@ -234,7 +233,7 @@ wasm_runtime_free_profile(const char *file, int line,
if (memory_in_use >= size)
memory_in_use -= size;
vm_mutex_lock(&profile_lock);
os_mutex_lock(&profile_lock);
profile = memory_profiles_list;
while (profile) {
@ -251,7 +250,7 @@ wasm_runtime_free_profile(const char *file, int line,
} else {
profile = wasm_runtime_malloc(sizeof(memory_profile_t));
if (!profile) {
vm_mutex_unlock(&profile_lock);
os_mutex_unlock(&profile_lock);
return;
}
@ -265,7 +264,7 @@ wasm_runtime_free_profile(const char *file, int line,
memory_profiles_list = profile;
}
vm_mutex_unlock(&profile_lock);
os_mutex_unlock(&profile_lock);
}
/**
@ -277,11 +276,11 @@ void memory_usage_summarize()
{
memory_profile_t *profile;
vm_mutex_lock(&profile_lock);
os_mutex_lock(&profile_lock);
profile = memory_profiles_list;
while (profile) {
bh_printf("malloc:%d:malloc_num:%d:free:%d:free_num:%d:%s\n",
os_printf("malloc:%d:malloc_num:%d:free:%d:free_num:%d:%s\n",
profile->total_malloc,
profile->malloc_num,
profile->total_free,
@ -290,14 +289,14 @@ void memory_usage_summarize()
profile = profile->next;
}
vm_mutex_unlock(&profile_lock);
os_mutex_unlock(&profile_lock);
}
void
memory_profile_print(const char *file, int line,
const char *func, int alloc)
{
bh_printf("location:%s@%d:used:%d:contribution:%d\n",
os_printf("location:%s@%d:used:%d:contribution:%d\n",
func, line, memory_in_use, alloc);
}

View File

@ -3,7 +3,6 @@
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "config.h"
#include "bh_platform.h"
#include "bh_common.h"
#include "bh_assert.h"
@ -30,14 +29,10 @@ wasm_runtime_env_init()
if (bh_platform_init() != 0)
return false;
if (bh_log_init() != 0)
return false;
if (vm_thread_sys_init() != 0)
return false;
if (wasm_native_init() == false)
if (wasm_native_init() == false) {
bh_platform_destroy();
return false;
}
return true;
}
@ -60,7 +55,7 @@ void
wasm_runtime_destroy()
{
wasm_native_destroy();
vm_thread_sys_destroy();
bh_platform_destroy();
wasm_runtime_memory_destroy();
}
@ -273,7 +268,7 @@ wasm_runtime_call_wasm(WASMExecEnv *exec_env,
return false;
}
exec_env->handle = vm_self_thread();
exec_env->handle = os_self_thread();
#if WASM_ENABLE_INTERP != 0
if (exec_env->module_inst->module_type == Wasm_Module_Bytecode)
@ -1375,7 +1370,7 @@ wasm_application_execute_func(WASMModuleInstanceCommon *module_inst,
/* print return value */
switch (type->types[type->param_count]) {
case VALUE_TYPE_I32:
bh_printf("0x%x:i32", argv1[0]);
os_printf("0x%x:i32", argv1[0]);
break;
case VALUE_TYPE_I64:
{
@ -1387,22 +1382,22 @@ wasm_application_execute_func(WASMModuleInstanceCommon *module_inst,
snprintf(buf, sizeof(buf), "%s", "0x%llx:i64");
else
snprintf(buf, sizeof(buf), "%s", "0x%lx:i64");
bh_printf(buf, u.val);
os_printf(buf, u.val);
break;
}
case VALUE_TYPE_F32:
bh_printf("%.7g:f32", *(float32*)argv1);
os_printf("%.7g:f32", *(float32*)argv1);
break;
case VALUE_TYPE_F64:
{
union { float64 val; uint32 parts[2]; } u;
u.parts[0] = argv1[0];
u.parts[1] = argv1[1];
bh_printf("%.7g:f64", u.val);
os_printf("%.7g:f64", u.val);
break;
}
}
bh_printf("\n");
os_printf("\n");
wasm_runtime_free(argv1);
return true;
@ -1413,7 +1408,7 @@ fail:
exception = wasm_runtime_get_exception(module_inst);
bh_assert(exception);
bh_printf("%s\n", exception);
os_printf("%s\n", exception);
return false;
}

View File

@ -8,7 +8,6 @@
#include "bh_platform.h"
#include "bh_common.h"
#include "bh_thread.h"
#include "wasm_exec_env.h"
#include "wasm_native.h"
#include "../include/wasm_export.h"

View File

@ -789,23 +789,23 @@ static void
print_supported_targets()
{
uint32 i;
bh_printf("Supported targets:\n");
os_printf("Supported targets:\n");
for (i = 0; i < sizeof(valid_archs) / sizeof(ArchItem); i++) {
bh_printf("%s ", valid_archs[i].arch);
os_printf("%s ", valid_archs[i].arch);
if (valid_archs[i].support_eb)
bh_printf("%seb ", valid_archs[i].arch);
os_printf("%seb ", valid_archs[i].arch);
}
bh_printf("\n");
os_printf("\n");
}
static void
print_supported_abis()
{
uint32 i;
bh_printf("Supported ABI: ");
os_printf("Supported ABI: ");
for (i = 0; i < sizeof(valid_abis) / sizeof(const char *); i++)
bh_printf("%s ", valid_abis[i]);
bh_printf("\n");
os_printf("%s ", valid_abis[i]);
os_printf("\n");
}
static bool
@ -917,6 +917,8 @@ aot_create_comp_context(AOTCompData *comp_data,
goto fail;
}
comp_ctx->is_jit_mode = true;
comp_ctx->target_machine =
LLVMGetExecutionEngineTargetMachine(comp_ctx->exec_engine);
}
else {
/* Create LLVM target machine */
@ -1026,24 +1028,24 @@ aot_create_comp_context(AOTCompData *comp_data,
get_target_arch_from_triple(triple_norm, comp_ctx->target_arch,
sizeof(comp_ctx->target_arch));
bh_printf("Create AoT compiler with:\n");
bh_printf(" target: %s\n", comp_ctx->target_arch);
bh_printf(" target cpu: %s\n", cpu);
bh_printf(" cpu features: %s\n", features);
bh_printf(" opt level: %d\n", opt_level);
bh_printf(" size level: %d\n", size_level);
os_printf("Create AoT compiler with:\n");
os_printf(" target: %s\n", comp_ctx->target_arch);
os_printf(" target cpu: %s\n", cpu);
os_printf(" cpu features: %s\n", features);
os_printf(" opt level: %d\n", opt_level);
os_printf(" size level: %d\n", size_level);
switch (option->output_format) {
case AOT_LLVMIR_UNOPT_FILE:
bh_printf(" output format: unoptimized LLVM IR\n");
os_printf(" output format: unoptimized LLVM IR\n");
break;
case AOT_LLVMIR_OPT_FILE:
bh_printf(" output format: optimized LLVM IR\n");
os_printf(" output format: optimized LLVM IR\n");
break;
case AOT_FORMAT_FILE:
bh_printf(" output format: AoT file\n");
os_printf(" output format: AoT file\n");
break;
case AOT_OBJECT_FILE:
bh_printf(" output format: native object file\n");
os_printf(" output format: native object file\n");
break;
}
@ -1155,7 +1157,7 @@ aot_destroy_comp_context(AOTCompContext *comp_ctx)
if (comp_ctx->pass_mgr)
LLVMDisposePassManager(comp_ctx->pass_mgr);
if (comp_ctx->target_machine)
if (comp_ctx->target_machine && !comp_ctx->is_jit_mode)
LLVMDisposeTargetMachine(comp_ctx->target_machine);
if (comp_ctx->builder)

View File

@ -15,6 +15,29 @@
extern "C" {
#endif
#define get_module_inst(exec_env) \
wasm_runtime_get_module_inst(exec_env)
#define validate_app_addr(offset, size) \
wasm_runtime_validate_app_addr(module_inst, offset, size)
#define validate_app_str_addr(offset) \
wasm_runtime_validate_app_str_addr(module_inst, offset)
#define addr_app_to_native(offset) \
wasm_runtime_addr_app_to_native(module_inst, offset)
#define addr_native_to_app(ptr) \
wasm_runtime_addr_native_to_app(module_inst, ptr)
#define module_malloc(size, p_native_addr) \
wasm_runtime_module_malloc(module_inst, size, p_native_addr)
#define module_free(offset) \
wasm_runtime_module_free(module_inst, offset)
/* Uninstantiated WASM module loaded from WASM binary file
or AoT binary file*/
struct WASMModuleCommon;

View File

@ -1401,7 +1401,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
/* fail to memory.grow, return -1 */
PUSH_I32(-1);
if (wasm_get_exception(module)) {
bh_printf("%s\n", wasm_get_exception(module));
os_printf("%s\n", wasm_get_exception(module));
wasm_set_exception(module, NULL);
}
}

View File

@ -729,7 +729,7 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst,
#endif /* end of WASM_ENABLE_LABELS_AS_VALUES */
#if WASM_ENABLE_FAST_INTERP != 0
static void *global_handle_table[WASM_INSTRUCTION_NUM] = { 0 };
static void **global_handle_table;
#endif
static void
@ -769,8 +769,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
#undef HANDLE_OPCODE
#if WASM_ENABLE_FAST_INTERP != 0
if (exec_env == NULL) {
bh_memcpy_s(global_handle_table, sizeof(void*) * WASM_INSTRUCTION_NUM,
handle_table, sizeof(void*) * WASM_INSTRUCTION_NUM);
global_handle_table = (void **)handle_table;
return;
}
#endif
@ -1240,7 +1239,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
/* fail to memory.grow, return -1 */
frame_lp[addr_ret] = -1;
if (wasm_get_exception(module)) {
bh_printf("%s\n", wasm_get_exception(module));
os_printf("%s\n", wasm_get_exception(module));
wasm_set_exception(module, NULL);
}
}
@ -2035,19 +2034,20 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
HANDLE_OP (WASM_OP_TEE_LOCAL):
{
GET_LOCAL_INDEX_TYPE_AND_OFFSET();
addr1 = GET_OFFSET();
switch (local_type) {
case VALUE_TYPE_I32:
case VALUE_TYPE_F32:
*(int32*)(frame_lp + local_offset) = GET_OPERAND(uint32, 0);
break;
case VALUE_TYPE_I64:
case VALUE_TYPE_F64:
PUT_I64_TO_ADDR((uint32*)(frame_lp + local_offset), GET_OPERAND(uint64, 0));
break;
default:
wasm_set_exception(module, "invalid local type");
goto got_exception;
if (local_type == VALUE_TYPE_I32
|| local_type == VALUE_TYPE_F32) {
*(int32*)(frame_lp + local_offset) = frame_lp[addr1];
}
else if (local_type == VALUE_TYPE_I32
|| local_type == VALUE_TYPE_F32) {
PUT_I64_TO_ADDR((uint32*)(frame_lp + local_offset),
GET_I64_FROM_ADDR(frame_lp + addr1));
}
else {
wasm_set_exception(module, "invalid local type");
goto got_exception;
}
HANDLE_OP_END ();

View File

@ -2311,7 +2311,7 @@ wasm_loader_find_block_addr(BlockAddr *block_addr_cache,
#if WASM_ENABLE_FAST_INTERP != 0
#if WASM_DEBUG_PREPROCESSOR != 0
#define LOG_OP(...) bh_printf(__VA_ARGS__)
#define LOG_OP(...) os_printf(__VA_ARGS__)
#else
#define LOG_OP(...)
#endif
@ -3886,6 +3886,7 @@ handle_next_reachable_block:
}
case WASM_OP_DROP:
case WASM_OP_DROP_64:
{
if (loader_ctx->stack_cell_num <= 0) {
set_error_buf(error_buf, error_buf_size,
@ -3915,7 +3916,7 @@ handle_next_reachable_block:
}
loader_ctx->frame_ref -= 2;
loader_ctx->stack_cell_num -= 2;
#if WASM_ENABLE_FAST_INTERP == 0
#if (WASM_ENABLE_FAST_INTERP == 0) || (WASM_ENABLE_JIT != 0)
*(p - 1) = WASM_OP_DROP_64;
#endif
#if WASM_ENABLE_FAST_INTERP != 0
@ -3930,6 +3931,7 @@ handle_next_reachable_block:
}
case WASM_OP_SELECT:
case WASM_OP_SELECT_64:
{
uint8 ref_type;
@ -3948,7 +3950,7 @@ handle_next_reachable_block:
break;
case REF_I64_2:
case REF_F64_2:
#if WASM_ENABLE_FAST_INTERP == 0
#if (WASM_ENABLE_FAST_INTERP == 0) || (WASM_ENABLE_JIT != 0)
*(p - 1) = WASM_OP_SELECT_64;
#endif
#if WASM_ENABLE_FAST_INTERP != 0

View File

@ -1108,7 +1108,8 @@ wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
{
#if WASM_ENABLE_MEMORY_GROW != 0
WASMMemoryInstance *memory = module->default_memory, *new_memory;
uint32 old_page_count = memory->cur_page_count, total_size_old;
uint32 old_page_count = memory->cur_page_count;
uint32 total_size_old = memory->end_addr - (uint8*)memory;
uint32 total_page_count = inc_page_count + memory->cur_page_count;
uint64 total_size = offsetof(WASMMemoryInstance, base_addr) +
memory->num_bytes_per_page * (uint64)total_page_count +
@ -1135,14 +1136,14 @@ wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
wasm_set_exception(module, "fail to enlarge memory.");
return false;
}
total_size_old = memory->end_addr - (uint8*)memory;
bh_memcpy_s((uint8*)new_memory, (uint32)total_size,
(uint8*)memory, total_size_old);
memset((uint8*)new_memory + total_size_old,
0, (uint32)total_size - total_size_old);
wasm_runtime_free(memory);
}
memset((uint8*)new_memory + total_size_old,
0, (uint32)total_size - total_size_old);
new_memory->cur_page_count = total_page_count;
new_memory->memory_data = new_memory->base_addr;
new_memory->global_data = new_memory->memory_data +

View File

@ -388,7 +388,7 @@ sprintf_out(int c, struct str_context *ctx)
static int
printf_out(int c, struct str_context *ctx)
{
bh_printf("%c", c);
os_printf("%c", c);
ctx->count++;
return c;
}
@ -470,13 +470,13 @@ snprintf_wrapper(wasm_exec_env_t exec_env, char *str, uint32 size,
static int
puts_wrapper(wasm_exec_env_t exec_env, const char *str)
{
return bh_printf("%s\n", str);
return os_printf("%s\n", str);
}
static int
putchar_wrapper(wasm_exec_env_t exec_env, int c)
{
bh_printf("%c", c);
os_printf("%c", c);
return 1;
}
@ -908,7 +908,7 @@ static void
llvm_stackrestore_wrapper(wasm_exec_env_t exec_env, uint32 llvm_stack)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
bh_printf("_llvm_stackrestore called!\n");
os_printf("_llvm_stackrestore called!\n");
wasm_runtime_set_llvm_stack(module_inst, llvm_stack);
}
@ -916,7 +916,7 @@ static uint32
llvm_stacksave_wrapper(wasm_exec_env_t exec_env)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
bh_printf("_llvm_stacksave called!\n");
os_printf("_llvm_stacksave called!\n");
return wasm_runtime_get_llvm_stack(module_inst);
}
@ -996,7 +996,7 @@ __cxa_throw_wrapper(wasm_exec_env_t exec_env,
static void
print_i32_wrapper(wasm_exec_env_t exec_env, int32 i32)
{
bh_printf("%d\n", i32);
os_printf("%d\n", i32);
}
#define REG_NATIVE_FUNC(func_name, signature) \
@ -1028,7 +1028,7 @@ static NativeSymbol native_symbols_libc_builtin[] = {
REG_NATIVE_FUNC(exit, "(i)"),
REG_NATIVE_FUNC(strtol, "($*i)i"),
REG_NATIVE_FUNC(strtoul, "($*i)i"),
REG_NATIVE_FUNC(memchr, "(*ii)"),
REG_NATIVE_FUNC(memchr, "(*ii)i"),
REG_NATIVE_FUNC(strncasecmp, "($$i)"),
REG_NATIVE_FUNC(strspn, "($$)i"),
REG_NATIVE_FUNC(strcspn, "($$)i"),

View File

@ -47,6 +47,7 @@
#include "str.h"
#include "bh_common.h"
#include "bh_assert.h"
#if 0 /* TODO: -std=gnu99 causes compile error, comment them first */
// struct iovec must have the same layout as __wasi_iovec_t.

View File

@ -1,144 +0,0 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
/**
* @file bh_log.h
* @date Tue Nov 8 18:19:10 2011
*
* @brief This log system supports wrapping multiple outputs into one
* log message. This is useful for outputting variable-length logs
* without additional memory overhead (the buffer for concatenating
* the message), e.g. exception stack trace, which cannot be printed
* by a single log calling without the help of an additional buffer.
* Avoiding additional memory buffer is useful for resource-constraint
* systems. It can minimize the impact of log system on applications
* and logs can be printed even when no enough memory is available.
* Functions with prefix "_" are private functions. Only macros that
* are not start with "_" are exposed and can be used.
*/
#ifndef _BH_LOG_H
#define _BH_LOG_H
#include <stdarg.h>
#include "bh_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* The following functions are the primitive operations of this log
* system. A normal usage of the log system is to call bh_log_printf
* or bh_log_vprintf one or multiple times and then call bh_log_commit
* to wrap (mark) the previous outputs into one log message. The
* bh_log and macros LOG_ERROR etc. can be used to output log messages
* that can be wrapped into one log calling.
*/
int _bh_log_init(void);
void _bh_log_set_verbose_level(int level);
void _bh_log_printf(const char *fmt, ...);
void _bh_log_vprintf(const char *fmt, va_list ap);
void _bh_log_commit(void);
#if WASM_ENABLE_LOG != 0
# define bh_log_init() _bh_log_init ()
# define bh_log_set_verbose_level(l) _bh_log_set_verbose_level (l)
# define bh_log_printf(...) _bh_log_printf (__VA_ARGS__)
# define bh_log_vprintf(...) _bh_log_vprintf (__VA_ARGS__)
# define bh_log_commit() _bh_log_commit ()
#else /* WASM_ENABLE_LOG != 0 */
# define bh_log_init() 0
# define bh_log_set_verbose_level(l) (void)0
# define bh_log_printf(...) (void)0
# define bh_log_vprintf(...) (void)0
# define bh_log_commit() (void)0
#endif /* WASM_ENABLE_LOG != 0 */
void _bh_log(const char *tag, const char *file, int line, const char *fmt, ...);
/* Always print fatal message */
# define LOG_FATAL(...) _bh_log ("V0.", NULL, 0, __VA_ARGS__)
#if WASM_ENABLE_LOG != 0
# define LOG_ERROR(...) _bh_log ("V1.", NULL, 0, __VA_ARGS__)
# define LOG_WARNING(...) _bh_log ("V2.", NULL, 0, __VA_ARGS__)
# define LOG_INFO_RELEASE(...) _bh_log ("V3.", NULL, 0, __VA_ARGS__)
# define LOG_INFO_APP_DEV(...) _bh_log ("V4.", NULL, 0, __VA_ARGS__)
# define LOG_VERBOSE(...) _bh_log ("V5.", NULL, 0, __VA_ARGS__)
# if BEIHAI_ENABLE_MEMORY_PROFILING != 0
# define LOG_PROFILE(...) _bh_log ("V3.", NULL, 0, __VA_ARGS__)
# else
# define LOG_PROFILE(...) (void)0
#endif
# if BEIHAI_ENABLE_QUEUE_PROFILING != 0
# define LOG_QUEUE_PROFILE(...) _bh_log ("V3.", NULL, 0, __VA_ARGS__)
# else
# define LOG_QUEUE_PROFILE(...) (void)0
#endif
# if BEIHAI_ENABLE_GC_STAT_PROFILING != 0
# define LOG_GC_STAT_PROFILE(...) _bh_log ("V3.", NULL, 0, __VA_ARGS__)
# else
# define LOG_GC_STAT_PROFILE(...) (void)0
#endif
#else /* WASM_ENABLE_LOG != 0 */
# define LOG_ERROR(...) (void)0
# define LOG_WARNING(...) (void)0
# define LOG_INFO_APP_DEV(...) (void)0
# define LOG_INFO_RELEASE(...) (void)0
# define LOG_VERBOSE(...) (void)0
# define LOG_PROFILE(...) (void)0
# define LOG_QUEUE_PROFILE(...) (void)0
# define LOG_GC_STAT_PROFILE(...) (void)0
#endif /* WASM_ENABLE_LOG != 0 */
#define LOG_PROFILE_INSTANCE_HEAP_CREATED(heap) \
LOG_PROFILE ("PROF.INSTANCE.HEAP_CREATED: HEAP=%08X", heap)
#define LOG_PROFILE_INSTANCE_THREAD_STARTED(heap) \
LOG_PROFILE ("PROF.INSTANCE.THREAD_STARTED: HEAP=%08X", heap)
#define LOG_PROFILE_HEAP_ALLOC(heap, size) \
LOG_PROFILE ("PROF.HEAP.ALLOC: HEAP=%08X SIZE=%d", heap, size)
#define LOG_PROFILE_HEAP_FREE(heap, size) \
LOG_PROFILE ("PROF.HEAP.FREE: HEAP=%08X SIZE=%d", heap, size)
#define LOG_PROFILE_HEAP_NEW(heap, size) \
LOG_PROFILE ("PROF.HEAP.NEW: HEAP=%08X SIZE=%d", heap, size)
#define LOG_PROFILE_HEAP_GC(heap, size) \
LOG_PROFILE ("PROF.HEAP.GC: HEAP=%08X SIZE=%d", heap, size)
#define LOG_PROFILE_STACK_PUSH(used) \
LOG_PROFILE ("PROF.STACK.PUSH: USED=%d", used)
#define LOG_PROFILE_STACK_POP() \
LOG_PROFILE ("PROF.STACK.POP")
/* Please add your component ahead of LOG_COM_MAX */
enum {
LOG_COM_APP_MANAGER = 0,
LOG_COM_GC,
LOG_COM_HMC,
LOG_COM_UTILS,
LOG_COM_VERIFIER_JEFF,
LOG_COM_VMCORE_JEFF,
LOG_COM_MAX
};
#if defined(BH_DEBUG)
void log_parse_coms(const char *coms);
int bh_log_dcom_is_enabled(int component);
#define LOG_DEBUG(component, ...) do { \
if (bh_log_dcom_is_enabled (component)) \
_bh_log ("V6: ", __FILE__, __LINE__, __VA_ARGS__); \
} while (0)
#else /* defined(BH_DEBUG) */
#define LOG_DEBUG(component, ...) (void)0
#endif /* defined(BH_DEBUG) */
#ifdef __cplusplus
}
#endif
#endif /* _BH_LOG_H */

View File

@ -20,7 +20,7 @@ static int hmu_is_in_heap(gc_heap_t* heap, hmu_t* hmu)
/* Node @p will be removed from the tree and left,right,parent pointers of node @p will be*/
/* set to be NULL. Other fields will not be touched.*/
/* The tree will be re-organized so that the order conditions are still satisified.*/
BH_STATIC void remove_tree_node(hmu_tree_node_t *p)
static void remove_tree_node(hmu_tree_node_t *p)
{
hmu_tree_node_t *q = NULL, **slot = NULL;
@ -92,19 +92,20 @@ static void unlink_hmu(gc_heap_t *heap, hmu_t *hmu)
if (HMU_IS_FC_NORMAL(size)) {
uint32 node_idx = size >> 3;
hmu_normal_node_t* node = heap->kfc_normal_list[node_idx].next;
hmu_normal_node_t** p = &(heap->kfc_normal_list[node_idx].next);
hmu_normal_node_t *node_prev = &heap->kfc_normal_list[node_idx];
hmu_normal_node_t *node =
get_hmu_normal_node_next(&heap->kfc_normal_list[node_idx]);
while (node) {
if ((hmu_t*) node == hmu) {
*p = node->next;
set_hmu_normal_node_next(node_prev, get_hmu_normal_node_next(node));
break;
}
p = &(node->next);
node = node->next;
node_prev = node;
node = get_hmu_normal_node_next(node);
}
if (!node) {
bh_printf("[GC_ERROR]couldn't find the node in the normal list");
os_printf("[GC_ERROR]couldn't find the node in the normal list");
}
} else {
remove_tree_node((hmu_tree_node_t *) hmu);
@ -154,7 +155,7 @@ void gci_add_fc(gc_heap_t *heap, hmu_t *hmu, gc_size_t size)
node_idx = size >> 3;
np->next = heap->kfc_normal_list[node_idx].next;
heap->kfc_normal_list[node_idx].next = np;
set_hmu_normal_node_next(&heap->kfc_normal_list[node_idx], np);
return;
}
@ -197,7 +198,7 @@ void gci_add_fc(gc_heap_t *heap, hmu_t *hmu, gc_size_t size)
/* A proper HMU will be returned. This HMU can include the header and given size. The returned HMU will be aligned to 8 bytes.*/
/* NULL will be returned if there are no proper HMU.*/
BH_STATIC hmu_t *alloc_hmu(gc_heap_t *heap, gc_size_t size)
static hmu_t *alloc_hmu(gc_heap_t *heap, gc_size_t size)
{
hmu_normal_node_t *node = NULL, *p = NULL;
uint32 node_idx = 0, init_node_idx = 0;
@ -217,7 +218,7 @@ BH_STATIC hmu_t *alloc_hmu(gc_heap_t *heap, gc_size_t size)
for (node_idx = init_node_idx; node_idx < HMU_NORMAL_NODE_CNT;
node_idx++) {
node = heap->kfc_normal_list + node_idx;
if (node->next)
if (get_hmu_normal_node_next(node))
break;
node = NULL;
}
@ -226,7 +227,7 @@ BH_STATIC hmu_t *alloc_hmu(gc_heap_t *heap, gc_size_t size)
if (node) {
bh_assert(node_idx >= init_node_idx);
p = node->next;
p = get_hmu_normal_node_next(node);
node->next = p->next;
bh_assert(((gc_int32)(uintptr_t)hmu_to_obj(p) & 7) == 0);
@ -316,7 +317,7 @@ BH_STATIC hmu_t *alloc_hmu(gc_heap_t *heap, gc_size_t size)
/* A proper HMU will be returned. This HMU can include the header and given size. The returned HMU will be aligned to 8 bytes.*/
/* NULL will be returned if there are no proper HMU.*/
BH_STATIC hmu_t* alloc_hmu_ex(gc_heap_t *heap, gc_size_t size)
static hmu_t* alloc_hmu_ex(gc_heap_t *heap, gc_size_t size)
{
hmu_t *ret = NULL;
@ -353,11 +354,14 @@ gc_object_t _gc_alloc_vo_i_heap(void *vheap,
gc_heap_t* heap = (gc_heap_t*) vheap;
hmu_t *hmu = NULL;
gc_object_t ret = (gc_object_t) NULL;
gc_size_t tot_size = 0;
gc_size_t tot_size = 0, tot_size_unaligned;
/* align size*/
tot_size = GC_ALIGN_8(size + HMU_SIZE + OBJ_PREFIX_SIZE + OBJ_SUFFIX_SIZE); /* hmu header, prefix, suffix*/
/* hmu header + prefix + obj + suffix */
tot_size_unaligned = HMU_SIZE + OBJ_PREFIX_SIZE + size + OBJ_SUFFIX_SIZE;
/* aligned size*/
tot_size = GC_ALIGN_8(tot_size_unaligned);
if (tot_size < size)
/* integer overflow */
return NULL;
gct_vm_mutex_lock(&heap->lock);
@ -376,9 +380,12 @@ gc_object_t _gc_alloc_vo_i_heap(void *vheap,
#endif
ret = hmu_to_obj(hmu);
if (tot_size > tot_size_unaligned)
/* clear buffer appended by GC_ALIGN_8() */
memset((uint8*)ret + size, 0, tot_size - tot_size_unaligned);
#if BH_ENABLE_MEMORY_PROFILING != 0
bh_printf("HEAP.ALLOC: heap: %p, size: %u", heap, size);
os_printf("HEAP.ALLOC: heap: %p, size: %u", heap, size);
#endif
FINISH:
@ -393,23 +400,25 @@ gc_object_t _gc_realloc_vo_i_heap(void *vheap, void *ptr,
gc_heap_t* heap = (gc_heap_t*) vheap;
hmu_t *hmu = NULL, *hmu_old = NULL;
gc_object_t ret = (gc_object_t) NULL, obj_old = (gc_object_t)ptr;
gc_size_t tot_size = 0, size_old = 0;
gc_size_t tot_size, tot_size_unaligned, tot_size_old = 0;
gc_size_t obj_size, obj_size_old;
/* hmu header + prefix + obj + suffix */
tot_size_unaligned = HMU_SIZE + OBJ_PREFIX_SIZE + size + OBJ_SUFFIX_SIZE;
/* aligned size*/
tot_size = GC_ALIGN_8(tot_size_unaligned);
if (tot_size < size)
/* integer overflow */
return NULL;
if (obj_old) {
hmu_old = obj_to_hmu(obj_old);
size_old = hmu_get_size(hmu_old);
size_old -= HMU_SIZE + OBJ_PREFIX_SIZE + OBJ_SUFFIX_SIZE;
if (size < size_old)
return NULL;
if (size == size_old)
tot_size_old = hmu_get_size(hmu_old);
if (tot_size <= tot_size_old)
/* current node alreay meets requirement */
return obj_old;
}
/* align size*/
tot_size = GC_ALIGN_8(size + HMU_SIZE + OBJ_PREFIX_SIZE + OBJ_SUFFIX_SIZE); /* hmu header, prefix, suffix*/
if (tot_size < size)
return NULL;
gct_vm_mutex_lock(&heap->lock);
hmu = alloc_hmu_ex(heap, tot_size);
@ -428,16 +437,19 @@ gc_object_t _gc_realloc_vo_i_heap(void *vheap, void *ptr,
ret = hmu_to_obj(hmu);
#if BH_ENABLE_MEMORY_PROFILING != 0
bh_printf("HEAP.ALLOC: heap: %p, size: %u", heap, size);
os_printf("HEAP.ALLOC: heap: %p, size: %u", heap, size);
#endif
FINISH:
gct_vm_mutex_unlock(&heap->lock);
if (ret) {
memset(ret, 0, size);
obj_size = tot_size - HMU_SIZE - OBJ_PREFIX_SIZE - OBJ_SUFFIX_SIZE;
memset(ret, 0, obj_size);
if (obj_old) {
memcpy(ret, obj_old, size_old);
obj_size_old = tot_size_old - HMU_SIZE
- OBJ_PREFIX_SIZE - OBJ_SUFFIX_SIZE;
bh_memcpy_s(ret, obj_size, obj_old, obj_size_old);
gc_free_h(vheap, obj_old);
}
}
@ -445,47 +457,6 @@ FINISH:
return ret;
}
/* see ems_gc.h for description*/
gc_object_t _gc_alloc_jo_i_heap(void *vheap,
gc_size_t size ALLOC_EXTRA_PARAMETERS)
{
gc_heap_t* heap = (gc_heap_t*) vheap;
gc_object_t ret = (gc_object_t) NULL;
hmu_t *hmu = NULL;
gc_size_t tot_size = 0;
bh_assert(gci_is_heap_valid(heap));
/* align size*/
tot_size = GC_ALIGN_8(size + HMU_SIZE + OBJ_PREFIX_SIZE + OBJ_SUFFIX_SIZE); /* hmu header, prefix, suffix*/
if (tot_size < size)
return NULL;
hmu = alloc_hmu_ex(heap, tot_size);
if (!hmu)
goto FINISH;
/* reset all fields*/
memset((char*) hmu + sizeof(*hmu), 0, tot_size - sizeof(*hmu));
/* hmu->header = 0; */
hmu_set_ut(hmu, HMU_JO);
hmu_unmark_jo(hmu);
#if defined(GC_VERIFY)
hmu_init_prefix_and_suffix(hmu, tot_size, file_name, line_number);
#endif
ret = hmu_to_obj(hmu);
#if BH_ENABLE_MEMORY_PROFILING != 0
bh_printf("HEAP.ALLOC: heap: %p, size: %u", heap, size);
#endif
FINISH:
return ret;
}
/* Do some checking to see if given pointer is a possible valid heap*/
/* Return GC_TRUE if all checking passed*/
@ -539,7 +510,7 @@ int gc_free_i_heap(void *vheap, gc_object_t obj ALLOC_EXTRA_PARAMETERS)
heap->total_free_size += size;
#endif
#if BH_ENABLE_MEMORY_PROFILING != 0
bh_printf("HEAP.FREE, heap: %p, size: %u\n",heap, size);
os_printf("HEAP.FREE, heap: %p, size: %u\n",heap, size);
#endif
if (!hmu_get_pinuse(hmu)) {
@ -582,12 +553,12 @@ int gc_free_i_heap(void *vheap, gc_object_t obj ALLOC_EXTRA_PARAMETERS)
void gc_dump_heap_stats(gc_heap_t *heap)
{
bh_printf("heap: %p, heap start: %p\n", heap, heap->base_addr);
bh_printf(
os_printf("heap: %p, heap start: %p\n", heap, heap->base_addr);
os_printf(
"total malloc: totalfree: %u, current: %u, highmark: %u, gc cnt: %u\n",
heap->total_free_size, heap->current_size, heap->highmark_size,
heap->total_gc_count);
bh_printf("g_total_malloc=%lu, g_total_free=%lu, occupied=%lu\n",
os_printf("g_total_malloc=%lu, g_total_free=%lu, occupied=%lu\n",
g_total_malloc, g_total_free, g_total_malloc - g_total_free);
}

View File

@ -44,13 +44,7 @@ extern "C" {
# error "Can not define GC_EMBEDDED and GC_STANDALONE at the same time"
#endif
#ifdef BH_TEST
# ifndef GC_TEST
# define GC_TEST
# endif
#endif
#ifdef BH_DEBUG
#if BH_DEBUG != 0
/*instrument mode ignore GC_DEBUG feature, for instrument testing gc_alloc_vo_i_heap only has func_name parameter*/
#if !defined INSTRUMENT_TEST_ENABLED && !defined GC_DEBUG
# define GC_DEBUG

View File

@ -11,8 +11,6 @@ extern "C" {
#endif
#include "bh_platform.h"
#include "bh_thread.h"
#include "bh_assert.h"
#include "ems_gc.h"
/* basic block managed by EMS gc is the so-called HMU (heap memory unit)*/
@ -146,8 +144,35 @@ extern void hmu_verify(hmu_t *hmu);
typedef struct _hmu_normal_node
{
hmu_t hmu_header;
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
struct {
uint32 parts[2];
} next;
#else
struct _hmu_normal_node *next;
}hmu_normal_node_t;
#endif
} hmu_normal_node_t;
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
static inline hmu_normal_node_t *
get_hmu_normal_node_next(hmu_normal_node_t *node)
{
hmu_normal_node_t *next;
bh_memcpy_s(&next, (uint32)sizeof(hmu_normal_node_t *),
&node->next.parts, (uint32)sizeof(uint32) * 2);
return next;
}
static inline void
set_hmu_normal_node_next(hmu_normal_node_t *node, hmu_normal_node_t *next)
{
bh_memcpy_s(&node->next.parts, (uint32)sizeof(uint32) * 2,
&next, (uint32)sizeof(hmu_normal_node_t *));
}
#else
#define get_hmu_normal_node_next(node) (node)->next
#define set_hmu_normal_node_next(node, _next) (node)->next = _next
#endif
typedef struct _hmu_tree_node
{
@ -156,7 +181,7 @@ typedef struct _hmu_tree_node
struct _hmu_tree_node *left;
struct _hmu_tree_node *right;
struct _hmu_tree_node *parent;
}hmu_tree_node_t;
} hmu_tree_node_t;
typedef struct _gc_heap_struct
{
@ -193,7 +218,7 @@ typedef struct _gc_heap_struct
gc_size_t gc_threshold_factor;
gc_int64 total_gc_time;
#endif
}gc_heap_t;
} gc_heap_t;
/*////// MISC internal used APIs*/
@ -254,10 +279,10 @@ extern int (*gct_vm_begin_rootset_enumeration)(void* heap);
extern int (*gct_vm_gc_finished)(void);
#else
#define gct_vm_get_java_object_ref_list bh_get_java_object_ref_list
#define gct_vm_mutex_init vm_mutex_init
#define gct_vm_mutex_destroy vm_mutex_destroy
#define gct_vm_mutex_lock vm_mutex_lock
#define gct_vm_mutex_unlock vm_mutex_unlock
#define gct_vm_mutex_init os_mutex_init
#define gct_vm_mutex_destroy os_mutex_destroy
#define gct_vm_mutex_lock os_mutex_lock
#define gct_vm_mutex_unlock os_mutex_unlock
#define gct_vm_get_gc_handle_for_current_instance app_manager_get_cur_applet_heap
#define gct_vm_begin_rootset_enumeration vm_begin_rootset_enumeration
#define gct_vm_gc_finished jeff_runtime_gc_finished

View File

@ -16,7 +16,7 @@ int gci_check_platform()
{
#define CHECK(x, y) do { \
if((x) != (y)) { \
bh_printf("Platform checking failed on LINE %d at FILE %s.",\
os_printf("Platform checking failed on LINE %d at FILE %s.",\
__LINE__, __FILE__); \
return GC_ERROR; \
} \
@ -48,12 +48,12 @@ gc_handle_t gc_init_with_pool(char *buf, gc_size_t buf_size)
/* check system compatibility*/
if (gci_check_platform() == GC_ERROR) {
bh_printf("Check platform compatibility failed");
os_printf("Check platform compatibility failed");
return NULL;
}
if (buf_size < 1024) {
bh_printf("[GC_ERROR]heap_init_size(%d) < 1024", buf_size);
os_printf("[GC_ERROR]heap_init_size(%d) < 1024", buf_size);
return NULL;
}
@ -65,12 +65,12 @@ gc_handle_t gc_init_with_pool(char *buf, gc_size_t buf_size)
ret = gct_vm_mutex_init(&heap->lock);
if (ret != BHT_OK) {
bh_printf("[GC_ERROR]failed to init lock ");
os_printf("[GC_ERROR]failed to init lock ");
return NULL;
}
#ifdef BH_FOOTPRINT
bh_printf("\nINIT HEAP 0x%08x %d\n", base_addr, heap_max_size);
os_printf("\nINIT HEAP 0x%08x %d\n", base_addr, heap_max_size);
#endif
/* init all data structures*/
@ -117,8 +117,8 @@ gc_handle_t gc_init_with_pool(char *buf, gc_size_t buf_size)
&& HMU_FC_NORMAL_MAX_SIZE < q->size); /*@NOTIFY*/
#if BH_ENABLE_MEMORY_PROFILING != 0
bh_printf("heap is successfully initialized with max_size=%u.",
heap_max_size);
os_printf("heap is successfully initialized with max_size=%u.",
heap_max_size);
#endif
return heap;
}

View File

@ -4,7 +4,6 @@
*/
#include "mem_alloc.h"
#include "config.h"
#if DEFAULT_MEM_ALLOCATOR == MEM_ALLOCATOR_EMS
@ -41,7 +40,6 @@ void mem_allocator_free(mem_allocator_t allocator, void *ptr)
#else /* else of DEFAULT_MEM_ALLOCATOR */
#include "tlsf/tlsf.h"
#include "bh_thread.h"
typedef struct mem_allocator_tlsf {
tlsf_t tlsf;
@ -79,7 +77,7 @@ mem_allocator_create(void *mem, uint32_t size)
allocator_tlsf->tlsf = tlsf;
if (vm_mutex_init(&allocator_tlsf->lock)) {
if (os_mutex_init(&allocator_tlsf->lock)) {
printf("Create mem allocator failed: tlsf_malloc failed.\n");
tlsf_free(tlsf, allocator_tlsf);
tlsf_destroy(tlsf);
@ -95,7 +93,7 @@ mem_allocator_destroy(mem_allocator_t allocator)
mem_allocator_tlsf *allocator_tlsf = (mem_allocator_tlsf *)allocator;
tlsf_t tlsf = allocator_tlsf->tlsf;
vm_mutex_destroy(&allocator_tlsf->lock);
os_mutex_destroy(&allocator_tlsf->lock);
tlsf_free(tlsf, allocator_tlsf);
tlsf_destroy(tlsf);
}
@ -110,9 +108,9 @@ mem_allocator_malloc(mem_allocator_t allocator, uint32_t size)
/* tlsf doesn't allow to allocate 0 byte */
size = 1;
vm_mutex_lock(&allocator_tlsf->lock);
os_mutex_lock(&allocator_tlsf->lock);
ret = tlsf_malloc(allocator_tlsf->tlsf, size);
vm_mutex_unlock(&allocator_tlsf->lock);
os_mutex_unlock(&allocator_tlsf->lock);
return ret;
}
@ -126,9 +124,9 @@ mem_allocator_realloc(mem_allocator_t allocator, void *ptr, uint32_t size)
/* tlsf doesn't allow to allocate 0 byte */
size = 1;
vm_mutex_lock(&allocator_tlsf->lock);
os_mutex_lock(&allocator_tlsf->lock);
ret = tlsf_realloc(allocator_tlsf->tlsf, ptr, size);
vm_mutex_unlock(&allocator_tlsf->lock);
os_mutex_unlock(&allocator_tlsf->lock);
return ret;
}
@ -137,9 +135,9 @@ mem_allocator_free(mem_allocator_t allocator, void *ptr)
{
if (ptr) {
mem_allocator_tlsf *allocator_tlsf = (mem_allocator_tlsf *)allocator;
vm_mutex_lock(&allocator_tlsf->lock);
os_mutex_lock(&allocator_tlsf->lock);
tlsf_free(allocator_tlsf->tlsf, ptr);
vm_mutex_unlock(&allocator_tlsf->lock);
os_mutex_unlock(&allocator_tlsf->lock);
}
}

View File

@ -6,7 +6,7 @@
#ifndef __MEM_ALLOC_H
#define __MEM_ALLOC_H
#include <inttypes.h>
#include "bh_platform.h"
#ifdef __cplusplus
extern "C" {

View File

@ -0,0 +1,10 @@
This folder contains the platform abstract layer for multiple platforms. To support a new platform, you can simply create a new folder here and implement all the APIs defined in [`include`](./include) folder.
Refer to [port_wamr.md](../../../doc/port_wamr.md) for how to port WAMR to a target platform.

View File

@ -3,15 +3,25 @@
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "bh_platform.h"
#include "bh_common.h"
#include <stdlib.h>
#include <string.h>
#include "platform_api_vmcore.h"
#include "platform_api_extension.h"
int
os_thread_sys_init();
void
os_thread_sys_destroy();
int
bh_platform_init()
{
return 0;
return os_thread_sys_init();
}
void
bh_platform_destroy()
{
os_thread_sys_destroy();
}
void *
@ -32,24 +42,24 @@ os_free(void *ptr)
}
void *
bh_mmap(void *hint, unsigned int size, int prot, int flags)
os_mmap(void *hint, unsigned int size, int prot, int flags)
{
return BH_MALLOC(size);
}
void
bh_munmap(void *addr, uint32 size)
os_munmap(void *addr, uint32 size)
{
return BH_FREE(addr);
}
int
bh_mprotect(void *addr, uint32 size, int prot)
os_mprotect(void *addr, uint32 size, int prot)
{
return 0;
}
void
bh_dcache_flush()
os_dcache_flush()
{
}

View File

@ -0,0 +1,341 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "platform_api_vmcore.h"
#include "platform_api_extension.h"
#define bh_assert(v) do { \
if (!(v)) { \
printf("\nASSERTION FAILED: %s, at %s, line %d\n", \
#v, __FILE__, __LINE__); \
aos_reboot(); \
while (1); \
} \
} while (0)
struct os_thread_data;
typedef struct os_thread_wait_node {
aos_sem_t sem;
os_thread_wait_list next;
} os_thread_wait_node;
typedef struct os_thread_data {
/* Thread body */
aos_task_t thread;
/* Thread start routine */
thread_start_routine_t start_routine;
/* Thread start routine argument */
void *arg;
/* Thread local root */
void *tlr;
/* Wait node of current thread */
os_thread_wait_node wait_node;
/* Lock for waiting list */
aos_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;
static bool is_thread_sys_inited = false;
/* Thread data of supervisor thread */
static os_thread_data supervisor_thread_data;
/* Thread data key */
static aos_task_key_t thread_data_key;
/* Thread name index */
static int thread_name_index;
int
os_thread_sys_init()
{
if (is_thread_sys_inited)
return BHT_OK;
if (aos_task_key_create(&thread_data_key) != 0)
return BHT_ERROR;
/* Initialize supervisor thread data */
memset(&supervisor_thread_data, 0, sizeof(supervisor_thread_data));
if (aos_sem_new(&supervisor_thread_data.wait_node.sem, 1) != 0) {
aos_task_key_delete(thread_data_key);
return BHT_ERROR;
}
if (aos_task_setspecific(thread_data_key, &supervisor_thread_data)) {
aos_sem_free(&supervisor_thread_data.wait_node.sem);
aos_task_key_delete(thread_data_key);
return BHT_ERROR;
}
is_thread_sys_inited = true;
return BHT_OK;
}
void
os_thread_sys_destroy()
{
if (is_thread_sys_inited) {
aos_task_key_delete(thread_data_key);
aos_sem_free(&supervisor_thread_data.wait_node.sem);
is_thread_sys_inited = false;
}
}
static os_thread_data *
thread_data_current()
{
return aos_task_getspecific(thread_data_key);
}
static void
os_thread_cleanup(void)
{
os_thread_data *thread_data = thread_data_current();
os_thread_wait_list thread_wait_list;
aos_mutex_t *wait_list_lock;
aos_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;
/* Free thread data firstly */
BH_FREE(thread_data);
aos_mutex_lock(wait_list_lock, AOS_WAIT_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;
aos_sem_signal(&head->sem);
head = next;
}
}
aos_mutex_unlock(wait_list_lock);
/* Free sem and lock */
aos_sem_free(wait_node_sem);
aos_mutex_free(wait_list_lock);
}
static void
os_thread_wrapper(void *arg)
{
os_thread_data *thread_data = arg;
/* Set thread custom data */
if (!aos_task_setspecific(thread_data_key, thread_data))
thread_data->start_routine(thread_data->arg);
os_thread_cleanup();
}
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_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];
if (!p_tid || !stack_size)
return BHT_ERROR;
/* Create and initialize thread data */
if (!(thread_data = BH_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 (aos_sem_new(&thread_data->wait_node.sem, 1) != 0)
goto fail1;
if (aos_mutex_new(&thread_data->wait_list_lock))
goto fail2;
snprintf(thread_name, sizeof(thread_name), "%s%d",
"wasm-thread-", ++thread_name_index);
/* Create the thread */
if (aos_task_new_ext((aos_task_t*)thread_data, thread_name,
os_thread_wrapper, thread_data,
stack_size, prio))
goto fail3;
aos_msleep(10);
*p_tid = (korp_tid)thread_data;
return BHT_OK;
fail3:
aos_mutex_free(&thread_data->wait_list_lock);
fail2:
aos_sem_free(&thread_data->wait_node.sem);
fail1:
BH_FREE(thread_data);
return BHT_ERROR;
}
korp_tid
os_self_thread()
{
return (korp_tid)aos_task_getspecific(thread_data_key);
}
int
os_thread_join (korp_tid thread, void **value_ptr)
{
(void)value_ptr;
os_thread_data *thread_data, *curr_thread_data;
/* Get thread data of current thread */
curr_thread_data = thread_data_current();
curr_thread_data->wait_node.next = NULL;
/* Get thread data */
thread_data = (os_thread_data*)thread;
aos_mutex_lock(&thread_data->wait_list_lock, AOS_WAIT_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;
}
aos_mutex_unlock(&thread_data->wait_list_lock);
/* Wait the sem */
aos_sem_wait(&curr_thread_data->wait_node.sem, AOS_WAIT_FOREVER);
return BHT_OK;
}
int
os_mutex_init(korp_mutex *mutex)
{
return aos_mutex_new(mutex) == 0 ? BHT_OK : BHT_ERROR;
}
int
os_mutex_destroy(korp_mutex *mutex)
{
aos_mutex_free(mutex);
return BHT_OK;
}
void
os_mutex_lock(korp_mutex *mutex)
{
aos_mutex_lock(mutex, AOS_WAIT_FOREVER);
}
void
os_mutex_unlock(korp_mutex *mutex)
{
aos_mutex_unlock(mutex);
}
int
os_cond_init(korp_cond *cond)
{
if (aos_mutex_new(&cond->wait_list_lock) != 0)
return BHT_ERROR;
cond->thread_wait_list = NULL;
return BHT_OK;
}
int
os_cond_destroy(korp_cond *cond)
{
aos_mutex_free(&cond->wait_list_lock);
return BHT_OK;
}
static int
os_cond_wait_internal(korp_cond *cond, korp_mutex *mutex,
bool timed, int mills)
{
os_thread_wait_node *node = &thread_data_current()->wait_node;
node->next = NULL;
aos_mutex_lock(&cond->wait_list_lock, AOS_WAIT_FOREVER);
if (!cond->thread_wait_list)
cond->thread_wait_list = node;
else {
/* Add to end of wait list */
os_thread_wait_node *p = cond->thread_wait_list;
while (p->next)
p = p->next;
p->next = node;
}
aos_mutex_unlock(&cond->wait_list_lock);
/* Unlock mutex, wait sem and lock mutex again */
aos_mutex_unlock(mutex);
aos_sem_wait(&node->sem, timed ? mills : AOS_WAIT_FOREVER);
aos_mutex_lock(mutex, AOS_WAIT_FOREVER);
/* Remove wait node from wait list */
aos_mutex_lock(&cond->wait_list_lock, AOS_WAIT_FOREVER);
if (cond->thread_wait_list == node)
cond->thread_wait_list = node->next;
else {
/* Remove from the wait list */
os_thread_wait_node *p = cond->thread_wait_list;
while (p->next != node)
p = p->next;
p->next = node->next;
}
aos_mutex_unlock(&cond->wait_list_lock);
return BHT_OK;
}
int
os_cond_wait(korp_cond *cond, korp_mutex *mutex)
{
return os_cond_wait_internal(cond, mutex, false, 0);
}
int
os_cond_reltimedwait(korp_cond *cond, korp_mutex *mutex, int useconds)
{
if (useconds == BHT_WAIT_FOREVER)
return os_cond_wait_internal(cond, mutex, false, 0);
else
return os_cond_wait_internal(cond, mutex, true, useconds / 1000);
}
int
os_cond_signal(korp_cond *cond)
{
/* Signal the head wait node of wait list */
aos_mutex_lock(&cond->wait_list_lock, AOS_WAIT_FOREVER);
if (cond->thread_wait_list)
aos_sem_signal(&cond->thread_wait_list->sem);
aos_mutex_unlock(&cond->wait_list_lock);
return BHT_OK;
}

View File

@ -0,0 +1,13 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "platform_api_vmcore.h"
uint64
os_time_get_boot_microsecond()
{
return (uint64)aos_now_ms() * 1000;
}

View File

@ -1,52 +0,0 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "bh_platform.h"
#include "bh_assert.h"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef BH_TEST
#include <setjmp.h>
#endif
#ifdef BH_TEST
/* for exception throwing */
jmp_buf bh_test_jb;
#endif
void bh_assert_internal(int v, const char *file_name, int line_number, const char *expr_string)
{
if(v) return;
if(!file_name) file_name = "NULL FILENAME";
if(!expr_string) expr_string = "NULL EXPR_STRING";
printf("\nASSERTION FAILED: %s, at FILE=%s, LINE=%d\n", expr_string, file_name, line_number);
#ifdef BH_TEST
longjmp(bh_test_jb, 1);
#endif
aos_reboot();
}
void bh_debug_internal(const char *file_name, int line_number, const char *fmt, ...)
{
#ifndef JEFF_TEST_VERIFIER
va_list args;
va_start(args, fmt);
bh_assert(file_name);
printf("\nDebug info FILE=%s, LINE=%d: ", file_name, line_number);
vprintf(fmt, args);
va_end(args);
printf("\n");
#endif
}

View File

@ -1,861 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#include "bh_platform.h"
#define __FDLIBM_STDC__
typedef uint32_t u_int32_t;
typedef uint64_t u_int64_t;
typedef union u32double_tag {
int *pint;
double *pdouble;
} U32DOUBLE;
static inline int *
pdouble2pint(double *pdouble)
{
U32DOUBLE u;
u.pdouble = pdouble;
return u.pint;
}
typedef union
{
double value;
struct
{
u_int32_t lsw;
u_int32_t msw;
} parts;
struct
{
u_int64_t w;
} xparts;
} ieee_double_shape_type_little;
typedef union
{
double value;
struct
{
u_int32_t msw;
u_int32_t lsw;
} parts;
struct
{
u_int64_t w;
} xparts;
} ieee_double_shape_type_big;
typedef union {
double d;
struct {
unsigned int manl :32;
unsigned int manh :20;
unsigned int exp :11;
unsigned int sign :1;
} bits;
} IEEEd2bits_L;
typedef union {
double d;
struct {
unsigned int sign :1;
unsigned int exp :11;
unsigned int manh :20;
unsigned int manl :32;
} bits;
} IEEEd2bits_B;
typedef union {
float f;
struct {
unsigned int man :23;
unsigned int exp :8;
unsigned int sign :1;
} bits;
} IEEEf2bits_L;
typedef union {
float f;
struct {
unsigned int sign :1;
unsigned int exp :8;
unsigned int man :23;
} bits;
} IEEEf2bits_B;
static union {
int a;
char b;
} __ue = { .a = 1 };
#define is_little_endian() (__ue.b == 1)
#define __HIL(x) *(1+pdouble2pint(&x))
#define __LOL(x) *(pdouble2pint(&x))
#define __HIB(x) *(int*)&x
#define __LOB(x) *(1+(int*)&x)
/* Get two 32 bit ints from a double. */
#define EXTRACT_WORDS_L(ix0,ix1,d) \
do { \
ieee_double_shape_type_little ew_u; \
ew_u.value = (d); \
(ix0) = ew_u.parts.msw; \
(ix1) = ew_u.parts.lsw; \
} while (0)
/* Set a double from two 32 bit ints. */
#define INSERT_WORDS_L(d,ix0,ix1) \
do { \
ieee_double_shape_type_little iw_u; \
iw_u.parts.msw = (ix0); \
iw_u.parts.lsw = (ix1); \
(d) = iw_u.value; \
} while (0)
/* Get two 32 bit ints from a double. */
#define EXTRACT_WORDS_B(ix0,ix1,d) \
do { \
ieee_double_shape_type_big ew_u; \
ew_u.value = (d); \
(ix0) = ew_u.parts.msw; \
(ix1) = ew_u.parts.lsw; \
} while (0)
/* Set a double from two 32 bit ints. */
#define INSERT_WORDS_B(d,ix0,ix1) \
do { \
ieee_double_shape_type_big iw_u; \
iw_u.parts.msw = (ix0); \
iw_u.parts.lsw = (ix1); \
(d) = iw_u.value; \
} while (0)
/* Get the more significant 32 bit int from a double. */
#define GET_HIGH_WORD_L(i,d) \
do { \
ieee_double_shape_type_little gh_u; \
gh_u.value = (d); \
(i) = gh_u.parts.msw; \
} while (0)
/* Get the more significant 32 bit int from a double. */
#define GET_HIGH_WORD_B(i,d) \
do { \
ieee_double_shape_type_big gh_u; \
gh_u.value = (d); \
(i) = gh_u.parts.msw; \
} while (0)
/* Set the more significant 32 bits of a double from an int. */
#define SET_HIGH_WORD_L(d,v) \
do { \
ieee_double_shape_type_little sh_u; \
sh_u.value = (d); \
sh_u.parts.msw = (v); \
(d) = sh_u.value; \
} while (0)
/* Set the more significant 32 bits of a double from an int. */
#define SET_HIGH_WORD_B(d,v) \
do { \
ieee_double_shape_type_big sh_u; \
sh_u.value = (d); \
sh_u.parts.msw = (v); \
(d) = sh_u.value; \
} while (0)
/*
* A union which permits us to convert between a float and a 32 bit
* int.
*/
typedef union
{
float value;
/* FIXME: Assumes 32 bit int. */
unsigned int word;
} ieee_float_shape_type;
/* Get a 32 bit int from a float. */
#define GET_FLOAT_WORD(i,d) \
do { \
ieee_float_shape_type gf_u; \
gf_u.value = (d); \
(i) = gf_u.word; \
} while (0)
/* Set a float from a 32 bit int. */
#define SET_FLOAT_WORD(d,i) \
do { \
ieee_float_shape_type sf_u; \
sf_u.word = (i); \
(d) = sf_u.value; \
} while (0)
/* Macro wrappers. */
#define EXTRACT_WORDS(ix0,ix1,d) do { \
if (is_little_endian()) \
EXTRACT_WORDS_L(ix0,ix1,d); \
else \
EXTRACT_WORDS_B(ix0,ix1,d); \
} while (0)
#define INSERT_WORDS(d,ix0,ix1) do { \
if (is_little_endian()) \
INSERT_WORDS_L(d,ix0,ix1); \
else \
INSERT_WORDS_B(d,ix0,ix1); \
} while (0)
#define GET_HIGH_WORD(i,d) \
do { \
if (is_little_endian()) \
GET_HIGH_WORD_L(i,d); \
else \
GET_HIGH_WORD_B(i,d); \
} while (0)
#define SET_HIGH_WORD(d,v) \
do { \
if (is_little_endian()) \
SET_HIGH_WORD_L(d,v); \
else \
SET_HIGH_WORD_B(d,v); \
} while (0)
#define __HI(x) (is_little_endian() ? __HIL(x) : __HIB(x))
#define __LO(x) (is_little_endian() ? __LOL(x) : __LOB(x))
/*
* Attempt to get strict C99 semantics for assignment with non-C99 compilers.
*/
#if FLT_EVAL_METHOD == 0 || __GNUC__ == 0
#define STRICT_ASSIGN(type, lval, rval) ((lval) = (rval))
#else
#define STRICT_ASSIGN(type, lval, rval) do { \
volatile type __lval; \
\
if (sizeof(type) >= sizeof(long double)) \
(lval) = (rval); \
else { \
__lval = (rval); \
(lval) = __lval; \
} \
} while (0)
#endif
#ifdef __FDLIBM_STDC__
static const double huge = 1.0e300;
#else
static double huge = 1.0e300;
#endif
#ifdef __STDC__
static const double
#else
static double
#endif
tiny = 1.0e-300;
#ifdef __STDC__
static const double
#else
static double
#endif
one= 1.00000000000000000000e+00; /* 0x3FF00000, 0x00000000 */
#ifdef __STDC__
static const double
#else
static double
#endif
TWO52[2]={
4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */
-4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */
};
static double freebsd_sqrt(double x);
static double freebsd_floor(double x);
static double freebsd_ceil(double x);
static double freebsd_fabs(double x);
static double freebsd_rint(double x);
static int freebsd_isnan(double x);
static double freebsd_sqrt(double x) /* wrapper sqrt */
{
double z;
int32_t sign = (int)0x80000000;
int32_t ix0,s0,q,m,t,i;
u_int32_t r,t1,s1,ix1,q1;
EXTRACT_WORDS(ix0,ix1,x);
/* take care of Inf and NaN */
if((ix0&0x7ff00000)==0x7ff00000) {
return x*x+x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf
sqrt(-inf)=sNaN */
}
/* take care of zero */
if(ix0<=0) {
if(((ix0&(~sign))|ix1)==0) return x;/* sqrt(+-0) = +-0 */
else if(ix0<0)
return (x-x)/(x-x); /* sqrt(-ve) = sNaN */
}
/* normalize x */
m = (ix0>>20);
if(m==0) { /* subnormal x */
while(ix0==0) {
m -= 21;
ix0 |= (ix1>>11); ix1 <<= 21;
}
for(i=0;(ix0&0x00100000)==0;i++) ix0<<=1;
m -= i-1;
ix0 |= (ix1>>(32-i));
ix1 <<= i;
}
m -= 1023; /* unbias exponent */
ix0 = (ix0&0x000fffff)|0x00100000;
if(m&1){ /* odd m, double x to make it even */
ix0 += ix0 + ((ix1&sign)>>31);
ix1 += ix1;
}
m >>= 1; /* m = [m/2] */
/* generate sqrt(x) bit by bit */
ix0 += ix0 + ((ix1&sign)>>31);
ix1 += ix1;
q = q1 = s0 = s1 = 0; /* [q,q1] = sqrt(x) */
r = 0x00200000; /* r = moving bit from right to left */
while(r!=0) {
t = s0+r;
if(t<=ix0) {
s0 = t+r;
ix0 -= t;
q += r;
}
ix0 += ix0 + ((ix1&sign)>>31);
ix1 += ix1;
r>>=1;
}
r = sign;
while(r!=0) {
t1 = s1+r;
t = s0;
if((t<ix0)||((t==ix0)&&(t1<=ix1))) {
s1 = t1+r;
if(((t1&sign)==sign)&&(s1&sign)==0) s0 += 1;
ix0 -= t;
if (ix1 < t1) ix0 -= 1;
ix1 -= t1;
q1 += r;
}
ix0 += ix0 + ((ix1&sign)>>31);
ix1 += ix1;
r>>=1;
}
/* use floating add to find out rounding direction */
if((ix0|ix1)!=0) {
z = one-tiny; /* trigger inexact flag */
if (z>=one) {
z = one+tiny;
if (q1==(u_int32_t)0xffffffff) { q1=0; q += 1;}
else if (z>one) {
if (q1==(u_int32_t)0xfffffffe) q+=1;
q1+=2;
} else
q1 += (q1&1);
}
}
ix0 = (q>>1)+0x3fe00000;
ix1 = q1>>1;
if ((q&1)==1) ix1 |= sign;
ix0 += (m <<20);
INSERT_WORDS(z,ix0,ix1);
return z;
}
static double freebsd_floor(double x)
{
int32_t i0,i1,j0;
u_int32_t i,j;
EXTRACT_WORDS(i0,i1,x);
j0 = ((i0>>20)&0x7ff)-0x3ff;
if(j0<20) {
if(j0<0) { /* raise inexact if x != 0 */
if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */
if(i0>=0) {i0=i1=0;}
else if(((i0&0x7fffffff)|i1)!=0)
{ i0=0xbff00000;i1=0;}
}
} else {
i = (0x000fffff)>>j0;
if(((i0&i)|i1)==0) return x; /* x is integral */
if(huge+x>0.0) { /* raise inexact flag */
if(i0<0) i0 += (0x00100000)>>j0;
i0 &= (~i); i1=0;
}
}
} else if (j0>51) {
if(j0==0x400) return x+x; /* inf or NaN */
else return x; /* x is integral */
} else {
i = ((u_int32_t)(0xffffffff))>>(j0-20);
if((i1&i)==0) return x; /* x is integral */
if(huge+x>0.0) { /* raise inexact flag */
if(i0<0) {
if(j0==20) i0+=1;
else {
j = i1+(1<<(52-j0));
if(j<i1) i0 +=1 ; /* got a carry */
i1=j;
}
}
i1 &= (~i);
}
}
INSERT_WORDS(x,i0,i1);
return x;
}
static double freebsd_ceil(double x)
{
int32_t i0,i1,j0;
u_int32_t i,j;
EXTRACT_WORDS(i0,i1,x);
j0 = ((i0>>20)&0x7ff)-0x3ff;
if(j0<20) {
if(j0<0) { /* raise inexact if x != 0 */
if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */
if(i0<0) {i0=0x80000000;i1=0;}
else if((i0|i1)!=0) { i0=0x3ff00000;i1=0;}
}
} else {
i = (0x000fffff)>>j0;
if(((i0&i)|i1)==0) return x; /* x is integral */
if(huge+x>0.0) { /* raise inexact flag */
if(i0>0) i0 += (0x00100000)>>j0;
i0 &= (~i); i1=0;
}
}
} else if (j0>51) {
if(j0==0x400) return x+x; /* inf or NaN */
else return x; /* x is integral */
} else {
i = ((u_int32_t)(0xffffffff))>>(j0-20);
if((i1&i)==0) return x; /* x is integral */
if(huge+x>0.0) { /* raise inexact flag */
if(i0>0) {
if(j0==20) i0+=1;
else {
j = i1 + (1<<(52-j0));
if(j<i1) i0+=1; /* got a carry */
i1 = j;
}
}
i1 &= (~i);
}
}
INSERT_WORDS(x,i0,i1);
return x;
}
static double freebsd_rint(double x)
{
int32_t i0,j0,sx;
u_int32_t i,i1;
double w,t;
EXTRACT_WORDS(i0,i1,x);
sx = (i0>>31)&1;
j0 = ((i0>>20)&0x7ff)-0x3ff;
if(j0<20) {
if(j0<0) {
if(((i0&0x7fffffff)|i1)==0) return x;
i1 |= (i0&0x0fffff);
i0 &= 0xfffe0000;
i0 |= ((i1|-i1)>>12)&0x80000;
SET_HIGH_WORD(x,i0);
STRICT_ASSIGN(double,w,TWO52[sx]+x);
t = w-TWO52[sx];
GET_HIGH_WORD(i0,t);
SET_HIGH_WORD(t,(i0&0x7fffffff)|(sx<<31));
return t;
} else {
i = (0x000fffff)>>j0;
if(((i0&i)|i1)==0) return x; /* x is integral */
i>>=1;
if(((i0&i)|i1)!=0) {
/*
* Some bit is set after the 0.5 bit. To avoid the
* possibility of errors from double rounding in
* w = TWO52[sx]+x, adjust the 0.25 bit to a lower
* guard bit. We do this for all j0<=51. The
* adjustment is trickiest for j0==18 and j0==19
* since then it spans the word boundary.
*/
if(j0==19) i1 = 0x40000000; else
if(j0==18) i1 = 0x80000000; else
i0 = (i0&(~i))|((0x20000)>>j0);
}
}
} else if (j0>51) {
if(j0==0x400) return x+x; /* inf or NaN */
else return x; /* x is integral */
} else {
i = ((u_int32_t)(0xffffffff))>>(j0-20);
if((i1&i)==0) return x; /* x is integral */
i>>=1;
if((i1&i)!=0) i1 = (i1&(~i))|((0x40000000)>>(j0-20));
}
INSERT_WORDS(x,i0,i1);
STRICT_ASSIGN(double,w,TWO52[sx]+x);
return w-TWO52[sx];
}
static int freebsd_isnan(double d)
{
if (is_little_endian()) {
IEEEd2bits_L u;
u.d = d;
return (u.bits.exp == 2047 && (u.bits.manl != 0 || u.bits.manh != 0));
}
else {
IEEEd2bits_B u;
u.d = d;
return (u.bits.exp == 2047 && (u.bits.manl != 0 || u.bits.manh != 0));
}
}
static double freebsd_fabs(double x)
{
u_int32_t high;
GET_HIGH_WORD(high,x);
SET_HIGH_WORD(x,high&0x7fffffff);
return x;
}
static const float huge_f = 1.0e30F;
static const float
TWO23[2]={
8.3886080000e+06, /* 0x4b000000 */
-8.3886080000e+06, /* 0xcb000000 */
};
static float
freebsd_truncf(float x)
{
int32_t i0,j0;
u_int32_t i;
GET_FLOAT_WORD(i0,x);
j0 = ((i0>>23)&0xff)-0x7f;
if(j0<23) {
if(j0<0) { /* raise inexact if x != 0 */
if(huge_f+x>0.0F) /* |x|<1, so return 0*sign(x) */
i0 &= 0x80000000;
} else {
i = (0x007fffff)>>j0;
if((i0&i)==0) return x; /* x is integral */
if(huge_f+x>0.0F) /* raise inexact flag */
i0 &= (~i);
}
} else {
if(j0==0x80) return x+x; /* inf or NaN */
else return x; /* x is integral */
}
SET_FLOAT_WORD(x,i0);
return x;
}
static float
freebsd_rintf(float x)
{
int32_t i0,j0,sx;
float w,t;
GET_FLOAT_WORD(i0,x);
sx = (i0>>31)&1;
j0 = ((i0>>23)&0xff)-0x7f;
if(j0<23) {
if(j0<0) {
if((i0&0x7fffffff)==0) return x;
STRICT_ASSIGN(float,w,TWO23[sx]+x);
t = w-TWO23[sx];
GET_FLOAT_WORD(i0,t);
SET_FLOAT_WORD(t,(i0&0x7fffffff)|(sx<<31));
return t;
}
STRICT_ASSIGN(float,w,TWO23[sx]+x);
return w-TWO23[sx];
}
if(j0==0x80) return x+x; /* inf or NaN */
else return x; /* x is integral */
}
static float
freebsd_ceilf(float x)
{
int32_t i0,j0;
u_int32_t i;
GET_FLOAT_WORD(i0,x);
j0 = ((i0>>23)&0xff)-0x7f;
if(j0<23) {
if(j0<0) { /* raise inexact if x != 0 */
if(huge_f+x>(float)0.0) {/* return 0*sign(x) if |x|<1 */
if(i0<0) {i0=0x80000000;}
else if(i0!=0) { i0=0x3f800000;}
}
} else {
i = (0x007fffff)>>j0;
if((i0&i)==0) return x; /* x is integral */
if(huge_f+x>(float)0.0) { /* raise inexact flag */
if(i0>0) i0 += (0x00800000)>>j0;
i0 &= (~i);
}
}
} else {
if(j0==0x80) return x+x; /* inf or NaN */
else return x; /* x is integral */
}
SET_FLOAT_WORD(x,i0);
return x;
}
static float
freebsd_floorf(float x)
{
int32_t i0,j0;
u_int32_t i;
GET_FLOAT_WORD(i0,x);
j0 = ((i0>>23)&0xff)-0x7f;
if(j0<23) {
if(j0<0) { /* raise inexact if x != 0 */
if(huge_f+x>(float)0.0) {/* return 0*sign(x) if |x|<1 */
if(i0>=0) {i0=0;}
else if((i0&0x7fffffff)!=0)
{ i0=0xbf800000;}
}
} else {
i = (0x007fffff)>>j0;
if((i0&i)==0) return x; /* x is integral */
if(huge_f+x>(float)0.0) { /* raise inexact flag */
if(i0<0) i0 += (0x00800000)>>j0;
i0 &= (~i);
}
}
} else {
if(j0==0x80) return x+x; /* inf or NaN */
else return x; /* x is integral */
}
SET_FLOAT_WORD(x,i0);
return x;
}
static float
freebsd_fminf(float x, float y)
{
if (is_little_endian()) {
IEEEf2bits_L u[2];
u[0].f = x;
u[1].f = y;
/* Check for NaNs to avoid raising spurious exceptions. */
if (u[0].bits.exp == 255 && u[0].bits.man != 0)
return (y);
if (u[1].bits.exp == 255 && u[1].bits.man != 0)
return (x);
/* Handle comparisons of signed zeroes. */
if (u[0].bits.sign != u[1].bits.sign)
return (u[u[1].bits.sign].f);
}
else {
IEEEf2bits_B u[2];
u[0].f = x;
u[1].f = y;
/* Check for NaNs to avoid raising spurious exceptions. */
if (u[0].bits.exp == 255 && u[0].bits.man != 0)
return (y);
if (u[1].bits.exp == 255 && u[1].bits.man != 0)
return (x);
/* Handle comparisons of signed zeroes. */
if (u[0].bits.sign != u[1].bits.sign)
return (u[u[1].bits.sign].f);
}
return (x < y ? x : y);
}
static float
freebsd_fmaxf(float x, float y)
{
if (is_little_endian()) {
IEEEf2bits_L u[2];
u[0].f = x;
u[1].f = y;
/* Check for NaNs to avoid raising spurious exceptions. */
if (u[0].bits.exp == 255 && u[0].bits.man != 0)
return (y);
if (u[1].bits.exp == 255 && u[1].bits.man != 0)
return (x);
/* Handle comparisons of signed zeroes. */
if (u[0].bits.sign != u[1].bits.sign)
return (u[u[0].bits.sign].f);
}
else {
IEEEf2bits_B u[2];
u[0].f = x;
u[1].f = y;
/* Check for NaNs to avoid raising spurious exceptions. */
if (u[0].bits.exp == 255 && u[0].bits.man != 0)
return (y);
if (u[1].bits.exp == 255 && u[1].bits.man != 0)
return (x);
/* Handle comparisons of signed zeroes. */
if (u[0].bits.sign != u[1].bits.sign)
return (u[u[0].bits.sign].f);
}
return (x > y ? x : y);
}
double sqrt(double x)
{
return freebsd_sqrt(x);
}
double floor(double x)
{
return freebsd_floor(x);
}
double ceil(double x)
{
return freebsd_ceil(x);
}
double fmin(double x, double y)
{
return x < y ? x : y;
}
double fmax(double x, double y)
{
return x > y ? x : y;
}
double rint(double x)
{
return freebsd_rint(x);
}
double fabs(double x)
{
return freebsd_fabs(x);
}
int isnan(double x)
{
return freebsd_isnan(x);
}
double trunc(double x)
{
return (x > 0) ? freebsd_floor(x) : freebsd_ceil(x);
}
int signbit(double x)
{
return ((__HI(x) & 0x80000000) >> 31);
}
float
truncf(float x)
{
return freebsd_truncf(x);
}
float
rintf(float x)
{
return freebsd_rintf(x);
}
float
ceilf(float x)
{
return freebsd_ceilf(x);
}
float
floorf(float x)
{
return freebsd_floorf(x);
}
float
fminf(float x, float y)
{
return freebsd_fminf(x, y);
}
float
fmaxf(float x, float y)
{
return freebsd_fmaxf(x, y);
}

View File

@ -1,131 +0,0 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#ifndef _BH_PLATFORM_H
#define _BH_PLATFORM_H
#include "bh_config.h"
#include "bh_types.h"
#include <aos/kernel.h>
#include <inttypes.h>
#include <stdbool.h>
#include <stdarg.h>
#include <ctype.h>
#include <limits.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef BH_PLATFORM_ALIOS_THINGS
#define BH_PLATFORM_ALIOS_THINGS
#endif
#define BH_APPLET_PRESERVED_STACK_SIZE (2 * BH_KB)
/* Default thread priority */
#define BH_THREAD_DEFAULT_PRIORITY 30
#define BH_ROUTINE_MODIFIER
/* Invalid thread tid */
#define INVALID_THREAD_ID NULL
#define BH_WAIT_FOREVER AOS_WAIT_FOREVER
typedef uint64_t uint64;
typedef int64_t int64;
typedef aos_task_t korp_thread;
typedef korp_thread *korp_tid;
typedef aos_task_t *aos_tid_t;
typedef aos_mutex_t korp_mutex;
typedef aos_sem_t korp_sem;
struct bh_thread_wait_node;
typedef struct bh_thread_wait_node *bh_thread_wait_list;
typedef struct korp_cond {
aos_mutex_t wait_list_lock;
bh_thread_wait_list thread_wait_list;
} korp_cond;
typedef void* (*thread_start_routine_t)(void*);
void *os_malloc(unsigned size);
void *os_realloc(void *ptr, unsigned size);
void os_free(void *ptr);
/* Unit test framework is based on C++, where the declaration of
snprintf is different. */
#ifndef __cplusplus
int snprintf(char *buffer, size_t count, const char *format, ...);
#endif
#ifndef NULL
#define NULL ((void*)0)
#endif
/**
* Return the offset of the given field in the given type.
*
* @param Type the type containing the filed
* @param field the field in the type
*
* @return the offset of field in Type
*/
#ifndef offsetof
#define offsetof(Type, field) ((size_t)(&((Type *)0)->field))
#endif
#define bh_printf printf
extern void bh_assert_internal(int v, const char *file_name, int line_number, const char *expr_string);
#define bh_assert(expr) bh_assert_internal((int)(expr), __FILE__, __LINE__, # expr)
/* math functions */
double sqrt(double x);
double floor(double x);
double ceil(double x);
double fmin(double x, double y);
double fmax(double x, double y);
double rint(double x);
double fabs(double x);
double trunc(double x);
float floorf(float x);
float ceilf(float x);
float fminf(float x, float y);
float fmaxf(float x, float y);
float rintf(float x);
float truncf(float x);
int signbit(double x);
int isnan(double x);
int bh_platform_init();
/* MMAP mode */
enum {
MMAP_PROT_NONE = 0,
MMAP_PROT_READ = 1,
MMAP_PROT_WRITE = 2,
MMAP_PROT_EXEC = 4
};
/* MMAP flags */
enum {
MMAP_MAP_NONE = 0,
/* Put the mapping into 0 to 2 G, supported only on x86_64 */
MMAP_MAP_32BIT = 1,
/* Don't interpret addr as a hint: place the mapping at exactly
that address. */
MMAP_MAP_FIXED = 2
};
void *bh_mmap(void *hint, unsigned int size, int prot, int flags);
void bh_munmap(void *addr, uint32 size);
int bh_mprotect(void *addr, uint32 size, int prot);
void bh_dcache_flush();
#endif /* end of _BH_PLATFORM_H */

View File

@ -1,33 +0,0 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "bh_platform.h"
#include <stdio.h>
void bh_log_emit(const char *fmt, va_list ap)
{
vprintf(fmt, ap);
}
int bh_fprintf(FILE *stream, const char *fmt, ...)
{
(void)stream;
va_list ap;
int ret;
va_start(ap, fmt);
ret = vprintf(fmt, ap);
va_end(ap);
return ret;
}
int bh_fflush(void *stream)
{
(void)stream;
return 0;
}

View File

@ -1,435 +0,0 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "bh_thread.h"
#include "bh_assert.h"
#include "bh_log.h"
#include <stdio.h>
#include <stdlib.h>
struct bh_thread_data;
typedef struct bh_thread_wait_node {
aos_sem_t sem;
bh_thread_wait_list next;
} bh_thread_wait_node;
typedef struct bh_thread_data {
/* Thread body */
aos_task_t thread;
/* Thread start routine */
thread_start_routine_t start_routine;
/* Thread start routine argument */
void *arg;
/* Thread local root */
void *tlr;
/* Wait node of current thread */
bh_thread_wait_node wait_node;
/* Lock for waiting list */
aos_mutex_t wait_list_lock;
/* Waiting list of other threads who are joining this thread */
bh_thread_wait_list thread_wait_list;
} bh_thread_data;
static bool is_thread_sys_inited = false;
/* Thread data of supervisor thread */
static bh_thread_data supervisor_thread_data;
/* Thread data key */
static aos_task_key_t thread_data_key;
/* Thread name index */
static int thread_name_index;
int
_vm_thread_sys_init()
{
if (is_thread_sys_inited)
return BHT_OK;
if (aos_task_key_create(&thread_data_key) != 0)
return BHT_ERROR;
/* Initialize supervisor thread data */
memset(&supervisor_thread_data, 0, sizeof(supervisor_thread_data));
if (aos_sem_new(&supervisor_thread_data.wait_node.sem, 1) != 0) {
aos_task_key_delete(thread_data_key);
return BHT_ERROR;
}
if (aos_task_setspecific(thread_data_key, &supervisor_thread_data)) {
aos_sem_free(&supervisor_thread_data.wait_node.sem);
aos_task_key_delete(thread_data_key);
return BHT_ERROR;
}
is_thread_sys_inited = true;
return BHT_OK;
}
void
vm_thread_sys_destroy()
{
if (is_thread_sys_inited) {
aos_task_key_delete(thread_data_key);
aos_sem_free(&supervisor_thread_data.wait_node.sem);
is_thread_sys_inited = false;
}
}
static bh_thread_data *
thread_data_current()
{
return aos_task_getspecific(thread_data_key);
}
static void
vm_thread_cleanup(void)
{
bh_thread_data *thread_data = thread_data_current();
bh_thread_wait_list thread_wait_list;
aos_mutex_t *wait_list_lock;
aos_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;
/* Free thread data firstly */
BH_FREE(thread_data);
aos_mutex_lock(wait_list_lock, AOS_WAIT_FOREVER);
if (thread_wait_list) {
/* Signal each joining thread */
bh_thread_wait_list head = thread_wait_list;
while (head) {
bh_thread_wait_list next = head->next;
aos_sem_signal(&head->sem);
head = next;
}
}
aos_mutex_unlock(wait_list_lock);
/* Free sem and lock */
aos_sem_free(wait_node_sem);
aos_mutex_free(wait_list_lock);
}
static void
vm_thread_wrapper(void *arg)
{
bh_thread_data *thread_data = arg;
/* Set thread custom data */
if (!aos_task_setspecific(thread_data_key, thread_data))
thread_data->start_routine(thread_data->arg);
vm_thread_cleanup();
}
int
_vm_thread_create(korp_tid *p_tid, thread_start_routine_t start,
void *arg, unsigned int stack_size)
{
return _vm_thread_create_with_prio(p_tid, start, arg, stack_size,
BH_THREAD_DEFAULT_PRIORITY);
}
int
_vm_thread_create_with_prio(korp_tid *p_tid, thread_start_routine_t start,
void *arg, unsigned int stack_size, int prio)
{
bh_thread_data *thread_data;
char thread_name[32];
if (!p_tid || !stack_size)
return BHT_ERROR;
/* Create and initialize thread data */
if (!(thread_data = BH_MALLOC(sizeof(bh_thread_data))))
return BHT_ERROR;
memset(thread_data, 0, sizeof(bh_thread_data));
thread_data->start_routine = start;
thread_data->arg = arg;
if (aos_sem_new(&thread_data->wait_node.sem, 1) != 0)
goto fail1;
if (aos_mutex_new(&thread_data->wait_list_lock))
goto fail2;
snprintf(thread_name, sizeof(thread_name), "%s%d",
"wasm-thread-", ++thread_name_index);
/* Create the thread */
if (aos_task_new_ext((aos_task_t*)thread_data, thread_name,
vm_thread_wrapper, thread_data,
stack_size, prio))
goto fail3;
aos_msleep(10);
*p_tid = (korp_tid)thread_data;
return BHT_OK;
fail3:
aos_mutex_free(&thread_data->wait_list_lock);
fail2:
aos_sem_free(&thread_data->wait_node.sem);
fail1:
BH_FREE(thread_data);
return BHT_ERROR;
}
korp_tid
_vm_self_thread()
{
return (korp_tid)aos_task_getspecific(thread_data_key);
}
void
vm_thread_exit(void * code)
{
vm_thread_cleanup();
aos_task_exit((int)(intptr_t)code);
}
int
_vm_thread_cancel (korp_tid thread)
{
/* TODO */
return 0;
}
int
_vm_thread_join (korp_tid thread, void **value_ptr, int mills)
{
(void)value_ptr;
bh_thread_data *thread_data, *curr_thread_data;
/* Get thread data of current thread */
curr_thread_data = thread_data_current();
curr_thread_data->wait_node.next = NULL;
/* Get thread data */
thread_data = (bh_thread_data*)thread;
aos_mutex_lock(&thread_data->wait_list_lock, AOS_WAIT_FOREVER);
if (!thread_data->thread_wait_list)
thread_data->thread_wait_list = &curr_thread_data->wait_node;
else {
/* Add to end of waiting list */
bh_thread_wait_node *p = thread_data->thread_wait_list;
while (p->next)
p = p->next;
p->next = &curr_thread_data->wait_node;
}
aos_mutex_unlock(&thread_data->wait_list_lock);
/* Wait the sem */
aos_sem_wait(&curr_thread_data->wait_node.sem, mills);
return BHT_OK;
}
int
_vm_thread_detach (korp_tid thread)
{
(void)thread;
return BHT_OK;
}
void *
_vm_tls_get(unsigned idx)
{
(void)idx;
bh_thread_data *thread_data;
bh_assert (idx == 0);
thread_data = thread_data_current();
return thread_data ? thread_data->tlr : NULL;
}
int
_vm_tls_put(unsigned idx, void * tls)
{
bh_thread_data *thread_data;
(void)idx;
bh_assert (idx == 0);
thread_data = thread_data_current();
bh_assert (thread_data != NULL);
thread_data->tlr = tls;
return BHT_OK;
}
int
_vm_mutex_init(korp_mutex *mutex)
{
return aos_mutex_new(mutex) == 0 ? BHT_OK : BHT_ERROR;
}
int
_vm_recursive_mutex_init(korp_mutex *mutex)
{
return aos_mutex_new(mutex) == 0 ? BHT_OK : BHT_ERROR;
}
int
_vm_mutex_destroy(korp_mutex *mutex)
{
aos_mutex_free(mutex);
return BHT_OK;
}
void
vm_mutex_lock(korp_mutex *mutex)
{
aos_mutex_lock(mutex, AOS_WAIT_FOREVER);
}
int
vm_mutex_trylock(korp_mutex *mutex)
{
return aos_mutex_lock(mutex, AOS_NO_WAIT);
}
void vm_mutex_unlock(korp_mutex *mutex)
{
aos_mutex_unlock(mutex);
}
int _vm_sem_init(korp_sem* sem, unsigned int c)
{
return aos_sem_new(sem, c) == 0 ? BHT_OK : BHT_ERROR;
}
int _vm_sem_destroy(korp_sem *sem)
{
aos_sem_free(sem);
return BHT_OK;
}
int _vm_sem_wait(korp_sem *sem)
{
return aos_sem_wait(sem, AOS_WAIT_FOREVER);
}
int _vm_sem_reltimedwait(korp_sem *sem, int mills)
{
return aos_sem_wait(sem, mills);
}
int _vm_sem_post(korp_sem *sem)
{
aos_sem_signal(sem);
return BHT_OK;
}
int
_vm_cond_init(korp_cond *cond)
{
if (aos_mutex_new(&cond->wait_list_lock) != 0)
return BHT_ERROR;
cond->thread_wait_list = NULL;
return BHT_OK;
}
int
_vm_cond_destroy(korp_cond *cond)
{
aos_mutex_free(&cond->wait_list_lock);
return BHT_OK;
}
static int
vm_cond_wait_internal(korp_cond *cond, korp_mutex *mutex,
bool timed, int mills)
{
bh_thread_wait_node *node = &thread_data_current()->wait_node;
node->next = NULL;
aos_mutex_lock(&cond->wait_list_lock, AOS_WAIT_FOREVER);
if (!cond->thread_wait_list)
cond->thread_wait_list = node;
else {
/* Add to end of wait list */
bh_thread_wait_node *p = cond->thread_wait_list;
while (p->next)
p = p->next;
p->next = node;
}
aos_mutex_unlock(&cond->wait_list_lock);
/* Unlock mutex, wait sem and lock mutex again */
aos_mutex_unlock(mutex);
aos_sem_wait(&node->sem, timed ? mills : AOS_WAIT_FOREVER);
aos_mutex_lock(mutex, AOS_WAIT_FOREVER);
/* Remove wait node from wait list */
aos_mutex_lock(&cond->wait_list_lock, AOS_WAIT_FOREVER);
if (cond->thread_wait_list == node)
cond->thread_wait_list = node->next;
else {
/* Remove from the wait list */
bh_thread_wait_node *p = cond->thread_wait_list;
while (p->next != node)
p = p->next;
p->next = node->next;
}
aos_mutex_unlock(&cond->wait_list_lock);
return BHT_OK;
}
int
_vm_cond_wait(korp_cond *cond, korp_mutex *mutex)
{
return vm_cond_wait_internal(cond, mutex, false, 0);
}
int
_vm_cond_reltimedwait(korp_cond *cond, korp_mutex *mutex, int mills)
{
return vm_cond_wait_internal(cond, mutex, true, mills);
}
int
_vm_cond_signal(korp_cond *cond)
{
/* Signal the head wait node of wait list */
aos_mutex_lock(&cond->wait_list_lock, AOS_WAIT_FOREVER);
if (cond->thread_wait_list)
aos_sem_signal(&cond->thread_wait_list->sem);
aos_mutex_unlock(&cond->wait_list_lock);
return BHT_OK;
}
int
_vm_cond_broadcast (korp_cond *cond)
{
/* Signal each wait node of wait list */
aos_mutex_lock(&cond->wait_list_lock, AOS_WAIT_FOREVER);
if (cond->thread_wait_list) {
bh_thread_wait_node *p = cond->thread_wait_list;
while (p) {
aos_sem_signal(&p->sem);
p = p->next;
}
}
aos_mutex_unlock(&cond->wait_list_lock);
return BHT_OK;
}

View File

@ -1,37 +0,0 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "bh_time.h"
/*
* This function returns milliseconds per tick.
* @return milliseconds per tick.
*/
uint64 _bh_time_get_tick_millisecond()
{
return aos_get_hz() / 1000;
}
/*
* This function returns milliseconds after boot.
* @return milliseconds after boot.
*/
uint64 _bh_time_get_boot_millisecond()
{
return (uint64)aos_now_ms();
}
uint64 _bh_time_get_millisecond_from_1970()
{
return (uint64)aos_now_ms();
}
size_t
_bh_time_strftime (char *str, size_t max, const char *format, int64 time)
{
str = aos_now_time_str(str, max);
return str ? strlen(str) + 1 : 0;
}

View File

@ -0,0 +1,63 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#ifndef _PLATFORM_INTERNAL_H
#define _PLATFORM_INTERNAL_H
#include <aos/kernel.h>
#include <inttypes.h>
#include <stdbool.h>
#include <stdarg.h>
#include <ctype.h>
#include <limits.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef BH_PLATFORM_ALIOS_THINGS
#define BH_PLATFORM_ALIOS_THINGS
#endif
#define BH_APPLET_PRESERVED_STACK_SIZE (2 * BH_KB)
/* Default thread priority */
#define BH_THREAD_DEFAULT_PRIORITY 30
typedef aos_task_t korp_thread;
typedef korp_thread *korp_tid;
typedef aos_task_t *aos_tid_t;
typedef aos_mutex_t korp_mutex;
struct os_thread_wait_node;
typedef struct os_thread_wait_node *os_thread_wait_list;
typedef struct korp_cond {
aos_mutex_t wait_list_lock;
os_thread_wait_list thread_wait_list;
} korp_cond;
#define os_printf printf
#define os_vprintf vprintf
/* math functions which are not provided by os*/
double sqrt(double x);
double floor(double x);
double ceil(double x);
double fmin(double x, double y);
double fmax(double x, double y);
double rint(double x);
double fabs(double x);
double trunc(double x);
float floorf(float x);
float ceilf(float x);
float fminf(float x, float y);
float fmaxf(float x, float y);
float rintf(float x);
float truncf(float x);
int signbit(double x);
int isnan(double x);
#endif /* end of _BH_PLATFORM_H */

View File

@ -1,13 +1,16 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
set (PLATFORM_SHARED_DIR ${CMAKE_CURRENT_LIST_DIR})
include_directories(${PLATFORM_SHARED_DIR})
include_directories(${PLATFORM_SHARED_DIR}/../include)
file (GLOB_RECURSE source_all ${PLATFORM_SHARED_DIR}/*.c)
set (PLATFORM_SHARED_SOURCE ${source_all})
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
set (PLATFORM_SHARED_DIR ${CMAKE_CURRENT_LIST_DIR})
add_definitions(-DBH_PLATFORM_ALIOS_THINGS)
include_directories(${PLATFORM_SHARED_DIR})
include_directories(${PLATFORM_SHARED_DIR}/../include)
include (${CMAKE_CURRENT_LIST_DIR}/../common/math/platform_api_math.cmake)
file (GLOB_RECURSE source_all ${PLATFORM_SHARED_DIR}/*.c)
set (PLATFORM_SHARED_SOURCE ${source_all} ${PLATFORM_COMMON_MATH_SOURCE})

View File

@ -1,58 +0,0 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "bh_platform.h"
#include "bh_assert.h"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef BH_TEST
#include <setjmp.h>
#endif
#ifdef BH_TEST
/* for exception throwing */
jmp_buf bh_test_jb;
#endif
void bh_assert_internal(int v, const char *file_name, int line_number,
const char *expr_string)
{
if (v)
return;
if (!file_name)
file_name = "NULL FILENAME";
if (!expr_string)
expr_string = "NULL EXPR_STRING";
printf("\nASSERTION FAILED: %s, at FILE=%s, LINE=%d\n", expr_string,
file_name, line_number);
#ifdef BH_TEST
longjmp(bh_test_jb, 1);
#endif
abort();
}
void bh_debug_internal(const char *file_name, int line_number, const char *fmt,
...)
{
#ifndef JEFF_TEST_VERIFIER
va_list args;
va_start(args, fmt);
bh_assert(file_name);
printf("\nDebug info FILE=%s, LINE=%d: ", file_name, line_number);
vprintf(fmt, args);
va_end(args);
printf("\n");
#endif
}

View File

@ -1,182 +0,0 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "bh_platform.h"
#include "bh_common.h"
#include "bh_assert.h"
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
int
bh_platform_init()
{
return 0;
}
void *
os_malloc(unsigned size)
{
return malloc(size);
}
void *
os_realloc(void *ptr, unsigned size)
{
return realloc(ptr, size);
}
void
os_free(void *ptr)
{
free(ptr);
}
char*
bh_read_file_to_buffer(const char *filename, uint32 *ret_size)
{
char *buffer;
int file;
uint32 file_size, read_size;
struct stat stat_buf;
if (!filename || !ret_size) {
printf("Read file to buffer failed: invalid filename or ret size.\n");
return NULL;
}
if ((file = open(filename, O_RDONLY, 0)) == -1) {
printf("Read file to buffer failed: open file %s failed.\n",
filename);
return NULL;
}
if (fstat(file, &stat_buf) != 0) {
printf("Read file to buffer failed: fstat file %s failed.\n",
filename);
close(file);
return NULL;
}
file_size = (uint32)stat_buf.st_size;
if (!(buffer = BH_MALLOC(file_size))) {
printf("Read file to buffer failed: alloc memory failed.\n");
close(file);
return NULL;
}
read_size = (uint32)read(file, buffer, file_size);
close(file);
if (read_size < file_size) {
printf("Read file to buffer failed: read file content failed.\n");
BH_FREE(buffer);
return NULL;
}
*ret_size = file_size;
return buffer;
}
void *
bh_mmap(void *hint, uint32 size, int prot, int flags)
{
int map_prot = PROT_NONE;
int map_flags = MAP_ANONYMOUS | MAP_PRIVATE;
uint64 request_size, page_size;
uint8 *addr, *addr_aligned;
uint32 i;
/* align to 2M if no less than 2M, else align to 4K */
page_size = size < 2 * 1024 * 1024 ? 4096 : 2 * 1024 * 1024;
request_size = (size + page_size - 1) & ~(page_size - 1);
request_size += page_size;
if (request_size >= UINT32_MAX)
return NULL;
if (prot & MMAP_PROT_READ)
map_prot |= PROT_READ;
if (prot & MMAP_PROT_WRITE)
map_prot |= PROT_WRITE;
if (prot & MMAP_PROT_EXEC)
map_prot |= PROT_EXEC;
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
if (flags & MMAP_MAP_32BIT)
map_flags |= MAP_32BIT;
#endif
if (flags & MMAP_MAP_FIXED)
map_flags |= MAP_FIXED;
/* try 5 times */
for (i = 0; i < 5; i ++) {
addr = mmap(hint, size, map_prot, map_flags, -1, 0);
if (addr != MAP_FAILED)
break;
}
if (addr == MAP_FAILED)
return NULL;
addr_aligned = (uint8*)(uintptr_t)
(((uint64)(uintptr_t)addr + page_size - 1) & ~(page_size - 1));
/* Unmap memory allocated before the aligned base address */
if (addr != addr_aligned) {
uint32 prefix_size = (uint32)(addr_aligned - addr);
munmap(addr, prefix_size);
request_size -= prefix_size;
}
/* Unmap memory allocated after the potentially unaligned end */
if (size != request_size) {
uint32 suffix_size = (uint32)(request_size - size);
munmap(addr_aligned + size, suffix_size);
request_size -= size;
}
if (size >= 2 * 1024 * 1024) {
/* Try to use huge page to improve performance */
if (!madvise(addr, size, MADV_HUGEPAGE))
/* make huge page become effective */
memset(addr, 0, size);
}
return addr_aligned;
}
void
bh_munmap(void *addr, uint32 size)
{
if (addr)
munmap(addr, size);
}
int
bh_mprotect(void *addr, uint32 size, int prot)
{
int map_prot = PROT_NONE;
if (!addr)
return 0;
if (prot & MMAP_PROT_READ)
map_prot |= PROT_READ;
if (prot & MMAP_PROT_WRITE)
map_prot |= PROT_WRITE;
if (prot & MMAP_PROT_EXEC)
map_prot |= PROT_EXEC;
return mprotect(addr, size, map_prot);
}

View File

@ -1,125 +0,0 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#ifndef _BH_PLATFORM_H
#define _BH_PLATFORM_H
#include "bh_config.h"
#include "bh_types.h"
#include <inttypes.h>
#include <stdbool.h>
#include <assert.h>
#include <time.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdarg.h>
#include <ctype.h>
#include <pthread.h>
#include <semaphore.h>
#include <limits.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <android/log.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef uint64_t uint64;
typedef int64_t int64;
#ifndef BH_PLATFORM_ANDROID
#define BH_PLATFORM_ANDROID
#endif
#define _STACK_SIZE_ADJUSTMENT (32 * 1024)
/* Stack size of applet threads's native part. */
#define BH_APPLET_PRESERVED_STACK_SIZE (8 * 1024 + _STACK_SIZE_ADJUSTMENT)
/* Default thread priority */
#define BH_THREAD_DEFAULT_PRIORITY 0
#define BH_ROUTINE_MODIFIER
#define BHT_TIMEDOUT ETIMEDOUT
#define INVALID_THREAD_ID 0xFFffFFff
typedef pthread_t korp_tid;
typedef pthread_mutex_t korp_mutex;
typedef sem_t korp_sem;
typedef pthread_cond_t korp_cond;
typedef pthread_t korp_thread;
typedef void* (*thread_start_routine_t)(void*);
void *os_malloc(unsigned size);
void *os_realloc(void *ptr, unsigned size);
void os_free(void *ptr);
#define bh_printf(...) (__android_log_print(ANDROID_LOG_INFO, "wasm_runtime::", __VA_ARGS__))
int snprintf(char *buffer, size_t count, const char *format, ...);
double fmod(double x, double y);
float fmodf(float x, float y);
double sqrt(double x);
#define BH_WAIT_FOREVER 0xFFFFFFFF
#ifndef NULL
# define NULL ((void*) 0)
#endif
/**
* Return the offset of the given field in the given type.
*
* @param Type the type containing the filed
* @param field the field in the type
*
* @return the offset of field in Type
*/
#ifndef offsetof
#define offsetof(Type, field) ((size_t)(&((Type *)0)->field))
#endif
#define bh_assert assert
char *bh_read_file_to_buffer(const char *filename, uint32 *ret_size);
int bh_platform_init();
/* MMAP mode */
enum {
MMAP_PROT_NONE = 0,
MMAP_PROT_READ = 1,
MMAP_PROT_WRITE = 2,
MMAP_PROT_EXEC = 4
};
/* MMAP flags */
enum {
MMAP_MAP_NONE = 0,
/* Put the mapping into 0 to 2 G, supported only on x86_64 */
MMAP_MAP_32BIT = 1,
/* Don't interpret addr as a hint: place the mapping at exactly
that address. */
MMAP_MAP_FIXED = 2
};
void *bh_mmap(void *hint, unsigned int size, int prot, int flags);
void bh_munmap(void *addr, uint32 size);
int bh_mprotect(void *addr, uint32 size, int prot);
#define bh_dcache_flush() (void)0
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,394 +0,0 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "bh_thread.h"
#include "bh_assert.h"
#include "bh_log.h"
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
static bool is_thread_sys_inited = false;
static korp_mutex thread_list_lock;
static pthread_key_t thread_local_storage_key[BH_MAX_TLS_NUM];
int _vm_thread_sys_init()
{
unsigned i, j;
int ret;
if (is_thread_sys_inited)
return 0;
for (i = 0; i < BH_MAX_TLS_NUM; i++) {
ret = pthread_key_create(&thread_local_storage_key[i], NULL);
if (ret)
goto fail;
}
ret = vm_mutex_init(&thread_list_lock);
if (ret)
goto fail;
is_thread_sys_inited = true;
return 0;
fail: for (j = 0; j < i; j++)
pthread_key_delete(thread_local_storage_key[j]);
return -1;
}
void vm_thread_sys_destroy(void)
{
if (is_thread_sys_inited) {
unsigned i;
for (i = 0; i < BH_MAX_TLS_NUM; i++)
pthread_key_delete(thread_local_storage_key[i]);
vm_mutex_destroy(&thread_list_lock);
is_thread_sys_inited = false;
}
}
typedef struct {
thread_start_routine_t start;
void* stack;
uint32 stack_size;
void* arg;
} thread_wrapper_arg;
static void *vm_thread_wrapper(void *arg)
{
thread_wrapper_arg * targ = arg;
LOG_VERBOSE("THREAD CREATE 0x%08x\n", &targ);
targ->stack = (void *)((uintptr_t)(&arg) & (uintptr_t)~0xfff);
_vm_tls_put(1, targ);
targ->start(targ->arg);
BH_FREE(targ);
_vm_tls_put(1, NULL);
return NULL;
}
int _vm_thread_create_with_prio(korp_tid *tid, thread_start_routine_t start,
void *arg, unsigned int stack_size, int prio)
{
(void)prio;
pthread_attr_t tattr;
thread_wrapper_arg *targ;
bh_assert(stack_size > 0);
bh_assert(tid);
bh_assert(start);
*tid = INVALID_THREAD_ID;
pthread_attr_init(&tattr);
pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_JOINABLE);
if (pthread_attr_setstacksize(&tattr, stack_size) != 0) {
bh_debug("Invalid thread stack size %u. Min stack size on Linux = %u",
stack_size, PTHREAD_STACK_MIN);
pthread_attr_destroy(&tattr);
return BHT_ERROR;
}
targ = (thread_wrapper_arg*) BH_MALLOC(sizeof(*targ));
if (!targ) {
pthread_attr_destroy(&tattr);
return BHT_ERROR;
}
targ->start = start;
targ->arg = arg;
targ->stack_size = stack_size;
if (pthread_create(tid, &tattr, vm_thread_wrapper, targ) != 0) {
pthread_attr_destroy(&tattr);
BH_FREE(targ);
return BHT_ERROR;
}
pthread_attr_destroy(&tattr);
return BHT_OK;
}
int _vm_thread_create(korp_tid *tid, thread_start_routine_t start, void *arg,
unsigned int stack_size)
{
return _vm_thread_create_with_prio(tid, start, arg, stack_size,
BH_THREAD_DEFAULT_PRIORITY);
}
korp_tid _vm_self_thread()
{
return (korp_tid) pthread_self();
}
void vm_thread_exit(void * code)
{
BH_FREE(_vm_tls_get(1));
_vm_tls_put(1, NULL);
pthread_exit(code);
}
void *_vm_tls_get(unsigned idx)
{
bh_assert(idx < BH_MAX_TLS_NUM);
return pthread_getspecific(thread_local_storage_key[idx]);
}
int _vm_tls_put(unsigned idx, void * tls)
{
bh_assert(idx < BH_MAX_TLS_NUM);
pthread_setspecific(thread_local_storage_key[idx], tls);
return BHT_OK;
}
int _vm_mutex_init(korp_mutex *mutex)
{
return pthread_mutex_init(mutex, NULL) == 0 ? BHT_OK : BHT_ERROR;
}
int _vm_recursive_mutex_init(korp_mutex *mutex)
{
int ret;
pthread_mutexattr_t mattr;
bh_assert(mutex);
ret = pthread_mutexattr_init(&mattr);
if (ret)
return BHT_ERROR;
pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_RECURSIVE_NP);
ret = pthread_mutex_init(mutex, &mattr);
pthread_mutexattr_destroy(&mattr);
return ret == 0 ? BHT_OK : BHT_ERROR;
}
int _vm_mutex_destroy(korp_mutex *mutex)
{
int ret;
bh_assert(mutex);
ret = pthread_mutex_destroy(mutex);
return ret == 0 ? BHT_OK : BHT_ERROR;
}
/* Returned error (EINVAL, EAGAIN and EDEADLK) from
locking the mutex indicates some logic error present in
the program somewhere.
Don't try to recover error for an existing unknown error.*/
void vm_mutex_lock(korp_mutex *mutex)
{
int ret;
bh_assert(mutex);
ret = pthread_mutex_lock(mutex);
if (0 != ret) {
printf("vm mutex lock failed (ret=%d)!\n", ret);
exit(-1);
}
}
int vm_mutex_trylock(korp_mutex *mutex)
{
int ret;
bh_assert(mutex);
ret = pthread_mutex_trylock(mutex);
return ret == 0 ? BHT_OK : BHT_ERROR;
}
/* Returned error (EINVAL, EAGAIN and EPERM) from
unlocking the mutex indicates some logic error present
in the program somewhere.
Don't try to recover error for an existing unknown error.*/
void vm_mutex_unlock(korp_mutex *mutex)
{
int ret;
bh_assert(mutex);
ret = pthread_mutex_unlock(mutex);
if (0 != ret) {
printf("vm mutex unlock failed (ret=%d)!\n", ret);
exit(-1);
}
}
int _vm_sem_init(korp_sem* sem, unsigned int c)
{
int ret;
bh_assert(sem);
ret = sem_init(sem, 0, c);
return ret == 0 ? BHT_OK : BHT_ERROR;
}
int _vm_sem_destroy(korp_sem *sem)
{
int ret;
bh_assert(sem);
ret = sem_destroy(sem);
return ret == 0 ? BHT_OK : BHT_ERROR;
}
int _vm_sem_wait(korp_sem *sem)
{
int ret;
bh_assert(sem);
ret = sem_wait(sem);
return ret == 0 ? BHT_OK : BHT_ERROR;
}
int _vm_sem_reltimedwait(korp_sem *sem, int mills)
{
int ret = BHT_OK;
struct timespec timeout;
const int mills_per_sec = 1000;
const int mills_to_nsec = 1E6;
bh_assert(sem);
if (mills == (int)BHT_WAIT_FOREVER) {
ret = sem_wait(sem);
} else {
timeout.tv_sec = mills / mills_per_sec;
timeout.tv_nsec = (mills % mills_per_sec) * mills_to_nsec;
timeout.tv_sec += time(NULL);
ret = sem_timedwait(sem, &timeout);
}
if (ret != BHT_OK) {
if (errno == BHT_TIMEDOUT) {
ret = BHT_TIMEDOUT;
errno = 0;
} else {
bh_debug("Faliure happens when timed wait is called");
bh_assert(0);
}
}
return ret;
}
int _vm_sem_post(korp_sem *sem)
{
bh_assert(sem);
return sem_post(sem) == 0 ? BHT_OK : BHT_ERROR;
}
int _vm_cond_init(korp_cond *cond)
{
bh_assert(cond);
if (pthread_cond_init(cond, NULL) != BHT_OK)
return BHT_ERROR;
return BHT_OK;
}
int _vm_cond_destroy(korp_cond *cond)
{
bh_assert(cond);
if (pthread_cond_destroy(cond) != BHT_OK)
return BHT_ERROR;
return BHT_OK;
}
int _vm_cond_wait(korp_cond *cond, korp_mutex *mutex)
{
bh_assert(cond);
bh_assert(mutex);
if (pthread_cond_wait(cond, mutex) != BHT_OK)
return BHT_ERROR;
return BHT_OK;
}
static void msec_nsec_to_abstime(struct timespec *ts, int64 msec, int32 nsec)
{
struct timeval tv;
gettimeofday(&tv, NULL);
ts->tv_sec = (long int)(tv.tv_sec + msec / 1000);
ts->tv_nsec = (long int)(tv.tv_usec * 1000 + (msec % 1000) * 1000000 + nsec);
if (ts->tv_nsec >= 1000000000L) {
ts->tv_sec++;
ts->tv_nsec -= 1000000000L;
}
}
int _vm_cond_reltimedwait(korp_cond *cond, korp_mutex *mutex, int mills)
{
int ret;
struct timespec abstime;
if (mills == (int)BHT_WAIT_FOREVER)
ret = pthread_cond_wait(cond, mutex);
else {
msec_nsec_to_abstime(&abstime, mills, 0);
ret = pthread_cond_timedwait(cond, mutex, &abstime);
}
if (ret != BHT_OK && ret != BHT_TIMEDOUT)
return BHT_ERROR;
return BHT_OK;
}
int _vm_cond_signal(korp_cond *cond)
{
bh_assert(cond);
if (pthread_cond_signal(cond) != BHT_OK)
return BHT_ERROR;
return BHT_OK;
}
int _vm_cond_broadcast(korp_cond *cond)
{
bh_assert(cond);
if (pthread_cond_broadcast(cond) != BHT_OK)
return BHT_ERROR;
return BHT_OK;
}
int _vm_thread_cancel(korp_tid thread)
{
return pthread_kill(thread, SIGABRT);
}
int _vm_thread_join(korp_tid thread, void **value_ptr, int mills)
{
(void)mills;
return pthread_join(thread, value_ptr);
}
int _vm_thread_detach(korp_tid thread)
{
return pthread_detach(thread);
}

View File

@ -1,71 +0,0 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "bh_time.h"
#include <unistd.h>
#include <stdio.h>
#include <sys/time.h>
/*
* This function returns milliseconds per tick.
* @return milliseconds per tick.
*/
uint64 _bh_time_get_tick_millisecond()
{
return (uint64)sysconf(_SC_CLK_TCK);
}
/*
* This function returns milliseconds after boot.
* @return milliseconds after boot.
*/
uint64 _bh_time_get_boot_millisecond()
{
struct timespec ts;
if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {
return 0;
}
return ((uint64) ts.tv_sec) * 1000 + ((uint64)ts.tv_nsec) / (1000 * 1000);
}
uint32 bh_get_tick_sec()
{
return (uint32)(_bh_time_get_boot_millisecond() / 1000);
}
/*
* This function returns GMT time milliseconds since from 1970.1.1, AKA UNIX time.
* @return milliseconds since from 1970.1.1.
*/
uint64 _bh_time_get_millisecond_from_1970()
{
struct timeval tv;
struct timezone tz;
gettimeofday(&tv, &tz);
return tv.tv_sec * 1000 + tv.tv_usec
- (tz.tz_dsttime == 0 ? 0 : 60 * 60 * 1000)
+ tz.tz_minuteswest * 60 * 1000;
}
size_t _bh_time_strftime(char *s, size_t max, const char *format, int64 time)
{
time_t time_sec = (time_t)(time / 1000);
struct timeval tv;
struct timezone tz;
struct tm *ltp;
gettimeofday(&tv, &tz);
time_sec -= tz.tz_minuteswest * 60;
ltp = localtime(&time_sec);
if (ltp == NULL) {
return 0;
}
return strftime(s, max, format, ltp);
}

View File

@ -3,21 +3,23 @@
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "bh_platform.h"
#include <stdio.h>
#include <android/log.h>
void bh_log_emit(const char *fmt, va_list ap)
#include "platform_api_vmcore.h"
#include "platform_api_extension.h"
int
bh_platform_init()
{
(void)__android_log_vprint(ANDROID_LOG_INFO, "wasm_runtime::", fmt, ap);
return 0;
}
int bh_fprintf(FILE *stream, const char *fmt, ...)
void
bh_platform_destroy()
{
(void)stream;
}
int os_printf(const char *fmt, ...)
{
int ret;
va_list ap;
int ret = 0;
va_start(ap, fmt);
ret = __android_log_vprint(ANDROID_LOG_INFO, "wasm_runtime::", fmt, ap);
@ -26,8 +28,8 @@ int bh_fprintf(FILE *stream, const char *fmt, ...)
return ret;
}
int bh_fflush(void *stream)
int os_vprintf(const char *fmt, va_list ap)
{
(void)stream;
return __android_log_print(ANDROID_LOG_INFO, "wasm_runtime::", "%s", "NOT IMPLEMENT");
return __android_log_print(ANDROID_LOG_INFO, "wasm_runtime::", fmt, ap);
}

View File

@ -0,0 +1,58 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#ifndef _PLATFORM_INTERNAL_H
#define _PLATFORM_INTERNAL_H
#include <inttypes.h>
#include <stdbool.h>
#include <assert.h>
#include <time.h>
#include <sys/time.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdarg.h>
#include <ctype.h>
#include <pthread.h>
#include <semaphore.h>
#include <limits.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <netinet/in.h>
#include <android/log.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef BH_PLATFORM_ANDROID
#define BH_PLATFORM_ANDROID
#endif
#define _STACK_SIZE_ADJUSTMENT (32 * 1024)
/* Stack size of applet threads's native part. */
#define BH_APPLET_PRESERVED_STACK_SIZE (8 * 1024 + _STACK_SIZE_ADJUSTMENT)
/* Default thread priority */
#define BH_THREAD_DEFAULT_PRIORITY 0
typedef pthread_t korp_tid;
typedef pthread_mutex_t korp_mutex;
typedef pthread_cond_t korp_cond;
typedef pthread_t korp_thread;
#ifdef __cplusplus
}
#endif
#endif /* end of _PLATFORM_INTERNAL_H */

View File

@ -3,15 +3,16 @@
set (PLATFORM_SHARED_DIR ${CMAKE_CURRENT_LIST_DIR})
add_definitions(-DBH_PLATFORM_ANDROID)
include_directories(${PLATFORM_SHARED_DIR})
include_directories(${PLATFORM_SHARED_DIR}/../include)
include (${CMAKE_CURRENT_LIST_DIR}/../common/posix/platform_api_posix.cmake)
file (GLOB_RECURSE source_all ${PLATFORM_SHARED_DIR}/*.c)
set (PLATFORM_SHARED_SOURCE ${source_all})
LIST (APPEND RUNTIME_LIB_HEADER_LIST "${PLATFORM_SHARED_DIR}/bh_platform.h")
set (PLATFORM_SHARED_SOURCE ${source_all} ${PLATFORM_COMMON_POSIX_SOURCE})
file (GLOB header ${PLATFORM_SHARED_DIR}/../include/*.h)
LIST (APPEND RUNTIME_LIB_HEADER_LIST ${header})
LIST (APPEND RUNTIME_LIB_HEADER_LIST ${header})

View File

@ -28,7 +28,7 @@
* $FreeBSD$
*/
#include "bh_platform.h"
#include "platform_common.h"
#define __FDLIBM_STDC__
@ -123,8 +123,8 @@ static union {
#define __HIL(x) *(1+pdouble2pint(&x))
#define __LOL(x) *(pdouble2pint(&x))
#define __HIB(x) *(int*)&x
#define __LOB(x) *(1+(int*)&x)
#define __HIB(x) *(pdouble2pint(&x))
#define __LOB(x) *(1+pdouble2pint(&x))
/* Get two 32 bit ints from a double. */

View File

@ -0,0 +1,8 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
set (PLATFORM_COMMON_MATH_DIR ${CMAKE_CURRENT_LIST_DIR})
file (GLOB_RECURSE source_all ${PLATFORM_COMMON_MATH_DIR}/*.c)
set (PLATFORM_COMMON_MATH_SOURCE ${source_all} )

View File

@ -0,0 +1,8 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
set (PLATFORM_COMMON_POSIX_DIR ${CMAKE_CURRENT_LIST_DIR})
file (GLOB_RECURSE source_all ${PLATFORM_COMMON_POSIX_DIR}/*.c)
set (PLATFORM_COMMON_POSIX_SOURCE ${source_all} )

View File

@ -0,0 +1,27 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "platform_api_vmcore.h"
void *
os_malloc(unsigned size)
{
return malloc(size);
}
void *
os_realloc(void *ptr, unsigned size)
{
return realloc(ptr, size);
}
void
os_free(void *ptr)
{
free(ptr);
}

View File

@ -3,88 +3,10 @@
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "bh_platform.h"
#include "bh_common.h"
#include "bh_assert.h"
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
int
bh_platform_init()
{
return 0;
}
#include "platform_api_vmcore.h"
void *
os_malloc(unsigned size)
{
return malloc(size);
}
void *
os_realloc(void *ptr, unsigned size)
{
return realloc(ptr, size);
}
void
os_free(void *ptr)
{
free(ptr);
}
char*
bh_read_file_to_buffer(const char *filename, uint32 *ret_size)
{
char *buffer;
int file;
uint32 file_size, read_size;
struct stat stat_buf;
if (!filename || !ret_size) {
printf("Read file to buffer failed: invalid filename or ret size.\n");
return NULL;
}
if ((file = open(filename, O_RDONLY, 0)) == -1) {
printf("Read file to buffer failed: open file %s failed.\n",
filename);
return NULL;
}
if (fstat(file, &stat_buf) != 0) {
printf("Read file to buffer failed: fstat file %s failed.\n",
filename);
close(file);
return NULL;
}
file_size = (uint32)stat_buf.st_size;
if (!(buffer = BH_MALLOC(file_size))) {
printf("Read file to buffer failed: alloc memory failed.\n");
close(file);
return NULL;
}
read_size = (uint32)read(file, buffer, file_size);
close(file);
if (read_size < file_size) {
printf("Read file to buffer failed: read file content failed.\n");
BH_FREE(buffer);
return NULL;
}
*ret_size = file_size;
return buffer;
}
void *
bh_mmap(void *hint, uint32 size, int prot, int flags)
os_mmap(void *hint, uint32 size, int prot, int flags)
{
int map_prot = PROT_NONE;
int map_flags = MAP_ANONYMOUS | MAP_PRIVATE;
@ -110,8 +32,10 @@ bh_mmap(void *hint, uint32 size, int prot, int flags)
map_prot |= PROT_EXEC;
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
#ifndef __APPLE__
if (flags & MMAP_MAP_32BIT)
map_flags |= MAP_32BIT;
#endif
#endif
if (flags & MMAP_MAP_FIXED)
@ -156,14 +80,14 @@ bh_mmap(void *hint, uint32 size, int prot, int flags)
}
void
bh_munmap(void *addr, uint32 size)
os_munmap(void *addr, uint32 size)
{
if (addr)
munmap(addr, size);
}
int
bh_mprotect(void *addr, uint32 size, int prot)
os_mprotect(void *addr, uint32 size, int prot)
{
int map_prot = PROT_NONE;
@ -182,3 +106,7 @@ bh_mprotect(void *addr, uint32 size, int prot)
return mprotect(addr, size, map_prot);
}
void
os_dcache_flush(void)
{
}

View File

@ -0,0 +1,220 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "platform_api_vmcore.h"
#include "platform_api_extension.h"
typedef struct {
thread_start_routine_t start;
void* stack;
uint32 stack_size;
void* arg;
} thread_wrapper_arg;
static void *os_thread_wrapper(void *arg)
{
thread_wrapper_arg * targ = arg;
printf("THREAD CREATE %p\n", &targ);
targ->stack = (void *)((uintptr_t)(&arg) & (uintptr_t)~0xfff);
targ->start(targ->arg);
BH_FREE(targ);
return NULL;
}
int os_thread_create_with_prio(korp_tid *tid, thread_start_routine_t start,
void *arg, unsigned int stack_size, int prio)
{
pthread_attr_t tattr;
thread_wrapper_arg *targ;
assert(stack_size > 0);
assert(tid);
assert(start);
pthread_attr_init(&tattr);
pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_JOINABLE);
if (pthread_attr_setstacksize(&tattr, stack_size) != 0) {
printf("Invalid thread stack size %u. Min stack size on Linux = %u",
stack_size, PTHREAD_STACK_MIN);
pthread_attr_destroy(&tattr);
return BHT_ERROR;
}
targ = (thread_wrapper_arg*) BH_MALLOC(sizeof(*targ));
if (!targ) {
pthread_attr_destroy(&tattr);
return BHT_ERROR;
}
targ->start = start;
targ->arg = arg;
targ->stack_size = stack_size;
if (pthread_create(tid, &tattr, os_thread_wrapper, targ) != 0) {
pthread_attr_destroy(&tattr);
BH_FREE(targ);
return BHT_ERROR;
}
pthread_attr_destroy(&tattr);
return BHT_OK;
}
int os_thread_create(korp_tid *tid, thread_start_routine_t start, void *arg,
unsigned int stack_size)
{
return os_thread_create_with_prio(tid, start, arg, stack_size,
BH_THREAD_DEFAULT_PRIORITY);
}
korp_tid os_self_thread()
{
return (korp_tid) pthread_self();
}
int os_mutex_init(korp_mutex *mutex)
{
return pthread_mutex_init(mutex, NULL) == 0 ? BHT_OK : BHT_ERROR;
}
int os_recursive_mutex_init(korp_mutex *mutex)
{
int ret;
pthread_mutexattr_t mattr;
assert(mutex);
ret = pthread_mutexattr_init(&mattr);
if (ret)
return BHT_ERROR;
pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_RECURSIVE);
ret = pthread_mutex_init(mutex, &mattr);
pthread_mutexattr_destroy(&mattr);
return ret == 0 ? BHT_OK : BHT_ERROR;
}
int os_mutex_destroy(korp_mutex *mutex)
{
int ret;
assert(mutex);
ret = pthread_mutex_destroy(mutex);
return ret == 0 ? BHT_OK : BHT_ERROR;
}
/* Returned error (EINVAL, EAGAIN and EDEADLK) from
locking the mutex indicates some logic error present in
the program somewhere.
Don't try to recover error for an existing unknown error.*/
void os_mutex_lock(korp_mutex *mutex)
{
int ret;
assert(mutex);
ret = pthread_mutex_lock(mutex);
if (0 != ret) {
printf("vm mutex lock failed (ret=%d)!\n", ret);
exit(-1);
}
}
/* Returned error (EINVAL, EAGAIN and EPERM) from
unlocking the mutex indicates some logic error present
in the program somewhere.
Don't try to recover error for an existing unknown error.*/
void os_mutex_unlock(korp_mutex *mutex)
{
int ret;
assert(mutex);
ret = pthread_mutex_unlock(mutex);
if (0 != ret) {
printf("vm mutex unlock failed (ret=%d)!\n", ret);
exit(-1);
}
}
int os_cond_init(korp_cond *cond)
{
assert(cond);
if (pthread_cond_init(cond, NULL) != BHT_OK)
return BHT_ERROR;
return BHT_OK;
}
int os_cond_destroy(korp_cond *cond)
{
assert(cond);
if (pthread_cond_destroy(cond) != BHT_OK)
return BHT_ERROR;
return BHT_OK;
}
int os_cond_wait(korp_cond *cond, korp_mutex *mutex)
{
assert(cond);
assert(mutex);
if (pthread_cond_wait(cond, mutex) != BHT_OK)
return BHT_ERROR;
return BHT_OK;
}
static void msec_nsec_to_abstime(struct timespec *ts, int usec)
{
struct timeval tv;
gettimeofday(&tv, NULL);
ts->tv_sec = (long int)(tv.tv_sec + usec / 1000000);
ts->tv_nsec = (long int)(tv.tv_usec * 1000 + (usec % 1000000) * 1000);
if (ts->tv_nsec >= 1000000000L) {
ts->tv_sec++;
ts->tv_nsec -= 1000000000L;
}
}
int os_cond_reltimedwait(korp_cond *cond, korp_mutex *mutex, int useconds)
{
int ret;
struct timespec abstime;
if (useconds == (int)BHT_WAIT_FOREVER)
ret = pthread_cond_wait(cond, mutex);
else {
msec_nsec_to_abstime(&abstime, useconds);
ret = pthread_cond_timedwait(cond, mutex, &abstime);
}
if (ret != BHT_OK && ret != ETIMEDOUT)
return BHT_ERROR;
return BHT_OK;
}
int os_cond_signal(korp_cond *cond)
{
assert(cond);
if (pthread_cond_signal(cond) != BHT_OK)
return BHT_ERROR;
return BHT_OK;
}
int os_thread_join(korp_tid thread, void **value_ptr)
{
return pthread_join(thread, value_ptr);
}

View File

@ -0,0 +1,18 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "platform_api_vmcore.h"
uint64
os_time_get_boot_microsecond()
{
struct timespec ts;
if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {
return 0;
}
return ((uint64) ts.tv_sec) * 1000 * 1000 + ((uint64)ts.tv_nsec) / 1000;
}

View File

@ -1,58 +0,0 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "bh_platform.h"
#include "bh_assert.h"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef BH_TEST
#include <setjmp.h>
#endif
#ifdef BH_TEST
/* for exception throwing */
jmp_buf bh_test_jb;
#endif
void bh_assert_internal(int v, const char *file_name, int line_number,
const char *expr_string)
{
if (v)
return;
if (!file_name)
file_name = "NULL FILENAME";
if (!expr_string)
expr_string = "NULL EXPR_STRING";
printf("\nASSERTION FAILED: %s, at FILE=%s, LINE=%d\n", expr_string,
file_name, line_number);
#ifdef BH_TEST
longjmp(bh_test_jb, 1);
#endif
abort();
}
void bh_debug_internal(const char *file_name, int line_number, const char *fmt,
...)
{
#ifndef JEFF_TEST_VERIFIER
va_list args;
va_start(args, fmt);
bh_assert(file_name);
printf("\nDebug info FILE=%s, LINE=%d: ", file_name, line_number);
vprintf(fmt, args);
va_end(args);
printf("\n");
#endif
}

View File

@ -1,123 +0,0 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#ifndef _BH_PLATFORM_H
#define _BH_PLATFORM_H
#include "bh_config.h"
#include "bh_types.h"
#include <inttypes.h>
#include <stdbool.h>
#include <assert.h>
#include <time.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdarg.h>
#include <ctype.h>
#include <pthread.h>
#include <limits.h>
#include <fcntl.h>
#include <semaphore.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef uint64_t uint64;
typedef int64_t int64;
#ifndef BH_PLATFORM_DARWIN
#define BH_PLATFORM_DARWIN
#endif
#define _STACK_SIZE_ADJUSTMENT (32 * 1024)
/* Stack size of applet threads's native part. */
#define BH_APPLET_PRESERVED_STACK_SIZE (8 * 1024 + _STACK_SIZE_ADJUSTMENT)
/* Default thread priority */
#define BH_THREAD_DEFAULT_PRIORITY 0
#define BH_ROUTINE_MODIFIER
#define BHT_TIMEDOUT ETIMEDOUT
#define INVALID_THREAD_ID 0xFFffFFff
typedef pthread_t korp_tid;
typedef pthread_mutex_t korp_mutex;
typedef sem_t korp_sem;
typedef pthread_cond_t korp_cond;
typedef pthread_t korp_thread;
typedef void* (*thread_start_routine_t)(void*);
void *os_malloc(unsigned size);
void *os_realloc(void *ptr, unsigned size);
void os_free(void *ptr);
#define bh_printf printf
/* int snprintf(char *buffer, size_t count, const char *format, ...); */
double fmod(double x, double y);
float fmodf(float x, float y);
double sqrt(double x);
#define BH_WAIT_FOREVER 0xFFFFFFFF
#ifndef NULL
# define NULL ((void*) 0)
#endif
/**
* Return the offset of the given field in the given type.
*
* @param Type the type containing the filed
* @param field the field in the type
*
* @return the offset of field in Type
*/
#ifndef offsetof
#define offsetof(Type, field) ((size_t)(&((Type *)0)->field))
#endif
#define bh_assert assert
char *bh_read_file_to_buffer(const char *filename, uint32 *ret_size);
int bh_platform_init();
/* MMAP mode */
enum {
MMAP_PROT_NONE = 0,
MMAP_PROT_READ = 1,
MMAP_PROT_WRITE = 2,
MMAP_PROT_EXEC = 4
};
/* MMAP flags */
enum {
MMAP_MAP_NONE = 0,
/* Put the mapping into 0 to 2 G, supported only on x86_64 */
MMAP_MAP_32BIT = 1,
/* Don't interpret addr as a hint: place the mapping at exactly
that address. */
MMAP_MAP_FIXED = 2
};
void *bh_mmap(void *hint, unsigned int size, int prot, int flags);
void bh_munmap(void *addr, uint32 size);
int bh_mprotect(void *addr, uint32 size, int prot);
#define bh_dcache_flush() (void)0
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,30 +0,0 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "bh_platform.h"
#include <stdio.h>
void bh_log_emit(const char *fmt, va_list ap)
{
vprintf(fmt, ap);
fflush(stdout);
}
int bh_fprintf(FILE *stream, const char *fmt, ...)
{
va_list ap;
int ret;
va_start(ap, fmt);
ret = vfprintf(stream ? stream : stdout, fmt, ap);
va_end(ap);
return ret;
}
int bh_fflush(void *stream)
{
return fflush(stream ? stream : stdout);
}

View File

@ -1,393 +0,0 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "bh_thread.h"
#include "bh_assert.h"
#include "bh_log.h"
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
static bool is_thread_sys_inited = false;
static korp_mutex thread_list_lock;
static pthread_key_t thread_local_storage_key[BH_MAX_TLS_NUM];
int _vm_thread_sys_init()
{
unsigned i, j;
int ret;
if (is_thread_sys_inited)
return 0;
for (i = 0; i < BH_MAX_TLS_NUM; i++) {
ret = pthread_key_create(&thread_local_storage_key[i], NULL);
if (ret)
goto fail;
}
ret = vm_mutex_init(&thread_list_lock);
if (ret)
goto fail;
is_thread_sys_inited = true;
return 0;
fail: for (j = 0; j < i; j++)
pthread_key_delete(thread_local_storage_key[j]);
return -1;
}
void vm_thread_sys_destroy(void)
{
if (is_thread_sys_inited) {
unsigned i;
for (i = 0; i < BH_MAX_TLS_NUM; i++)
pthread_key_delete(thread_local_storage_key[i]);
vm_mutex_destroy(&thread_list_lock);
is_thread_sys_inited = false;
}
}
typedef struct {
thread_start_routine_t start;
void* stack;
uint32 stack_size;
void* arg;
} thread_wrapper_arg;
static void *vm_thread_wrapper(void *arg)
{
thread_wrapper_arg * targ = arg;
LOG_VERBOSE("THREAD CREATE 0x%08x\n", &targ);
targ->stack = (void *)((uintptr_t)(&arg) & (uintptr_t)~0xfff);
_vm_tls_put(1, targ);
targ->start(targ->arg);
BH_FREE(targ);
_vm_tls_put(1, NULL);
return NULL;
}
int _vm_thread_create_with_prio(korp_tid *tid, thread_start_routine_t start,
void *arg, unsigned int stack_size, int prio)
{
pthread_attr_t tattr;
thread_wrapper_arg *targ;
bh_assert(stack_size > 0);
bh_assert(tid);
bh_assert(start);
*tid = INVALID_THREAD_ID;
pthread_attr_init(&tattr);
pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_JOINABLE);
if (pthread_attr_setstacksize(&tattr, stack_size) != 0) {
bh_debug("Invalid thread stack size %u. Min stack size on Linux = %u",
stack_size, PTHREAD_STACK_MIN);
pthread_attr_destroy(&tattr);
return BHT_ERROR;
}
targ = (thread_wrapper_arg*) BH_MALLOC(sizeof(*targ));
if (!targ) {
pthread_attr_destroy(&tattr);
return BHT_ERROR;
}
targ->start = start;
targ->arg = arg;
targ->stack_size = stack_size;
if (pthread_create(tid, &tattr, vm_thread_wrapper, targ) != 0) {
pthread_attr_destroy(&tattr);
BH_FREE(targ);
return BHT_ERROR;
}
pthread_attr_destroy(&tattr);
return BHT_OK;
}
int _vm_thread_create(korp_tid *tid, thread_start_routine_t start, void *arg,
unsigned int stack_size)
{
return _vm_thread_create_with_prio(tid, start, arg, stack_size,
BH_THREAD_DEFAULT_PRIORITY);
}
korp_tid _vm_self_thread()
{
return (korp_tid) pthread_self();
}
void vm_thread_exit(void * code)
{
BH_FREE(_vm_tls_get(1));
_vm_tls_put(1, NULL);
pthread_exit(code);
}
void *_vm_tls_get(unsigned idx)
{
bh_assert(idx < BH_MAX_TLS_NUM);
return pthread_getspecific(thread_local_storage_key[idx]);
}
int _vm_tls_put(unsigned idx, void * tls)
{
bh_assert(idx < BH_MAX_TLS_NUM);
pthread_setspecific(thread_local_storage_key[idx], tls);
return BHT_OK;
}
int _vm_mutex_init(korp_mutex *mutex)
{
return pthread_mutex_init(mutex, NULL) == 0 ? BHT_OK : BHT_ERROR;
}
int _vm_recursive_mutex_init(korp_mutex *mutex)
{
int ret;
pthread_mutexattr_t mattr;
bh_assert(mutex);
ret = pthread_mutexattr_init(&mattr);
if (ret)
return BHT_ERROR;
pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_RECURSIVE);
ret = pthread_mutex_init(mutex, &mattr);
pthread_mutexattr_destroy(&mattr);
return ret == 0 ? BHT_OK : BHT_ERROR;
}
int _vm_mutex_destroy(korp_mutex *mutex)
{
int ret;
bh_assert(mutex);
ret = pthread_mutex_destroy(mutex);
return ret == 0 ? BHT_OK : BHT_ERROR;
}
/* Returned error (EINVAL, EAGAIN and EDEADLK) from
locking the mutex indicates some logic error present in
the program somewhere.
Don't try to recover error for an existing unknown error.*/
void vm_mutex_lock(korp_mutex *mutex)
{
int ret;
bh_assert(mutex);
ret = pthread_mutex_lock(mutex);
if (0 != ret) {
printf("vm mutex lock failed (ret=%d)!\n", ret);
exit(-1);
}
}
int vm_mutex_trylock(korp_mutex *mutex)
{
int ret;
bh_assert(mutex);
ret = pthread_mutex_trylock(mutex);
return ret == 0 ? BHT_OK : BHT_ERROR;
}
/* Returned error (EINVAL, EAGAIN and EPERM) from
unlocking the mutex indicates some logic error present
in the program somewhere.
Don't try to recover error for an existing unknown error.*/
void vm_mutex_unlock(korp_mutex *mutex)
{
int ret;
bh_assert(mutex);
ret = pthread_mutex_unlock(mutex);
if (0 != ret) {
printf("vm mutex unlock failed (ret=%d)!\n", ret);
exit(-1);
}
}
int _vm_sem_init(korp_sem* sem, unsigned int c)
{
int ret;
bh_assert(sem);
ret = sem_init(sem, 0, c);
return ret == 0 ? BHT_OK : BHT_ERROR;
}
int _vm_sem_destroy(korp_sem *sem)
{
int ret;
bh_assert(sem);
ret = sem_destroy(sem);
return ret == 0 ? BHT_OK : BHT_ERROR;
}
int _vm_sem_wait(korp_sem *sem)
{
int ret;
bh_assert(sem);
ret = sem_wait(sem);
return ret == 0 ? BHT_OK : BHT_ERROR;
}
/*int _vm_sem_reltimedwait(korp_sem *sem, int mills)
{
int ret = BHT_OK;
struct timespec timeout;
const int mills_per_sec = 1000;
const int mills_to_nsec = 1E6;
bh_assert(sem);
if (mills == (int)BHT_WAIT_FOREVER) {
ret = sem_wait(sem);
} else {
timeout.tv_sec = mills / mills_per_sec;
timeout.tv_nsec = (mills % mills_per_sec) * mills_to_nsec;
timeout.tv_sec += time(NULL);
ret = sem_timedwait(sem, &timeout);
}
if (ret != BHT_OK) {
if (errno == BHT_TIMEDOUT) {
ret = BHT_TIMEDOUT;
errno = 0;
} else {
bh_debug("Faliure happens when timed wait is called");
bh_assert(0);
}
}
return ret;
}
*/
int _vm_sem_post(korp_sem *sem)
{
bh_assert(sem);
return sem_post(sem) == 0 ? BHT_OK : BHT_ERROR;
}
int _vm_cond_init(korp_cond *cond)
{
bh_assert(cond);
if (pthread_cond_init(cond, NULL) != BHT_OK)
return BHT_ERROR;
return BHT_OK;
}
int _vm_cond_destroy(korp_cond *cond)
{
bh_assert(cond);
if (pthread_cond_destroy(cond) != BHT_OK)
return BHT_ERROR;
return BHT_OK;
}
int _vm_cond_wait(korp_cond *cond, korp_mutex *mutex)
{
bh_assert(cond);
bh_assert(mutex);
if (pthread_cond_wait(cond, mutex) != BHT_OK)
return BHT_ERROR;
return BHT_OK;
}
static void msec_nsec_to_abstime(struct timespec *ts, int64 msec, int32 nsec)
{
struct timeval tv;
gettimeofday(&tv, NULL);
ts->tv_sec = (long int)(tv.tv_sec + msec / 1000);
ts->tv_nsec = (long int)(tv.tv_usec * 1000 + (msec % 1000) * 1000000 + nsec);
if (ts->tv_nsec >= 1000000000L) {
ts->tv_sec++;
ts->tv_nsec -= 1000000000L;
}
}
int _vm_cond_reltimedwait(korp_cond *cond, korp_mutex *mutex, int mills)
{
int ret;
struct timespec abstime;
if (mills == (int)BHT_WAIT_FOREVER)
ret = pthread_cond_wait(cond, mutex);
else {
msec_nsec_to_abstime(&abstime, mills, 0);
ret = pthread_cond_timedwait(cond, mutex, &abstime);
}
if (ret != BHT_OK && ret != BHT_TIMEDOUT)
return BHT_ERROR;
return BHT_OK;
}
int _vm_cond_signal(korp_cond *cond)
{
bh_assert(cond);
if (pthread_cond_signal(cond) != BHT_OK)
return BHT_ERROR;
return BHT_OK;
}
int _vm_cond_broadcast(korp_cond *cond)
{
bh_assert(cond);
if (pthread_cond_broadcast(cond) != BHT_OK)
return BHT_ERROR;
return BHT_OK;
}
int _vm_thread_cancel(korp_tid thread)
{
return pthread_cancel(thread);
}
int _vm_thread_join(korp_tid thread, void **value_ptr, int mills)
{
return pthread_join(thread, value_ptr);
}
int _vm_thread_detach(korp_tid thread)
{
return pthread_detach(thread);
}

View File

@ -1,70 +0,0 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "bh_time.h"
#include <unistd.h>
#include <stdio.h>
#include <sys/timeb.h>
#include <time.h>
/*
* This function returns milliseconds per tick.
* @return milliseconds per tick.
*/
uint64 _bh_time_get_tick_millisecond()
{
return (uint64)sysconf(_SC_CLK_TCK);
}
/*
* This function returns milliseconds after boot.
* @return milliseconds after boot.
*/
uint64 _bh_time_get_boot_millisecond()
{
struct timespec ts;
if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {
return 0;
}
return ((uint64) ts.tv_sec) * 1000 + ((uint64)ts.tv_nsec) / (1000 * 1000);
}
uint32 bh_get_tick_sec()
{
return (uint32)(_bh_time_get_boot_millisecond() / 1000);
}
/*
* This function returns GMT time milliseconds since from 1970.1.1, AKA UNIX time.
* @return milliseconds since from 1970.1.1.
*/
uint64 _bh_time_get_millisecond_from_1970()
{
struct timeb tp;
ftime(&tp);
return ((uint64) tp.time) * 1000 + tp.millitm
- (tp.dstflag == 0 ? 0 : 60 * 60 * 1000)
+ ((uint64)tp.timezone) * 60 * 1000;
}
size_t _bh_time_strftime(char *s, size_t max, const char *format, int64 time)
{
time_t time_sec = (time_t)(time / 1000);
struct timeb tp;
struct tm *ltp;
ftime(&tp);
time_sec -= tp.timezone * 60;
ltp = localtime(&time_sec);
if (ltp == NULL) {
return 0;
}
return strftime(s, max, format, ltp);
}

View File

@ -3,15 +3,16 @@
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "bh_platform.h"
#include <stdio.h>
#include "platform_api_vmcore.h"
void bh_log_emit(const char *fmt, va_list ap)
{
bh_vprintf_sgx(fmt, ap);
}
int bh_fflush(void *stream)
int
bh_platform_init()
{
return 0;
}
void
bh_platform_destroy()
{
}

View File

@ -0,0 +1,61 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#ifndef _PLATFORM_INTERNAL_H
#define _PLATFORM_INTERNAL_H
#include <inttypes.h>
#include <stdbool.h>
#include <assert.h>
#include <time.h>
#include <sys/time.h>
#include <sys/timeb.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdarg.h>
#include <ctype.h>
#include <pthread.h>
#include <semaphore.h>
#include <limits.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <netinet/in.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef BH_PLATFORM_DARWIN
#define BH_PLATFORM_DARWIN
#endif
#define _STACK_SIZE_ADJUSTMENT (32 * 1024)
/* Stack size of applet threads's native part. */
#define BH_APPLET_PRESERVED_STACK_SIZE (8 * 1024 + _STACK_SIZE_ADJUSTMENT)
/* Default thread priority */
#define BH_THREAD_DEFAULT_PRIORITY 0
typedef pthread_t korp_tid;
typedef pthread_mutex_t korp_mutex;
typedef pthread_cond_t korp_cond;
typedef pthread_t korp_thread;
#define os_printf printf
#define os_vprintf vprintf
#ifdef __cplusplus
}
#endif
#endif /* end of _PLATFORM_INTERNAL_H */

View File

@ -3,11 +3,16 @@
set (PLATFORM_SHARED_DIR ${CMAKE_CURRENT_LIST_DIR})
add_definitions(-DBH_PLATFORM_DARWIN)
include_directories(${PLATFORM_SHARED_DIR})
include_directories(${PLATFORM_SHARED_DIR}/../include)
include (${CMAKE_CURRENT_LIST_DIR}/../common/posix/platform_api_posix.cmake)
file (GLOB_RECURSE source_all ${PLATFORM_SHARED_DIR}/*.c)
set (PLATFORM_SHARED_SOURCE ${source_all})
set (PLATFORM_SHARED_SOURCE ${source_all} ${PLATFORM_COMMON_POSIX_SOURCE})
file (GLOB header ${PLATFORM_SHARED_DIR}/../include/*.h)
LIST (APPEND RUNTIME_LIB_HEADER_LIST ${header})

View File

@ -1,62 +0,0 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#ifndef _BH_ASSERT_H
#define _BH_ASSERT_H
#include "bh_config.h"
#include "bh_platform.h"
#ifdef BH_TEST
# ifndef BH_DEBUG
# error "BH_TEST should be defined under BH_DEBUG"
# endif
#endif
#ifdef BH_TEST
# if defined(WIN32) || defined(__linux__)
# else
# error "Test case can not run on the current platform"
# endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifdef BH_DEBUG
void bh_assert_internal(int v, const char *file_name, int line_number,
const char *expr_string);
#define bh_assert(expr) bh_assert_internal((int)(expr), __FILE__, __LINE__, #expr)
void bh_debug_internal(const char *file_name, int line_number,
const char *fmt, ...);
#if defined(WIN32)
#define bh_debug(fmt, ...) bh_debug_internal(__FILE__, __LINE__, fmt, __VA_ARGS__)
#elif defined(__linux__)
#define bh_debug bh_debug_internal(__FILE__, __LINE__, "");printf
#else
#error "Unsupported platform"
#endif
#else /* else of BH_DEBUG */
#define bh_debug if(0)printf
#endif /* end of BH_DEBUG */
#ifdef BH_TEST
#define BH_STATIC
#else
#define BH_STATIC static
#endif /* end of BH_TEST */
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,53 +0,0 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
/**
* @file bh_config.h
* @date Tue Sep 13 14:53:17 2011
*
* @brief Configurations for different platforms and targets. Make
* sure all source files in Beihai project include this header file
* directly or indirectly.
*/
#ifndef BH_CONFIG
#include "config.h"
#define BH_KB (1024)
#define BH_MB ((BH_KB)*1024)
#define BH_GB ((BH_MB)*1024)
#ifndef BH_MALLOC
#define BH_MALLOC os_malloc
#endif
#ifndef BH_FREE
#define BH_FREE os_free
#endif
#ifndef WA_MALLOC
#include <stdlib.h>
#define WA_MALLOC malloc
#endif
#ifndef WA_FREE
#include <stdlib.h>
#define WA_FREE free
#endif
#ifdef __cplusplus
extern "C" {
#endif
void *wasm_runtime_malloc(unsigned int size);
void wasm_runtime_free(void *ptr);
#ifdef __cplusplus
}
#endif
#endif /* end of BH_CONFIG */

View File

@ -1,398 +0,0 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#ifndef _BH_THREAD_H
#define _BH_THREAD_H
#ifdef __cplusplus
extern "C" {
#endif
#include "bh_config.h"
#include "bh_platform.h"
#define BH_MAX_THREAD 32
#define BH_MAX_TLS_NUM 2
#define BHT_ERROR (-1)
#define BHT_TIMED_OUT (1)
#define BHT_OK (0)
#define BHT_NO_WAIT 0x00000000
#define BHT_WAIT_FOREVER 0xFFFFFFFF
/**
* vm_thread_sys_init
* initiation function for beihai thread system. Invoked at the beginning of beihai intiation.
*
* @return 0 if succuess.
*/
int _vm_thread_sys_init(void);
#ifdef _INSTRUMENT_TEST_ENABLED
int vm_thread_sys_init_instr(const char*func_name);
#define vm_thread_sys_init(void) vm_thread_sys_init_instr(__FUNCTION__)
#else
#define vm_thread_sys_init _vm_thread_sys_init
#endif
void vm_thread_sys_destroy(void);
/**
* This function creates a thread
*
* @param p_tid [OUTPUT] the pointer of tid
* @param start main routine of the thread
* @param arg argument passed to main routine
* @param stack_size bytes of stack size
*
* @return 0 if success.
*/
int _vm_thread_create(korp_tid *p_tid, thread_start_routine_t start, void *arg,
unsigned int stack_size);
#ifdef _INSTRUMENT_TEST_ENABLED
int vm_thread_create_instr(korp_tid *p_tid, thread_start_routine_t start, void *arg, unsigned int stack_size, const char*func_name);
#define vm_thread_create(p_tid, start, arg, stack_size) vm_thread_create_instr(p_tid, start, arg, stack_size, __FUNCTION__)
#else
#define vm_thread_create _vm_thread_create
#endif
/**
* This function creates a thread
*
* @param p_tid [OUTPUT] the pointer of tid
* @param start main routine of the thread
* @param arg argument passed to main routine
* @param stack_size bytes of stack size
* @param prio the priority
*
* @return 0 if success.
*/
int _vm_thread_create_with_prio(korp_tid *p_tid, thread_start_routine_t start,
void *arg, unsigned int stack_size, int prio);
#ifdef _INSTRUMENT_TEST_ENABLED
int vm_thread_create_with_prio_instr(korp_tid *p_tid, thread_start_routine_t start, void *arg, unsigned int stack_size, int prio, const char*func_name);
#define vm_thread_create_with_prio(p_tid, start, arg, stack_size) vm_thread_create_instr(p_tid, start, arg, stack_size, prio, __FUNCTION__)
#else
#define vm_thread_create_with_prio _vm_thread_create_with_prio
#endif
/**
* This function never returns.
*
* @param code not used
*/
void vm_thread_exit(void *code);
/**
* This function gets current thread id
*
* @return current thread id
*/
korp_tid _vm_self_thread(void);
#ifdef _INSTRUMENT_TEST_ENABLED
korp_tid vm_self_thread_instr(const char*func_name);
#define vm_self_thread(void) vm_self_thread_instr(__FUNCTION__)
#else
#define vm_self_thread _vm_self_thread
#endif
/**
* This function saves a pointer in thread local storage. One thread can only save one pointer.
*
* @param idx tls array index
* @param ptr pointer need save as TLS
*
* @return 0 if success
*/
int _vm_tls_put(unsigned idx, void *ptr);
#ifdef _INSTRUMENT_TEST_ENABLED
int vm_tls_put_instr(unsigned idx, void *ptr, const char*func_name);
#define vm_tls_put(idx, ptr) vm_tls_put_instr(idx, ptr, __FUNCTION__)
#else
#define vm_tls_put _vm_tls_put
#endif
/**
* This function gets a pointer saved in TLS.
*
* @param idx tls array index
*
* @return the pointer saved in TLS.
*/
void *_vm_tls_get(unsigned idx);
#ifdef _INSTRUMENT_TEST_ENABLED
void *vm_tls_get_instr(unsigned idx, const char*func_name);
#define vm_tls_get(idx) vm_tls_get_instr(idx, __FUNCTION__)
#else
#define vm_tls_get _vm_tls_get
#endif
#define vm_thread_testcancel(void)
/**
* This function creates a non-recursive mutex
*
* @param mutex [OUTPUT] pointer to mutex initialized.
*
* @return 0 if success
*/
int _vm_mutex_init(korp_mutex *mutex);
#ifdef INSTRUMENT_TEST_ENABLED
int vm_mutex_init_instr(korp_mutex *mutex, const char*func_name);
#define vm_mutex_init(mutex) vm_mutex_init_instr(mutex, __FUNCTION__)
#else
#define vm_mutex_init _vm_mutex_init
#endif
/**
* This function creates a recursive mutex
*
* @param mutex [OUTPUT] pointer to mutex initialized.
*
* @return 0 if success
*/
int _vm_recursive_mutex_init(korp_mutex *mutex);
#ifdef INSTRUMENT_TEST_ENABLED
int vm_recursive_mutex_init_instr(korp_mutex *mutex, const char*func_name);
#define vm_recursive_mutex_init(mutex) vm_recursive_mutex_init_instr(mutex, __FUNCTION__)
#else
#define vm_recursive_mutex_init _vm_recursive_mutex_init
#endif
/**
* This function destroys a mutex
*
* @param mutex pointer to mutex need destroy
*
* @return 0 if success
*/
int _vm_mutex_destroy(korp_mutex *mutex);
#ifdef _INSTRUMENT_TEST_ENABLED
int vm_mutex_destroy_instr(korp_mutex *mutex, const char*func_name);
#define vm_mutex_destroy(mutex) vm_mutex_destroy_instr(mutex, __FUNCTION__)
#else
#define vm_mutex_destroy _vm_mutex_destroy
#endif
/**
* This function locks the mutex
*
* @param mutex pointer to mutex need lock
*
* @return Void
*/
void vm_mutex_lock(korp_mutex *mutex);
/**
* This function locks the mutex without waiting
*
* @param mutex pointer to mutex need lock
*
* @return 0 if success
*/
int vm_mutex_trylock(korp_mutex *mutex);
/**
* This function unlocks the mutex
*
* @param mutex pointer to mutex need unlock
*
* @return Void
*/
void vm_mutex_unlock(korp_mutex *mutex);
/**
* This function creates a semaphone
*
* @param sem [OUTPUT] pointer to semaphone
* @param c counter of semaphone
*
* @return 0 if success
*/
int _vm_sem_init(korp_sem *sem, unsigned int c);
#ifdef _INSTRUMENT_TEST_ENABLED
int vm_sem_init_instr(korp_sem *sem, unsigned int c, const char*func_name);
#define vm_sem_init(sem, c) vm_sem_init_instr(sem, c, __FUNCTION__)
#else
#define vm_sem_init _vm_sem_init
#endif
/**
* This function destroys a semaphone
*
* @param sem pointer to semaphone need destroy
*
* @return 0 if success
*/
int _vm_sem_destroy(korp_sem *sem);
#ifdef _INSTRUMENT_TEST_ENABLED
int vm_sem_destroy_instr(korp_sem *sem, const char*func_name);
#define vm_sem_destroy(sem) vm_sem_destroy_instr(sem, __FUNCTION__)
#else
#define vm_sem_destroy _vm_sem_destroy
#endif
/**
* This function performs wait operation on semaphone
*
* @param sem pointer to semaphone need perform wait operation
*
* @return 0 if success
*/
int _vm_sem_wait(korp_sem *sem);
#ifdef _INSTRUMENT_TEST_ENABLED
int vm_sem_wait_instr(korp_sem *sem, const char*func_name);
#define vm_sem_wait(sem) vm_sem_wait_instr(sem, __FUNCTION__)
#else
#define vm_sem_wait _vm_sem_wait
#endif
/**
* This function performs wait operation on semaphone with a timeout
*
* @param sem pointer to semaphone need perform wait operation
* @param mills wait milliseconds to return
*
* @return 0 if success
* @return BH_TIMEOUT if time out
*/
int _vm_sem_reltimedwait(korp_sem *sem, int mills);
#ifdef _INSTRUMENT_TEST_ENABLED
int vm_sem_reltimedwait_instr(korp_sem *sem, int mills, const char*func_name);
#define vm_sem_reltimedwait(sem, mills) vm_sem_reltimedwait_instr(sem, mills, __FUNCTION__)
#else
#define vm_sem_reltimedwait _vm_sem_reltimedwait
#endif
/**
* This function performs post operation on semaphone
*
* @param sem pointer to semaphone need perform post operation
*
* @return 0 if success
*/
int _vm_sem_post(korp_sem *sem);
#ifdef _INSTRUMENT_TEST_ENABLED
int vm_sem_post_instr(korp_sem *sem, const char*func_name);
#define vm_sem_post(sem) vm_sem_post_instr(sem, __FUNCTION__)
#else
#define vm_sem_post _vm_sem_post
#endif
/**
* This function creates a condition variable
*
* @param cond [OUTPUT] pointer to condition variable
*
* @return 0 if success
*/
int _vm_cond_init(korp_cond *cond);
#ifdef INSTRUMENT_TEST_ENABLED
int vm_cond_init_instr(korp_cond *cond, const char*func_name);
#define vm_cond_init(cond) vm_cond_init_instr(cond, __FUNCTION__)
#else
#define vm_cond_init _vm_cond_init
#endif
/**
* This function destroys condition variable
*
* @param cond pointer to condition variable
*
* @return 0 if success
*/
int _vm_cond_destroy(korp_cond *cond);
#ifdef _INSTRUMENT_TEST_ENABLED
int vm_cond_destroy_instr(korp_cond *cond, const char*func_name);
#define vm_cond_destroy(cond) vm_cond_destroy_instr(cond, __FUNCTION__)
#else
#define vm_cond_destroy _vm_cond_destroy
#endif
/**
* This function will block on a condition varible.
*
* @param cond pointer to condition variable
* @param mutex pointer to mutex to protect the condition variable
*
* @return 0 if success
*/
int _vm_cond_wait(korp_cond *cond, korp_mutex *mutex);
#ifdef _INSTRUMENT_TEST_ENABLED
int vm_cond_wait_instr(korp_cond *cond, korp_mutex *mutex, const char*func_name);
#define vm_cond_wait(cond, mutex) vm_cond_wait_instr(cond, mutex, __FUNCTION__)
#else
#define vm_cond_wait _vm_cond_wait
#endif
/**
* This function will block on a condition varible or return if time specified passes.
*
* @param cond pointer to condition variable
* @param mutex pointer to mutex to protect the condition variable
* @param mills milliseconds to wait
*
* @return 0 if success
*/
int _vm_cond_reltimedwait(korp_cond *cond, korp_mutex *mutex, int mills);
#ifdef _INSTRUMENT_TEST_ENABLED
int vm_cond_reltimedwait_instr(korp_cond *cond, korp_mutex *mutex, int mills, const char*func_name);
#define vm_cond_reltimedwait(cond, mutex, mills) vm_cond_reltimedwait_instr(cond, mutex, mills, __FUNCTION__)
#else
#define vm_cond_reltimedwait _vm_cond_reltimedwait
#endif
/**
* This function signals the condition variable
*
* @param cond condition variable
*
* @return 0 if success
*/
int _vm_cond_signal(korp_cond *cond);
#ifdef _INSTRUMENT_TEST_ENABLED
int vm_cond_signal_instr(korp_cond *cond, const char*func_name);
#define vm_cond_signal(cond) vm_cond_signal_instr(cond, __FUNCTION__)
#else
#define vm_cond_signal _vm_cond_signal
#endif
int _vm_cond_broadcast(korp_cond *cond);
#ifdef _INSTRUMENT_TEST_ENABLED
int vm_cond_broadcast_instr(korp_cond *cond, const char*func_name);
#define vm_cond_broadcast(cond) vm_cond_broadcast_instr(cond, __FUNCTION__)
#else
#define vm_cond_broadcast _vm_cond_broadcast
#endif
int _vm_thread_cancel(korp_tid thread);
#ifdef _INSTRUMENT_TEST_ENABLED
int vm_thread_cancel_instr(korp_tid thread, const char*func_name);
#define vm_thread_cancel(thread) vm_thread_cancel_instr(thread, __FUNCTION__)
#else
#define vm_thread_cancel _vm_thread_cancel
#endif
int _vm_thread_join(korp_tid thread, void **value_ptr, int mills);
#ifdef _INSTRUMENT_TEST_ENABLED
int vm_thread_join_instr(korp_tid thread, void **value_ptr, int mills, const char*func_name);
#define vm_thread_join(thread, value_ptr, mills) vm_thread_join_instr(thread, value_ptr, mills, __FUNCTION__)
#else
#define vm_thread_join _vm_thread_join
#endif
int _vm_thread_detach(korp_tid thread);
#ifdef _INSTRUMENT_TEST_ENABLED
int vm_thread_detach_instr(korp_tid thread, const char*func_name);
#define vm_thread_detach(thread) vm_thread_detach_instr(thread, __FUNCTION__)
#else
#define vm_thread_detach _vm_thread_detach
#endif
#ifdef __cplusplus
}
#endif
#endif /* #ifndef _BH_THREAD_H */

View File

@ -1,86 +0,0 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#ifndef _BH_TIME_H
#define _BH_TIME_H
#ifdef __cplusplus
extern "C" {
#endif
#include "bh_config.h"
#include "bh_types.h"
#include "bh_platform.h"
/*
* This function returns milliseconds per tick.
* @return milliseconds per tick.
*/
extern uint64 _bh_time_get_tick_millisecond(void);
#ifdef _INSTRUMENT_TEST_ENABLED
extern uint64 bh_time_get_tick_millisecond_instr(const char*func_name);
#define bh_time_get_tick_millisecond() bh_time_get_tick_millisecond_instr(__FUNCTION__)
#else
#define bh_time_get_tick_millisecond _bh_time_get_tick_millisecond
#endif
/*
* This function returns milliseconds after boot.
* @return milliseconds after boot.
*/
extern uint64 _bh_time_get_boot_millisecond(void);
#ifdef _INSTRUMENT_TEST_ENABLED
extern uint64 bh_time_get_boot_millisecond_instr(const char*func_name);
#define bh_time_get_boot_millisecond() bh_time_get_boot_millisecond_instr(__FUNCTION__)
#else
#define bh_time_get_boot_millisecond _bh_time_get_boot_millisecond
#endif
extern uint32 bh_get_tick_sec();
#define bh_get_tick_ms _bh_time_get_boot_millisecond
/*
* This function returns GMT milliseconds since from 1970.1.1, AKA UNIX time.
* @return milliseconds since from 1970.1.1.
*/
extern uint64 _bh_time_get_millisecond_from_1970(void);
#ifdef _INSTRUMENT_TEST_ENABLED
extern uint64 bh_time_get_millisecond_from_1970_instr(const char*func_name);
#define bh_time_get_millisecond_from_1970() bh_time_get_millisecond_from_1970_instr(__FUNCTION__)
#else
#define bh_time_get_millisecond_from_1970 _bh_time_get_millisecond_from_1970
#endif
/**
* This function sets timezone with specific hours.
*
* @param hours represents the deviation (in hours) of the local time from GMT (can be a positive or a negative number)
* @param half_hour if true, adds half an hour to the local time calculation. For example, if hours=(+5) then the time will be GMT +5:30; if hours=(-5) then the time will be GMT -4:30.
* @param daylight_save if true, applies the daylight saving scheme when calculating the local time (adds one hour to the local time calculation)
*/
extern void bh_set_timezone(int hours, int half_hour, int daylight_save);
/**
* This functions returns the offset in seconds which needs to be added GMT to get the local time.
*
*
* @return offset in secords which needs to be added GMT to get the local time.
*/
extern int bh_get_timezone_offset(void);
size_t bh_time_strftime(char *s, size_t max, const char *format, int64 time);
#ifdef _INSTRUMENT_TEST_ENABLED
size_t bh_time_strftime_instr(char *s, size_t max, const char *format, int64 time, const char*func_name);
#define bh_time_strftime(s, max, format, time) bh_time_strftime_instr(s, max, format, time, __FUNCTION__)
#else
#define bh_time_strftime _bh_time_strftime
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,33 +0,0 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#ifndef _BH_TYPES_H
#define _BH_TYPES_H
#include "bh_config.h"
typedef unsigned char uint8;
typedef char int8;
typedef unsigned short uint16;
typedef short int16;
typedef unsigned int uint32;
typedef int int32;
typedef float float32;
typedef double float64;
#include "bh_platform.h"
#ifndef NULL
#define NULL (void*)0
#endif
#ifndef __cplusplus
#define true 1
#define false 0
#define inline __inline
#endif
#endif

View File

@ -0,0 +1,140 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#ifndef PLATFORM_API_EXTENSION_H
#define PLATFORM_API_EXTENSION_H
#include "platform_common.h"
/**
* The related data structures should be defined
* in platform_internal.h
**/
#include "platform_internal.h"
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************
* *
* Extension interface *
* *
***************************************************/
/**
* NOTES:
* 1. If you are building VM core only, it must be implemented to
* enable multi-thread support, otherwise no need to implement it
* 2. To build the app-mgr and app-framework, you must implement it
*/
/**
* Ceates a thread
*
* @param p_tid [OUTPUT] the pointer of tid
* @param start main routine of the thread
* @param arg argument passed to main routine
* @param stack_size bytes of stack size
*
* @return 0 if success.
*/
int os_thread_create(korp_tid *p_tid, thread_start_routine_t start, void *arg,
unsigned int stack_size);
/**
* Creates a thread with priority
*
* @param p_tid [OUTPUT] the pointer of tid
* @param start main routine of the thread
* @param arg argument passed to main routine
* @param stack_size bytes of stack size
* @param prio the priority
*
* @return 0 if success.
*/
int os_thread_create_with_prio(korp_tid *p_tid, thread_start_routine_t start,
void *arg, unsigned int stack_size, int prio);
/**
* Waits for the thread specified by thread to terminate
*
* @param thread the thread to wait
* @param retval if not NULL, output the exit status of the terminated thread
*
* @return return 0 if success
*/
int os_thread_join(korp_tid thread, void **retval);
/**
* Suspend execution of the calling thread for (at least)
* usec microseconds
*
* @param return 0 if success, -1 otherwise
*/
int os_usleep(uint32 usec);
/**
* Creates a recursive mutex
*
* @param mutex [OUTPUT] pointer to mutex initialized.
*
* @return 0 if success
*/
int os_recursive_mutex_init(korp_mutex *mutex);
/**
* This function creates a condition variable
*
* @param cond [OUTPUT] pointer to condition variable
*
* @return 0 if success
*/
int os_cond_init(korp_cond *cond);
/**
* This function destroys condition variable
*
* @param cond pointer to condition variable
*
* @return 0 if success
*/
int os_cond_destroy(korp_cond *cond);
/**
* Wait a condition variable.
*
* @param cond pointer to condition variable
* @param mutex pointer to mutex to protect the condition variable
*
* @return 0 if success
*/
int os_cond_wait(korp_cond *cond, korp_mutex *mutex);
/**
* Wait a condition varible or return if time specified passes.
*
* @param cond pointer to condition variable
* @param mutex pointer to mutex to protect the condition variable
* @param useconds microseconds to wait
*
* @return 0 if success
*/
int os_cond_reltimedwait(korp_cond *cond, korp_mutex *mutex, int useconds);
/**
* Signals the condition variable
*
* @param cond condition variable
*
* @return 0 if success
*/
int os_cond_signal(korp_cond *cond);
#ifdef __cplusplus
}
#endif
#endif /* #ifndef PLATFORM_API_EXTENSION_H */

View File

@ -0,0 +1,122 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#ifndef _PLATFORM_API_VMCORE_H
#define _PLATFORM_API_VMCORE_H
#include "platform_common.h"
#include "platform_internal.h"
#ifdef __cplusplus
extern "C" {
#endif
/****************************************************
* Section 1 *
* Interfaces required by the runtime *
****************************************************/
/**
* Initialize the platform internal resources if needed,
* this function is called by wasm_runtime_init() and
* wasm_runtime_full_init()
*
* @return 0 if success
*/
int bh_platform_init();
/**
* Destroy the platform internal resources if needed,
* this function is called by wasm_runtime_destroy()
*/
void bh_platform_destroy();
/**
******** memory allocator APIs **********
*/
void *os_malloc(unsigned size);
void *os_realloc(void *ptr, unsigned size);
void os_free(void *ptr);
/**
* Note: the above APIs can simply return NULL if wasm runtime
* isn't initialized with Alloc_With_System_Allocator.
* Refer to wasm_runtime_full_init().
*/
int os_printf(const char *format, ...);
int os_vprintf(const char *format, va_list ap);
/**
* Get microseconds after boot.
*/
uint64 os_time_get_boot_microsecond(void);
/**
* Get current thread id.
* Implementation optional: Used by runtime for logging only.
*/
korp_tid os_self_thread(void);
/**
************** mutext APIs ***********
* vmcore: Not required until pthread is supported by runtime
* app-mgr: Must be implemented
*/
int os_mutex_init(korp_mutex *mutex);
int os_mutex_destroy(korp_mutex *mutex);
void os_mutex_lock(korp_mutex *mutex);
void os_mutex_unlock(korp_mutex *mutex);
/**************************************************
* Section 2 *
* APIs required by WAMR AOT *
**************************************************/
/* Memory map modes */
enum {
MMAP_PROT_NONE = 0,
MMAP_PROT_READ = 1,
MMAP_PROT_WRITE = 2,
MMAP_PROT_EXEC = 4
};
/* Memory map flags */
enum {
MMAP_MAP_NONE = 0,
/* Put the mapping into 0 to 2 G, supported only on x86_64 */
MMAP_MAP_32BIT = 1,
/* Don't interpret addr as a hint: place the mapping at exactly
that address. */
MMAP_MAP_FIXED = 2
};
void *os_mmap(void *hint, unsigned int size, int prot, int flags);
void os_munmap(void *addr, uint32 size);
int os_mprotect(void *addr, uint32 size, int prot);
/**
* Flush cpu data cache, in some CPUs, after applying relocation to the
* AOT code, the code may haven't been written back to the cpu data cache,
* which may cause unexpected behaviour when executing the AOT code.
* Implement this function if required, or just leave it empty.
*/
void os_dcache_flush(void);
#ifdef __cplusplus
}
#endif
#endif /* #ifndef _PLATFORM_API_VMCORE_H */

View File

@ -0,0 +1,73 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#ifndef _PLATFORM_COMMON_H
#define _PLATFORM_COMMON_H
#ifdef __cplusplus
extern "C" {
#endif
#include "../../../config.h"
#include "platform_internal.h"
#define BH_MAX_THREAD 32
#define BHT_ERROR (-1)
#define BHT_TIMED_OUT (1)
#define BHT_OK (0)
#define BHT_NO_WAIT 0x00000000
#define BHT_WAIT_FOREVER 0xFFFFFFFF
#define BH_KB (1024)
#define BH_MB ((BH_KB)*1024)
#define BH_GB ((BH_MB)*1024)
#ifndef BH_MALLOC
#define BH_MALLOC os_malloc
#endif
#ifndef BH_FREE
#define BH_FREE os_free
#endif
void *BH_MALLOC(unsigned int size);
void BH_FREE(void *ptr);
#ifndef NULL
#define NULL (void*)0
#endif
#ifndef __cplusplus
#define true 1
#define false 0
#define inline __inline
#endif
/* Return the offset of the given field in the given type */
#ifndef offsetof
#define offsetof(Type, field) ((size_t)(&((Type *)0)->field))
#endif
typedef uint8_t uint8;
typedef int8_t int8;
typedef uint16_t uint16;
typedef int16_t int16;
typedef uint32_t uint32;
typedef int32_t int32;
typedef float float32;
typedef double float64;
typedef uint64_t uint64;
typedef int64_t int64;
typedef void* (*thread_start_routine_t)(void*);
#ifdef __cplusplus
}
#endif
#endif /* #ifndef _PLATFORM_COMMON_H */

View File

@ -1,58 +0,0 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "bh_platform.h"
#include "bh_assert.h"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef BH_TEST
#include <setjmp.h>
#endif
#ifdef BH_TEST
/* for exception throwing */
jmp_buf bh_test_jb;
#endif
#define FIXED_BUFFER_SIZE (1<<9)
void bh_assert_internal(int v, const char *file_name, int line_number,
const char *expr_string)
{
if (v)
return;
if (!file_name)
file_name = "NULL FILENAME";
if (!expr_string)
expr_string = "NULL EXPR_STRING";
bh_printf_sgx("\nASSERTION FAILED: %s, at FILE=%s, LINE=%d\n", expr_string,
file_name, line_number);
#ifdef BH_TEST
longjmp(bh_test_jb, 1);
#endif
abort();
}
void bh_debug_internal(const char *file_name, int line_number, const char *fmt,
...)
{
#ifndef JEFF_TEST_VERIFIER
va_list args;
char msg[FIXED_BUFFER_SIZE] = { '\0' };
va_start(args, fmt);
vsnprintf(msg, FIXED_BUFFER_SIZE, fmt, args);
va_end(args);
bh_printf_sgx("\nDebug info FILE=%s, LINE=%d: ", file_name, line_number);
bh_printf_sgx(msg);
bh_printf_sgx("\n");
#endif
}

View File

@ -1,126 +0,0 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#ifndef _BH_PLATFORM_H
#define _BH_PLATFORM_H
#include "bh_config.h"
#include "bh_types.h"
#include <inttypes.h>
#include <stdbool.h>
#include <assert.h>
#include <time.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdarg.h>
#include <ctype.h>
#include <limits.h>
#include <errno.h>
#include <sgx_thread.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef void (*bh_print_function_t)(const char* message);
void bh_set_print_function(bh_print_function_t pf);
extern int bh_printf_sgx(const char *message, ...);
extern int bh_vprintf_sgx(const char * format, va_list arg);
typedef uint64_t uint64;
typedef int64_t int64;
#ifndef BH_PLATFORM_LINUX_SGX
#define BH_PLATFORM_LINUX_SGX
#endif
/* NEED qsort */
#define _STACK_SIZE_ADJUSTMENT (32 * 1024)
/* Stack size of applet threads's native part. */
#define BH_APPLET_PRESERVED_STACK_SIZE (8 * 1024 + _STACK_SIZE_ADJUSTMENT)
/* Default thread priority */
#define BH_THREAD_DEFAULT_PRIORITY 0
#define BH_ROUTINE_MODIFIER
#define BHT_TIMEDOUT ETIMEDOUT
#define INVALID_THREAD_ID 0xFFffFFff
typedef int korp_sem;
typedef void* (*thread_start_routine_t)(void*);
typedef sgx_thread_mutex_t korp_mutex;
typedef sgx_thread_t korp_tid;
typedef sgx_thread_t korp_thread;
typedef sgx_thread_cond_t korp_cond;
void *os_malloc(unsigned size);
void *os_realloc(void *ptr, unsigned size);
void os_free(void *ptr);
#define bh_printf bh_printf_sgx
int snprintf(char *buffer, size_t count, const char *format, ...);
int strncasecmp(const char *s1, const char *s2, size_t n);
double fmod(double x, double y);
float fmodf(float x, float y);
double sqrt(double x);
#define BH_WAIT_FOREVER 0xFFFFFFFF
#ifndef NULL
# define NULL ((void*) 0)
#endif
/**
* Return the offset of the given field in the given type.
*
* @param Type the type containing the filed
* @param field the field in the type
*
* @return the offset of field in Type
*/
#ifndef offsetof
#define offsetof(Type, field) ((size_t)(&((Type *)0)->field))
#endif
#define bh_assert assert
int bh_platform_init();
/* MMAP mode */
enum {
MMAP_PROT_NONE = 0,
MMAP_PROT_READ = 1,
MMAP_PROT_WRITE = 2,
MMAP_PROT_EXEC = 4
};
/* MMAP flags */
enum {
MMAP_MAP_NONE = 0,
/* Put the mapping into 0 to 2 G, supported only on x86_64 */
MMAP_MAP_32BIT = 1,
/* Don't interpret addr as a hint: place the mapping at exactly
that address. */
MMAP_MAP_FIXED = 2
};
void *bh_mmap(void *hint, unsigned int size, int prot, int flags);
void bh_munmap(void *addr, uint32 size);
int bh_mprotect(void *addr, uint32 size, int prot);
#define bh_dcache_flush() (void)0
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,181 +0,0 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "bh_thread.h"
#include "bh_assert.h"
#include <stdio.h>
#include <stdlib.h>
#include <sgx_thread.h>
int _vm_thread_sys_init()
{
return 0;
}
void vm_thread_sys_destroy(void)
{
}
int _vm_thread_create_with_prio(korp_tid *tid, thread_start_routine_t start,
void *arg, unsigned int stack_size, int prio)
{
return BHT_ERROR;
// return BHT_OK;
}
int _vm_thread_create(korp_tid *tid, thread_start_routine_t start, void *arg,
unsigned int stack_size)
{
return _vm_thread_create_with_prio(tid, start, arg, stack_size,
BH_THREAD_DEFAULT_PRIORITY);
}
korp_tid _vm_self_thread()
{
return sgx_thread_self();
}
void vm_thread_exit(void * code)
{
}
// storage for one thread
static __thread void *_tls_store = NULL;
void *_vm_tls_get(unsigned idx)
{
return _tls_store;
}
int _vm_tls_put(unsigned idx, void * tls)
{
_tls_store = tls;
return BHT_OK;
//return BHT_ERROR;
}
int _vm_mutex_init(korp_mutex *mutex)
{
sgx_thread_mutex_t m = SGX_THREAD_MUTEX_INITIALIZER;
*mutex = m;
return BHT_OK;
}
int _vm_recursive_mutex_init(korp_mutex *mutex)
{
sgx_thread_mutex_t m = SGX_THREAD_RECURSIVE_MUTEX_INITIALIZER;
*mutex = m;
return BHT_OK;
}
int _vm_mutex_destroy(korp_mutex *mutex)
{
sgx_thread_mutex_destroy(mutex);
return BHT_OK;
}
/* Returned error (EINVAL, EAGAIN and EDEADLK) from
locking the mutex indicates some logic error present in
the program somewhere.
Don't try to recover error for an existing unknown error.*/
void vm_mutex_lock(korp_mutex *mutex)
{
sgx_thread_mutex_lock(mutex);
}
int vm_mutex_trylock(korp_mutex *mutex)
{
return (sgx_thread_mutex_trylock(mutex) == 0? BHT_OK: BHT_ERROR);
}
/* Returned error (EINVAL, EAGAIN and EPERM) from
unlocking the mutex indicates some logic error present
in the program somewhere.
Don't try to recover error for an existing unknown error.*/
void vm_mutex_unlock(korp_mutex *mutex)
{
sgx_thread_mutex_unlock(mutex);
}
int _vm_sem_init(korp_sem* sem, unsigned int c)
{
return BHT_OK;
//return BHT_ERROR;
}
int _vm_sem_destroy(korp_sem *sem)
{
return BHT_OK;
//return BHT_ERROR;
}
int _vm_sem_wait(korp_sem *sem)
{
return BHT_OK;
//return BHT_ERROR;
}
int _vm_sem_reltimedwait(korp_sem *sem, int mills)
{
return BHT_OK;
//return BHT_ERROR;
}
int _vm_sem_post(korp_sem *sem)
{
return BHT_OK;
//return BHT_ERROR;
}
int _vm_cond_init(korp_cond *cond)
{
return BHT_OK;
//return BHT_ERROR;
}
int _vm_cond_destroy(korp_cond *cond)
{
return BHT_OK;
//return BHT_ERROR;
}
int _vm_cond_wait(korp_cond *cond, korp_mutex *mutex)
{
return BHT_OK;
//return BHT_ERROR;
}
int _vm_cond_reltimedwait(korp_cond *cond, korp_mutex *mutex, int mills)
{
return BHT_OK;
//return BHT_ERROR;
}
int _vm_cond_signal(korp_cond *cond)
{
return BHT_OK;
//return BHT_ERROR;
}
int _vm_cond_broadcast(korp_cond *cond)
{
return BHT_OK;
//return BHT_ERROR;
}
int _vm_thread_cancel(korp_tid thread)
{
return 0;
}
int _vm_thread_join(korp_tid thread, void **value_ptr, int mills)
{
return 0;
}
int _vm_thread_detach(korp_tid thread)
{
return 0;
}

View File

@ -1,53 +0,0 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "bh_time.h"
#include <unistd.h>
#include <stdio.h>
#include <time.h>
/*
* This function returns milliseconds per tick.
* @return milliseconds per tick.
*/
uint64 _bh_time_get_tick_millisecond()
{
//TODO:
return 0;
}
/*
* This function returns milliseconds after boot.
* @return milliseconds after boot.
*/
uint64 _bh_time_get_boot_millisecond()
{
//TODO
return 0;
}
uint32 bh_get_tick_sec()
{
//TODO
return 0;
}
/*
* This function returns GMT time milliseconds since from 1970.1.1, AKA UNIX time.
* @return milliseconds since from 1970.1.1.
*/
uint64 _bh_time_get_millisecond_from_1970()
{
//TODO
return 0;
}
size_t _bh_time_strftime(char *s, size_t max, const char *format, int64 time)
{
//TODO
return 0;
}

View File

@ -0,0 +1,53 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#ifndef _PLATFORM_INTERNAL_H
#define _PLATFORM_INTERNAL_H
#include <inttypes.h>
#include <stdbool.h>
#include <assert.h>
#include <time.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <unistd.h>
#include <stdarg.h>
#include <ctype.h>
#include <limits.h>
#include <errno.h>
#include <sgx_thread.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef BH_PLATFORM_LINUX_SGX
#define BH_PLATFORM_LINUX_SGX
#endif
#define _STACK_SIZE_ADJUSTMENT (32 * 1024)
/* Stack size of applet threads's native part. */
#define BH_APPLET_PRESERVED_STACK_SIZE (8 * 1024 + _STACK_SIZE_ADJUSTMENT)
/* Default thread priority */
#define BH_THREAD_DEFAULT_PRIORITY 0
typedef sgx_thread_t korp_thread;
typedef sgx_thread_t korp_tid;
typedef sgx_thread_mutex_t korp_mutex;
typedef sgx_thread_cond_t korp_cond;
typedef void (*os_print_function_t)(const char* message);
void os_set_print_function(os_print_function_t pf);
#ifdef __cplusplus
}
#endif
#endif /* end of _PLATFORM_INTERNAL_H */

View File

@ -3,22 +3,27 @@
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "bh_common.h"
#include "bh_platform.h"
#include "platform_api_vmcore.h"
#include "platform_api_extension.h"
#include <unistd.h>
#if WASM_ENABLE_AOT != 0
#include "sgx_rsrv_mem_mngr.h"
#endif
#define FIXED_BUFFER_SIZE (1<<9)
static bh_print_function_t print_function = NULL;
static os_print_function_t print_function = NULL;
int bh_platform_init()
{
return 0;
}
void
bh_platform_destroy()
{
}
void *
os_malloc(unsigned size)
{
@ -47,12 +52,12 @@ int puts(const char *s)
return 0;
}
void bh_set_print_function(bh_print_function_t pf)
void os_set_print_function(os_print_function_t pf)
{
print_function = pf;
}
int bh_printf_sgx(const char *message, ...)
int os_printf(const char *message, ...)
{
if (print_function != NULL) {
char msg[FIXED_BUFFER_SIZE] = { '\0' };
@ -66,7 +71,7 @@ int bh_printf_sgx(const char *message, ...)
return 0;
}
int bh_vprintf_sgx(const char * format, va_list arg)
int os_vprintf(const char * format, va_list arg)
{
if (print_function != NULL) {
char msg[FIXED_BUFFER_SIZE] = { '\0' };
@ -77,7 +82,7 @@ int bh_vprintf_sgx(const char * format, va_list arg)
return 0;
}
void* bh_mmap(void *hint, unsigned int size, int prot, int flags)
void* os_mmap(void *hint, unsigned int size, int prot, int flags)
{
#if WASM_ENABLE_AOT != 0
int mprot = 0;
@ -87,7 +92,7 @@ void* bh_mmap(void *hint, unsigned int size, int prot, int flags)
ret = sgx_alloc_rsrv_mem(alignedSize);
if (ret == NULL) {
bh_printf_sgx("bh_mmap(size=%d, alignedSize=%d, prot=0x%x) failed.",size, alignedSize, prot);
os_printf_sgx("os_mmap(size=%d, alignedSize=%d, prot=0x%x) failed.",size, alignedSize, prot);
return NULL;
}
if (prot & MMAP_PROT_READ)
@ -98,7 +103,7 @@ void* bh_mmap(void *hint, unsigned int size, int prot, int flags)
mprot |= SGX_PROT_EXEC;
st = sgx_tprotect_rsrv_mem(ret, alignedSize, mprot);
if (st != SGX_SUCCESS){
bh_printf_sgx("bh_mmap(size=%d,prot=0x%x) failed to set protect.",size, prot);
os_printf_sgx("os_mmap(size=%d,prot=0x%x) failed to set protect.",size, prot);
sgx_free_rsrv_mem(ret, alignedSize);
return NULL;
}
@ -109,14 +114,14 @@ void* bh_mmap(void *hint, unsigned int size, int prot, int flags)
#endif
}
void bh_munmap(void *addr, uint32 size)
void os_munmap(void *addr, uint32 size)
{
#if WASM_ENABLE_AOT != 0
sgx_free_rsrv_mem(addr, size);
#endif
}
int bh_mprotect(void *addr, uint32 size, int prot)
int os_mprotect(void *addr, uint32 size, int prot)
{
#if WASM_ENABLE_AOT != 0
int mprot = 0;
@ -129,10 +134,16 @@ int bh_mprotect(void *addr, uint32 size, int prot)
if (prot & MMAP_PROT_EXEC)
mprot |= SGX_PROT_EXEC;
st = sgx_tprotect_rsrv_mem(addr, size, mprot);
if (st != SGX_SUCCESS) bh_printf_sgx("bh_mprotect(addr=0x%lx,size=%d,prot=0x%x) failed.", addr, size, prot);
if (st != SGX_SUCCESS) os_printf_sgx("os_mprotect(addr=0x%lx,size=%d,prot=0x%x) failed.", addr, size, prot);
return (st == SGX_SUCCESS? 0:-1);
#else
return -1;
#endif
}
void
os_dcache_flush(void)
{
}

View File

@ -0,0 +1,44 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "platform_api_vmcore.h"
#include "platform_api_extension.h"
korp_tid os_self_thread()
{
return sgx_thread_self();
}
int os_mutex_init(korp_mutex *mutex)
{
sgx_thread_mutex_t m = SGX_THREAD_MUTEX_INITIALIZER;
*mutex = m;
return BHT_OK;
}
int os_mutex_destroy(korp_mutex *mutex)
{
sgx_thread_mutex_destroy(mutex);
return BHT_OK;
}
/* Returned error (EINVAL, EAGAIN and EDEADLK) from
locking the mutex indicates some logic error present in
the program somewhere.
Don't try to recover error for an existing unknown error.*/
void os_mutex_lock(korp_mutex *mutex)
{
sgx_thread_mutex_lock(mutex);
}
/* Returned error (EINVAL, EAGAIN and EPERM) from
unlocking the mutex indicates some logic error present
in the program somewhere.
Don't try to recover error for an existing unknown error.*/
void os_mutex_unlock(korp_mutex *mutex)
{
sgx_thread_mutex_unlock(mutex);
}

View File

@ -0,0 +1,14 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "platform_api_vmcore.h"
uint64
os_time_get_boot_microsecond()
{
/* TODO */
return 0;
}

View File

@ -3,6 +3,8 @@
set (PLATFORM_SHARED_DIR ${CMAKE_CURRENT_LIST_DIR})
add_definitions(-DBH_PLATFORM_LINUX_SGX)
include_directories(${PLATFORM_SHARED_DIR})
include_directories(${PLATFORM_SHARED_DIR}/../include)

View File

@ -1,58 +0,0 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "bh_platform.h"
#include "bh_assert.h"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef BH_TEST
#include <setjmp.h>
#endif
#ifdef BH_TEST
/* for exception throwing */
jmp_buf bh_test_jb;
#endif
void bh_assert_internal(int v, const char *file_name, int line_number,
const char *expr_string)
{
if (v)
return;
if (!file_name)
file_name = "NULL FILENAME";
if (!expr_string)
expr_string = "NULL EXPR_STRING";
printf("\nASSERTION FAILED: %s, at FILE=%s, LINE=%d\n", expr_string,
file_name, line_number);
#ifdef BH_TEST
longjmp(bh_test_jb, 1);
#endif
abort();
}
void bh_debug_internal(const char *file_name, int line_number, const char *fmt,
...)
{
#ifndef JEFF_TEST_VERIFIER
va_list args;
va_start(args, fmt);
bh_assert(file_name);
printf("\nDebug info FILE=%s, LINE=%d: ", file_name, line_number);
vprintf(fmt, args);
va_end(args);
printf("\n");
#endif
}

View File

@ -1,182 +0,0 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "bh_platform.h"
#include "bh_common.h"
#include "bh_assert.h"
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
int
bh_platform_init()
{
return 0;
}
void *
os_malloc(unsigned size)
{
return malloc(size);
}
void *
os_realloc(void *ptr, unsigned size)
{
return realloc(ptr, size);
}
void
os_free(void *ptr)
{
free(ptr);
}
char*
bh_read_file_to_buffer(const char *filename, uint32 *ret_size)
{
char *buffer;
int file;
uint32 file_size, read_size;
struct stat stat_buf;
if (!filename || !ret_size) {
printf("Read file to buffer failed: invalid filename or ret size.\n");
return NULL;
}
if ((file = open(filename, O_RDONLY, 0)) == -1) {
printf("Read file to buffer failed: open file %s failed.\n",
filename);
return NULL;
}
if (fstat(file, &stat_buf) != 0) {
printf("Read file to buffer failed: fstat file %s failed.\n",
filename);
close(file);
return NULL;
}
file_size = (uint32)stat_buf.st_size;
if (!(buffer = BH_MALLOC(file_size))) {
printf("Read file to buffer failed: alloc memory failed.\n");
close(file);
return NULL;
}
read_size = (uint32)read(file, buffer, file_size);
close(file);
if (read_size < file_size) {
printf("Read file to buffer failed: read file content failed.\n");
BH_FREE(buffer);
return NULL;
}
*ret_size = file_size;
return buffer;
}
void *
bh_mmap(void *hint, uint32 size, int prot, int flags)
{
int map_prot = PROT_NONE;
int map_flags = MAP_ANONYMOUS | MAP_PRIVATE;
uint64 request_size, page_size;
uint8 *addr, *addr_aligned;
uint32 i;
/* align to 2M if no less than 2M, else align to 4K */
page_size = size < 2 * 1024 * 1024 ? 4096 : 2 * 1024 * 1024;
request_size = (size + page_size - 1) & ~(page_size - 1);
request_size += page_size;
if (request_size >= UINT32_MAX)
return NULL;
if (prot & MMAP_PROT_READ)
map_prot |= PROT_READ;
if (prot & MMAP_PROT_WRITE)
map_prot |= PROT_WRITE;
if (prot & MMAP_PROT_EXEC)
map_prot |= PROT_EXEC;
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
if (flags & MMAP_MAP_32BIT)
map_flags |= MAP_32BIT;
#endif
if (flags & MMAP_MAP_FIXED)
map_flags |= MAP_FIXED;
/* try 5 times */
for (i = 0; i < 5; i ++) {
addr = mmap(hint, size, map_prot, map_flags, -1, 0);
if (addr != MAP_FAILED)
break;
}
if (addr == MAP_FAILED)
return NULL;
addr_aligned = (uint8*)(uintptr_t)
(((uint64)(uintptr_t)addr + page_size - 1) & ~(page_size - 1));
/* Unmap memory allocated before the aligned base address */
if (addr != addr_aligned) {
uint32 prefix_size = (uint32)(addr_aligned - addr);
munmap(addr, prefix_size);
request_size -= prefix_size;
}
/* Unmap memory allocated after the potentially unaligned end */
if (size != request_size) {
uint32 suffix_size = (uint32)(request_size - size);
munmap(addr_aligned + size, suffix_size);
request_size -= size;
}
if (size >= 2 * 1024 * 1024) {
/* Try to use huge page to improve performance */
if (!madvise(addr, size, MADV_HUGEPAGE))
/* make huge page become effective */
memset(addr, 0, size);
}
return addr_aligned;
}
void
bh_munmap(void *addr, uint32 size)
{
if (addr)
munmap(addr, size);
}
int
bh_mprotect(void *addr, uint32 size, int prot)
{
int map_prot = PROT_NONE;
if (!addr)
return 0;
if (prot & MMAP_PROT_READ)
map_prot |= PROT_READ;
if (prot & MMAP_PROT_WRITE)
map_prot |= PROT_WRITE;
if (prot & MMAP_PROT_EXEC)
map_prot |= PROT_EXEC;
return mprotect(addr, size, map_prot);
}

View File

@ -1,130 +0,0 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#ifndef _BH_PLATFORM_H
#define _BH_PLATFORM_H
#include "bh_config.h"
#include "bh_types.h"
#include <inttypes.h>
#include <stdbool.h>
#include <assert.h>
#include <time.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdarg.h>
#include <ctype.h>
#include <pthread.h>
#include <semaphore.h>
#include <limits.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <netinet/in.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef uint64_t uint64;
typedef int64_t int64;
extern void DEBUGME(void);
#define DIE do{bh_debug("Die here\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); DEBUGME(void); while(1);}while(0)
#ifndef BH_PLATFORM_LINUX
#define BH_PLATFORM_LINUX
#endif
/* NEED qsort */
#define _STACK_SIZE_ADJUSTMENT (32 * 1024)
/* Stack size of applet threads's native part. */
#define BH_APPLET_PRESERVED_STACK_SIZE (8 * 1024 + _STACK_SIZE_ADJUSTMENT)
/* Default thread priority */
#define BH_THREAD_DEFAULT_PRIORITY 0
#define BH_ROUTINE_MODIFIER
#define BHT_TIMEDOUT ETIMEDOUT
#define INVALID_THREAD_ID 0xFFffFFff
typedef pthread_t korp_tid;
typedef pthread_mutex_t korp_mutex;
typedef sem_t korp_sem;
typedef pthread_cond_t korp_cond;
typedef pthread_t korp_thread;
typedef void* (*thread_start_routine_t)(void*);
void *os_malloc(unsigned size);
void *os_realloc(void *ptr, unsigned size);
void os_free(void *ptr);
#define bh_printf printf
int snprintf(char *buffer, size_t count, const char *format, ...);
double fmod(double x, double y);
float fmodf(float x, float y);
double sqrt(double x);
#define BH_WAIT_FOREVER 0xFFFFFFFF
#ifndef NULL
# define NULL ((void*) 0)
#endif
/**
* Return the offset of the given field in the given type.
*
* @param Type the type containing the filed
* @param field the field in the type
*
* @return the offset of field in Type
*/
#ifndef offsetof
#define offsetof(Type, field) ((size_t)(&((Type *)0)->field))
#endif
#define bh_assert assert
char *bh_read_file_to_buffer(const char *filename, uint32 *ret_size);
int bh_platform_init();
/* MMAP mode */
enum {
MMAP_PROT_NONE = 0,
MMAP_PROT_READ = 1,
MMAP_PROT_WRITE = 2,
MMAP_PROT_EXEC = 4
};
/* MMAP flags */
enum {
MMAP_MAP_NONE = 0,
/* Put the mapping into 0 to 2 G, supported only on x86_64 */
MMAP_MAP_32BIT = 1,
/* Don't interpret addr as a hint: place the mapping at exactly
that address. */
MMAP_MAP_FIXED = 2
};
void *bh_mmap(void *hint, unsigned int size, int prot, int flags);
void bh_munmap(void *addr, uint32 size);
int bh_mprotect(void *addr, uint32 size, int prot);
#define bh_dcache_flush() (void)0
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,30 +0,0 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "bh_platform.h"
#include <stdio.h>
void bh_log_emit(const char *fmt, va_list ap)
{
vprintf(fmt, ap);
fflush(stdout);
}
int bh_fprintf(FILE *stream, const char *fmt, ...)
{
va_list ap;
int ret;
va_start(ap, fmt);
ret = vfprintf(stream ? stream : stdout, fmt, ap);
va_end(ap);
return ret;
}
int bh_fflush(void *stream)
{
return fflush(stream ? stream : stdout);
}

View File

@ -1,392 +0,0 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "bh_thread.h"
#include "bh_assert.h"
#include "bh_log.h"
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
static bool is_thread_sys_inited = false;
static korp_mutex thread_list_lock;
static pthread_key_t thread_local_storage_key[BH_MAX_TLS_NUM];
int _vm_thread_sys_init()
{
unsigned i, j;
int ret;
if (is_thread_sys_inited)
return 0;
for (i = 0; i < BH_MAX_TLS_NUM; i++) {
ret = pthread_key_create(&thread_local_storage_key[i], NULL);
if (ret)
goto fail;
}
ret = vm_mutex_init(&thread_list_lock);
if (ret)
goto fail;
is_thread_sys_inited = true;
return 0;
fail: for (j = 0; j < i; j++)
pthread_key_delete(thread_local_storage_key[j]);
return -1;
}
void vm_thread_sys_destroy(void)
{
if (is_thread_sys_inited) {
unsigned i;
for (i = 0; i < BH_MAX_TLS_NUM; i++)
pthread_key_delete(thread_local_storage_key[i]);
vm_mutex_destroy(&thread_list_lock);
is_thread_sys_inited = false;
}
}
typedef struct {
thread_start_routine_t start;
void* stack;
uint32 stack_size;
void* arg;
} thread_wrapper_arg;
static void *vm_thread_wrapper(void *arg)
{
thread_wrapper_arg * targ = arg;
LOG_VERBOSE("THREAD CREATE 0x%08x\n", &targ);
targ->stack = (void *)((uintptr_t)(&arg) & (uintptr_t)~0xfff);
_vm_tls_put(1, targ);
targ->start(targ->arg);
BH_FREE(targ);
_vm_tls_put(1, NULL);
return NULL;
}
int _vm_thread_create_with_prio(korp_tid *tid, thread_start_routine_t start,
void *arg, unsigned int stack_size, int prio)
{
pthread_attr_t tattr;
thread_wrapper_arg *targ;
bh_assert(stack_size > 0);
bh_assert(tid);
bh_assert(start);
*tid = INVALID_THREAD_ID;
pthread_attr_init(&tattr);
pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_JOINABLE);
if (pthread_attr_setstacksize(&tattr, stack_size) != 0) {
bh_debug("Invalid thread stack size %u. Min stack size on Linux = %u",
stack_size, PTHREAD_STACK_MIN);
pthread_attr_destroy(&tattr);
return BHT_ERROR;
}
targ = (thread_wrapper_arg*) BH_MALLOC(sizeof(*targ));
if (!targ) {
pthread_attr_destroy(&tattr);
return BHT_ERROR;
}
targ->start = start;
targ->arg = arg;
targ->stack_size = stack_size;
if (pthread_create(tid, &tattr, vm_thread_wrapper, targ) != 0) {
pthread_attr_destroy(&tattr);
BH_FREE(targ);
return BHT_ERROR;
}
pthread_attr_destroy(&tattr);
return BHT_OK;
}
int _vm_thread_create(korp_tid *tid, thread_start_routine_t start, void *arg,
unsigned int stack_size)
{
return _vm_thread_create_with_prio(tid, start, arg, stack_size,
BH_THREAD_DEFAULT_PRIORITY);
}
korp_tid _vm_self_thread()
{
return (korp_tid) pthread_self();
}
void vm_thread_exit(void * code)
{
BH_FREE(_vm_tls_get(1));
_vm_tls_put(1, NULL);
pthread_exit(code);
}
void *_vm_tls_get(unsigned idx)
{
bh_assert(idx < BH_MAX_TLS_NUM);
return pthread_getspecific(thread_local_storage_key[idx]);
}
int _vm_tls_put(unsigned idx, void * tls)
{
bh_assert(idx < BH_MAX_TLS_NUM);
pthread_setspecific(thread_local_storage_key[idx], tls);
return BHT_OK;
}
int _vm_mutex_init(korp_mutex *mutex)
{
return pthread_mutex_init(mutex, NULL) == 0 ? BHT_OK : BHT_ERROR;
}
int _vm_recursive_mutex_init(korp_mutex *mutex)
{
int ret;
pthread_mutexattr_t mattr;
bh_assert(mutex);
ret = pthread_mutexattr_init(&mattr);
if (ret)
return BHT_ERROR;
pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_RECURSIVE_NP);
ret = pthread_mutex_init(mutex, &mattr);
pthread_mutexattr_destroy(&mattr);
return ret == 0 ? BHT_OK : BHT_ERROR;
}
int _vm_mutex_destroy(korp_mutex *mutex)
{
int ret;
bh_assert(mutex);
ret = pthread_mutex_destroy(mutex);
return ret == 0 ? BHT_OK : BHT_ERROR;
}
/* Returned error (EINVAL, EAGAIN and EDEADLK) from
locking the mutex indicates some logic error present in
the program somewhere.
Don't try to recover error for an existing unknown error.*/
void vm_mutex_lock(korp_mutex *mutex)
{
int ret;
bh_assert(mutex);
ret = pthread_mutex_lock(mutex);
if (0 != ret) {
printf("vm mutex lock failed (ret=%d)!\n", ret);
exit(-1);
}
}
int vm_mutex_trylock(korp_mutex *mutex)
{
int ret;
bh_assert(mutex);
ret = pthread_mutex_trylock(mutex);
return ret == 0 ? BHT_OK : BHT_ERROR;
}
/* Returned error (EINVAL, EAGAIN and EPERM) from
unlocking the mutex indicates some logic error present
in the program somewhere.
Don't try to recover error for an existing unknown error.*/
void vm_mutex_unlock(korp_mutex *mutex)
{
int ret;
bh_assert(mutex);
ret = pthread_mutex_unlock(mutex);
if (0 != ret) {
printf("vm mutex unlock failed (ret=%d)!\n", ret);
exit(-1);
}
}
int _vm_sem_init(korp_sem* sem, unsigned int c)
{
int ret;
bh_assert(sem);
ret = sem_init(sem, 0, c);
return ret == 0 ? BHT_OK : BHT_ERROR;
}
int _vm_sem_destroy(korp_sem *sem)
{
int ret;
bh_assert(sem);
ret = sem_destroy(sem);
return ret == 0 ? BHT_OK : BHT_ERROR;
}
int _vm_sem_wait(korp_sem *sem)
{
int ret;
bh_assert(sem);
ret = sem_wait(sem);
return ret == 0 ? BHT_OK : BHT_ERROR;
}
int _vm_sem_reltimedwait(korp_sem *sem, int mills)
{
int ret = BHT_OK;
struct timespec timeout;
const int mills_per_sec = 1000;
const int mills_to_nsec = 1E6;
bh_assert(sem);
if (mills == (int)BHT_WAIT_FOREVER) {
ret = sem_wait(sem);
} else {
timeout.tv_sec = mills / mills_per_sec;
timeout.tv_nsec = (mills % mills_per_sec) * mills_to_nsec;
timeout.tv_sec += time(NULL);
ret = sem_timedwait(sem, &timeout);
}
if (ret != BHT_OK) {
if (errno == BHT_TIMEDOUT) {
ret = BHT_TIMEDOUT;
errno = 0;
} else {
bh_debug("Faliure happens when timed wait is called");
bh_assert(0);
}
}
return ret;
}
int _vm_sem_post(korp_sem *sem)
{
bh_assert(sem);
return sem_post(sem) == 0 ? BHT_OK : BHT_ERROR;
}
int _vm_cond_init(korp_cond *cond)
{
bh_assert(cond);
if (pthread_cond_init(cond, NULL) != BHT_OK)
return BHT_ERROR;
return BHT_OK;
}
int _vm_cond_destroy(korp_cond *cond)
{
bh_assert(cond);
if (pthread_cond_destroy(cond) != BHT_OK)
return BHT_ERROR;
return BHT_OK;
}
int _vm_cond_wait(korp_cond *cond, korp_mutex *mutex)
{
bh_assert(cond);
bh_assert(mutex);
if (pthread_cond_wait(cond, mutex) != BHT_OK)
return BHT_ERROR;
return BHT_OK;
}
static void msec_nsec_to_abstime(struct timespec *ts, int64 msec, int32 nsec)
{
struct timeval tv;
gettimeofday(&tv, NULL);
ts->tv_sec = (long int)(tv.tv_sec + msec / 1000);
ts->tv_nsec = (long int)(tv.tv_usec * 1000 + (msec % 1000) * 1000000 + nsec);
if (ts->tv_nsec >= 1000000000L) {
ts->tv_sec++;
ts->tv_nsec -= 1000000000L;
}
}
int _vm_cond_reltimedwait(korp_cond *cond, korp_mutex *mutex, int mills)
{
int ret;
struct timespec abstime;
if (mills == (int)BHT_WAIT_FOREVER)
ret = pthread_cond_wait(cond, mutex);
else {
msec_nsec_to_abstime(&abstime, mills, 0);
ret = pthread_cond_timedwait(cond, mutex, &abstime);
}
if (ret != BHT_OK && ret != BHT_TIMEDOUT)
return BHT_ERROR;
return BHT_OK;
}
int _vm_cond_signal(korp_cond *cond)
{
bh_assert(cond);
if (pthread_cond_signal(cond) != BHT_OK)
return BHT_ERROR;
return BHT_OK;
}
int _vm_cond_broadcast(korp_cond *cond)
{
bh_assert(cond);
if (pthread_cond_broadcast(cond) != BHT_OK)
return BHT_ERROR;
return BHT_OK;
}
int _vm_thread_cancel(korp_tid thread)
{
return pthread_cancel(thread);
}
int _vm_thread_join(korp_tid thread, void **value_ptr, int mills)
{
return pthread_join(thread, value_ptr);
}
int _vm_thread_detach(korp_tid thread)
{
return pthread_detach(thread);
}

View File

@ -1,70 +0,0 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "bh_time.h"
#include <unistd.h>
#include <stdio.h>
#include <sys/timeb.h>
#include <time.h>
/*
* This function returns milliseconds per tick.
* @return milliseconds per tick.
*/
uint64 _bh_time_get_tick_millisecond()
{
return (uint64)sysconf(_SC_CLK_TCK);
}
/*
* This function returns milliseconds after boot.
* @return milliseconds after boot.
*/
uint64 _bh_time_get_boot_millisecond()
{
struct timespec ts;
if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {
return 0;
}
return ((uint64) ts.tv_sec) * 1000 + ((uint64)ts.tv_nsec) / (1000 * 1000);
}
uint32 bh_get_tick_sec()
{
return (uint32)(_bh_time_get_boot_millisecond() / 1000);
}
/*
* This function returns GMT time milliseconds since from 1970.1.1, AKA UNIX time.
* @return milliseconds since from 1970.1.1.
*/
uint64 _bh_time_get_millisecond_from_1970()
{
struct timeb tp;
ftime(&tp);
return ((uint64) tp.time) * 1000 + tp.millitm
- (tp.dstflag == 0 ? 0 : 60 * 60 * 1000)
+ ((uint64)tp.timezone) * 60 * 1000;
}
size_t _bh_time_strftime(char *s, size_t max, const char *format, int64 time)
{
time_t time_sec = (time_t)(time / 1000);
struct timeb tp;
struct tm *ltp;
ftime(&tp);
time_sec -= tp.timezone * 60;
ltp = localtime(&time_sec);
if (ltp == NULL) {
return 0;
}
return strftime(s, max, format, ltp);
}

View File

@ -0,0 +1,18 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "platform_api_vmcore.h"
int
bh_platform_init()
{
return 0;
}
void
bh_platform_destroy()
{
}

View File

@ -0,0 +1,61 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#ifndef _PLATFORM_INTERNAL_H
#define _PLATFORM_INTERNAL_H
#include <inttypes.h>
#include <stdbool.h>
#include <assert.h>
#include <time.h>
#include <sys/time.h>
#include <sys/timeb.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdarg.h>
#include <ctype.h>
#include <pthread.h>
#include <semaphore.h>
#include <limits.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <netinet/in.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef BH_PLATFORM_LINUX
#define BH_PLATFORM_LINUX
#endif
#define _STACK_SIZE_ADJUSTMENT (32 * 1024)
/* Stack size of applet threads's native part. */
#define BH_APPLET_PRESERVED_STACK_SIZE (8 * 1024 + _STACK_SIZE_ADJUSTMENT)
/* Default thread priority */
#define BH_THREAD_DEFAULT_PRIORITY 0
typedef pthread_t korp_tid;
typedef pthread_mutex_t korp_mutex;
typedef pthread_cond_t korp_cond;
typedef pthread_t korp_thread;
#define os_printf printf
#define os_vprintf vprintf
#ifdef __cplusplus
}
#endif
#endif /* end of _PLATFORM_INTERNAL_H */

Some files were not shown because too many files have changed in this diff Show More