Add build configuration for Mac (#110)

* Add build configuration for Mac

This patch implements Mac build basically based on Linux platform
implementations and configurations.

The document to build it on Mac has been updated as well.

* Update wasm_application.h

* Update lib_export.h

Add comments for the functions.
This commit is contained in:
Jonathan Dong 2019-09-06 16:51:36 +08:00 committed by wenyongh
parent 4a14e54e86
commit 8deef78624
18 changed files with 1427 additions and 1 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
.vscode
**/*build/

View File

@ -67,6 +67,25 @@ cd build
cmake ..
make
```
Mac
-------------------------
Make sure to install Xcode from App Store firstly, and install cmake.
If you use Homebrew, install cmake from the command line:
``` Bash
brew install cmake
```
Then build the source codes:
```
cd core/iwasm/products/darwin/
mkdir build
cd build
cmake ..
make
```
VxWorks
-------------------------
VxWorks 7 SR0620 release is validated.

View File

@ -0,0 +1,107 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
cmake_minimum_required (VERSION 2.8)
project (iwasm)
set (PLATFORM "darwin")
# Reset default linker flags
set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
set (CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
# Enable repl mode if want to test spec cases
# add_definitions(-DWASM_ENABLE_REPL)
if (NOT ("$ENV{VALGRIND}" STREQUAL "YES"))
add_definitions(-DNVALGRIND)
endif ()
# Currently build as 64-bit by default.
set (BUILD_AS_64BIT_SUPPORT "YES")
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
if (${BUILD_AS_64BIT_SUPPORT} STREQUAL "YES")
# Add -fPIC flag if build as 64-bit
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "${CMAKE_SHARED_LIBRARY_LINK_C_FLAGS} -fPIC")
else ()
add_definitions (-m32)
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -m32")
set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -m32")
endif ()
endif ()
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif (NOT CMAKE_BUILD_TYPE)
message ("CMAKE_BUILD_TYPE = " ${CMAKE_BUILD_TYPE})
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl")
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffunction-sections -fdata-sections -Wall -Wno-unused-parameter -Wno-pedantic")
set (CMAKE_MACOSX_RPATH True)
set (SHARED_LIB_DIR ../../../shared-lib)
include_directories (.
../../runtime/include
../../runtime/platform/include
${SHARED_LIB_DIR}/include)
enable_language (ASM)
include (../../runtime/platform/${PLATFORM}/platform.cmake)
include (../../runtime/utils/utils.cmake)
include (../../runtime/vmcore-wasm/vmcore.cmake)
include (../../lib/native/base/wasm_lib_base.cmake)
include (../../lib/native/libc/wasm_libc.cmake)
include (${SHARED_LIB_DIR}/platform/${PLATFORM}/shared_platform.cmake)
include (${SHARED_LIB_DIR}/mem-alloc/mem_alloc.cmake)
include (${SHARED_LIB_DIR}/utils/shared_utils.cmake)
add_library (vmlib
${WASM_PLATFORM_LIB_SOURCE}
${WASM_UTILS_LIB_SOURCE}
${VMCORE_LIB_SOURCE}
${WASM_LIB_BASE_DIR}/base_lib_export.c
${WASM_LIBC_SOURCE}
${PLATFORM_SHARED_SOURCE}
${MEM_ALLOC_SHARED_SOURCE}
${UTILS_SHARED_SOURCE})
add_executable (iwasm main.c ext_lib_export.c)
install (TARGETS iwasm DESTINATION bin)
target_link_libraries (iwasm vmlib -lm -ldl -lpthread)
add_library (libiwasm SHARED
${WASM_PLATFORM_LIB_SOURCE}
${WASM_UTILS_LIB_SOURCE}
${VMCORE_LIB_SOURCE}
${WASM_LIB_BASE_DIR}/base_lib_export.c
${WASM_LIBC_SOURCE}
${PLATFORM_SHARED_SOURCE}
${MEM_ALLOC_SHARED_SOURCE}
${UTILS_SHARED_SOURCE}
ext_lib_export.c)
install (TARGETS libiwasm DESTINATION lib)
set_target_properties (libiwasm PROPERTIES OUTPUT_NAME iwasm)
target_link_libraries (libiwasm -lm -ldl -lpthread)

View File

@ -0,0 +1,21 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "lib_export.h"
static NativeSymbol extended_native_symbol_defs[] = { };
#include "ext_lib_export.h"

View File

@ -0,0 +1,251 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "bh_platform.h"
#include "wasm_application.h"
#include "wasm_assert.h"
#include "wasm_log.h"
#include "wasm_platform_log.h"
#include "wasm_thread.h"
#include "wasm_export.h"
#include "wasm_memory.h"
#include "bh_memory.h"
static int app_argc;
static char **app_argv;
static int print_help()
{
wasm_printf("Usage: iwasm [-options] wasm_file [args...]\n");
wasm_printf("options:\n");
wasm_printf(" -f|--function name Specify function name to run in module\n"
" rather than main\n");
#if WASM_ENABLE_LOG != 0
wasm_printf(" -v=X Set log verbose level (0 to 2, default is 1),\n"
" larger level with more log\n");
#endif
wasm_printf(" --repl Start a very simple REPL (read-eval-print-loop) mode\n"
" that runs commands in the form of `FUNC ARG...`\n");
return 1;
}
static void*
app_instance_main(wasm_module_inst_t module_inst)
{
const char *exception;
wasm_application_execute_main(module_inst, app_argc, app_argv);
if ((exception = wasm_runtime_get_exception(module_inst)))
wasm_printf("%s\n", exception);
return NULL;
}
static void*
app_instance_func(wasm_module_inst_t module_inst, const char *func_name)
{
const char *exception;
wasm_application_execute_func(module_inst, func_name, app_argc - 1,
app_argv + 1);
if ((exception = wasm_runtime_get_exception(module_inst)))
wasm_printf("%s\n", exception);
return NULL;
}
/**
* Split a space separated strings into an array of strings
* Returns NULL on failure
* Memory must be freed by caller
* Based on: http://stackoverflow.com/a/11198630/471795
*/
static char **
split_string(char *str, int *count)
{
char **res = NULL;
char *p;
int idx = 0;
/* split string and append tokens to 'res' */
do {
p = strtok(str, " ");
str = NULL;
res = (char**) realloc(res, sizeof(char*) * (idx + 1));
if (res == NULL) {
return NULL;
}
res[idx++] = p;
} while (p);
if (count) {
*count = idx - 1;
}
return res;
}
static void*
app_instance_repl(wasm_module_inst_t module_inst)
{
char *cmd = NULL;
size_t len = 0;
ssize_t n;
while ((wasm_printf("webassembly> "), n = getline(&cmd, &len, stdin)) != -1) {
wasm_assert(n > 0);
if (cmd[n - 1] == '\n') {
if (n == 1)
continue;
else
cmd[n - 1] = '\0';
}
app_argv = split_string(cmd, &app_argc);
if (app_argv == NULL) {
LOG_ERROR("Wasm prepare param failed: split string failed.\n");
break;
}
if (app_argc != 0) {
wasm_application_execute_func(module_inst, app_argv[0],
app_argc - 1, app_argv + 1);
}
free(app_argv);
}
free(cmd);
return NULL;
}
#define USE_GLOBAL_HEAP_BUF 0
#if USE_GLOBAL_HEAP_BUF != 0
static char global_heap_buf[10 * 1024 * 1024] = { 0 };
#endif
int main(int argc, char *argv[])
{
char *wasm_file = NULL;
const char *func_name = NULL;
uint8 *wasm_file_buf = NULL;
int wasm_file_size;
wasm_module_t wasm_module = NULL;
wasm_module_inst_t wasm_module_inst = NULL;
char error_buf[128];
#if WASM_ENABLE_LOG != 0
int log_verbose_level = 1;
#endif
bool is_repl_mode = false;
/* Process options. */
for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++) {
if (!strcmp(argv[0], "-f") || !strcmp(argv[0], "--function")) {
argc--, argv++;
if (argc < 2) {
print_help();
return 0;
}
func_name = argv[0];
}
#if WASM_ENABLE_LOG != 0
else if (!strncmp(argv[0], "-v=", 3)) {
log_verbose_level = atoi(argv[0] + 3);
if (log_verbose_level < 0 || log_verbose_level > 2)
return print_help();
}
#endif
else if (!strcmp(argv[0], "--repl"))
is_repl_mode = true;
else
return print_help();
}
if (argc == 0)
return print_help();
wasm_file = argv[0];
app_argc = argc;
app_argv = argv;
#if USE_GLOBAL_HEAP_BUF != 0
if (bh_memory_init_with_pool(global_heap_buf, sizeof(global_heap_buf))
!= 0) {
wasm_printf("Init memory with global heap buffer failed.\n");
return -1;
}
#else
if (bh_memory_init_with_allocator(malloc, free)) {
wasm_printf("Init memory with memory allocator failed.\n");
return -1;
}
#endif
/* initialize runtime environment */
if (!wasm_runtime_init())
goto fail1;
wasm_log_set_verbose_level(log_verbose_level);
/* load WASM byte buffer from WASM bin file */
if (!(wasm_file_buf = (uint8*) bh_read_file_to_buffer(wasm_file,
&wasm_file_size)))
goto fail2;
/* load WASM module */
if (!(wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size,
error_buf, sizeof(error_buf)))) {
wasm_printf("%s\n", error_buf);
goto fail3;
}
/* instantiate the module */
if (!(wasm_module_inst = wasm_runtime_instantiate(wasm_module,
64 * 1024, /* stack size */
64 * 1024, /* heap size */
error_buf,
sizeof(error_buf)))) {
wasm_printf("%s\n", error_buf);
goto fail4;
}
if (is_repl_mode)
app_instance_repl(wasm_module_inst);
else if (func_name)
app_instance_func(wasm_module_inst, func_name);
else
app_instance_main(wasm_module_inst);
/* destroy the module instance */
wasm_runtime_deinstantiate(wasm_module_inst);
fail4:
/* unload the module */
wasm_runtime_unload(wasm_module);
fail3:
/* free the file buffer */
wasm_free(wasm_file_buf);
fail2:
/* destroy runtime environment */
wasm_runtime_destroy();
fail1:
bh_memory_destroy();
return 0;
}

View File

@ -40,7 +40,13 @@ int
get_base_lib_export_apis(NativeSymbol **p_base_lib_apis);
/**
* Get the exported APIs of extend lib
* Get the exported APIs of extended lib, this API isn't provided by WASM VM,
* it must be provided by developer to register the extended native APIs,
* for example, developer can register his native APIs to extended_native_symbol_defs,
* array, and include file ext_lib_export.h which implements this API.
* And if developer hasn't any native API to register, he can define an empty
* extended_native_symbol_defs array, and then include file ext_lib_export.h to
* implements this API.
*
* @param p_base_lib_apis return the exported API array of extend lib
*

View File

@ -0,0 +1,65 @@
/*
* Copyright (C) 2019 Taobao (China) Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _WASM_APPLICATION_H
#define _WASM_APPLICATION_H
//#include "wasm_runtime.h"
#ifdef __cplusplus
extern "C" {
#endif
struct WASMModuleInstance;
/**
* Find the unique main function from a WASM module instance
* and execute that function.
*
* @param module_inst the WASM module instance
* @param argc the number of arguments
* @param argv the arguments array
*
* @return true if the main function is called, false otherwise and exception will be thrown,
* the caller can call wasm_runtime_get_exception to get exception info.
*/
bool
wasm_application_execute_main(struct WASMModuleInstance *module_inst,
int argc, char *argv[]);
/**
* Find the specified function in argv[0] from a WASM module instance
* and execute that function.
*
* @param module_inst the WASM module instance
* @param name the name of the function to execute
* @param argc the number of arguments
* @param argv the arguments array
*
* @return true if the specified function is called, false otherwise and exception will be thrown,
* the caller can call wasm_runtime_get_exception to get exception info.
*/
bool
wasm_application_execute_func(struct WASMModuleInstance *module_inst,
char *name, int argc, char *argv[]);
#ifdef __cplusplus
}
#endif
#endif /* end of _WASM_APPLICATION_H */

View File

@ -0,0 +1,25 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
add_definitions (-D__POSIX__ -D_XOPEN_SOURCE=600 -D_POSIX_C_SOURCE=200809L)
set (PLATFORM_LIB_DIR ${CMAKE_CURRENT_LIST_DIR})
include_directories(${PLATFORM_LIB_DIR})
include_directories(${PLATFORM_LIB_DIR}/../include)
file (GLOB_RECURSE source_all ${PLATFORM_LIB_DIR}/*.c)
set (WASM_PLATFORM_LIB_SOURCE ${source_all})

View File

@ -0,0 +1,25 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "wasm_native.h"
void*
wasm_platform_native_func_lookup(const char *module_name,
const char *func_name)
{
return NULL;
}

View File

@ -18,6 +18,7 @@
#include <stdlib.h>
#include <string.h>
#include "wasm.h"
#include "wasm_application.h"
#include "wasm_interp.h"
#include "wasm_runtime.h"
#include "wasm_thread.h"

View File

@ -0,0 +1,69 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "bh_platform.h"
#include "bh_assert.h"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef BH_TEST
#include <setjmp.h>
#endif
#ifdef BH_TEST
/* for exception throwing */
jmp_buf bh_test_jb;
#endif
void bh_assert_internal(int v, const char *file_name, int line_number,
const char *expr_string)
{
if (v)
return;
if (!file_name)
file_name = "NULL FILENAME";
if (!expr_string)
expr_string = "NULL EXPR_STRING";
printf("\nASSERTION FAILED: %s, at FILE=%s, LINE=%d\n", expr_string,
file_name, line_number);
#ifdef BH_TEST
longjmp(bh_test_jb, 1);
#endif
abort();
}
void bh_debug_internal(const char *file_name, int line_number, const char *fmt,
...)
{
#ifndef JEFF_TEST_VERIFIER
va_list args;
va_start(args, fmt);
bh_assert(file_name);
printf("\nDebug info FILE=%s, LINE=%d: ", file_name, line_number);
vprintf(fmt, args);
va_end(args);
printf("\n");
#endif
}

View File

@ -0,0 +1,81 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "bh_definition.h"
#include "bh_platform.h"
int bh_return(int ret)
{
return ret;
}
#define RSIZE_MAX 0x7FFFFFFF
int b_memcpy_s(void * s1, unsigned int s1max, const void * s2, unsigned int n)
{
char *dest = (char*) s1;
char *src = (char*) s2;
if (n == 0) {
return 0;
}
if (s1 == NULL || s1max > RSIZE_MAX) {
return -1;
}
if (s2 == NULL || n > s1max) {
memset(dest, 0, s1max);
return -1;
}
memcpy(dest, src, n);
return 0;
}
int b_strcat_s(char * s1, size_t s1max, const char * s2)
{
if (NULL
== s1|| NULL == s2 || s1max < (strlen(s1) + strlen(s2) + 1) || s1max > RSIZE_MAX) {
return -1;
}
strcat(s1, s2);
return 0;
}
int b_strcpy_s(char * s1, size_t s1max, const char * s2)
{
if (NULL
== s1|| NULL == s2 || s1max < (strlen(s2) + 1) || s1max > RSIZE_MAX) {
return -1;
}
strcpy(s1, s2);
return 0;
}
int fopen_s(FILE ** pFile, const char *filename, const char *mode)
{
if (NULL == pFile || NULL == filename || NULL == mode) {
return -1;
}
*pFile = fopen(filename, mode);
if (NULL == *pFile)
return -1;
return 0;
}

View File

@ -0,0 +1,82 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "bh_platform.h"
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
char *bh_strdup(const char *s)
{
char *s1 = NULL;
if (s && (s1 = bh_malloc(strlen(s) + 1)))
memcpy(s1, s, strlen(s) + 1);
return s1;
}
int bh_platform_init()
{
return 0;
}
char*
bh_read_file_to_buffer(const char *filename, int *ret_size)
{
char *buffer;
int file;
int 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 = 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 = 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,122 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _BH_PLATFORM_H
#define _BH_PLATFORM_H
#include "bh_config.h"
#include "bh_types.h"
#include "bh_memory.h"
#include <inttypes.h>
#include <stdbool.h>
#include <assert.h>
#include <time.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdarg.h>
#include <ctype.h>
#include <pthread.h>
#include <limits.h>
#include <semaphore.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef uint64_t uint64;
typedef int64_t int64;
extern void DEBUGME(void);
#define DIE do{bh_debug("Die here\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); DEBUGME(void); while(1);}while(0)
#define BH_PLATFORM "Darwin"
/* NEED qsort */
#define _STACK_SIZE_ADJUSTMENT (32 * 1024)
/* Stack size of applet threads's native part. */
#define BH_APPLET_PRESERVED_STACK_SIZE (8 * 1024 + _STACK_SIZE_ADJUSTMENT)
/* Default thread priority */
#define BH_THREAD_DEFAULT_PRIORITY 0
#define BH_ROUTINE_MODIFIER
#define BHT_TIMEDOUT ETIMEDOUT
#define INVALID_THREAD_ID 0xFFffFFff
typedef pthread_t korp_tid;
typedef pthread_mutex_t korp_mutex;
typedef sem_t korp_sem;
typedef pthread_cond_t korp_cond;
typedef pthread_t korp_thread;
typedef void* (*thread_start_routine_t)(void*);
#define wa_malloc bh_malloc
#define wa_free bh_free
#define wa_strdup bh_strdup
//int snprintf(char *buffer, size_t count, const char *format, ...);
double fmod(double x, double y);
float fmodf(float x, float y);
double sqrt(double x);
#define BH_WAIT_FOREVER 0xFFFFFFFF
#ifndef NULL
# define NULL ((void*) 0)
#endif
/**
* Return the offset of the given field in the given type.
*
* @param Type the type containing the filed
* @param field the field in the type
*
* @return the offset of field in Type
*/
#ifndef offsetof
#define offsetof(Type, field) ((size_t)(&((Type *)0)->field))
#endif
#define bh_assert assert
int b_memcpy_s(void * s1, unsigned int s1max, const void * s2,
unsigned int n);
int b_strcat_s(char * s1, size_t s1max, const char * s2);
int b_strcpy_s(char * s1, size_t s1max, const char * s2);
int fopen_s(FILE ** pFile, const char *filename, const char *mode);
char *bh_read_file_to_buffer(const char *filename, int *ret_size);
char *bh_strdup(const char *s);
int bh_platform_init();
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,41 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "bh_platform.h"
#include <stdio.h>
void bh_log_emit(const char *fmt, va_list ap)
{
vprintf(fmt, ap);
fflush(stdout);
}
int bh_fprintf(FILE *stream, const char *fmt, ...)
{
va_list ap;
int ret;
va_start(ap, fmt);
ret = vfprintf(stream ? stream : stdout, fmt, ap);
va_end(ap);
return ret;
}
int bh_fflush(void *stream)
{
return fflush(stream ? stream : stdout);
}

View File

@ -0,0 +1,405 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "bh_thread.h"
#include "bh_assert.h"
#include "bh_log.h"
#include "bh_memory.h"
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
static bool is_thread_sys_inited = false;
static korp_mutex thread_list_lock;
static pthread_key_t thread_local_storage_key[BH_MAX_TLS_NUM];
int _vm_thread_sys_init()
{
unsigned i, j;
int ret;
if (is_thread_sys_inited)
return 0;
for (i = 0; i < BH_MAX_TLS_NUM; i++) {
ret = pthread_key_create(&thread_local_storage_key[i], NULL);
if (ret)
goto fail;
}
ret = vm_mutex_init(&thread_list_lock);
if (ret)
goto fail;
is_thread_sys_inited = true;
return 0;
fail: for (j = 0; j < i; j++)
pthread_key_delete(thread_local_storage_key[j]);
return -1;
}
void vm_thread_sys_destroy(void)
{
if (is_thread_sys_inited) {
unsigned i;
for (i = 0; i < BH_MAX_TLS_NUM; i++)
pthread_key_delete(thread_local_storage_key[i]);
vm_mutex_destroy(&thread_list_lock);
is_thread_sys_inited = false;
}
}
typedef struct {
thread_start_routine_t start;
void* stack;
int stack_size;
void* arg;
} thread_wrapper_arg;
static void *vm_thread_wrapper(void *arg)
{
thread_wrapper_arg * targ = arg;
LOG_VERBOSE("THREAD CREATE 0x%08x\n", &targ);
targ->stack = (void *)((uintptr_t)(&arg) & ~0xfff);
_vm_tls_put(1, targ);
targ->start(targ->arg);
bh_free(targ);
_vm_tls_put(1, NULL);
return NULL;
}
int _vm_thread_create_with_prio(korp_tid *tid, thread_start_routine_t start,
void *arg, unsigned int stack_size, int prio)
{
pthread_attr_t tattr;
thread_wrapper_arg *targ;
bh_assert(stack_size > 0);
bh_assert(tid);
bh_assert(start);
*tid = INVALID_THREAD_ID;
pthread_attr_init(&tattr);
pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_JOINABLE);
if (pthread_attr_setstacksize(&tattr, stack_size) != 0) {
bh_debug("Invalid thread stack size %u. Min stack size on Linux = %u",
stack_size, PTHREAD_STACK_MIN);
pthread_attr_destroy(&tattr);
return BHT_ERROR;
}
targ = (thread_wrapper_arg*) bh_malloc(sizeof(*targ));
if (!targ) {
pthread_attr_destroy(&tattr);
return BHT_ERROR;
}
targ->start = start;
targ->arg = arg;
targ->stack_size = stack_size;
if (pthread_create(tid, &tattr, vm_thread_wrapper, targ) != 0) {
pthread_attr_destroy(&tattr);
bh_free(targ);
return BHT_ERROR;
}
pthread_attr_destroy(&tattr);
return BHT_OK;
}
int _vm_thread_create(korp_tid *tid, thread_start_routine_t start, void *arg,
unsigned int stack_size)
{
return _vm_thread_create_with_prio(tid, start, arg, stack_size,
BH_THREAD_DEFAULT_PRIORITY);
}
korp_tid _vm_self_thread()
{
return (korp_tid) pthread_self();
}
void vm_thread_exit(void * code)
{
bh_free(_vm_tls_get(1));
_vm_tls_put(1, NULL);
pthread_exit(code);
}
void *_vm_tls_get(unsigned idx)
{
bh_assert(idx < BH_MAX_TLS_NUM);
return pthread_getspecific(thread_local_storage_key[idx]);
}
int _vm_tls_put(unsigned idx, void * tls)
{
bh_assert(idx < BH_MAX_TLS_NUM);
pthread_setspecific(thread_local_storage_key[idx], tls);
return BHT_OK;
}
int _vm_mutex_init(korp_mutex *mutex)
{
return pthread_mutex_init(mutex, NULL) == 0 ? BHT_OK : BHT_ERROR;
}
int _vm_recursive_mutex_init(korp_mutex *mutex)
{
int ret;
pthread_mutexattr_t mattr;
bh_assert(mutex);
ret = pthread_mutexattr_init(&mattr);
if (ret)
return BHT_ERROR;
pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_RECURSIVE);
ret = pthread_mutex_init(mutex, &mattr);
pthread_mutexattr_destroy(&mattr);
return ret == 0 ? BHT_OK : BHT_ERROR;
}
int _vm_mutex_destroy(korp_mutex *mutex)
{
int ret;
bh_assert(mutex);
ret = pthread_mutex_destroy(mutex);
return ret == 0 ? BHT_OK : BHT_ERROR;
}
/* Returned error (EINVAL, EAGAIN and EDEADLK) from
locking the mutex indicates some logic error present in
the program somewhere.
Don't try to recover error for an existing unknown error.*/
void vm_mutex_lock(korp_mutex *mutex)
{
int ret;
bh_assert(mutex);
ret = pthread_mutex_lock(mutex);
if (0 != ret) {
printf("vm mutex lock failed (ret=%d)!\n", ret);
exit(-1);
}
}
int vm_mutex_trylock(korp_mutex *mutex)
{
int ret;
bh_assert(mutex);
ret = pthread_mutex_trylock(mutex);
return ret == 0 ? BHT_OK : BHT_ERROR;
}
/* Returned error (EINVAL, EAGAIN and EPERM) from
unlocking the mutex indicates some logic error present
in the program somewhere.
Don't try to recover error for an existing unknown error.*/
void vm_mutex_unlock(korp_mutex *mutex)
{
int ret;
bh_assert(mutex);
ret = pthread_mutex_unlock(mutex);
if (0 != ret) {
printf("vm mutex unlock failed (ret=%d)!\n", ret);
exit(-1);
}
}
int _vm_sem_init(korp_sem* sem, unsigned int c)
{
int ret;
bh_assert(sem);
ret = sem_init(sem, 0, c);
return ret == 0 ? BHT_OK : BHT_ERROR;
}
int _vm_sem_destroy(korp_sem *sem)
{
int ret;
bh_assert(sem);
ret = sem_destroy(sem);
return ret == 0 ? BHT_OK : BHT_ERROR;
}
int _vm_sem_wait(korp_sem *sem)
{
int ret;
bh_assert(sem);
ret = sem_wait(sem);
return ret == 0 ? BHT_OK : BHT_ERROR;
}
/*int _vm_sem_reltimedwait(korp_sem *sem, int mills)
{
int ret = BHT_OK;
struct timespec timeout;
const int mills_per_sec = 1000;
const int mills_to_nsec = 1E6;
bh_assert(sem);
if (mills == BHT_WAIT_FOREVER) {
ret = sem_wait(sem);
} else {
timeout.tv_sec = mills / mills_per_sec;
timeout.tv_nsec = (mills % mills_per_sec) * mills_to_nsec;
timeout.tv_sec += time(NULL);
ret = sem_timedwait(sem, &timeout);
}
if (ret != BHT_OK) {
if (errno == BHT_TIMEDOUT) {
ret = BHT_TIMEDOUT;
errno = 0;
} else {
bh_debug("Faliure happens when timed wait is called");
bh_assert(0);
}
}
return ret;
}
*/
int _vm_sem_post(korp_sem *sem)
{
bh_assert(sem);
return sem_post(sem) == 0 ? BHT_OK : BHT_ERROR;
}
int _vm_cond_init(korp_cond *cond)
{
bh_assert(cond);
if (pthread_cond_init(cond, NULL) != BHT_OK)
return BHT_ERROR;
return BHT_OK;
}
int _vm_cond_destroy(korp_cond *cond)
{
bh_assert(cond);
if (pthread_cond_destroy(cond) != BHT_OK)
return BHT_ERROR;
return BHT_OK;
}
int _vm_cond_wait(korp_cond *cond, korp_mutex *mutex)
{
bh_assert(cond);
bh_assert(mutex);
if (pthread_cond_wait(cond, mutex) != BHT_OK)
return BHT_ERROR;
return BHT_OK;
}
static void msec_nsec_to_abstime(struct timespec *ts, int64 msec, int32 nsec)
{
struct timeval tv;
gettimeofday(&tv, NULL);
ts->tv_sec = tv.tv_sec + msec / 1000;
ts->tv_nsec = tv.tv_usec * 1000 + (msec % 1000) * 1000000 + nsec;
if (ts->tv_nsec >= 1000000000L) {
ts->tv_sec++;
ts->tv_nsec -= 1000000000L;
}
}
int _vm_cond_reltimedwait(korp_cond *cond, korp_mutex *mutex, int mills)
{
int ret;
struct timespec abstime;
if (mills == BHT_WAIT_FOREVER)
ret = pthread_cond_wait(cond, mutex);
else {
msec_nsec_to_abstime(&abstime, mills, 0);
ret = pthread_cond_timedwait(cond, mutex, &abstime);
}
if (ret != BHT_OK && ret != BHT_TIMEDOUT)
return BHT_ERROR;
return BHT_OK;
}
int _vm_cond_signal(korp_cond *cond)
{
bh_assert(cond);
if (pthread_cond_signal(cond) != BHT_OK)
return BHT_ERROR;
return BHT_OK;
}
int _vm_cond_broadcast(korp_cond *cond)
{
bh_assert(cond);
if (pthread_cond_broadcast(cond) != BHT_OK)
return BHT_ERROR;
return BHT_OK;
}
int _vm_thread_cancel(korp_tid thread)
{
return pthread_cancel(thread);
}
int _vm_thread_join(korp_tid thread, void **value_ptr, int mills)
{
return pthread_join(thread, value_ptr);
}
int _vm_thread_detach(korp_tid thread)
{
return pthread_detach(thread);
}

View File

@ -0,0 +1,80 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "bh_time.h"
#include <unistd.h>
#include <stdio.h>
#include <sys/timeb.h>
#include <time.h>
/*
* This function returns milliseconds per tick.
* @return milliseconds per tick.
*/
uint64 _bh_time_get_tick_millisecond()
{
return sysconf(_SC_CLK_TCK);
}
/*
* This function returns milliseconds after boot.
* @return milliseconds after boot.
*/
uint64 _bh_time_get_boot_millisecond()
{
struct timespec ts;
if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {
return 0;
}
return ((uint64) ts.tv_sec) * 1000 + ts.tv_nsec / (1000 * 1000);
}
uint32 bh_get_tick_sec()
{
return _bh_time_get_boot_millisecond() / 1000;
}
/*
* This function returns GMT time milliseconds since from 1970.1.1, AKA UNIX time.
* @return milliseconds since from 1970.1.1.
*/
uint64 _bh_time_get_millisecond_from_1970()
{
struct timeb tp;
ftime(&tp);
return ((uint64) tp.time) * 1000 + tp.millitm
- (tp.dstflag == 0 ? 0 : 60 * 60 * 1000) + tp.timezone * 60 * 1000;
}
size_t _bh_time_strftime(char *s, size_t max, const char *format, int64 time)
{
time_t time_sec = time / 1000;
struct timeb tp;
struct tm *ltp;
ftime(&tp);
time_sec -= tp.timezone * 60;
ltp = localtime(&time_sec);
if (ltp == NULL) {
return 0;
}
return strftime(s, max, format, ltp);
}

View File

@ -0,0 +1,24 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set (PLATFORM_SHARED_DIR ${CMAKE_CURRENT_LIST_DIR})
include_directories(${PLATFORM_SHARED_DIR})
include_directories(${PLATFORM_SHARED_DIR}/../include)
file (GLOB_RECURSE source_all ${PLATFORM_SHARED_DIR}/*.c)
set (PLATFORM_SHARED_SOURCE ${source_all})