wasm-micro-runtime/core/shared/utils/bh_queue.c
wenyongh 46b93b9d22 Enable AoT and wamr-sdk, and change arguments of call wasm API (#157)
* 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
2020-01-21 13:26:14 +08:00

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