re-org platform APIs, simplify porting process (#201)
Co-authored-by: Xu Jun <jun1.xu@intel.com>
This commit is contained in:
@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#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
|
||||
}
|
||||
|
||||
@ -1,182 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "bh_platform.h"
|
||||
#include "bh_common.h"
|
||||
#include "bh_assert.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
int
|
||||
bh_platform_init()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *
|
||||
os_malloc(unsigned size)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void *
|
||||
os_realloc(void *ptr, unsigned size)
|
||||
{
|
||||
return realloc(ptr, size);
|
||||
}
|
||||
|
||||
void
|
||||
os_free(void *ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void *
|
||||
bh_mmap(void *hint, uint32 size, int prot, int flags)
|
||||
{
|
||||
int map_prot = PROT_NONE;
|
||||
int map_flags = MAP_ANONYMOUS | MAP_PRIVATE;
|
||||
uint64 request_size, page_size;
|
||||
uint8 *addr, *addr_aligned;
|
||||
uint32 i;
|
||||
|
||||
/* align to 2M if no less than 2M, else align to 4K */
|
||||
page_size = size < 2 * 1024 * 1024 ? 4096 : 2 * 1024 * 1024;
|
||||
request_size = (size + page_size - 1) & ~(page_size - 1);
|
||||
request_size += page_size;
|
||||
|
||||
if (request_size >= UINT32_MAX)
|
||||
return NULL;
|
||||
|
||||
if (prot & MMAP_PROT_READ)
|
||||
map_prot |= PROT_READ;
|
||||
|
||||
if (prot & MMAP_PROT_WRITE)
|
||||
map_prot |= PROT_WRITE;
|
||||
|
||||
if (prot & MMAP_PROT_EXEC)
|
||||
map_prot |= PROT_EXEC;
|
||||
|
||||
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
|
||||
if (flags & MMAP_MAP_32BIT)
|
||||
map_flags |= MAP_32BIT;
|
||||
#endif
|
||||
|
||||
if (flags & MMAP_MAP_FIXED)
|
||||
map_flags |= MAP_FIXED;
|
||||
|
||||
/* try 5 times */
|
||||
for (i = 0; i < 5; i ++) {
|
||||
addr = mmap(hint, size, map_prot, map_flags, -1, 0);
|
||||
if (addr != MAP_FAILED)
|
||||
break;
|
||||
}
|
||||
if (addr == MAP_FAILED)
|
||||
return NULL;
|
||||
|
||||
addr_aligned = (uint8*)(uintptr_t)
|
||||
(((uint64)(uintptr_t)addr + page_size - 1) & ~(page_size - 1));
|
||||
|
||||
/* Unmap memory allocated before the aligned base address */
|
||||
if (addr != addr_aligned) {
|
||||
uint32 prefix_size = (uint32)(addr_aligned - addr);
|
||||
munmap(addr, prefix_size);
|
||||
request_size -= prefix_size;
|
||||
}
|
||||
|
||||
/* Unmap memory allocated after the potentially unaligned end */
|
||||
if (size != request_size) {
|
||||
uint32 suffix_size = (uint32)(request_size - size);
|
||||
munmap(addr_aligned + size, suffix_size);
|
||||
request_size -= size;
|
||||
}
|
||||
|
||||
if (size >= 2 * 1024 * 1024) {
|
||||
/* Try to use huge page to improve performance */
|
||||
if (!madvise(addr, size, MADV_HUGEPAGE))
|
||||
/* make huge page become effective */
|
||||
memset(addr, 0, size);
|
||||
}
|
||||
|
||||
return addr_aligned;
|
||||
}
|
||||
|
||||
void
|
||||
bh_munmap(void *addr, uint32 size)
|
||||
{
|
||||
if (addr)
|
||||
munmap(addr, size);
|
||||
}
|
||||
|
||||
int
|
||||
bh_mprotect(void *addr, uint32 size, int prot)
|
||||
{
|
||||
int map_prot = PROT_NONE;
|
||||
|
||||
if (!addr)
|
||||
return 0;
|
||||
|
||||
if (prot & MMAP_PROT_READ)
|
||||
map_prot |= PROT_READ;
|
||||
|
||||
if (prot & MMAP_PROT_WRITE)
|
||||
map_prot |= PROT_WRITE;
|
||||
|
||||
if (prot & MMAP_PROT_EXEC)
|
||||
map_prot |= PROT_EXEC;
|
||||
|
||||
return mprotect(addr, size, map_prot);
|
||||
}
|
||||
|
||||
@ -1,130 +0,0 @@
|
||||
/*
|
||||
* 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 "bh_config.h"
|
||||
#include "bh_types.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 <semaphore.h>
|
||||
#include <limits.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.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)
|
||||
|
||||
#ifndef BH_PLATFORM_LINUX
|
||||
#define BH_PLATFORM_LINUX
|
||||
#endif
|
||||
|
||||
/* 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*);
|
||||
|
||||
void *os_malloc(unsigned size);
|
||||
void *os_realloc(void *ptr, unsigned size);
|
||||
void os_free(void *ptr);
|
||||
|
||||
#define bh_printf printf
|
||||
|
||||
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
|
||||
|
||||
char *bh_read_file_to_buffer(const char *filename, uint32 *ret_size);
|
||||
|
||||
int bh_platform_init();
|
||||
|
||||
/* MMAP mode */
|
||||
enum {
|
||||
MMAP_PROT_NONE = 0,
|
||||
MMAP_PROT_READ = 1,
|
||||
MMAP_PROT_WRITE = 2,
|
||||
MMAP_PROT_EXEC = 4
|
||||
};
|
||||
|
||||
/* MMAP flags */
|
||||
enum {
|
||||
MMAP_MAP_NONE = 0,
|
||||
/* Put the mapping into 0 to 2 G, supported only on x86_64 */
|
||||
MMAP_MAP_32BIT = 1,
|
||||
/* Don't interpret addr as a hint: place the mapping at exactly
|
||||
that address. */
|
||||
MMAP_MAP_FIXED = 2
|
||||
};
|
||||
|
||||
void *bh_mmap(void *hint, unsigned int size, int prot, int flags);
|
||||
void bh_munmap(void *addr, uint32 size);
|
||||
int bh_mprotect(void *addr, uint32 size, int prot);
|
||||
#define bh_dcache_flush() (void)0
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#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);
|
||||
}
|
||||
@ -1,392 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "bh_thread.h"
|
||||
#include "bh_assert.h"
|
||||
#include "bh_log.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;
|
||||
uint32 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) & (uintptr_t)~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_NP);
|
||||
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 == (int)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 = (long int)(tv.tv_sec + msec / 1000);
|
||||
ts->tv_nsec = (long int)(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 == (int)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);
|
||||
}
|
||||
|
||||
@ -1,70 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#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 (uint64)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 + ((uint64)ts.tv_nsec) / (1000 * 1000);
|
||||
}
|
||||
|
||||
uint32 bh_get_tick_sec()
|
||||
{
|
||||
return (uint32)(_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)
|
||||
+ ((uint64)tp.timezone) * 60 * 1000;
|
||||
}
|
||||
|
||||
size_t _bh_time_strftime(char *s, size_t max, const char *format, int64 time)
|
||||
{
|
||||
time_t time_sec = (time_t)(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);
|
||||
}
|
||||
|
||||
18
core/shared/platform/linux/platform_init.c
Normal file
18
core/shared/platform/linux/platform_init.c
Normal file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "platform_api_vmcore.h"
|
||||
|
||||
int
|
||||
bh_platform_init()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
bh_platform_destroy()
|
||||
{
|
||||
}
|
||||
|
||||
61
core/shared/platform/linux/platform_internal.h
Normal file
61
core/shared/platform/linux/platform_internal.h
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#ifndef _PLATFORM_INTERNAL_H
|
||||
#define _PLATFORM_INTERNAL_H
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/timeb.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <limits.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef BH_PLATFORM_LINUX
|
||||
#define BH_PLATFORM_LINUX
|
||||
#endif
|
||||
|
||||
#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
|
||||
|
||||
typedef pthread_t korp_tid;
|
||||
typedef pthread_mutex_t korp_mutex;
|
||||
typedef pthread_cond_t korp_cond;
|
||||
typedef pthread_t korp_thread;
|
||||
|
||||
#define os_printf printf
|
||||
#define os_vprintf vprintf
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of _PLATFORM_INTERNAL_H */
|
||||
|
||||
@ -3,15 +3,16 @@
|
||||
|
||||
set (PLATFORM_SHARED_DIR ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
add_definitions(-DBH_PLATFORM_LINUX)
|
||||
|
||||
include_directories(${PLATFORM_SHARED_DIR})
|
||||
include_directories(${PLATFORM_SHARED_DIR}/../include)
|
||||
|
||||
include (${CMAKE_CURRENT_LIST_DIR}/../common/posix/platform_api_posix.cmake)
|
||||
|
||||
file (GLOB_RECURSE source_all ${PLATFORM_SHARED_DIR}/*.c)
|
||||
|
||||
set (PLATFORM_SHARED_SOURCE ${source_all})
|
||||
|
||||
LIST (APPEND RUNTIME_LIB_HEADER_LIST "${PLATFORM_SHARED_DIR}/bh_platform.h")
|
||||
set (PLATFORM_SHARED_SOURCE ${source_all} ${PLATFORM_COMMON_POSIX_SOURCE})
|
||||
|
||||
file (GLOB header ${PLATFORM_SHARED_DIR}/../include/*.h)
|
||||
LIST (APPEND RUNTIME_LIB_HEADER_LIST ${header})
|
||||
LIST (APPEND RUNTIME_LIB_HEADER_LIST ${header})
|
||||
|
||||
Reference in New Issue
Block a user