mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-02-06 06:55:07 +00:00
Modify os_cond_reltimedwait to support long time wait (#461)
Modify the argument of os_cond_reltimedwait to uint64 type to support long time wait, and handle possible integer overflow.
This commit is contained in:
parent
a84d51271c
commit
388530c738
|
@ -42,17 +42,18 @@ wasm_timer_callback(timer_id_t id, unsigned int mod_id)
|
|||
|
||||
void * thread_modulers_timer_check(void * arg)
|
||||
{
|
||||
int ms_to_expiry;
|
||||
uint32 ms_to_expiry;
|
||||
uint64 us_to_wait;
|
||||
|
||||
while (timer_thread_run) {
|
||||
ms_to_expiry = -1;
|
||||
ms_to_expiry = (uint32)-1;
|
||||
os_mutex_lock(&g_timer_ctx_list_mutex);
|
||||
timer_ctx_node_t* elem = (timer_ctx_node_t*)
|
||||
bh_list_first_elem(&g_timer_ctx_list);
|
||||
while (elem) {
|
||||
int next = check_app_timers(elem->timer_ctx);
|
||||
if (next != -1) {
|
||||
if (ms_to_expiry == -1 || ms_to_expiry > next)
|
||||
uint32 next = check_app_timers(elem->timer_ctx);
|
||||
if (next != (uint32)-1) {
|
||||
if (ms_to_expiry == (uint32)-1 || ms_to_expiry > next)
|
||||
ms_to_expiry = next;
|
||||
}
|
||||
|
||||
|
@ -60,11 +61,13 @@ void * thread_modulers_timer_check(void * arg)
|
|||
}
|
||||
os_mutex_unlock(&g_timer_ctx_list_mutex);
|
||||
|
||||
if (ms_to_expiry == -1)
|
||||
ms_to_expiry = 60 * 1000;
|
||||
if (ms_to_expiry == (uint32)-1)
|
||||
us_to_wait = BHT_WAIT_FOREVER;
|
||||
else
|
||||
us_to_wait = (uint64)ms_to_expiry * 1000;
|
||||
os_mutex_lock(&g_timer_ctx_list_mutex);
|
||||
os_cond_reltimedwait(&g_timer_ctx_list_cond, &g_timer_ctx_list_mutex,
|
||||
ms_to_expiry * 1000);
|
||||
us_to_wait);
|
||||
os_mutex_unlock(&g_timer_ctx_list_mutex);
|
||||
}
|
||||
|
||||
|
|
|
@ -848,7 +848,7 @@ pthread_cond_wait_wrapper(wasm_exec_env_t exec_env, uint32 *cond, uint32 *mutex)
|
|||
*/
|
||||
static int32
|
||||
pthread_cond_timedwait_wrapper(wasm_exec_env_t exec_env, uint32 *cond,
|
||||
uint32 *mutex, uint32 useconds)
|
||||
uint32 *mutex, uint64 useconds)
|
||||
{
|
||||
ThreadInfoNode *cond_info_node, *mutex_info_node;
|
||||
|
||||
|
@ -1014,7 +1014,7 @@ static NativeSymbol native_symbols_lib_pthread[] = {
|
|||
REG_NATIVE_FUNC(pthread_mutex_destroy, "(*)i"),
|
||||
REG_NATIVE_FUNC(pthread_cond_init, "(**)i"),
|
||||
REG_NATIVE_FUNC(pthread_cond_wait, "(**)i"),
|
||||
REG_NATIVE_FUNC(pthread_cond_timedwait, "(**i)i"),
|
||||
REG_NATIVE_FUNC(pthread_cond_timedwait, "(**I)i"),
|
||||
REG_NATIVE_FUNC(pthread_cond_signal, "(*)i"),
|
||||
REG_NATIVE_FUNC(pthread_cond_destroy, "(*)i"),
|
||||
REG_NATIVE_FUNC(pthread_key_create, "(*i)i"),
|
||||
|
@ -1028,4 +1028,4 @@ get_lib_pthread_export_apis(NativeSymbol **p_lib_pthread_apis)
|
|||
{
|
||||
*p_lib_pthread_apis = native_symbols_lib_pthread;
|
||||
return sizeof(native_symbols_lib_pthread) / sizeof(NativeSymbol);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -273,7 +273,7 @@ os_cond_destroy(korp_cond *cond)
|
|||
|
||||
static int
|
||||
os_cond_wait_internal(korp_cond *cond, korp_mutex *mutex,
|
||||
bool timed, int mills)
|
||||
bool timed, uint32 mills)
|
||||
{
|
||||
os_thread_wait_node *node = &thread_data_current()->wait_node;
|
||||
|
||||
|
@ -319,12 +319,25 @@ os_cond_wait(korp_cond *cond, korp_mutex *mutex)
|
|||
}
|
||||
|
||||
int
|
||||
os_cond_reltimedwait(korp_cond *cond, korp_mutex *mutex, int useconds)
|
||||
os_cond_reltimedwait(korp_cond *cond, korp_mutex *mutex, uint64 useconds)
|
||||
{
|
||||
if (useconds == BHT_WAIT_FOREVER)
|
||||
if (useconds == BHT_WAIT_FOREVER) {
|
||||
return os_cond_wait_internal(cond, mutex, false, 0);
|
||||
else
|
||||
return os_cond_wait_internal(cond, mutex, true, useconds / 1000);
|
||||
}
|
||||
else {
|
||||
uint64 mills_64 = useconds / 1000;
|
||||
uint32 mills;
|
||||
|
||||
if (mills_64 < (uint64)(UINT32_MAX - 1)) {
|
||||
mills = (uint64)mills_64;
|
||||
}
|
||||
else {
|
||||
mills = UINT32_MAX - 1;
|
||||
os_printf("Warning: os_cond_reltimedwait exceeds limit, "
|
||||
"set to max timeout instead\n");
|
||||
}
|
||||
return os_cond_wait_internal(cond, mutex, true, mills);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -404,12 +404,25 @@ int os_cond_wait(korp_cond *cond, korp_mutex *mutex)
|
|||
return os_cond_wait_internal(cond, mutex, false, 0);
|
||||
}
|
||||
|
||||
int os_cond_reltimedwait(korp_cond *cond, korp_mutex *mutex, int useconds)
|
||||
int os_cond_reltimedwait(korp_cond *cond, korp_mutex *mutex, uint64 useconds)
|
||||
{
|
||||
if (useconds == BHT_WAIT_FOREVER)
|
||||
if (useconds == BHT_WAIT_FOREVER) {
|
||||
return os_cond_wait_internal(cond, mutex, false, 0);
|
||||
else
|
||||
return os_cond_wait_internal(cond, mutex, true, useconds / 1000);
|
||||
}
|
||||
else {
|
||||
uint64 mills_64 = useconds / 1000;
|
||||
int32 mills;
|
||||
|
||||
if (mills_64 < (uint64)INT32_MAX) {
|
||||
mills = (int32)mills_64;
|
||||
}
|
||||
else {
|
||||
mills = INT32_MAX;
|
||||
os_printf("Warning: os_cond_reltimedwait exceeds limit, "
|
||||
"set to max timeout instead\n");
|
||||
}
|
||||
return os_cond_wait_internal(cond, mutex, true, mills);
|
||||
}
|
||||
}
|
||||
|
||||
int os_cond_signal(korp_cond *cond)
|
||||
|
|
|
@ -163,27 +163,48 @@ int os_cond_wait(korp_cond *cond, korp_mutex *mutex)
|
|||
return BHT_OK;
|
||||
}
|
||||
|
||||
static void msec_nsec_to_abstime(struct timespec *ts, int usec)
|
||||
static void msec_nsec_to_abstime(struct timespec *ts, uint64 usec)
|
||||
{
|
||||
struct timeval tv;
|
||||
long int tv_sec_new, tv_nsec_new;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
ts->tv_sec = (long int)(tv.tv_sec + usec / 1000000);
|
||||
ts->tv_nsec = (long int)(tv.tv_usec * 1000 + (usec % 1000000) * 1000);
|
||||
tv_sec_new = (long int)(tv.tv_sec + usec / 1000000);
|
||||
if (tv_sec_new >= tv.tv_sec) {
|
||||
ts->tv_sec = tv_sec_new;
|
||||
}
|
||||
else {
|
||||
/* integer overflow */
|
||||
ts->tv_sec = LONG_MAX;
|
||||
os_printf("Warning: os_cond_reltimedwait exceeds limit, "
|
||||
"set to max timeout instead\n");
|
||||
}
|
||||
|
||||
if (ts->tv_nsec >= 1000000000L) {
|
||||
tv_nsec_new = (long int)(tv.tv_usec * 1000 + (usec % 1000000) * 1000);
|
||||
if (tv.tv_usec * 1000 >= tv.tv_usec
|
||||
&& tv_nsec_new >= tv.tv_usec * 1000) {
|
||||
ts->tv_nsec = tv_nsec_new;
|
||||
}
|
||||
else {
|
||||
/* integer overflow */
|
||||
ts->tv_nsec = LONG_MAX;
|
||||
os_printf("Warning: os_cond_reltimedwait exceeds limit, "
|
||||
"set to max timeout instead\n");
|
||||
}
|
||||
|
||||
if (ts->tv_nsec >= 1000000000L && ts->tv_sec < LONG_MAX) {
|
||||
ts->tv_sec++;
|
||||
ts->tv_nsec -= 1000000000L;
|
||||
}
|
||||
}
|
||||
|
||||
int os_cond_reltimedwait(korp_cond *cond, korp_mutex *mutex, int useconds)
|
||||
int os_cond_reltimedwait(korp_cond *cond, korp_mutex *mutex, uint64 useconds)
|
||||
{
|
||||
int ret;
|
||||
struct timespec abstime;
|
||||
|
||||
if (useconds == (int)BHT_WAIT_FOREVER)
|
||||
if (useconds == BHT_WAIT_FOREVER)
|
||||
ret = pthread_cond_wait(cond, mutex);
|
||||
else {
|
||||
msec_nsec_to_abstime(&abstime, useconds);
|
||||
|
@ -290,7 +311,6 @@ mask_signals(int how)
|
|||
__attribute__((noreturn)) static void
|
||||
signal_callback(int sig_num, siginfo_t *sig_info, void *sig_ucontext)
|
||||
{
|
||||
int i;
|
||||
void *sig_addr = sig_info->si_addr;
|
||||
|
||||
mask_signals(SIG_BLOCK);
|
||||
|
@ -314,12 +334,7 @@ signal_callback(int sig_num, siginfo_t *sig_info, void *sig_ucontext)
|
|||
break;
|
||||
}
|
||||
|
||||
/* divived by 0 to make it abort */
|
||||
i = os_printf(" ");
|
||||
os_printf("%d\n", i / (i - 1));
|
||||
/* access NULL ptr to make it abort */
|
||||
os_printf("%d\n", *(uint32*)(uintptr_t)(i - 1));
|
||||
exit(1);
|
||||
abort();
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -138,7 +138,7 @@ int os_cond_wait(korp_cond *cond, korp_mutex *mutex);
|
|||
*
|
||||
* @return 0 if success
|
||||
*/
|
||||
int os_cond_reltimedwait(korp_cond *cond, korp_mutex *mutex, int useconds);
|
||||
int os_cond_reltimedwait(korp_cond *cond, korp_mutex *mutex, uint64 useconds);
|
||||
|
||||
/**
|
||||
* Signals the condition variable
|
||||
|
|
|
@ -19,8 +19,7 @@ extern "C" {
|
|||
#define BHT_TIMED_OUT (1)
|
||||
#define BHT_OK (0)
|
||||
|
||||
#define BHT_NO_WAIT 0x00000000
|
||||
#define BHT_WAIT_FOREVER 0xFFFFFFFF
|
||||
#define BHT_WAIT_FOREVER ((uint64)-1LL)
|
||||
|
||||
#define BH_KB (1024)
|
||||
#define BH_MB ((BH_KB)*1024)
|
||||
|
|
|
@ -129,7 +129,7 @@ int os_cond_wait(korp_cond *cond, korp_mutex *mutex)
|
|||
return BHT_OK;
|
||||
}
|
||||
|
||||
int os_cond_reltimedwait(korp_cond *cond, korp_mutex *mutex, int useconds)
|
||||
int os_cond_reltimedwait(korp_cond *cond, korp_mutex *mutex, uint64 useconds)
|
||||
{
|
||||
os_printf("warning: SGX pthread_cond_timedwait isn't supported, "
|
||||
"calling pthread_cond_wait instead!\n");
|
||||
|
|
|
@ -399,11 +399,10 @@ os_cond_wait(korp_cond *cond, korp_mutex *mutex)
|
|||
}
|
||||
|
||||
int
|
||||
os_cond_reltimedwait(korp_cond *cond, korp_mutex *mutex, int useconds)
|
||||
os_cond_reltimedwait(korp_cond *cond, korp_mutex *mutex, uint64 useconds)
|
||||
{
|
||||
uint64 useconds64 = (uint64) useconds;
|
||||
return os_cond_wait_internal(cond, mutex,
|
||||
(useconds64 != BHT_WAIT_FOREVER), useconds64);
|
||||
(useconds != BHT_WAIT_FOREVER), useconds);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -125,7 +125,7 @@ static void msec_nsec_to_abstime(struct timespec *ts, int usec)
|
|||
}
|
||||
}
|
||||
|
||||
int os_cond_reltimedwait(korp_cond *cond, korp_mutex *mutex, int useconds)
|
||||
int os_cond_reltimedwait(korp_cond *cond, korp_mutex *mutex, uint64 useconds)
|
||||
{
|
||||
return BHT_OK;
|
||||
}
|
||||
|
|
|
@ -420,13 +420,26 @@ int os_cond_wait(korp_cond *cond, korp_mutex *mutex)
|
|||
return os_cond_wait_internal(cond, mutex, false, 0);
|
||||
}
|
||||
|
||||
int os_cond_reltimedwait(korp_cond *cond, korp_mutex *mutex, int useconds)
|
||||
int os_cond_reltimedwait(korp_cond *cond, korp_mutex *mutex, uint64 useconds)
|
||||
{
|
||||
|
||||
if (useconds == BHT_WAIT_FOREVER)
|
||||
if (useconds == BHT_WAIT_FOREVER) {
|
||||
return os_cond_wait_internal(cond, mutex, false, 0);
|
||||
else
|
||||
return os_cond_wait_internal(cond, mutex, true, useconds / 1000);
|
||||
}
|
||||
else {
|
||||
uint64 mills_64 = useconds / 1000;
|
||||
int32 mills;
|
||||
|
||||
if (mills_64 < (uint64)INT32_MAX) {
|
||||
mills = (int32)mills_64;
|
||||
}
|
||||
else {
|
||||
mills = INT32_MAX;
|
||||
os_printf("Warning: os_cond_reltimedwait exceeds limit, "
|
||||
"set to max timeout instead\n");
|
||||
}
|
||||
return os_cond_wait_internal(cond, mutex, true, mills);
|
||||
}
|
||||
}
|
||||
|
||||
int os_cond_signal(korp_cond *cond)
|
||||
|
|
|
@ -171,7 +171,7 @@ void bh_free_msg(bh_queue_node *msg)
|
|||
bh_queue_free(msg);
|
||||
}
|
||||
|
||||
bh_message_t bh_get_msg(bh_queue *queue, int timeout)
|
||||
bh_message_t bh_get_msg(bh_queue *queue, uint64 timeout_us)
|
||||
{
|
||||
bh_queue_node *msg = NULL;
|
||||
bh_queue_mutex_lock(&queue->queue_lock);
|
||||
|
@ -180,13 +180,13 @@ bh_message_t bh_get_msg(bh_queue *queue, int timeout)
|
|||
bh_assert(queue->head == NULL);
|
||||
bh_assert(queue->tail == NULL);
|
||||
|
||||
if (timeout == 0) {
|
||||
if (timeout_us == 0) {
|
||||
bh_queue_mutex_unlock(&queue->queue_lock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bh_queue_cond_timedwait(&queue->queue_wait_cond, &queue->queue_lock,
|
||||
timeout);
|
||||
timeout_us);
|
||||
}
|
||||
|
||||
if (queue->cnt == 0) {
|
||||
|
@ -226,7 +226,7 @@ void bh_queue_enter_loop_run(bh_queue *queue,
|
|||
return;
|
||||
|
||||
while (!queue->exit_loop_run) {
|
||||
bh_queue_node * message = bh_get_msg(queue, (int)BHT_WAIT_FOREVER);
|
||||
bh_queue_node * message = bh_get_msg(queue, BHT_WAIT_FOREVER);
|
||||
|
||||
if (message) {
|
||||
handle_cb(message, arg);
|
||||
|
|
|
@ -56,7 +56,7 @@ bool bh_post_msg(bh_queue *queue, unsigned short tag, void *body,
|
|||
unsigned int len);
|
||||
bool bh_post_msg2(bh_queue *queue, bh_message_t msg);
|
||||
|
||||
bh_message_t bh_get_msg(bh_queue *queue, int timeout);
|
||||
bh_message_t bh_get_msg(bh_queue *queue, uint64 timeout_us);
|
||||
|
||||
unsigned
|
||||
bh_queue_get_message_count(bh_queue *queue);
|
||||
|
|
|
@ -396,7 +396,6 @@ handle_expired_timers(timer_ctx_t ctx, app_timer_t *expired)
|
|||
if (t->is_periodic) {
|
||||
/* if it is repeating, then reschedule it; */
|
||||
reschedule_timer(ctx, t);
|
||||
|
||||
}
|
||||
else {
|
||||
/* else move it to idle list */
|
||||
|
@ -423,10 +422,10 @@ get_expiry_ms(timer_ctx_t ctx)
|
|||
return ms_to_next_expiry;
|
||||
}
|
||||
|
||||
int
|
||||
uint32
|
||||
check_app_timers(timer_ctx_t ctx)
|
||||
{
|
||||
app_timer_t *t, *expired = NULL;
|
||||
app_timer_t *t, *expired = NULL, *expired_end = NULL;
|
||||
uint64 now = bh_get_tick_ms();
|
||||
|
||||
os_mutex_lock(&ctx->mutex);
|
||||
|
@ -436,8 +435,15 @@ check_app_timers(timer_ctx_t ctx)
|
|||
if (now >= t->expiry) {
|
||||
ctx->app_timers = t->next;
|
||||
|
||||
t->next = expired;
|
||||
expired = t;
|
||||
/* append t to the end of expired list */
|
||||
t->next = NULL;
|
||||
if (!expired_end) {
|
||||
expired = expired_end = t;
|
||||
}
|
||||
else {
|
||||
expired_end->next = t;
|
||||
expired_end = t;
|
||||
}
|
||||
|
||||
t = ctx->app_timers;
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ bool sys_timer_destroy(timer_ctx_t ctx, uint32 timer_id);
|
|||
bool sys_timer_cancel(timer_ctx_t ctx, uint32 timer_id);
|
||||
bool sys_timer_restart(timer_ctx_t ctx, uint32 timer_id, int interval);
|
||||
void cleanup_app_timers(timer_ctx_t ctx);
|
||||
int check_app_timers(timer_ctx_t ctx);
|
||||
uint32 check_app_timers(timer_ctx_t ctx);
|
||||
uint32 get_expiry_ms(timer_ctx_t ctx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#ifndef _WAMR_LIB_PTHREAD_H
|
||||
#define _WAMR_LIB_PTHREAD_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* Data type define of pthread, mutex, cond and key */
|
||||
typedef unsigned int pthread_t;
|
||||
typedef unsigned int pthread_mutex_t;
|
||||
|
@ -41,7 +43,7 @@ int pthread_cond_init(pthread_cond_t *cond, const void *attr);
|
|||
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
|
||||
|
||||
int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
unsigned int useconds);
|
||||
uint64_t useconds);
|
||||
|
||||
int pthread_cond_signal(pthread_cond_t *cond);
|
||||
|
||||
|
@ -56,4 +58,4 @@ void *pthread_getspecific(pthread_key_t key);
|
|||
|
||||
int pthread_key_delete(pthread_key_t key);
|
||||
|
||||
#endif /* end of _WAMR_LIB_PTHREAD_H */
|
||||
#endif /* end of _WAMR_LIB_PTHREAD_H */
|
||||
|
|
Loading…
Reference in New Issue
Block a user