You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

155 lines
4.8 KiB

/*
* Copyright (C) 2015 Kaspar Schleiser <kaspar@schleiser.de>
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup core_thread
* @brief Thread flags
* @{
*
* @file
* @brief Thread flags API
*
* This API can be used to notify threads of conditions in a race-free
* and allocation-less way.
*
* Each thread can handle up to 16 boolean flags, stored as a bitmask in the
* flags field of its thread. Those flags can be set or unset, using
* thread_flags_set(), from ISR's, other threads or even by the thread itself.
*
* A thread can wait for any combination of its flags to become set, using
* thread_flags_wait_any() or thread_flags_wait_all().
* Those functions clear flags that caused them to return.
* It is not possible to wait for flags to become unset.
*
* Thread flags have certain properties that make them the preferred choice
* over messages or mutexes in some circumstances:
*
* - setting thread flags cannot fail
* If messages are used to notify a thread of a condition from within an ISR,
* and the receiving thread is not waiting, has no queue or the queue is
* full, the ISR cannot deliver the message. A thread flag can always be set.
*
* - thread flags are very flexible
* With thread flags it is possible to wait for multiple conditions and
* messages at the same time. When mutexes are used to notify about events,
* only one event can be waited for.
*
* Usually, if it is only of interest that an event occurred, but not how many
* of them, thread flags should be considered.
*
* Note that some flags (currently the three most significant bits) are used by
* core functions and should not be set by the user. They can be waited for.
*
* @author Kaspar Schleiser <kaspar@schleiser.de>
*/
#ifndef THREAD_FLAGS_H
#define THREAD_FLAGS_H
#include "kernel_types.h"
#include "sched.h" /* for thread_t typedef */
#ifdef __cplusplus
extern "C" {
#endif
/**
* @name reserved thread flags
* @{
*/
#define THREAD_FLAG_MSG_WAITING (0x1<<15)
#define THREAD_FLAG_MUTEX_UNLOCKED (0x1<<14)
#define THREAD_FLAG_TIMEOUT (0x1<<13)
/** @} */
/**
* @name Define type of thread_flags_t
*/
typedef uint16_t thread_flags_t;
/**
* @brief Set thread flags, possibly waking it up
*
* @param[in] thread thread to work on
* @param[in] mask additional flags to be set for the current thread,
* represented as a bitmask
*/
void thread_flags_set(thread_t *thread, thread_flags_t mask);
/**
* @brief Clear current thread's flags
*
* @param[in] mask unset flags for the current thread,
* represented as a bitmask
*
* @returns flags that have actually been cleared (mask & thread->flags before clear)
*/
thread_flags_t thread_flags_clear(thread_flags_t mask);
/**
* @brief Wait for any flag in mask to become set (blocking)
*
* If any of the flags in mask are already set, this function will return
* immediately, otherwise, it will suspend the thread (as
* THREAD_STATUS_WAIT_ANY) until any of the flags in mask get set.
*
* Both ways, it will clear and return (sched_active_thread-flags & mask).
*
* @param[in] mask mask of flags to wait for
*
* @returns flags that caused return/wakeup ((sched_active_thread-flags & mask).
*/
thread_flags_t thread_flags_wait_any(thread_flags_t mask);
/**
* @brief Wait for all flags in mask to become set (blocking)
*
* If all the flags in mask are already set, this function will return
* immediately, otherwise, it will suspend the thread (as
* THREAD_STATUS_WAIT_ALL) until all of the flags in mask have been set.
*
* Both ways, it will clear and return (sched_active_thread-flags & mask).
*
* @param[in] mask mask of flags to wait for
*
* @returns mask
*/
thread_flags_t thread_flags_wait_all(thread_flags_t mask);
/**
* @brief Wait for any flags in mask to become set (blocking), one at a time
*
* This function is like thread_flags_wait_any(), but will only clear and return
* one flag at a time, least significant set bit first.
*
* @param[in] mask mask of flags to wait for
*
* @returns flag that triggered the return / wait
*/
thread_flags_t thread_flags_wait_one(thread_flags_t mask);
/**
* @brief Possibly Wake up thread waiting for flags
*
* Wakes up a thread if it is thread flag blocked and its condition is met.
* Has to be called with interrupts disabled.
* Does not trigger yield.
*
* @internal
*
* @param[in] thread thread to possibly wake up
* @return 1 if @p thread has been woken up
* 0 otherwise
*/
int thread_flags_wake(thread_t *thread);
#ifdef __cplusplus
}
#endif
/** @} */
#endif /* THREAD_FLAGS_H */