mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-05-09 21:26:21 +00:00

* Implement memory profiler, optimize memory usage, modify code indent * Implement memory.grow and limit heap space base offset to 1G; modify iwasm build type to Release and 64 bit by default * Add a new extension library: connection * Fix bug of reading magic number and version in big endian platform * Re-org platform APIs: move most platform APIs from iwasm to shared-lib * Enhance wasm loader to fix some security issues * Fix issue about illegal load of EXC_RETURN into PC on stm32 board * Updates that let a restricted version of the interpreter run in SGX * Enable native/app address validation and conversion for wasm app * Remove wasm_application_exectue_* APIs from wasm_export.h which makes confused * Refine binary size and fix several minor issues Optimize interpreter LOAD/STORE opcodes to decrease the binary size Fix issues when using iwasm library: _bh_log undefined, bh_memory.h not found Remove unused _stdin/_stdout/_stderr global variables resolve in libc wrapper Add macros of global heap size, stack size, heap size for Zephyr main.c Clear compile warning of wasm_application.c * Add more strict security checks for libc wrapper API's * Use one libc wrapper copy for sgx and other platforms; remove bh_printf macro for other platform header files * Enhance security of libc strcpy/sprintf wrapper function * Fix issue of call native for x86_64/arm/mips, add module inst parameter for native wrapper functions * Remove get_module_inst() and fix issue of call native * Refine wgl lib: remove module_inst parameter from widget functions; move function index check to runtime instantiate * Refine interpreter call native process, refine memory boudary check * Fix issues of invokeNative function of arm/mips/general version * Add a switch to build simple sample without gui support * Add BUILD_TARGET setting in makefile to replace cpu compiler flags in source code * Re-org shared lib header files, remove unused info; fix compile issues of vxworks * Add build target general * Remove unused files * Update license header * test push * Restore file * Sync up with internal/feature * Sync up with internal/feature * Rename build_wamr_app to build_wasm_app * Fix small issues of README * Enhance malformed wasm file checking Fix issue of print hex int and implement utf8 string check Fix wasi file read/write right issue Fix minor issue of build wasm app doc * Sync up with internal/feature * Sync up with internal/feature: fix interpreter arm issue, fix read leb issue * Sync up with internal/feature * Fix bug of config.h and rename wasi config.h to ssp_config.h * Sync up with internal/feature * Import wamr aot * update document * update document * Update document, disable WASI in 32bit * update document * remove files * update document * Update document * update document * update document * update samples * Sync up with internal repo
249 lines
5.4 KiB
C
249 lines
5.4 KiB
C
/*
|
|
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
*/
|
|
|
|
#include "bh_queue.h"
|
|
#include "bh_thread.h"
|
|
#include "bh_memory.h"
|
|
#include "bh_time.h"
|
|
#include "bh_common.h"
|
|
|
|
typedef struct _bh_queue_node {
|
|
struct _bh_queue_node * next;
|
|
struct _bh_queue_node * prev;
|
|
unsigned short tag;
|
|
unsigned int len;
|
|
void * body;
|
|
bh_msg_cleaner msg_cleaner;
|
|
} bh_queue_node;
|
|
|
|
struct bh_queue {
|
|
bh_queue_mutex queue_lock;
|
|
bh_queue_cond queue_wait_cond;
|
|
unsigned int cnt;
|
|
unsigned int max;
|
|
unsigned int drops;
|
|
bh_queue_node * head;
|
|
bh_queue_node * tail;
|
|
|
|
bool exit_loop_run;
|
|
};
|
|
|
|
char * bh_message_payload(bh_message_t message)
|
|
{
|
|
return message->body;
|
|
}
|
|
|
|
uint32 bh_message_payload_len(bh_message_t message)
|
|
{
|
|
return message->len;
|
|
}
|
|
|
|
int bh_message_type(bh_message_t message)
|
|
{
|
|
return message->tag;
|
|
}
|
|
|
|
bh_queue *
|
|
bh_queue_create()
|
|
{
|
|
int ret;
|
|
bh_queue *queue = bh_queue_malloc(sizeof(bh_queue));
|
|
|
|
if (queue) {
|
|
memset(queue, 0, sizeof(bh_queue));
|
|
queue->max = DEFAULT_QUEUE_LENGTH;
|
|
|
|
ret = bh_queue_mutex_init(&queue->queue_lock);
|
|
if (ret != 0) {
|
|
bh_queue_free(queue);
|
|
return NULL;
|
|
}
|
|
|
|
ret = bh_queue_cond_init(&queue->queue_wait_cond);
|
|
if (ret != 0) {
|
|
bh_queue_mutex_destroy(&queue->queue_lock);
|
|
bh_queue_free(queue);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
return queue;
|
|
}
|
|
|
|
void bh_queue_destroy(bh_queue *queue)
|
|
{
|
|
bh_queue_node *node;
|
|
|
|
if (!queue)
|
|
return;
|
|
|
|
bh_queue_mutex_lock(&queue->queue_lock);
|
|
while (queue->head) {
|
|
node = queue->head;
|
|
queue->head = node->next;
|
|
|
|
bh_free_msg(node);
|
|
}
|
|
bh_queue_mutex_unlock(&queue->queue_lock);
|
|
|
|
bh_queue_cond_destroy(&queue->queue_wait_cond);
|
|
bh_queue_mutex_destroy(&queue->queue_lock);
|
|
bh_queue_free(queue);
|
|
}
|
|
|
|
bool bh_post_msg2(bh_queue *queue, bh_queue_node *msg)
|
|
{
|
|
if (queue->cnt >= queue->max) {
|
|
queue->drops++;
|
|
bh_free_msg(msg);
|
|
return false;
|
|
}
|
|
|
|
bh_queue_mutex_lock(&queue->queue_lock);
|
|
|
|
if (queue->cnt == 0) {
|
|
bh_assert(queue->head == NULL);
|
|
bh_assert(queue->tail == NULL);
|
|
queue->head = queue->tail = msg;
|
|
msg->next = msg->prev = NULL;
|
|
queue->cnt = 1;
|
|
|
|
bh_queue_cond_signal(&queue->queue_wait_cond);
|
|
} else {
|
|
msg->next = NULL;
|
|
msg->prev = queue->tail;
|
|
queue->tail->next = msg;
|
|
queue->tail = msg;
|
|
queue->cnt++;
|
|
}
|
|
|
|
bh_queue_mutex_unlock(&queue->queue_lock);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool bh_post_msg(bh_queue *queue, unsigned short tag, void *body,
|
|
unsigned int len)
|
|
{
|
|
bh_queue_node *msg = bh_new_msg(tag, body, len, NULL);
|
|
if (msg == NULL) {
|
|
queue->drops++;
|
|
if (len != 0 && body)
|
|
bh_free(body);
|
|
return false;
|
|
}
|
|
|
|
if (!bh_post_msg2(queue, msg)) {
|
|
// bh_post_msg2 already freed the msg for failure
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bh_queue_node * bh_new_msg(unsigned short tag, void *body, unsigned int len,
|
|
void * handler)
|
|
{
|
|
bh_queue_node *msg = (bh_queue_node*) bh_queue_malloc(
|
|
sizeof(bh_queue_node));
|
|
if (msg == NULL)
|
|
return NULL;
|
|
memset(msg, 0, sizeof(bh_queue_node));
|
|
msg->len = len;
|
|
msg->body = body;
|
|
msg->tag = tag;
|
|
msg->msg_cleaner = (bh_msg_cleaner) handler;
|
|
|
|
return msg;
|
|
}
|
|
|
|
void bh_free_msg(bh_queue_node *msg)
|
|
{
|
|
if (msg->msg_cleaner) {
|
|
msg->msg_cleaner(msg->body);
|
|
bh_queue_free(msg);
|
|
return;
|
|
}
|
|
|
|
// note: sometime we just use the payload pointer for a integer value
|
|
// len!=0 is the only indicator about the body is an allocated buffer.
|
|
if (msg->body && msg->len)
|
|
bh_queue_free(msg->body);
|
|
|
|
bh_queue_free(msg);
|
|
}
|
|
|
|
bh_message_t bh_get_msg(bh_queue *queue, int timeout)
|
|
{
|
|
bh_queue_node *msg = NULL;
|
|
bh_queue_mutex_lock(&queue->queue_lock);
|
|
|
|
if (queue->cnt == 0) {
|
|
bh_assert(queue->head == NULL);
|
|
bh_assert(queue->tail == NULL);
|
|
|
|
if (timeout == 0) {
|
|
bh_queue_mutex_unlock(&queue->queue_lock);
|
|
return NULL;
|
|
}
|
|
|
|
bh_queue_cond_timedwait(&queue->queue_wait_cond, &queue->queue_lock,
|
|
timeout);
|
|
}
|
|
|
|
if (queue->cnt == 0) {
|
|
bh_assert(queue->head == NULL);
|
|
bh_assert(queue->tail == NULL);
|
|
} else if (queue->cnt == 1) {
|
|
bh_assert(queue->head == queue->tail);
|
|
|
|
msg = queue->head;
|
|
queue->head = queue->tail = NULL;
|
|
queue->cnt = 0;
|
|
} else {
|
|
msg = queue->head;
|
|
queue->head = queue->head->next;
|
|
queue->head->prev = NULL;
|
|
queue->cnt--;
|
|
}
|
|
|
|
bh_queue_mutex_unlock(&queue->queue_lock);
|
|
|
|
return msg;
|
|
}
|
|
|
|
unsigned bh_queue_get_message_count(bh_queue *queue)
|
|
{
|
|
if (!queue)
|
|
return 0;
|
|
|
|
return queue->cnt;
|
|
}
|
|
|
|
void bh_queue_enter_loop_run(bh_queue *queue,
|
|
bh_queue_handle_msg_callback handle_cb,
|
|
void *arg)
|
|
{
|
|
if (!queue)
|
|
return;
|
|
|
|
while (!queue->exit_loop_run) {
|
|
bh_queue_node * message = bh_get_msg(queue, (int)BH_WAIT_FOREVER);
|
|
|
|
if (message) {
|
|
handle_cb(message, arg);
|
|
bh_free_msg(message);
|
|
}
|
|
}
|
|
}
|
|
|
|
void bh_queue_exit_loop_run(bh_queue *queue)
|
|
{
|
|
if (queue) {
|
|
queue->exit_loop_run = true;
|
|
bh_queue_cond_signal(&queue->queue_wait_cond);
|
|
}
|
|
}
|