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
177 changed files with 2954 additions and 7904 deletions

View File

@ -1,10 +0,0 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
include_directories (. ../include ../platform/include ../platform/${WAMR_BUILD_PLATFORM} coap/er-coap coap/extension)
file (GLOB_RECURSE source_all *.c )
add_library (vmutilslib ${source_all})

View File

@ -1,5 +0,0 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
obj-y += bh_list.o bh_log.o attr-container.o bh_queue.o
obj-y += coap/

View File

@ -0,0 +1,31 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "bh_assert.h"
void bh_assert_internal(int v, const char *file_name, int line_number,
const char *expr_string)
{
int i;
if (v)
return;
if (!file_name)
file_name = "NULL FILENAME";
if (!expr_string)
expr_string = "NULL EXPR_STRING";
os_printf("\nASSERTION FAILED: %s, at file %s, line %d\n",
expr_string, file_name, line_number);
i = os_printf(" ");
/* divived by 0 to make it abort */
os_printf("%d\n", i / (i - 1));
while (1);
}

View File

@ -0,0 +1,29 @@
/*
* 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_platform.h"
#ifdef __cplusplus
extern "C" {
#endif
#if BH_DEBUG != 0
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)(uintptr_t)(expr), \
__FILE__, __LINE__, #expr)
#else
#define bh_assert(expr) (void)0
#endif /* end of BH_DEBUG */
#ifdef __cplusplus
}
#endif
#endif /* end of _BH_ASSERT_H */

View File

@ -3,7 +3,6 @@
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "bh_platform.h"
#include "bh_common.h"
#ifdef RSIZE_MAX
@ -34,7 +33,7 @@ b_memcpy_s(void * s1, unsigned int s1max,
}
int
b_strcat_s(char * s1, size_t s1max, const char * s2)
b_strcat_s(char * s1, unsigned int s1max, const char * s2)
{
if (NULL == s1 || NULL == s2
|| s1max < (strlen(s1) + strlen(s2) + 1)
@ -47,7 +46,7 @@ b_strcat_s(char * s1, size_t s1max, const char * s2)
}
int
b_strcpy_s(char * s1, size_t s1max, const char * s2)
b_strcpy_s(char * s1, unsigned int s1max, const char * s2)
{
if (NULL == s1 || NULL == s2
|| s1max < (strlen(s2) + 1)

View File

@ -0,0 +1,47 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#ifndef _BH_COMMON_H
#define _BH_COMMON_H
#include "bh_platform.h"
#ifdef __cplusplus
extern "C" {
#endif
#define bh_memcpy_s(dest, dlen, src, slen) do { \
int _ret = slen == 0 ? 0 : b_memcpy_s (dest, dlen, src, slen); \
(void)_ret; \
bh_assert (_ret == 0); \
} while (0)
#define bh_strcat_s(dest, dlen, src) do { \
int _ret = b_strcat_s (dest, dlen, src); \
(void)_ret; \
bh_assert (_ret == 0); \
} while (0)
#define bh_strcpy_s(dest, dlen, src) do { \
int _ret = b_strcpy_s (dest, dlen, src); \
(void)_ret; \
bh_assert (_ret == 0); \
} while (0)
int b_memcpy_s(void * s1, unsigned int s1max, const void * s2, unsigned int n);
int b_strcat_s(char * s1, unsigned int s1max, const char * s2);
int b_strcpy_s(char * s1, unsigned int s1max, const char * s2);
/* strdup with string allocated by BH_MALLOC */
char *bh_strdup(const char *s);
/* strdup with string allocated by WA_MALLOC */
char *wa_strdup(const char *s);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -4,9 +4,6 @@
*/
#include "bh_hashmap.h"
#include "bh_log.h"
#include "bh_thread.h"
typedef struct HashMapElem {
void *key;
@ -65,7 +62,7 @@ bh_hash_map_create(uint32 size, bool use_lock,
map->lock = (korp_mutex*)
((uint8*)map + offsetof(HashMap, elements)
+ sizeof(HashMapElem) * size);
if (vm_mutex_init(map->lock)) {
if (os_mutex_init(map->lock)) {
LOG_ERROR("HashMap create failed: init map lock failed.\n");
BH_FREE(map);
return NULL;
@ -92,7 +89,7 @@ bh_hash_map_insert(HashMap *map, void *key, void *value)
}
if (map->lock) {
vm_mutex_lock(map->lock);
os_mutex_lock(map->lock);
}
index = map->hash_func(key) % map->size;
@ -116,13 +113,13 @@ bh_hash_map_insert(HashMap *map, void *key, void *value)
map->elements[index] = elem;
if (map->lock) {
vm_mutex_unlock(map->lock);
os_mutex_unlock(map->lock);
}
return true;
fail:
if (map->lock) {
vm_mutex_unlock(map->lock);
os_mutex_unlock(map->lock);
}
return false;
}
@ -140,7 +137,7 @@ bh_hash_map_find(HashMap *map, void *key)
}
if (map->lock) {
vm_mutex_lock(map->lock);
os_mutex_lock(map->lock);
}
index = map->hash_func(key) % map->size;
@ -150,7 +147,7 @@ bh_hash_map_find(HashMap *map, void *key)
if (map->key_equal_func(elem->key, key)) {
value = elem->value;
if (map->lock) {
vm_mutex_unlock(map->lock);
os_mutex_unlock(map->lock);
}
return value;
}
@ -158,7 +155,7 @@ bh_hash_map_find(HashMap *map, void *key)
}
if (map->lock) {
vm_mutex_unlock(map->lock);
os_mutex_unlock(map->lock);
}
return NULL;
}
@ -176,7 +173,7 @@ bh_hash_map_update(HashMap *map, void *key, void *value,
}
if (map->lock) {
vm_mutex_lock(map->lock);
os_mutex_lock(map->lock);
}
index = map->hash_func(key) % map->size;
@ -188,7 +185,7 @@ bh_hash_map_update(HashMap *map, void *key, void *value,
*p_old_value = elem->value;
elem->value = value;
if (map->lock) {
vm_mutex_unlock(map->lock);
os_mutex_unlock(map->lock);
}
return true;
}
@ -196,7 +193,7 @@ bh_hash_map_update(HashMap *map, void *key, void *value,
}
if (map->lock) {
vm_mutex_unlock(map->lock);
os_mutex_unlock(map->lock);
}
return false;
}
@ -214,7 +211,7 @@ bh_hash_map_remove(HashMap *map, void *key,
}
if (map->lock) {
vm_mutex_lock(map->lock);
os_mutex_lock(map->lock);
}
index = map->hash_func(key) % map->size;
@ -235,7 +232,7 @@ bh_hash_map_remove(HashMap *map, void *key,
BH_FREE(elem);
if (map->lock) {
vm_mutex_unlock(map->lock);
os_mutex_unlock(map->lock);
}
return true;
}
@ -245,7 +242,7 @@ bh_hash_map_remove(HashMap *map, void *key,
}
if (map->lock) {
vm_mutex_unlock(map->lock);
os_mutex_unlock(map->lock);
}
return false;
}
@ -262,7 +259,7 @@ bh_hash_map_destroy(HashMap *map)
}
if (map->lock) {
vm_mutex_lock(map->lock);
os_mutex_lock(map->lock);
}
for (index = 0; index < map->size; index++) {
@ -283,8 +280,8 @@ bh_hash_map_destroy(HashMap *map)
}
if (map->lock) {
vm_mutex_unlock(map->lock);
vm_mutex_destroy(map->lock);
os_mutex_unlock(map->lock);
os_mutex_destroy(map->lock);
}
BH_FREE(map);
return true;

View File

@ -0,0 +1,132 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#ifndef WASM_HASHMAP_H
#define WASM_HASHMAP_H
#include "bh_platform.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Maximum initial size of hash map */
#define HASH_MAP_MAX_SIZE 65536
struct HashMap;
typedef struct HashMap HashMap;
/* Hash function: to get the hash value of key. */
typedef uint32 (*HashFunc)(const void *key);
/* Key equal function: to check whether two keys are equal. */
typedef bool (*KeyEqualFunc)(void *key1, void *key2);
/* Key destroy function: to destroy the key, auto called
when an hash element is removed. */
typedef void (*KeyDestroyFunc)(void *key);
/* Value destroy function: to destroy the value, auto called
when an hash element is removed. */
typedef void (*ValueDestroyFunc)(void *key);
/**
* Create a hash map.
*
* @param size: the initial size of the hash map
* @param use_lock whether to lock the hash map when operating on it
* @param hash_func hash function of the key, must be specified
* @param key_equal_func key equal function, check whether two keys
* are equal, must be specified
* @param key_destroy_func key destroy function, called when an hash element
* is removed if it is not NULL
* @param value_destroy_func value destroy function, called when an hash
* element is removed if it is not NULL
*
* @return the hash map created, NULL if failed
*/
HashMap*
bh_hash_map_create(uint32 size, bool use_lock,
HashFunc hash_func,
KeyEqualFunc key_equal_func,
KeyDestroyFunc key_destroy_func,
ValueDestroyFunc value_destroy_func);
/**
* Insert an element to the hash map
*
* @param map the hash map to insert element
* @key the key of the element
* @value the value of the element
*
* @return true if success, false otherwise
* Note: fail if key is NULL or duplicated key exists in the hash map,
*/
bool
bh_hash_map_insert(HashMap *map, void *key, void *value);
/**
* Find an element in the hash map
*
* @param map the hash map to find element
* @key the key of the element
*
* @return the value of the found element if success, NULL otherwise
*/
void*
bh_hash_map_find(HashMap *map, void *key);
/**
* Update an element in the hash map with new value
*
* @param map the hash map to update element
* @key the key of the element
* @value the new value of the element
* @p_old_value if not NULL, copies the old value to it
*
* @return true if success, false otherwise
* Note: the old value won't be destroyed by value destroy function,
* it will be copied to p_old_value for user to process.
*/
bool
bh_hash_map_update(HashMap *map, void *key, void *value,
void **p_old_value);
/**
* Remove an element from the hash map
*
* @param map the hash map to remove element
* @key the key of the element
* @p_old_key if not NULL, copies the old key to it
* @p_old_value if not NULL, copies the old value to it
*
* @return true if success, false otherwise
* Note: the old key and old value won't be destroyed by key destroy
* function and value destroy function, they will be copied to
* p_old_key and p_old_value for user to process.
*/
bool
bh_hash_map_remove(HashMap *map, void *key,
void **p_old_key, void **p_old_value);
/**
* Destroy the hashmap
*
* @param map the hash map to destroy
*
* @return true if success, false otherwise
* Note: the key destroy function and value destroy function will be
* called to destroy each element's key and value if they are
* not NULL.
*/
bool
bh_hash_map_destroy(HashMap *map);
#ifdef __cplusplus
}
#endif
#endif /* endof WASM_HASHMAP_H */

View File

@ -4,9 +4,8 @@
*/
#include "bh_list.h"
#include "bh_assert.h"
#ifdef BH_DEBUG
#if BH_DEBUG != 0
/**
* Test whehter a pointer value has exist in given list.
*
@ -15,7 +14,7 @@
* @return <code>true</code> if the pointer has been in the list;
* <code>false</code> otherwise.
*/
BH_STATIC bool bh_list_is_elem_exist(bh_list *list, void *elem);
static bool bh_list_is_elem_exist(bh_list *list, void *elem);
#endif
bh_list_status bh_list_init(bh_list *list)
@ -28,13 +27,13 @@ bh_list_status bh_list_init(bh_list *list)
return BH_LIST_SUCCESS;
}
bh_list_status _bh_list_insert(bh_list *list, void *elem)
bh_list_status bh_list_insert(bh_list *list, void *elem)
{
bh_list_link *p = NULL;
if (!list || !elem)
return BH_LIST_ERROR;
#ifdef BH_DEBUG
#if BH_DEBUG != 0
bh_assert (!bh_list_is_elem_exist(list, elem));
#endif
p = (bh_list_link *) elem;
@ -87,8 +86,8 @@ void* bh_list_elem_next(void *node)
return (node ? ((bh_list_link *) node)->next : NULL);
}
#ifdef BH_DEBUG
BH_STATIC bool bh_list_is_elem_exist(bh_list *list, void *elem)
#if BH_DEBUG != 0
static bool bh_list_is_elem_exist(bh_list *list, void *elem)
{
bh_list_link *p = NULL;

102
core/shared/utils/bh_list.h Normal file
View File

@ -0,0 +1,102 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#ifndef _BH_LIST_H
#define _BH_LIST_H
#ifdef __cplusplus
extern "C" {
#endif
#include "bh_platform.h"
/* List user should embedded bh_list_link into list elem data structure
* definition. And bh_list_link data field should be the first field.
* For example, if we would like to use bh_list for our own data type A,
* A must be defined as a structure like below:
* struct A {
* bh_list_link l;
* ...
* };
*
* bh_list_link is defined as a structure (not typedef void*).
* It will make extend list into bi-direction easy.
*/
typedef struct bh_list_link {
struct bh_list_link *next;
} bh_list_link;
typedef struct bh_list {
bh_list_link head;
uint32 len;
} bh_list;
/* list operation return value */
typedef enum bh_list_status {
BH_LIST_SUCCESS = 0,
BH_LIST_ERROR = -1
} bh_list_status;
/**
* Initialize a list.
*
* @param list pointer to list.
* @return <code>BH_LIST_ERROR</code> if OK;
* <code>BH_LIST_ERROR</code> if list pointer is NULL.
*/
bh_list_status bh_list_init(bh_list *list);
/**
* Insert an elem pointer into list. The list node memory is maintained by list while
* elem memory is the responsibility of list user.
*
* @param list pointer to list.
* @param elem pointer to elem that will be inserted into list.
* @return <code>BH_LIST_ERROR</code> if OK;
* <code>BH_LIST_ERROR</code> if input is invalid or no memory available.
*/
extern bh_list_status bh_list_insert(bh_list *list, void *elem);
/**
* Remove an elem pointer from list. The list node memory is maintained by list while
* elem memory is the responsibility of list user.
*
* @param list pointer to list.
* @param elem pointer to elem that will be inserted into list.
* @return <code>BH_LIST_ERROR</code> if OK;
* <code>BH_LIST_ERROR</code> if element does not exist in given list.
*/
bh_list_status bh_list_remove(bh_list *list, void *elem);
/**
* Get the list length.
*
* @param list pointer to list.
* @return the length of the list.
*/
uint32 bh_list_length(bh_list *list);
/**
* Get the first elem in the list.
*
* @param list pointer to list.
* @return pointer to the first node.
*/
void* bh_list_first_elem(bh_list *list);
/**
* Get the next elem of given list input elem.
*
* @param node pointer to list node.
* @return pointer to next list node.
*/
void* bh_list_elem_next(void *node);
#ifdef __cplusplus
}
#endif
#endif /* #ifndef _BH_LIST_H */

View File

@ -2,213 +2,53 @@
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
/**
* @file bh_log.c
* @date Tue Nov 8 18:20:06 2011
*
* @brief Implementation of Beihai's log system.
*/
#include "bh_assert.h"
#include "bh_time.h"
#include "bh_thread.h"
#include "bh_log.h"
#include "bh_platform_log.h"
/**
* The verbose level of the log system. Only those verbose logs whose
* levels are less than or equal to this value are outputed.
*/
static int log_verbose_level;
static uint32 log_verbose_level = LOG_LEVEL_WARNING;
/**
* The lock for protecting the global output stream of logs.
*/
static korp_mutex log_stream_lock;
/**
* The current logging thread that owns the log_stream_lock.
*/
static korp_tid cur_logging_thread = INVALID_THREAD_ID;
/**
* Whether the currently being printed log is ennabled.
*/
static bool cur_log_enabled;
int _bh_log_init()
{
log_verbose_level = 3;
return vm_mutex_init(&log_stream_lock);
}
void _bh_log_set_verbose_level(int level)
void
bh_log_set_verbose_level(uint32 level)
{
log_verbose_level = level;
}
void _bh_log_printf(const char *fmt, ...)
void
bh_log(LogLevel log_level, const char *file, int line, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
_bh_log_vprintf(fmt, ap);
va_end(ap);
}
korp_tid self;
char buf[32] = { 0 };
uint64 usec;
uint32 t, h, m, s, mills;
#ifndef BH_PLATFORM_ANDROID
/**
* Return true if the given tag is enabled by the configuration.
*
* @param tag the tag (or prefix) of the log message.
*
* @return true if the log should be enabled.
*/
static bool is_log_enabled(const char *tag)
{
/* Print all non-verbose or verbose logs whose levels are less than
or equal to the configured verbose level. */
return tag[0] != 'V' || tag[1] - '0' <= log_verbose_level;
}
/**
* Helper function for converting "..." to va_list.
*/
static void bh_log_emit_helper(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
bh_log_emit(fmt, ap);
va_end(ap);
}
#endif
extern size_t _bh_time_strftime(char *s, size_t max, const char *format,
int64 time);
void _bh_log_vprintf(const char *fmt, va_list ap)
{
#ifndef BH_PLATFORM_ANDROID
korp_tid self = vm_self_thread();
/* Try to own the log stream and start the log output. */
if (self != cur_logging_thread) {
vm_mutex_lock(&log_stream_lock);
cur_logging_thread = self;
if (fmt && (cur_log_enabled = is_log_enabled(fmt))) {
char buf[32];
bh_time_strftime(buf, 32, "%Y-%m-%d %H:%M:%S",
(int64)bh_time_get_millisecond_from_1970());
bh_log_emit_helper("\n[%s - %X]: ", buf, (int) self);
/* Strip the "Vn." prefix. */
if (fmt && strlen(fmt) >= 3 && fmt[0] == 'V' && fmt[1] && fmt[2])
fmt += 3;
}
}
#else
// since we are using android log, do not worry about that
cur_log_enabled = true;
#endif//BH_PLATFORM_ANDROID
if (cur_log_enabled && fmt)
bh_log_emit(fmt, ap);
}
void _bh_log_commit()
{
if (vm_self_thread() != cur_logging_thread)
/* Ignore the single commit without printing anything. */
if (log_level > log_verbose_level)
return;
cur_logging_thread = INVALID_THREAD_ID;
vm_mutex_unlock(&log_stream_lock);
}
self = os_self_thread();
void _bh_log(const char *tag, const char *file, int line, const char *fmt, ...)
{
va_list ap;
usec = os_time_get_boot_microsecond();
t = (uint32)(usec / 1000000) % (24 * 60 * 60);
h = t / (60 * 60);
t = t % (60 * 60);
m = t / 60;
s = t % 60;
mills = (uint32)(usec % 1000);
#ifndef BH_PLATFORM_ANDROID
if (tag)
_bh_log_printf(tag);
snprintf(buf, sizeof(buf), "%02u:%02u:%02u:%03u", h, m, s, mills);
os_printf("[%s - %X]: ", buf, (uint32)self);
if (file)
_bh_log_printf("%s:%d", file, line);
#else
(void)tag;
(void)file;
(void)line;
#endif//BH_PLATFORM_ANDROID
os_printf("%s, line %d, ", file, line);
va_start(ap, fmt);
_bh_log_vprintf(fmt, ap);
os_vprintf(fmt, ap);
va_end(ap);
_bh_log_commit();
os_printf("\n");
}
#if defined(BH_DEBUG)
BH_STATIC char com_switchs[LOG_COM_MAX]; /* 0: off; 1: on */
BH_STATIC char *com_names[LOG_COM_MAX] = {"app_manager", "gc", "hmc", "utils",
"verifier_jeff", "vmcore_jeff"};
BH_STATIC int com_find_name(const char **com)
{
int i;
const char *c, *name;
for (i = 0; i < LOG_COM_MAX; i++) {
c = *com;
name = com_names[i];
while (*name != '\0') {
if (*c != *name)
break;
c++;
name++;
}
if (*name == '\0') {
*com = c;
return i;
}
}
return LOG_COM_MAX;
}
void log_parse_coms(const char *coms)
{
int i;
for (i = LOG_COM_MAX; i--; )
com_switchs[i] = 0;
com_switchs[LOG_COM_UTILS] = 1; /* utils is a common part */
if (coms == NULL)
return;
while (*coms != '\0') {
i = com_find_name(&coms);
if (i == LOG_COM_MAX)
break;
com_switchs[i] = 1;
if (*coms == '\0')
return;
if (*coms != ';')
break;
/* *com == ';' */
coms++;
}
/* Log the message without aborting. */
LOG_DEBUG(LOG_COM_UTILS, "The component names for logging are not right: %s.", coms);
}
int bh_log_dcom_is_enabled(int component)
{
return com_switchs[component];
}
#endif /* defined(BH_DEBUG) */

View File

@ -0,0 +1,54 @@
/*
* 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 "bh_platform.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
LOG_LEVEL_FATAL = 0,
LOG_LEVEL_ERROR = 1,
LOG_LEVEL_WARNING = 2,
LOG_LEVEL_DEBUG = 3,
LOG_LEVEL_VERBOSE = 4
} LogLevel;
void
bh_log_set_verbose_level(uint32 level);
void
bh_log(LogLevel log_level, const char *file, int line, const char *fmt, ...);
#define LOG_FATAL(...) bh_log(LOG_LEVEL_FATAL, __FILE__, __LINE__, __VA_ARGS__)
#define LOG_ERROR(...) bh_log(LOG_LEVEL_ERROR, NULL, 0, __VA_ARGS__)
#define LOG_DEBUG(...) bh_log(LOG_LEVEL_DEBUG, __FILE__, __LINE__, 0, __VA_ARGS__)
#define LOG_WARNING(...) bh_log(LOG_LEVEL_WARNING, NULL, 0, __VA_ARGS__)
#define LOG_VERBOSE(...) bh_log(LOG_LEVEL_VERBOSE, NULL, 0, __VA_ARGS__)
#ifdef __cplusplus
}
#endif
#endif /* _BH_LOG_H */

View File

@ -0,0 +1,40 @@
/*
* 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 "../platform/include/platform_common.h"
#include "../platform/include/platform_api_vmcore.h"
#include "../platform/include/platform_api_extension.h"
#include "bh_assert.h"
#include "bh_common.h"
#include "bh_hashmap.h"
#include "bh_list.h"
#include "bh_log.h"
#include "bh_queue.h"
#include "runtime_timer.h"
/**
* WA_MALLOC/WA_FREE need to be redefined for both
* runtime native and WASM app respectively.
*
* Some source files are shared for building native and WASM,
* and this the mem allocator API for these files.
*
* Here we define it for the native world
*/
#ifndef WA_MALLOC
#define WA_MALLOC wasm_runtime_malloc
#endif
#ifndef WA_FREE
#define WA_FREE wasm_runtime_free
#endif
#endif /* #ifndef _BH_PLATFORM_H */

View File

@ -4,13 +4,10 @@
*/
#include "bh_queue.h"
#include "bh_thread.h"
#include "bh_time.h"
#include "bh_common.h"
typedef struct _bh_queue_node {
struct _bh_queue_node * next;
struct _bh_queue_node * prev;
typedef struct bh_queue_node {
struct bh_queue_node * next;
struct bh_queue_node * prev;
unsigned short tag;
unsigned int len;
void * body;
@ -124,7 +121,7 @@ bool bh_post_msg2(bh_queue *queue, bh_queue_node *msg)
}
bool bh_post_msg(bh_queue *queue, unsigned short tag, void *body,
unsigned int len)
unsigned int len)
{
bh_queue_node *msg = bh_new_msg(tag, body, len, NULL);
if (msg == NULL) {
@ -143,10 +140,10 @@ bool bh_post_msg(bh_queue *queue, unsigned short tag, void *body,
}
bh_queue_node * bh_new_msg(unsigned short tag, void *body, unsigned int len,
void * handler)
void * handler)
{
bh_queue_node *msg = (bh_queue_node*) bh_queue_malloc(
sizeof(bh_queue_node));
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));
@ -189,7 +186,7 @@ bh_message_t bh_get_msg(bh_queue *queue, int timeout)
}
bh_queue_cond_timedwait(&queue->queue_wait_cond, &queue->queue_lock,
timeout);
timeout);
}
if (queue->cnt == 0) {
@ -222,14 +219,14 @@ unsigned bh_queue_get_message_count(bh_queue *queue)
}
void bh_queue_enter_loop_run(bh_queue *queue,
bh_queue_handle_msg_callback handle_cb,
void *arg)
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);
bh_queue_node * message = bh_get_msg(queue, (int)BHT_WAIT_FOREVER);
if (message) {
handle_cb(message, arg);

View File

@ -0,0 +1,76 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#ifndef _BH_QUEUE_H
#define _BH_QUEUE_H
#ifdef __cplusplus
extern "C" {
#endif
#include "bh_platform.h"
struct bh_queue_node;
typedef struct bh_queue_node * bh_message_t;
struct bh_queue;
typedef struct bh_queue bh_queue;
typedef void (*bh_queue_handle_msg_callback)(void *message, void *arg);
#define bh_queue_malloc BH_MALLOC
#define bh_queue_free BH_FREE
#define bh_queue_mutex korp_mutex
#define bh_queue_cond korp_cond
#define bh_queue_mutex_init os_mutex_init
#define bh_queue_mutex_destroy os_mutex_destroy
#define bh_queue_mutex_lock os_mutex_lock
#define bh_queue_mutex_unlock os_mutex_unlock
#define bh_queue_cond_init os_cond_init
#define bh_queue_cond_destroy os_cond_destroy
#define bh_queue_cond_wait os_cond_wait
#define bh_queue_cond_timedwait os_cond_reltimedwait
#define bh_queue_cond_signal os_cond_signal
#define bh_queue_cond_broadcast os_cond_broadcast
typedef void (*bh_msg_cleaner)(void *msg);
bh_queue *
bh_queue_create();
void
bh_queue_destroy(bh_queue *queue);
char * bh_message_payload(bh_message_t message);
uint32 bh_message_payload_len(bh_message_t message);
int bh_message_type(bh_message_t message);
bh_message_t bh_new_msg(unsigned short tag, void *body, unsigned int len,
void * handler);
void bh_free_msg(bh_message_t msg);
bool bh_post_msg(bh_queue *queue, unsigned short tag, void *body,
unsigned int len);
bool bh_post_msg2(bh_queue *queue, bh_message_t msg);
bh_message_t bh_get_msg(bh_queue *queue, int timeout);
unsigned
bh_queue_get_message_count(bh_queue *queue);
void
bh_queue_enter_loop_run(bh_queue *queue,
bh_queue_handle_msg_callback handle_cb,
void *arg);
void
bh_queue_exit_loop_run(bh_queue *queue);
#ifdef __cplusplus
}
#endif
#endif /* #ifndef _BH_QUEUE_H */

View File

@ -3,10 +3,8 @@
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "bh_log.h"
#include "bh_vector.h"
static uint8*
alloc_vector_data(uint32 length, uint32 size_elem)
{

View File

@ -0,0 +1,125 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#ifndef _WASM_VECTOR_H
#define _WASM_VECTOR_H
#include "bh_platform.h"
#ifdef __cplusplus
extern "C" {
#endif
#define DEFAULT_VECTOR_INIT_SIZE 8
typedef struct Vector {
/* size of each element */
uint32 size_elem;
/* max element number */
uint32 max_elements;
/* current element num */
uint32 num_elements;
/* vector data allocated */
uint8 *data;
} Vector;
/**
* Initialize vector
*
* @param vector the vector to init
* @param init_length the initial length of the vector
* @param size_elem size of each element
*
* @return true if success, false otherwise
*/
bool
bh_vector_init(Vector *vector, uint32 init_length, uint32 size_elem);
/**
* Set element of vector
*
* @param vector the vector to set
* @param index the index of the element to set
* @param elem_buf the element buffer which stores the element data
*
* @return true if success, false otherwise
*/
bool
bh_vector_set(Vector *vector, uint32 index, const void *elem_buf);
/**
* Get element of vector
*
* @param vector the vector to get
* @param index the index of the element to get
* @param elem_buf the element buffer to store the element data,
* whose length must be no less than element size
*
* @return true if success, false otherwise
*/
bool
bh_vector_get(const Vector *vector, uint32 index, void *elem_buf);
/**
* Insert element of vector
*
* @param vector the vector to insert
* @param index the index of the element to insert
* @param elem_buf the element buffer which stores the element data
*
* @return true if success, false otherwise
*/
bool
bh_vector_insert(Vector *vector, uint32 index, const void *elem_buf);
/**
* Append element to the end of vector
*
* @param vector the vector to append
* @param elem_buf the element buffer which stores the element data
*
* @return true if success, false otherwise
*/
bool
bh_vector_append(Vector *vector, const void *elem_buf);
/**
* Remove element from vector
*
* @param vector the vector to remove element
* @param index the index of the element to remove
* @param old_elem_buf if not NULL, copies the element data to the buffer
*
* @return true if success, false otherwise
*/
bool
bh_vector_remove(Vector *vector, uint32 index, void *old_elem_buf);
/**
* Return the size of the vector
*
* @param vector the vector to get size
*
* @return return the size of the vector
*/
uint32
bh_vector_size(const Vector *vector);
/**
* Destroy the vector
*
* @param vector the vector to destroy
*
* @return true if success, false otherwise
*/
bool
bh_vector_destroy(Vector *vector);
#ifdef __cplusplus
}
#endif
#endif /* endof _WASM_VECTOR_H */

View File

@ -4,8 +4,6 @@
*/
#include "runtime_timer.h"
#include "bh_thread.h"
#include "bh_time.h"
#define PRINT(...)
//#define PRINT printf
@ -34,13 +32,18 @@ struct _timer_ctx {
check_timer_expiry_f refresh_checker;
};
uint64 bh_get_tick_ms()
{
return os_time_get_boot_microsecond() / 1000;
}
uint32 bh_get_elpased_ms(uint32 * last_system_clock)
{
uint32 elpased_ms;
// attention: the bh_get_tick_ms() return 64 bits integer.
// but the bh_get_elpased_ms() is designed to use 32 bits clock count.
uint32 now = (uint32) bh_get_tick_ms();
uint32 now = (uint32)bh_get_tick_ms();
// system clock overrun
if (now < *last_system_clock) {
@ -57,7 +60,7 @@ uint32 bh_get_elpased_ms(uint32 * last_system_clock)
static app_timer_t * remove_timer_from(timer_ctx_t ctx, uint32 timer_id,
bool active_list)
{
vm_mutex_lock(&ctx->mutex);
os_mutex_lock(&ctx->mutex);
app_timer_t ** head;
if (active_list)
head = &ctx->g_app_timers;
@ -76,7 +79,7 @@ static app_timer_t * remove_timer_from(timer_ctx_t ctx, uint32 timer_id,
prev->next = t->next;
PRINT("removed timer [%d] after [%d] from list %d\n", t->id, prev->id, active_list);
}
vm_mutex_unlock(&ctx->mutex);
os_mutex_unlock(&ctx->mutex);
if (active_list && prev == NULL && ctx->refresh_checker)
ctx->refresh_checker(ctx);
@ -88,7 +91,7 @@ static app_timer_t * remove_timer_from(timer_ctx_t ctx, uint32 timer_id,
}
}
vm_mutex_unlock(&ctx->mutex);
os_mutex_unlock(&ctx->mutex);
return NULL;
}
@ -111,7 +114,7 @@ static app_timer_t * remove_timer(timer_ctx_t ctx, uint32 timer_id,
static void reschedule_timer(timer_ctx_t ctx, app_timer_t * timer)
{
vm_mutex_lock(&ctx->mutex);
os_mutex_lock(&ctx->mutex);
app_timer_t * t = ctx->g_app_timers;
app_timer_t * prev = NULL;
@ -130,7 +133,7 @@ static void reschedule_timer(timer_ctx_t ctx, app_timer_t * timer)
PRINT("rescheduled timer [%d] after [%d]\n", timer->id, prev->id);
}
vm_mutex_unlock(&ctx->mutex);
os_mutex_unlock(&ctx->mutex);
// ensure the refresh_checker() is called out of the lock
if (prev == NULL && ctx->refresh_checker)
@ -154,7 +157,7 @@ static void reschedule_timer(timer_ctx_t ctx, app_timer_t * timer)
PRINT("rescheduled timer [%d] as first\n", timer->id);
}
vm_mutex_unlock(&ctx->mutex);
os_mutex_unlock(&ctx->mutex);
// ensure the refresh_checker() is called out of the lock
if (prev == NULL && ctx->refresh_checker)
@ -165,11 +168,11 @@ static void reschedule_timer(timer_ctx_t ctx, app_timer_t * timer)
static void release_timer(timer_ctx_t ctx, app_timer_t * t)
{
if (ctx->pre_allocated) {
vm_mutex_lock(&ctx->mutex);
os_mutex_lock(&ctx->mutex);
t->next = ctx->free_timers;
ctx->free_timers = t;
PRINT("recycle timer :%d\n", t->id);
vm_mutex_unlock(&ctx->mutex);
os_mutex_unlock(&ctx->mutex);
} else {
PRINT("destroy timer :%d\n", t->id);
BH_FREE(t);
@ -220,8 +223,8 @@ timer_ctx_t create_timer_ctx(timer_callback_f timer_handler,
prealloc_num--;
}
vm_cond_init(&ctx->cond);
vm_mutex_init(&ctx->mutex);
os_cond_init(&ctx->cond);
os_mutex_init(&ctx->mutex);
PRINT("timer ctx created. pre-alloc: %d\n", ctx->pre_allocated);
@ -247,8 +250,8 @@ void destroy_timer_ctx(timer_ctx_t ctx)
cleanup_app_timers(ctx);
vm_cond_destroy(&ctx->cond);
vm_mutex_destroy(&ctx->mutex);
os_cond_destroy(&ctx->cond);
os_mutex_destroy(&ctx->mutex);
BH_FREE(ctx);
}
@ -259,10 +262,10 @@ unsigned int timer_ctx_get_owner(timer_ctx_t ctx)
void add_idle_timer(timer_ctx_t ctx, app_timer_t * timer)
{
vm_mutex_lock(&ctx->mutex);
os_mutex_lock(&ctx->mutex);
timer->next = ctx->idle_timers;
ctx->idle_timers = timer;
vm_mutex_unlock(&ctx->mutex);
os_mutex_unlock(&ctx->mutex);
}
uint32 sys_create_timer(timer_ctx_t ctx, int interval, bool is_period,
@ -376,21 +379,21 @@ int get_expiry_ms(timer_ctx_t ctx)
int ms_to_next_expiry;
uint64 now = bh_get_tick_ms();
vm_mutex_lock(&ctx->mutex);
os_mutex_lock(&ctx->mutex);
if (ctx->g_app_timers == NULL)
ms_to_next_expiry = 7 * 24 * 60 * 60 * 1000; // 1 week
else if (ctx->g_app_timers->expiry >= now)
ms_to_next_expiry = (int)(ctx->g_app_timers->expiry - now);
else
ms_to_next_expiry = 0;
vm_mutex_unlock(&ctx->mutex);
os_mutex_unlock(&ctx->mutex);
return ms_to_next_expiry;
}
int check_app_timers(timer_ctx_t ctx)
{
vm_mutex_lock(&ctx->mutex);
os_mutex_lock(&ctx->mutex);
app_timer_t * t = ctx->g_app_timers;
app_timer_t * expired = NULL;
@ -409,7 +412,7 @@ int check_app_timers(timer_ctx_t ctx)
break;
}
}
vm_mutex_unlock(&ctx->mutex);
os_mutex_unlock(&ctx->mutex);
handle_expired_timers(ctx, expired);
@ -418,11 +421,11 @@ int check_app_timers(timer_ctx_t ctx)
void cleanup_app_timers(timer_ctx_t ctx)
{
vm_mutex_lock(&ctx->mutex);
os_mutex_lock(&ctx->mutex);
release_timer_list(&ctx->g_app_timers);
release_timer_list(&ctx->idle_timers);
vm_mutex_unlock(&ctx->mutex);
os_mutex_unlock(&ctx->mutex);
}

View File

@ -12,7 +12,8 @@
extern "C" {
#endif
uint32 bh_get_elpased_ms(uint32 * last_system_clock);
uint64 bh_get_tick_ms();
uint32 bh_get_elpased_ms(uint32 *last_system_clock);
struct _timer_ctx;
typedef struct _timer_ctx * timer_ctx_t;
@ -20,12 +21,13 @@ typedef void (*timer_callback_f)(uint32 id, unsigned int owner);
typedef void (*check_timer_expiry_f)(timer_ctx_t ctx);
timer_ctx_t create_timer_ctx(timer_callback_f timer_handler,
check_timer_expiry_f, int prealloc_num, unsigned int owner);
check_timer_expiry_f, int prealloc_num,
unsigned int owner);
void destroy_timer_ctx(timer_ctx_t);
unsigned int timer_ctx_get_owner(timer_ctx_t ctx);
uint32 sys_create_timer(timer_ctx_t ctx, int interval, bool is_period,
bool auto_start);
bool auto_start);
bool sys_timer_destroy(timer_ctx_t ctx, uint32 timer_id);
bool sys_timer_cancel(timer_ctx_t ctx, uint32 timer_id);
bool sys_timer_restart(timer_ctx_t ctx, uint32 timer_id, int interval);

View File

@ -4,10 +4,8 @@
set (UTILS_SHARED_DIR ${CMAKE_CURRENT_LIST_DIR})
include_directories(${UTILS_SHARED_DIR})
include_directories(${UTILS_SHARED_DIR}/../include)
file (GLOB_RECURSE source_all ${UTILS_SHARED_DIR}/*.c)
file (GLOB source_all ${UTILS_SHARED_DIR}/*.c)
set (UTILS_SHARED_SOURCE ${source_all})

View File

@ -0,0 +1,53 @@
#include "bh_read_file.h"
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
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;
}

View File

@ -0,0 +1,23 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#ifndef _BH_FILE_H
#define _BH_FILE_H
#include "bh_platform.h"
#ifdef __cplusplus
extern "C" {
#endif
char *
bh_read_file_to_buffer(const char *filename, uint32 *ret_size);
#ifdef __cplusplus
}
#endif
#endif /* end of _BH_FILE_H */

View File

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