1 /* 2 * Copyright (c) 2017, Linaro Limited. and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 /* 8 * @file zephyr/condition.c 9 * @brief Zephyr libmetal condition variable handling. 10 */ 11 12 #include <metal/condition.h> 13 #include <metal/irq.h> 14 15 extern void metal_generic_default_poll(void); 16 metal_condition_wait(struct metal_condition * cv,metal_mutex_t * m)17int metal_condition_wait(struct metal_condition *cv, 18 metal_mutex_t *m) 19 { 20 uintptr_t tmpmptr = 0, mptr = (uintptr_t)m; 21 int v; 22 unsigned int flags; 23 24 /* Check if the mutex has been acquired */ 25 if (!cv || !m || !metal_mutex_is_acquired(m)) { 26 return -EINVAL; 27 } 28 29 if (!atomic_compare_exchange_strong(&cv->mptr, &tmpmptr, mptr)) { 30 if (tmpmptr != mptr) { 31 return -EINVAL; 32 } 33 } 34 35 v = atomic_load(&cv->v); 36 37 /* Release the mutex first. */ 38 metal_mutex_release(m); 39 do { 40 flags = metal_irq_save_disable(); 41 if (atomic_load(&cv->v) != v) { 42 metal_irq_restore_enable(flags); 43 break; 44 } 45 metal_generic_default_poll(); 46 metal_irq_restore_enable(flags); 47 } while (1); 48 /* Acquire the mutex again. */ 49 metal_mutex_acquire(m); 50 return 0; 51 } 52