WebAssembly Micro Runtime first version
This commit is contained in:
69
core/shared-lib/platform/linux/bh_assert.c
Normal file
69
core/shared-lib/platform/linux/bh_assert.c
Normal 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
|
||||
}
|
||||
|
||||
81
core/shared-lib/platform/linux/bh_definition.c
Normal file
81
core/shared-lib/platform/linux/bh_definition.c
Normal 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;
|
||||
}
|
||||
27
core/shared-lib/platform/linux/bh_platform.c
Executable file
27
core/shared-lib/platform/linux/bh_platform.c
Executable file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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 <stdlib.h>
|
||||
#include <string.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;
|
||||
}
|
||||
129
core/shared-lib/platform/linux/bh_platform.h
Normal file
129
core/shared-lib/platform/linux/bh_platform.h
Normal file
@ -0,0 +1,129 @@
|
||||
/*
|
||||
* 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 <assert.h>
|
||||
|
||||
#ifndef __cplusplus
|
||||
int snprintf(char *buffer, size_t count, const char *format, ...);
|
||||
#endif
|
||||
|
||||
#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 "Linux"
|
||||
|
||||
/* NEED qsort */
|
||||
|
||||
#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>
|
||||
|
||||
#define _STACK_SIZE_ADJUSTMENT (32 * 1024)
|
||||
|
||||
/* Stack size of applet manager thread. */
|
||||
#define BH_APPLET_MANAGER_THREAD_STACK_SIZE (8 * 1024 + _STACK_SIZE_ADJUSTMENT)
|
||||
|
||||
/* Stack size of HMC thread. */
|
||||
#define BH_HMC_THREAD_STACK_SIZE (4 * 1024 + _STACK_SIZE_ADJUSTMENT)
|
||||
|
||||
/* Stack size of watchdog thread. */
|
||||
#define BH_WATCHDOG_THREAD_SIZE (4 * 1024 + _STACK_SIZE_ADJUSTMENT)
|
||||
|
||||
/* Stack size of applet threads's native part. */
|
||||
#define BH_APPLET_PRESERVED_STACK_SIZE (8 * 1024 + _STACK_SIZE_ADJUSTMENT)
|
||||
|
||||
/* Stack size of remote invoke listen thread. */
|
||||
#define BH_REMOTE_INVOKE_THREAD_STACK_SIZE (4 * 1024 + _STACK_SIZE_ADJUSTMENT)
|
||||
|
||||
/* Stack size of remote post listen thread. */
|
||||
#define BH_REMOTE_POST_THREAD_STACK_SIZE (4 * 1024 + _STACK_SIZE_ADJUSTMENT)
|
||||
|
||||
/* Maximal recursion depth of interpreter. */
|
||||
#define BH_MAX_INTERP_RECURSION_DEPTH 8
|
||||
|
||||
/* Default thread priority */
|
||||
#define BH_THREAD_DEFAULT_PRIORITY 0
|
||||
|
||||
#define BH_ROUTINE_MODIFIER
|
||||
#define BHT_TIMEDOUT ETIMEDOUT
|
||||
|
||||
#define INVALID_THREAD_ID 0xFFffFFff
|
||||
#define INVALID_SEM_ID SEM_FAILED
|
||||
|
||||
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
|
||||
|
||||
double fmod(double x, double y);
|
||||
float fmodf(float x, float y);
|
||||
|
||||
/* Definitions for applet debugging */
|
||||
#define APPLET_DEBUG_LISTEN_PORT 8000
|
||||
#define BH_SOCKET_INVALID_SOCK -1
|
||||
#define BH_WAIT_FOREVER 0xFFFFFFFF
|
||||
typedef int bh_socket_t;
|
||||
|
||||
#ifndef NULL
|
||||
# define NULL ((void*) 0)
|
||||
#endif
|
||||
|
||||
#define bh_assert assert
|
||||
|
||||
extern int b_memcpy_s(void * s1, unsigned int s1max, const void * s2,
|
||||
unsigned int n);
|
||||
extern int b_strcat_s(char * s1, size_t s1max, const char * s2);
|
||||
extern int b_strcpy_s(char * s1, size_t s1max, const char * s2);
|
||||
extern int fopen_s(FILE ** pFile, const char *filename, const char *mode);
|
||||
|
||||
extern char *bh_strdup(const char *s);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
41
core/shared-lib/platform/linux/bh_platform_log.c
Normal file
41
core/shared-lib/platform/linux/bh_platform_log.c
Normal 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);
|
||||
}
|
||||
404
core/shared-lib/platform/linux/bh_thread.c
Executable file
404
core/shared-lib/platform/linux/bh_thread.c
Executable file
@ -0,0 +1,404 @@
|
||||
/*
|
||||
* 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 *) ((unsigned int) (&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_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 == 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);
|
||||
}
|
||||
|
||||
80
core/shared-lib/platform/linux/bh_time.c
Executable file
80
core/shared-lib/platform/linux/bh_time.c
Executable 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);
|
||||
}
|
||||
|
||||
24
core/shared-lib/platform/linux/shared_platform.cmake
Normal file
24
core/shared-lib/platform/linux/shared_platform.cmake
Normal 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})
|
||||
|
||||
Reference in New Issue
Block a user