WebAssembly Micro Runtime first version
This commit is contained in:
67
core/shared-lib/platform/win32/bh_assert.c
Normal file
67
core/shared-lib/platform/win32/bh_assert.c
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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>
|
||||
|
||||
#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
|
||||
}
|
||||
|
||||
22
core/shared-lib/platform/win32/bh_definition.c
Normal file
22
core/shared-lib/platform/win32/bh_definition.c
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* 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"
|
||||
|
||||
int bh_return(int ret)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
93
core/shared-lib/platform/win32/bh_platform.h
Executable file
93
core/shared-lib/platform/win32/bh_platform.h
Executable file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* 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"
|
||||
|
||||
#ifndef NVALGRIND
|
||||
#define NVALGRIND
|
||||
#endif
|
||||
|
||||
/* Reserve bytes on applet stack for native functions called from
|
||||
* Java methods to avoid undetectable stack overflow.
|
||||
*/
|
||||
#ifndef APPLET_PRESERVED_STACK_SIZE
|
||||
#define APPLET_PRESERVED_STACK_SIZE (16 * BH_KB)
|
||||
#endif
|
||||
|
||||
typedef unsigned __int64 uint64;
|
||||
typedef __int64 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_INVALID_HANDLE
|
||||
#define BH_INVALID_HANDLE NULL
|
||||
#endif
|
||||
|
||||
#define BH_PLATFORM "AMULET"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <math.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)
|
||||
|
||||
/* Maximal recursion depth of interpreter. */
|
||||
#define BH_MAX_INTERP_RECURSION_DEPTH 8
|
||||
|
||||
#define wa_malloc bh_malloc
|
||||
#define wa_free bh_free
|
||||
|
||||
#define snprintf _snprintf
|
||||
|
||||
#define BH_ROUTINE_MODIFIER __stdcall
|
||||
|
||||
typedef void *korp_tid;
|
||||
#define INVALID_THREAD_ID 0
|
||||
|
||||
typedef void *korp_mutex;
|
||||
typedef void *korp_sem;
|
||||
|
||||
typedef struct {
|
||||
korp_sem s;
|
||||
unsigned waiting_count;
|
||||
} korp_cond;
|
||||
|
||||
typedef void* (BH_ROUTINE_MODIFIER *thread_start_routine_t)(void*);
|
||||
|
||||
#endif
|
||||
|
||||
39
core/shared-lib/platform/win32/bh_platform_log.c
Executable file
39
core/shared-lib/platform/win32/bh_platform_log.c
Executable file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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 <stdio.h>
|
||||
#include "bh_platform.h"
|
||||
|
||||
void bh_log_emit(const char *fmt, va_list ap)
|
||||
{
|
||||
vprintf(fmt, ap);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
int bh_fprintf(FILE *stream, const char *fmt, ...)
|
||||
{
|
||||
int ret;
|
||||
va_list ap;
|
||||
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);
|
||||
}
|
||||
342
core/shared-lib/platform/win32/bh_thread.c
Executable file
342
core/shared-lib/platform/win32/bh_thread.c
Executable file
@ -0,0 +1,342 @@
|
||||
/*
|
||||
* 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 <windows.h>
|
||||
#include <process.h>
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define THREAD_STACK_ADJUSTMENT (32 * 1024)
|
||||
#else
|
||||
#define THREAD_STACK_ADJUSTMENT 0
|
||||
#endif
|
||||
|
||||
static korp_mutex thread_list_lock;
|
||||
static DWORD tls_indexes[BH_MAX_TLS_NUM];
|
||||
|
||||
typedef struct {
|
||||
int zero_padding;
|
||||
thread_start_routine_t start;
|
||||
void* stack;
|
||||
void* args;
|
||||
int stack_size;
|
||||
} vm_thread_block;
|
||||
|
||||
static DWORD tb_index;
|
||||
|
||||
int _vm_thread_sys_init()
|
||||
{
|
||||
unsigned int i;
|
||||
for (i = 0; i < BH_MAX_TLS_NUM; i++) {
|
||||
tls_indexes[i] = TlsAlloc();
|
||||
if (tls_indexes[i] == TLS_OUT_OF_INDEXES)
|
||||
return BHT_ERROR;
|
||||
}
|
||||
|
||||
tb_index = TlsAlloc();
|
||||
if (tb_index == TLS_OUT_OF_INDEXES)
|
||||
return BHT_ERROR;
|
||||
|
||||
return vm_mutex_init(&thread_list_lock);
|
||||
}
|
||||
|
||||
static unsigned int BH_ROUTINE_MODIFIER beihai_starter(void* arg)
|
||||
{
|
||||
vm_thread_block* tb = (vm_thread_block*) arg;
|
||||
TlsSetValue(tb_index, tb);
|
||||
tb->stack = (void *) &arg;
|
||||
tb->start(tb->args);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _vm_thread_create(korp_tid *tid, thread_start_routine_t start, void *arg,
|
||||
unsigned int stack_size)
|
||||
{
|
||||
unsigned int default_stack_size = 20 * 1024;
|
||||
vm_thread_block* tb;
|
||||
bh_assert(tid);
|
||||
bh_assert(start);
|
||||
|
||||
if (stack_size == 0)
|
||||
stack_size = default_stack_size;
|
||||
|
||||
#ifdef _DEBUG
|
||||
stack_size = THREAD_STACK_ADJUSTMENT + stack_size*3;
|
||||
#endif
|
||||
|
||||
tb = (vm_thread_block*) bh_malloc(sizeof(*tb));
|
||||
if (tb == NULL)
|
||||
return BHT_ERROR;
|
||||
|
||||
memset(tb, 0, sizeof(*tb));
|
||||
|
||||
tb->start = start;
|
||||
tb->stack_size = stack_size;
|
||||
tb->args = arg;
|
||||
|
||||
*tid = (korp_tid) _beginthreadex(NULL, stack_size, beihai_starter,
|
||||
(void*) tb, 0, NULL);
|
||||
|
||||
/* TODO: to deal with the handle; how to close it? */
|
||||
return (*tid == INVALID_THREAD_ID) ? BHT_ERROR : BHT_OK;
|
||||
}
|
||||
|
||||
korp_tid _vm_self_thread()
|
||||
{
|
||||
return (korp_tid) GetCurrentThread();
|
||||
}
|
||||
|
||||
void vm_thread_exit(void *code)
|
||||
{
|
||||
vm_thread_block *tb = (vm_thread_block*) TlsGetValue(tb_index);
|
||||
bh_free(tb);
|
||||
_endthreadex((unsigned int) code);
|
||||
}
|
||||
|
||||
void* vm_get_stackaddr()
|
||||
{
|
||||
vm_thread_block *tb = (vm_thread_block*) TlsGetValue(tb_index);
|
||||
return (char *) tb->stack + THREAD_STACK_ADJUSTMENT - tb->stack_size;
|
||||
}
|
||||
|
||||
void *_vm_tls_get(unsigned idx)
|
||||
{
|
||||
bh_assert(idx < BH_MAX_TLS_NUM);
|
||||
return TlsGetValue(tls_indexes[idx]);
|
||||
}
|
||||
|
||||
int _vm_tls_put(unsigned idx, void *tls)
|
||||
{
|
||||
BOOL r;
|
||||
|
||||
bh_assert(idx < BH_MAX_TLS_NUM);
|
||||
r = TlsSetValue(tls_indexes[idx], tls);
|
||||
return (r == FALSE) ? BHT_ERROR : BHT_OK;
|
||||
}
|
||||
|
||||
int _vm_mutex_init(korp_mutex *mutex)
|
||||
{
|
||||
bh_assert(mutex);
|
||||
*mutex = CreateMutex(NULL, FALSE, NULL);
|
||||
return (*mutex == 0) ? BHT_ERROR : BHT_OK;
|
||||
}
|
||||
|
||||
int _vm_mutex_destroy(korp_mutex *mutex)
|
||||
{
|
||||
return BHT_OK;
|
||||
}
|
||||
|
||||
/* Returned error (e.g. ERROR_INVALID_HANDLE) 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)
|
||||
{
|
||||
DWORD ret;
|
||||
|
||||
bh_assert(mutex);
|
||||
ret = WaitForSingleObject(*mutex, INFINITE);
|
||||
if (WAIT_FAILED == ret) {
|
||||
LOG_FATAL("vm mutex lock failed (ret=%d)!\n", GetLastError());
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
int vm_mutex_trylock(korp_mutex *mutex)
|
||||
{
|
||||
DWORD ret;
|
||||
|
||||
bh_assert(mutex);
|
||||
ret = WaitForSingleObject(*mutex, 0);
|
||||
if (WAIT_FAILED == ret) {
|
||||
LOG_FATAL("vm mutex lock failed (ret=%d)!\n", GetLastError());
|
||||
exit(-1);
|
||||
}
|
||||
return ret == WAIT_OBJECT_0 ? BHT_OK : BHT_ERROR;
|
||||
}
|
||||
|
||||
/* Returned error (e.g. ERROR_INVALID_HANDLE) 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)
|
||||
{
|
||||
BOOL ret;
|
||||
|
||||
bh_assert(mutex);
|
||||
ret = ReleaseMutex(*mutex);
|
||||
if (FALSE == ret) {
|
||||
LOG_FATAL("vm mutex unlock failed (ret=%d)!\n", GetLastError());
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
#define BH_SEM_COUNT_MAX 0xFFFF
|
||||
|
||||
int _vm_sem_init(korp_sem *sem, unsigned int count)
|
||||
{
|
||||
bh_assert(sem);
|
||||
bh_assert(count <= BH_SEM_COUNT_MAX);
|
||||
*sem = CreateSemaphore(NULL, count, BH_SEM_COUNT_MAX, NULL);
|
||||
|
||||
return (*sem == NULL) ? BHT_ERROR : BHT_OK;
|
||||
}
|
||||
|
||||
int _vm_sem_destroy(korp_sem *sem)
|
||||
{
|
||||
return BHT_OK;
|
||||
}
|
||||
|
||||
int _vm_sem_P(korp_sem *sem)
|
||||
{
|
||||
DWORD r;
|
||||
bh_assert(sem);
|
||||
r = WaitForSingleObject(*sem, INFINITE);
|
||||
|
||||
return (r == WAIT_FAILED) ? BHT_ERROR : BHT_OK;
|
||||
}
|
||||
|
||||
int _vm_sem_reltimedP(korp_sem *sem, int mills)
|
||||
{
|
||||
DWORD r;
|
||||
bh_assert(sem);
|
||||
|
||||
if (mills == BHT_WAIT_FOREVER)
|
||||
mills = INFINITE;
|
||||
|
||||
r = WaitForSingleObject(*sem, (unsigned int) mills);
|
||||
|
||||
switch (r) {
|
||||
case WAIT_OBJECT_0:
|
||||
return BHT_OK;
|
||||
case WAIT_TIMEOUT:
|
||||
return BHT_TIMEDOUT;
|
||||
default:
|
||||
return BHT_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
int _vm_sem_V(korp_sem *sem)
|
||||
{
|
||||
BOOL r;
|
||||
bh_assert(sem);
|
||||
r = ReleaseSemaphore(*sem, 1, NULL);
|
||||
return (r == FALSE) ? BHT_ERROR : BHT_OK;
|
||||
}
|
||||
|
||||
int _vm_cond_init(korp_cond *cond)
|
||||
{
|
||||
bh_assert(cond);
|
||||
cond->waiting_count = 0;
|
||||
return vm_sem_init(&cond->s, 0);
|
||||
}
|
||||
|
||||
int _vm_cond_destroy(korp_cond *cond)
|
||||
{
|
||||
bh_assert(cond);
|
||||
return vm_sem_destroy(&cond->s);
|
||||
}
|
||||
|
||||
int _vm_cond_wait(korp_cond *cond, korp_mutex *mutex)
|
||||
{
|
||||
bh_assert(cond);
|
||||
bh_assert(mutex);
|
||||
|
||||
cond->waiting_count++;
|
||||
|
||||
vm_mutex_unlock(mutex);
|
||||
|
||||
if (vm_sem_P(&cond->s) != BHT_OK)
|
||||
return BHT_ERROR;
|
||||
|
||||
vm_mutex_lock(mutex);
|
||||
|
||||
cond->waiting_count--;
|
||||
|
||||
return BHT_OK;
|
||||
}
|
||||
|
||||
int _vm_cond_reltimedwait(korp_cond *cond, korp_mutex *mutex, int mills)
|
||||
{
|
||||
int r;
|
||||
|
||||
bh_assert(cond);
|
||||
bh_assert(mutex);
|
||||
|
||||
cond->waiting_count++;
|
||||
|
||||
vm_mutex_unlock(mutex);
|
||||
|
||||
r = vm_sem_reltimedP(&cond->s, mills);
|
||||
|
||||
if ((r != BHT_OK) && (r != BHT_TIMEDOUT))
|
||||
return BHT_ERROR;
|
||||
|
||||
vm_mutex_lock(mutex);
|
||||
|
||||
cond->waiting_count--;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int _vm_cond_signal(korp_cond *cond)
|
||||
{
|
||||
bh_assert(cond);
|
||||
|
||||
if (cond->waiting_count == 0)
|
||||
return BHT_OK;
|
||||
|
||||
if (vm_sem_V(&cond->s) != BHT_OK)
|
||||
return BHT_ERROR;
|
||||
|
||||
return BHT_OK;
|
||||
}
|
||||
|
||||
int _vm_cond_broadcast(korp_cond *cond)
|
||||
{
|
||||
/* FIXME: use pthread's API to implement this and above
|
||||
functions. */
|
||||
|
||||
unsigned count = cond->waiting_count;
|
||||
|
||||
for (; count > 0; count--)
|
||||
vm_sem_V(&cond->s);
|
||||
|
||||
return BHT_OK;
|
||||
}
|
||||
|
||||
int _vm_thread_cancel(korp_tid thread)
|
||||
{
|
||||
/* FIXME: implement this with Windows API. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _vm_thread_join(korp_tid thread, void **value_ptr)
|
||||
{
|
||||
/* FIXME: implement this with Windows API. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _vm_thread_detach(korp_tid thread)
|
||||
{
|
||||
/* FIXME: implement this with Windows API. */
|
||||
return 0;
|
||||
}
|
||||
101
core/shared-lib/platform/win32/bh_time.c
Executable file
101
core/shared-lib/platform/win32/bh_time.c
Executable file
@ -0,0 +1,101 @@
|
||||
/*
|
||||
* 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 <stdio.h>
|
||||
#include "bh_time.h"
|
||||
|
||||
#include <time.h>
|
||||
#include <sys/timeb.h>
|
||||
|
||||
/* Since GetTickCount64 is not supported on Windows XP, use a temporary method
|
||||
* to solve the issue. However, GetTickCount return a DWORD value and overflow
|
||||
* may happen (http://msdn.microsoft.com/en-us/library/ms724408(v=vs.85).aspx).
|
||||
*
|
||||
* TODO: Implement GetTickCount64 on Windows XP by self or check overflow issues.
|
||||
*/
|
||||
#if (WINVER >= 0x0600)
|
||||
extern uint64 __stdcall GetTickCount64(void);
|
||||
#else
|
||||
extern uint32 __stdcall GetTickCount(void);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This function returns milliseconds per tick.
|
||||
* @return milliseconds per tick.
|
||||
*/
|
||||
uint64 _bh_time_get_tick_millisecond()
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function returns milliseconds after boot.
|
||||
* @return milliseconds after boot.
|
||||
*/
|
||||
uint64 _bh_time_get_boot_millisecond()
|
||||
{
|
||||
/* Since GetTickCount64 is not supported on Windows XP, use a temporary method
|
||||
* to solve the issue. However, GetTickCount return a DWORD value and overflow
|
||||
* may happen (http://msdn.microsoft.com/en-us/library/ms724408(v=vs.85).aspx).
|
||||
*
|
||||
* TODO: Implement GetTickCount64 on Windows XP by self or check overflow issues.
|
||||
*/
|
||||
#if (WINVER >= 0x0600)
|
||||
return GetTickCount64();
|
||||
#else
|
||||
return GetTickCount();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 local_time;
|
||||
|
||||
if (NULL == s)
|
||||
return 0;
|
||||
|
||||
ftime(&tp);
|
||||
time_sec -= tp.timezone * 60;
|
||||
if (localtime_s(&local_time, &time_sec) != 0)
|
||||
return 0;
|
||||
|
||||
return strftime(s, max, format, &local_time);
|
||||
}
|
||||
|
||||
int bh_time_get(uint8 *timeoff_info, int16 timeoff_info_len, uint32* time)
|
||||
{
|
||||
return BH_UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
int bh_time_set(uint32 ntp, uint8 *timeoff_info)
|
||||
{
|
||||
return BH_UNIMPLEMENTED;
|
||||
}
|
||||
Reference in New Issue
Block a user