Files
libmetal/lib/system/linux/condition.h
Arnaud Pouliquen d3a27c1454 lib: fix file headers for doxygen generation
- start by "/**",
- fix file relative path,
- fix typos,

Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen@foss.st.com>
2026-01-13 10:33:04 +01:00

76 lines
1.8 KiB
C

/*
* Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/**
* @file linux/condition.h
* @brief Linux condition variable primitives for libmetal.
*/
#ifndef __METAL_CONDITION__H__
#error "Include metal/condition.h instead of metal/linux/condition.h"
#endif
#ifndef __METAL_LINUX_CONDITION__H__
#define __METAL_LINUX_CONDITION__H__
#include <unistd.h>
#include <sys/syscall.h>
#include <linux/futex.h>
#include <metal/atomic.h>
#include <metal/errno.h>
#include <stdint.h>
#include <limits.h>
#ifdef __cplusplus
extern "C" {
#endif
struct metal_condition {
atomic_uintptr_t mptr; /**< mutex pointer.
* The condition variable is attached to
* this mutex when it is waiting.
* It is also used to check correctness
* in case there are multiple waiters.
*/
atomic_int waiters; /**< number of waiters. */
atomic_int wakeups; /**< number of wakeups. */
};
/** Static metal condition variable initialization. */
#define METAL_CONDITION_INIT { ATOMIC_VAR_INIT(0), ATOMIC_VAR_INIT(0), \
ATOMIC_VAR_INIT(0) }
static inline void metal_condition_init(struct metal_condition *cv)
{
atomic_init(&cv->mptr, 0);
atomic_init(&cv->waiters, 0);
atomic_init(&cv->wakeups, 0);
}
static inline int metal_condition_signal(struct metal_condition *cv)
{
if (!cv)
return -EINVAL;
atomic_fetch_add(&cv->wakeups, 1);
if (atomic_load(&cv->waiters) > 0)
syscall(SYS_futex, &cv->wakeups, FUTEX_WAKE, 1, NULL, NULL, 0);
return 0;
}
static inline int metal_condition_broadcast(struct metal_condition *cv)
{
if (!cv)
return -EINVAL;
atomic_fetch_add(&cv->wakeups, 1);
if (atomic_load(&cv->waiters) > 0)
syscall(SYS_futex, &cv->wakeups, FUTEX_WAKE, INT_MAX, NULL, NULL, 0);
return 0;
}
#endif /* __METAL_LINUX_CONDITION__H__ */