Implement Windows thread/mutex/cond APIs to support multi-thread (#627)

Implement Windows thread/mutex/cond related APIs to support Windows multi-thread feature
Change Windows HW boundary check implementation for multi-thread: change SEH to VEH
Fix wasm-c-api issue of getting AOTFunctionInstance by index, fix wasm-c-api compile warnings
Enable to build invokeNative_general.c with cmake variable
Fix several issues in lib-pthread
Disable two LLVM passes in multi-thread mode to reserve volatile semantic
Update docker script and document to build iwasm with Docker image

Signed-off-by: Wenyong Huang <wenyong.huang@intel.com>
This commit is contained in:
Wenyong Huang
2021-05-11 16:48:49 +08:00
committed by GitHub
parent 9710d9325f
commit 64b5459066
21 changed files with 1022 additions and 653 deletions

View File

@ -7,33 +7,6 @@
#include "bh_platform.h"
#include "mem_alloc.h"
#define BH_ENABLE_MEMORY_PROFILING 0
#if BH_ENABLE_MEMORY_PROFILING != 0
/* Memory profile data of a function */
typedef struct memory_profile {
struct memory_profile *next;
const char *function_name;
const char *file_name;
int line_in_file;
int malloc_num;
int free_num;
int total_malloc;
int total_free;
} memory_profile_t;
/* Memory in use which grows when BH_MALLOC was called
* and decreases when bh_free was called */
static unsigned int memory_in_use = 0;
/* Memory profile data list */
static memory_profile_t *memory_profiles_list = NULL;
/* Lock of the memory profile list */
static korp_mutex profile_lock;
#endif /* end of BH_ENABLE_MEMORY_PROFILING */
typedef enum Memory_Mode {
MEMORY_MODE_UNKNOWN = 0,
MEMORY_MODE_POOL,
@ -58,9 +31,6 @@ wasm_memory_init_with_pool(void *mem, unsigned int bytes)
if (_allocator) {
memory_mode = MEMORY_MODE_POOL;
pool_allocator = _allocator;
#if BH_ENABLE_MEMORY_PROFILING != 0
os_mutex_init(&profile_lock);
#endif
global_pool_size = bytes;
return true;
}
@ -78,9 +48,6 @@ wasm_memory_init_with_allocator(void *_malloc_func,
malloc_func = _malloc_func;
realloc_func = _realloc_func;
free_func = _free_func;
#if BH_ENABLE_MEMORY_PROFILING != 0
os_mutex_init(&profile_lock);
#endif
return true;
}
LOG_ERROR("Init memory with allocator (%p, %p, %p) failed.\n",
@ -108,9 +75,6 @@ wasm_runtime_memory_init(mem_alloc_type_t mem_alloc_type,
void
wasm_runtime_memory_destroy()
{
#if BH_ENABLE_MEMORY_PROFILING != 0
os_mutex_destroy(&profile_lock);
#endif
if (memory_mode == MEMORY_MODE_POOL)
mem_allocator_destroy(pool_allocator);
memory_mode = MEMORY_MODE_UNKNOWN;
@ -201,197 +165,3 @@ wasm_runtime_free(void *ptr)
{
wasm_runtime_free_internal(ptr);
}
#if 0
static uint64 total_malloc = 0;
static uint64 total_free = 0;
void *
wasm_runtime_malloc(unsigned int size)
{
void *ret = wasm_runtime_malloc_internal(size + 8);
if (ret) {
total_malloc += size;
*(uint32 *)ret = size;
return (uint8 *)ret + 8;
}
else
return NULL;
}
void *
wasm_runtime_realloc(void *ptr, unsigned int size)
{
if (!ptr)
return wasm_runtime_malloc(size);
else {
uint8 *ptr_old = (uint8 *)ptr - 8;
uint32 size_old = *(uint32 *)ptr_old;
ptr = wasm_runtime_realloc_internal(ptr_old, size + 8);
if (ptr) {
total_free += size_old;
total_malloc += size;
*(uint32 *)ptr = size;
return (uint8 *)ptr + 8;
}
return NULL;
}
}
void
wasm_runtime_free(void *ptr)
{
if (ptr) {
uint8 *ptr_old = (uint8 *)ptr - 8;
uint32 size_old = *(uint32 *)ptr_old;
total_free += size_old;
wasm_runtime_free_internal(ptr_old);
}
}
void dump_memory_usage()
{
os_printf("Memory usage:\n");
os_printf(" total malloc: %"PRIu64"\n", total_malloc);
os_printf(" total free: %"PRIu64"\n", total_free);
}
#endif
#if BH_ENABLE_MEMORY_PROFILING != 0
void
memory_profile_print(const char *file, int line,
const char *func, int alloc)
{
os_printf("location:%s@%d:used:%d:contribution:%d\n",
func, line, memory_in_use, alloc);
}
void *
wasm_runtime_malloc_profile(const char *file, int line,
const char *func, unsigned int size)
{
void *p = wasm_runtime_malloc(size + 8);
if (p) {
memory_profile_t *profile;
os_mutex_lock(&profile_lock);
profile = memory_profiles_list;
while (profile) {
if (strcmp(profile->function_name, func) == 0
&& strcmp(profile->file_name, file) == 0) {
break;
}
profile = profile->next;
}
if (profile) {
profile->total_malloc += size;/* TODO: overflow check */
profile->malloc_num++;
} else {
profile = wasm_runtime_malloc(sizeof(memory_profile_t));
if (!profile) {
os_mutex_unlock(&profile_lock);
bh_memcpy_s(p, size + 8, &size, sizeof(size));
return (char *)p + 8;
}
memset(profile, 0, sizeof(memory_profile_t));
profile->file_name = file;
profile->line_in_file = line;
profile->function_name = func;
profile->malloc_num = 1;
profile->total_malloc = size;
profile->next = memory_profiles_list;
memory_profiles_list = profile;
}
os_mutex_unlock(&profile_lock);
bh_memcpy_s(p, size + 8, &size, sizeof(size));
memory_in_use += size;
memory_profile_print(file, line, func, size);
return (char *)p + 8;
}
return NULL;
}
void
wasm_runtime_free_profile(const char *file, int line,
const char *func, void *ptr)
{
unsigned int size = *(unsigned int *)((char *)ptr - 8);
memory_profile_t *profile;
wasm_runtime_free((char *)ptr - 8);
if (memory_in_use >= size)
memory_in_use -= size;
os_mutex_lock(&profile_lock);
profile = memory_profiles_list;
while (profile) {
if (strcmp(profile->function_name, func) == 0
&& strcmp(profile->file_name, file) == 0) {
break;
}
profile = profile->next;
}
if (profile) {
profile->total_free += size;/* TODO: overflow check */
profile->free_num++;
} else {
profile = wasm_runtime_malloc(sizeof(memory_profile_t));
if (!profile) {
os_mutex_unlock(&profile_lock);
return;
}
memset(profile, 0, sizeof(memory_profile_t));
profile->file_name = file;
profile->line_in_file = line;
profile->function_name = func;
profile->free_num = 1;
profile->total_free = size;
profile->next = memory_profiles_list;
memory_profiles_list = profile;
}
os_mutex_unlock(&profile_lock);
}
/**
* Summarize memory usage and print it out
* Can use awk to analyze the output like below:
* awk -F: '{print $2,$4,$6,$8,$9}' OFS="\t" ./out.txt | sort -n -r -k 1
*/
void memory_usage_summarize()
{
memory_profile_t *profile;
os_mutex_lock(&profile_lock);
profile = memory_profiles_list;
while (profile) {
os_printf("malloc:%d:malloc_num:%d:free:%d:free_num:%d:%s\n",
profile->total_malloc,
profile->malloc_num,
profile->total_free,
profile->free_num,
profile->function_name);
profile = profile->next;
}
os_mutex_unlock(&profile_lock);
}
#endif /* end of BH_ENABLE_MEMORY_PROFILING */