re-org platform APIs, simplify porting process (#201)
Co-authored-by: Xu Jun <jun1.xu@intel.com>
This commit is contained in:
@ -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})
|
||||
|
||||
@ -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/
|
||||
31
core/shared/utils/bh_assert.c
Normal file
31
core/shared/utils/bh_assert.c
Normal 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);
|
||||
}
|
||||
|
||||
29
core/shared/utils/bh_assert.h
Normal file
29
core/shared/utils/bh_assert.h
Normal 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 */
|
||||
|
||||
@ -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)
|
||||
47
core/shared/utils/bh_common.h
Normal file
47
core/shared/utils/bh_common.h
Normal 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
|
||||
@ -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;
|
||||
|
||||
132
core/shared/utils/bh_hashmap.h
Normal file
132
core/shared/utils/bh_hashmap.h
Normal 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 */
|
||||
|
||||
@ -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
102
core/shared/utils/bh_list.h
Normal 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 */
|
||||
|
||||
@ -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) */
|
||||
|
||||
|
||||
54
core/shared/utils/bh_log.h
Normal file
54
core/shared/utils/bh_log.h
Normal 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 */
|
||||
40
core/shared/utils/bh_platform.h
Normal file
40
core/shared/utils/bh_platform.h
Normal 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 */
|
||||
|
||||
@ -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);
|
||||
|
||||
76
core/shared/utils/bh_queue.h
Normal file
76
core/shared/utils/bh_queue.h
Normal 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 */
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
125
core/shared/utils/bh_vector.h
Normal file
125
core/shared/utils/bh_vector.h
Normal 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 */
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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})
|
||||
|
||||
|
||||
53
core/shared/utils/uncommon/bh_read_file.c
Normal file
53
core/shared/utils/uncommon/bh_read_file.c
Normal 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;
|
||||
}
|
||||
|
||||
23
core/shared/utils/uncommon/bh_read_file.h
Normal file
23
core/shared/utils/uncommon/bh_read_file.h
Normal 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 */
|
||||
|
||||
11
core/shared/utils/uncommon/shared_uncommon.cmake
Normal file
11
core/shared/utils/uncommon/shared_uncommon.cmake
Normal 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})
|
||||
|
||||
Reference in New Issue
Block a user