mirror of
https://github.com/OpenAMP/libmetal.git
synced 2026-02-08 05:47:48 +08:00
Use atomic type for mutex pointer this is required by the atomic operation. atomic exchange is used to verify the mutex used on condition wait. Signed-off-by: Wendy Liang <wendy.liang@xilinx.com>
41 lines
936 B
C
41 lines
936 B
C
/*
|
|
* Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved.
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
|
|
/*
|
|
* @file generic/condition.c
|
|
* @brief Generic libmetal condition variable handling.
|
|
*/
|
|
|
|
#include <metal/condition.h>
|
|
|
|
int metal_condition_wait(struct metal_condition *cv,
|
|
metal_mutex_t *m)
|
|
{
|
|
uintptr_t tmpmptr = 0, mptr = (uintptr_t)m;
|
|
int v = 0;
|
|
|
|
/* Check if the mutex has been acquired */
|
|
if (!cv || !m || !metal_mutex_is_acquired(m))
|
|
return -EINVAL;
|
|
|
|
if (!atomic_compare_exchange_strong(&cv->mptr, &tmpmptr, mptr)) {
|
|
if (tmpmptr != mptr)
|
|
return -EINVAL;
|
|
}
|
|
|
|
v = atomic_load(&cv->wakeups);
|
|
atomic_fetch_add(&cv->waiters, 1);
|
|
|
|
/* Release the mutex before sleeping. */
|
|
metal_mutex_release(m);
|
|
syscall(SYS_futex, &cv->wakeups, FUTEX_WAIT, v, NULL, NULL, 0);
|
|
atomic_fetch_sub(&cv->waiters, 1);
|
|
/* Acquire the mutex after it's waken up. */
|
|
metal_mutex_acquire(m);
|
|
|
|
return 0;
|
|
}
|