From 5c73ee43c159089f1df4ea46dc77590bcad394c6 Mon Sep 17 00:00:00 2001 From: Marcus Winter Date: Tue, 21 Jun 2016 09:52:10 +0200 Subject: [PATCH] mtapi_c: fixed problem with non monotonic time readings and timeouts --- mtapi_c/src/embb_mtapi_action_t.c | 16 ++++++++++++++++ mtapi_c/src/embb_mtapi_group_t.c | 16 ++++++++++++++++ mtapi_c/src/embb_mtapi_queue_t.c | 16 ++++++++++++++++ mtapi_c/src/embb_mtapi_scheduler_t.c | 8 ++++++++ 4 files changed, 56 insertions(+) diff --git a/mtapi_c/src/embb_mtapi_action_t.c b/mtapi_c/src/embb_mtapi_action_t.c index dff3606..c4d1714 100644 --- a/mtapi_c/src/embb_mtapi_action_t.c +++ b/mtapi_c/src/embb_mtapi_action_t.c @@ -289,10 +289,12 @@ void mtapi_action_delete( embb_mtapi_thread_context_t * context = NULL; embb_duration_t wait_duration; + embb_time_t start_time; embb_time_t end_time; if (MTAPI_INFINITE < timeout) { embb_duration_set_milliseconds( &wait_duration, (unsigned long long)timeout); + embb_time_now(&start_time); embb_time_in(&end_time, &wait_duration); } @@ -309,6 +311,12 @@ void mtapi_action_delete( if (MTAPI_INFINITE < timeout) { embb_time_t current_time; embb_time_now(¤t_time); + if (embb_time_compare(¤t_time, &start_time) < 0) { + /* time has moved backwards, maybe a wraparound or jitter + move end_time backward to avoid endeless loop */ + start_time = current_time; + embb_time_in(&end_time, &wait_duration); + } if (embb_time_compare(¤t_time, &end_time) > 0) { /* timeout! */ local_status = MTAPI_TIMEOUT; @@ -362,10 +370,12 @@ void mtapi_action_disable( embb_mtapi_thread_context_t * context = NULL; embb_duration_t wait_duration; + embb_time_t start_time; embb_time_t end_time; if (MTAPI_INFINITE < timeout) { embb_duration_set_milliseconds( &wait_duration, (unsigned long long)timeout); + embb_time_now(&start_time); embb_time_in(&end_time, &wait_duration); } @@ -382,6 +392,12 @@ void mtapi_action_disable( if (MTAPI_INFINITE < timeout) { embb_time_t current_time; embb_time_now(¤t_time); + if (embb_time_compare(¤t_time, &start_time) < 0) { + /* time has moved backwards, maybe a wraparound or jitter + move end_time backward to avoid endeless loop */ + start_time = current_time; + embb_time_in(&end_time, &wait_duration); + } if (embb_time_compare(¤t_time, &end_time) > 0) { /* timeout! */ local_status = MTAPI_TIMEOUT; diff --git a/mtapi_c/src/embb_mtapi_group_t.c b/mtapi_c/src/embb_mtapi_group_t.c index c0d4082..10c41b8 100644 --- a/mtapi_c/src/embb_mtapi_group_t.c +++ b/mtapi_c/src/embb_mtapi_group_t.c @@ -213,10 +213,12 @@ void mtapi_group_wait_all( node->group_pool, group); embb_duration_t wait_duration; + embb_time_t start_time; embb_time_t end_time; if (MTAPI_INFINITE < timeout) { embb_duration_set_milliseconds( &wait_duration, (unsigned long long)timeout); + embb_time_now(&start_time); embb_time_in(&end_time, &wait_duration); } @@ -232,6 +234,12 @@ void mtapi_group_wait_all( if (MTAPI_INFINITE < timeout) { embb_time_t current_time; embb_time_now(¤t_time); + if (embb_time_compare(¤t_time, &start_time) < 0) { + /* time has moved backwards, maybe a wraparound or jitter + move end_time backward to avoid endeless loop */ + start_time = current_time; + embb_time_in(&end_time, &wait_duration); + } if (embb_time_compare(¤t_time, &end_time) > 0) { /* timeout! */ local_status = MTAPI_TIMEOUT; @@ -300,10 +308,12 @@ void mtapi_group_wait_any( embb_mtapi_thread_context_t * context = NULL; embb_duration_t wait_duration; + embb_time_t start_time; embb_time_t end_time; if (MTAPI_INFINITE < timeout) { embb_duration_set_milliseconds( &wait_duration, (unsigned long long)timeout); + embb_time_now(&start_time); embb_time_in(&end_time, &wait_duration); } @@ -318,6 +328,12 @@ void mtapi_group_wait_any( if (MTAPI_INFINITE < timeout) { embb_time_t current_time; embb_time_now(¤t_time); + if (embb_time_compare(¤t_time, &start_time) < 0) { + /* time has moved backwards, maybe a wraparound or jitter + move end_time backward to avoid endeless loop */ + start_time = current_time; + embb_time_in(&end_time, &wait_duration); + } if (embb_time_compare(¤t_time, &end_time) > 0) { /* timeout! */ local_status = MTAPI_TIMEOUT; diff --git a/mtapi_c/src/embb_mtapi_queue_t.c b/mtapi_c/src/embb_mtapi_queue_t.c index 5e9599f..be85611 100644 --- a/mtapi_c/src/embb_mtapi_queue_t.c +++ b/mtapi_c/src/embb_mtapi_queue_t.c @@ -360,10 +360,12 @@ void mtapi_queue_delete( embb_mtapi_thread_context_t * context = NULL; embb_duration_t wait_duration; + embb_time_t start_time; embb_time_t end_time; if (MTAPI_INFINITE < timeout) { embb_duration_set_milliseconds( &wait_duration, (unsigned long long)timeout); + embb_time_now(&start_time); embb_time_in(&end_time, &wait_duration); } @@ -381,6 +383,12 @@ void mtapi_queue_delete( if (MTAPI_INFINITE < timeout) { embb_time_t current_time; embb_time_now(¤t_time); + if (embb_time_compare(¤t_time, &start_time) < 0) { + /* time has moved backwards, maybe a wraparound or jitter + move end_time backward to avoid endeless loop */ + start_time = current_time; + embb_time_in(&end_time, &wait_duration); + } if (embb_time_compare(¤t_time, &end_time) > 0) { /* timeout! */ local_status = MTAPI_TIMEOUT; @@ -435,10 +443,12 @@ void mtapi_queue_disable( embb_mtapi_scheduler_get_current_thread_context(node->scheduler); embb_duration_t wait_duration; + embb_time_t start_time; embb_time_t end_time; if (MTAPI_INFINITE < timeout) { embb_duration_set_milliseconds( &wait_duration, (unsigned long long)timeout); + embb_time_now(&start_time); embb_time_in(&end_time, &wait_duration); } @@ -448,6 +458,12 @@ void mtapi_queue_disable( if (MTAPI_INFINITE < timeout) { embb_time_t current_time; embb_time_now(¤t_time); + if (embb_time_compare(¤t_time, &start_time) < 0) { + /* time has moved backwards, maybe a wraparound or jitter + move end_time backward to avoid endeless loop */ + start_time = current_time; + embb_time_in(&end_time, &wait_duration); + } if (embb_time_compare(¤t_time, &end_time) > 0) { /* timeout! */ local_status = MTAPI_TIMEOUT; diff --git a/mtapi_c/src/embb_mtapi_scheduler_t.c b/mtapi_c/src/embb_mtapi_scheduler_t.c index d7549c6..7e4052c 100644 --- a/mtapi_c/src/embb_mtapi_scheduler_t.c +++ b/mtapi_c/src/embb_mtapi_scheduler_t.c @@ -407,6 +407,7 @@ mtapi_boolean_t embb_mtapi_scheduler_wait_for_task( embb_mtapi_node_t* node = embb_mtapi_node_get_instance(); embb_mtapi_thread_context_t * context = NULL; embb_duration_t wait_duration; + embb_time_t start_time; embb_time_t end_time; assert(MTAPI_NULL != node); @@ -414,6 +415,7 @@ mtapi_boolean_t embb_mtapi_scheduler_wait_for_task( if (MTAPI_INFINITE < timeout) { embb_duration_set_milliseconds(&wait_duration, (unsigned long long)timeout); + embb_time_now(&start_time); embb_time_in(&end_time, &wait_duration); } @@ -431,6 +433,12 @@ mtapi_boolean_t embb_mtapi_scheduler_wait_for_task( if (MTAPI_INFINITE < timeout) { embb_time_t current_time; embb_time_now(¤t_time); + if (embb_time_compare(¤t_time, &start_time) < 0) { + /* time has moved backwards, maybe a wraparound or jitter + move end_time backward to avoid endeless loop */ + start_time = current_time; + embb_time_in(&end_time, &wait_duration); + } if (embb_time_compare(¤t_time, &end_time) > 0) { /* timeout! */ return MTAPI_FALSE; -- libgit2 0.26.0