1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

sys/xtimer: implement mutex lock with timeout

This commit is contained in:
Victor Arino 2016-11-22 18:21:36 +01:00
parent 51d13ee906
commit 17d6d2a5b5
2 changed files with 47 additions and 0 deletions

View File

@ -32,6 +32,7 @@
#include <stdint.h>
#include "timex.h"
#include "msg.h"
#include "mutex.h"
#include "board.h"
#include "periph_conf.h"
@ -425,6 +426,19 @@ static inline bool xtimer_less(xtimer_ticks32_t a, xtimer_ticks32_t b);
*/
static inline bool xtimer_less64(xtimer_ticks64_t a, xtimer_ticks64_t b);
/**
* @brief lock a mutex but with timeout
*
* @note this requires core_thread_flags to be enabled
*
* @param[in] mutex mutex to lock
* @param[in] us timeout in microseconds relative
*
* @return 0, when returned after mutex was locked
* @return -1, when the timeout occcured
*/
int xtimer_mutex_lock_timeout(mutex_t *mutex, uint64_t us);
/**
* @brief xtimer backoff value
*

View File

@ -26,12 +26,19 @@
#include "thread.h"
#include "irq.h"
#include "div.h"
#include "list.h"
#include "timex.h"
#define ENABLE_DEBUG 0
#include "debug.h"
typedef struct {
mutex_t *mutex;
thread_t *thread;
int timeout;
} mutex_thread_t;
static void _callback_unlock_mutex(void* arg)
{
mutex_t *mutex = (mutex_t *) arg;
@ -220,3 +227,29 @@ int _xtimer_msg_receive_timeout(msg_t *msg, uint32_t timeout_ticks)
_xtimer_set_msg(&t, timeout_ticks, &tmsg, sched_active_pid);
return _msg_wait(msg, &tmsg, &t);
}
static void _mutex_timeout(void *arg)
{
mutex_thread_t *mt = (mutex_thread_t *)arg;
mt->timeout = 1;
sched_set_status(mt->thread, STATUS_PENDING);
list_remove(&mt->mutex->queue, (list_node_t *)&mt->thread->rq_entry);
thread_yield_higher();
}
int xtimer_mutex_lock_timeout(mutex_t *mutex, uint64_t timeout)
{
xtimer_t t;
mutex_thread_t mt = { mutex, (thread_t *)sched_active_thread, 0 };
if (timeout != 0) {
t.callback = _mutex_timeout;
t.arg = (void *)((mutex_thread_t *)&mt);
_xtimer_set64(&t, timeout, timeout >> 32);
}
mutex_lock(mutex);
xtimer_remove(&t);
return -mt.timeout;
}