Merge pull request #4903 from kaspar030/xtimer_fixes
sys: xtimer: fix some race conditions
This commit is contained in:
commit
b3b880be6a
@ -251,11 +251,8 @@ void xtimer_set(xtimer_t *timer, uint32_t offset);
|
|||||||
* @note this function runs in O(n) with n being the number of active timers
|
* @note this function runs in O(n) with n being the number of active timers
|
||||||
*
|
*
|
||||||
* @param[in] timer ptr to timer structure that will be removed
|
* @param[in] timer ptr to timer structure that will be removed
|
||||||
*
|
|
||||||
* @return 1 on success
|
|
||||||
* @return 0 when timer was not active
|
|
||||||
*/
|
*/
|
||||||
int xtimer_remove(xtimer_t *timer);
|
void xtimer_remove(xtimer_t *timer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief receive a message blocking but with timeout
|
* @brief receive a message blocking but with timeout
|
||||||
|
|||||||
@ -40,6 +40,7 @@ static xtimer_t *long_list_head = NULL;
|
|||||||
static void _add_timer_to_list(xtimer_t **list_head, xtimer_t *timer);
|
static void _add_timer_to_list(xtimer_t **list_head, xtimer_t *timer);
|
||||||
static void _add_timer_to_long_list(xtimer_t **list_head, xtimer_t *timer);
|
static void _add_timer_to_long_list(xtimer_t **list_head, xtimer_t *timer);
|
||||||
static void _shoot(xtimer_t *timer);
|
static void _shoot(xtimer_t *timer);
|
||||||
|
static void _remove(xtimer_t *timer);
|
||||||
static inline void _lltimer_set(uint32_t target);
|
static inline void _lltimer_set(uint32_t target);
|
||||||
static uint32_t _time_left(uint32_t target, uint32_t reference);
|
static uint32_t _time_left(uint32_t target, uint32_t reference);
|
||||||
|
|
||||||
@ -94,7 +95,10 @@ void _xtimer_set64(xtimer_t *timer, uint32_t offset, uint32_t long_offset)
|
|||||||
xtimer_set(timer, (uint32_t) offset);
|
xtimer_set(timer, (uint32_t) offset);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
xtimer_remove(timer);
|
int state = disableIRQ();
|
||||||
|
if (_is_set(timer)) {
|
||||||
|
_remove(timer);
|
||||||
|
}
|
||||||
|
|
||||||
_xtimer_now64(&timer->target, &timer->long_target);
|
_xtimer_now64(&timer->target, &timer->long_target);
|
||||||
timer->target += offset;
|
timer->target += offset;
|
||||||
@ -103,7 +107,6 @@ void _xtimer_set64(xtimer_t *timer, uint32_t offset, uint32_t long_offset)
|
|||||||
timer->long_target++;
|
timer->long_target++;
|
||||||
}
|
}
|
||||||
|
|
||||||
int state = disableIRQ();
|
|
||||||
_add_timer_to_long_list(&long_list_head, timer);
|
_add_timer_to_long_list(&long_list_head, timer);
|
||||||
restoreIRQ(state);
|
restoreIRQ(state);
|
||||||
DEBUG("xtimer_set64(): added longterm timer (long_target=%" PRIu32 " target=%" PRIu32 ")\n",
|
DEBUG("xtimer_set64(): added longterm timer (long_target=%" PRIu32 " target=%" PRIu32 ")\n",
|
||||||
@ -173,13 +176,17 @@ int _xtimer_set_absolute(xtimer_t *timer, uint32_t target)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned state = disableIRQ();
|
||||||
|
if (_is_set(timer)) {
|
||||||
|
_remove(timer);
|
||||||
|
}
|
||||||
|
|
||||||
timer->target = target;
|
timer->target = target;
|
||||||
timer->long_target = _long_cnt;
|
timer->long_target = _long_cnt;
|
||||||
if (target < now) {
|
if (target < now) {
|
||||||
timer->long_target++;
|
timer->long_target++;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned state = disableIRQ();
|
|
||||||
if ( (timer->long_target > _long_cnt) || !_this_high_period(target) ) {
|
if ( (timer->long_target > _long_cnt) || !_this_high_period(target) ) {
|
||||||
DEBUG("xtimer_set_absolute(): the timer doesn't fit into the low-level timer's mask.\n");
|
DEBUG("xtimer_set_absolute(): the timer doesn't fit into the low-level timer's mask.\n");
|
||||||
_add_timer_to_long_list(&long_list_head, timer);
|
_add_timer_to_long_list(&long_list_head, timer);
|
||||||
@ -240,14 +247,8 @@ static int _remove_timer_from_list(xtimer_t **list_head, xtimer_t *timer)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int xtimer_remove(xtimer_t *timer)
|
static void _remove(xtimer_t *timer)
|
||||||
{
|
{
|
||||||
if (!_is_set(timer)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned state = disableIRQ();
|
|
||||||
int res = 0;
|
|
||||||
if (timer_list_head == timer) {
|
if (timer_list_head == timer) {
|
||||||
uint32_t next;
|
uint32_t next;
|
||||||
timer_list_head = timer->next;
|
timer_list_head = timer->next;
|
||||||
@ -261,17 +262,21 @@ int xtimer_remove(xtimer_t *timer)
|
|||||||
_lltimer_set(next);
|
_lltimer_set(next);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
res = _remove_timer_from_list(&timer_list_head, timer) ||
|
if (!_remove_timer_from_list(&timer_list_head, timer)) {
|
||||||
_remove_timer_from_list(&overflow_list_head, timer) ||
|
if (!_remove_timer_from_list(&overflow_list_head, timer)) {
|
||||||
_remove_timer_from_list(&long_list_head, timer);
|
_remove_timer_from_list(&long_list_head, timer);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
timer->target = 0;
|
void xtimer_remove(xtimer_t *timer)
|
||||||
timer->long_target = 0;
|
{
|
||||||
|
int state = disableIRQ();
|
||||||
|
if (_is_set(timer)) {
|
||||||
|
_remove(timer);
|
||||||
|
}
|
||||||
restoreIRQ(state);
|
restoreIRQ(state);
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t _time_left(uint32_t target, uint32_t reference)
|
static uint32_t _time_left(uint32_t target, uint32_t reference)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user