1 /* 2 * Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 /* 8 * @file generic/condition.c 9 * @brief Generic 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 if (!atomic_compare_exchange_strong(&cv->mptr, &tmpmptr, mptr)) { 29 if (tmpmptr != mptr) 30 return -EINVAL; 31 } 32 33 v = atomic_load(&cv->v); 34 35 /* Release the mutex first. */ 36 metal_mutex_release(m); 37 do { 38 flags = metal_irq_save_disable(); 39 if (atomic_load(&cv->v) != v) { 40 metal_irq_restore_enable(flags); 41 break; 42 } 43 metal_generic_default_poll(); 44 metal_irq_restore_enable(flags); 45 } while (1); 46 /* Acquire the mutex again. */ 47 metal_mutex_acquire(m); 48 return 0; 49 } 50