124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===-- Predicate.h ---------------------------------------------*- C++ -*-===// 224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// The LLVM Compiler Infrastructure 424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// This file is distributed under the University of Illinois Open Source 624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// License. See LICENSE.TXT for details. 724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===----------------------------------------------------------------------===// 924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 1024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#ifndef liblldb_Predicate_h_ 1124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#define liblldb_Predicate_h_ 1224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#if defined(__cplusplus) 1324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 1424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Host/Mutex.h" 1524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Host/Condition.h" 1624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <stdint.h> 1724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <time.h> 1824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 1924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//#define DB_PTHREAD_LOG_EVENTS 2024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 2124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 2224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner/// Enumerations for broadcasting. 2324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 2424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnernamespace lldb_private { 2524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 2624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnertypedef enum 2724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 2824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner eBroadcastNever, ///< No broadcast will be sent when the value is modified. 2924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner eBroadcastAlways, ///< Always send a broadcast when the value is modified. 3024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner eBroadcastOnChange ///< Only broadcast if the value changes when the value is modified. 3124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 3224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} PredicateBroadcastType; 3324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 3424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 3524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner/// @class Predicate Predicate.h "lldb/Host/Predicate.h" 3624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner/// @brief A C++ wrapper class for providing threaded access to a value 3724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner/// of type T. 3824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner/// 3924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner/// A templatized class that provides multi-threaded access to a value 4024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner/// of type T. Threads can efficiently wait for bits within T to be set 4124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner/// or reset, or wait for T to be set to be equal/not equal to a 4224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner/// specified values. 4324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 4424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnertemplate <class T> 4524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerclass Predicate 4624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 4724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerpublic: 4824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 4924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner //------------------------------------------------------------------ 5024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// Default constructor. 5124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// 5224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// Initializes the mutex, condition and value with their default 5324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// constructors. 5424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner //------------------------------------------------------------------ 5524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Predicate () : 5654e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton m_value(), 5724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_mutex(), 5854e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton m_condition() 5924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 6024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 6124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 6224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner //------------------------------------------------------------------ 6324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// Construct with initial T value \a initial_value. 6424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// 6524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// Initializes the mutex and condition with their default 6624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// constructors, and initializes the value with \a initial_value. 6724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// 6824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// @param[in] initial_value 6924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// The initial value for our T object. 7024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner //------------------------------------------------------------------ 7124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Predicate (T initial_value) : 7254e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton m_value(initial_value), 7324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_mutex(), 7454e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton m_condition() 7524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 7624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 7724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 7824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner //------------------------------------------------------------------ 7924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// Destructor. 8024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// 8124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// Destrory the condition, mutex, and T objects. 8224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner //------------------------------------------------------------------ 8324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ~Predicate () 8424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 8524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 8624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 8724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 8824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner //------------------------------------------------------------------ 8924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// Value get accessor. 9024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// 9124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// Copies the current \a m_value in a thread safe manor and returns 9224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// the copied value. 9324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// 9424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// @return 9524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// A copy of the current value. 9624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner //------------------------------------------------------------------ 9724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner T 9824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner GetValue () const 9924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 10024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Mutex::Locker locker(m_mutex); 10124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner T value = m_value; 10224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return value; 10324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 10424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 10524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner //------------------------------------------------------------------ 10624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// Value set accessor. 10724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// 10824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// Set the contained \a m_value to \a new_value in a thread safe 10924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// way and broadcast if needed. 11024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// 11124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// @param[in] value 11224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// The new value to set. 11324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// 11424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// @param[in] broadcast_type 11524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// A value indicating when and if to broadast. See the 11624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// PredicateBroadcastType enumeration for details. 11724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// 11824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// @see Predicate::Broadcast() 11924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner //------------------------------------------------------------------ 12024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner void 12124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SetValue (T value, PredicateBroadcastType broadcast_type) 12224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 12324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Mutex::Locker locker(m_mutex); 12424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#ifdef DB_PTHREAD_LOG_EVENTS 12522f44d5f0a70e43825abadcc8f475ea4b4353509Enrico Granata printf("%s (value = 0x%8.8x, broadcast_type = %i)\n", __FUNCTION__, value, broadcast_type); 12624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#endif 12724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const T old_value = m_value; 12824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_value = value; 12924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 13024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Broadcast(old_value, broadcast_type); 13124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 13224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 13324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner //------------------------------------------------------------------ 13424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// Set some bits in \a m_value. 13524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// 13624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// Logically set the bits \a bits in the contained \a m_value in a 13724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// thread safe way and broadcast if needed. 13824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// 13924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// @param[in] bits 14024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// The bits to set in \a m_value. 14124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// 14224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// @param[in] broadcast_type 14324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// A value indicating when and if to broadast. See the 14424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// PredicateBroadcastType enumeration for details. 14524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// 14624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// @see Predicate::Broadcast() 14724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner //------------------------------------------------------------------ 14824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner void 14924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SetValueBits (T bits, PredicateBroadcastType broadcast_type) 15024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 15124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Mutex::Locker locker(m_mutex); 15224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#ifdef DB_PTHREAD_LOG_EVENTS 15322f44d5f0a70e43825abadcc8f475ea4b4353509Enrico Granata printf("%s (bits = 0x%8.8x, broadcast_type = %i)\n", __FUNCTION__, bits, broadcast_type); 15424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#endif 15524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const T old_value = m_value; 15624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_value |= bits; 15724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 15824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Broadcast(old_value, broadcast_type); 15924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 16024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 16124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner //------------------------------------------------------------------ 16224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// Reset some bits in \a m_value. 16324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// 16424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// Logically reset (clear) the bits \a bits in the contained 16524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// \a m_value in a thread safe way and broadcast if needed. 16624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// 16724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// @param[in] bits 16824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// The bits to clear in \a m_value. 16924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// 17024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// @param[in] broadcast_type 17124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// A value indicating when and if to broadast. See the 17224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// PredicateBroadcastType enumeration for details. 17324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// 17424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// @see Predicate::Broadcast() 17524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner //------------------------------------------------------------------ 17624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner void 17724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ResetValueBits (T bits, PredicateBroadcastType broadcast_type) 17824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 17924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Mutex::Locker locker(m_mutex); 18024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#ifdef DB_PTHREAD_LOG_EVENTS 18122f44d5f0a70e43825abadcc8f475ea4b4353509Enrico Granata printf("%s (bits = 0x%8.8x, broadcast_type = %i)\n", __FUNCTION__, bits, broadcast_type); 18224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#endif 18324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const T old_value = m_value; 18424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_value &= ~bits; 18524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 18624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Broadcast(old_value, broadcast_type); 18724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 18824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 18924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner //------------------------------------------------------------------ 19024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// Wait for bits to be set in \a m_value. 19124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// 19224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// Waits in a thread safe way for any bits in \a bits to get 19324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// logically set in \a m_value. If any bits are already set in 19424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// \a m_value, this function will return without waiting. 19524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// 19651d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// It is possible for the value to be changed between the time 19751d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// the bits are set and the time the waiting thread wakes up. 19851d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// If the bits are no longer set when the waiting thread wakes 19951d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// up, it will go back into a wait state. It may be necessary 20051d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// for the calling code to use additional thread synchronization 20151d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// methods to detect transitory states. 20251d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// 20324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// @param[in] bits 20424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// The bits we are waiting to be set in \a m_value. 20524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// 20624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// @param[in] abstime 20724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// If non-NULL, the absolute time at which we should stop 20824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// waiting, else wait an infinite amount of time. 20924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// 21024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// @return 21124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// Any bits of the requested bits that actually were set within 21224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// the time specified. Zero if a timeout or unrecoverable error 21324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// occurred. 21424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner //------------------------------------------------------------------ 21524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner T 21624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner WaitForSetValueBits (T bits, const TimeValue *abstime = NULL) 21724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 21824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner int err = 0; 21924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // pthread_cond_timedwait() or pthread_cond_wait() will atomically 22024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // unlock the mutex and wait for the condition to be set. When either 22124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // function returns, they will re-lock the mutex. We use an auto lock/unlock 22224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // class (Mutex::Locker) to allow us to return at any point in this 22324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // function and not have to worry about unlocking the mutex. 22424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Mutex::Locker locker(m_mutex); 22524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#ifdef DB_PTHREAD_LOG_EVENTS 22622f44d5f0a70e43825abadcc8f475ea4b4353509Enrico Granata printf("%s (bits = 0x%8.8x, abstime = %p), m_value = 0x%8.8x\n", __FUNCTION__, bits, abstime, m_value); 22724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#endif 22824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner while (err == 0 && ((m_value & bits) == 0)) 22924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 2308533e994d3076ef517e2cf7f3030bbc6a7273a9bJim Ingham err = m_condition.Wait (m_mutex, abstime); 23124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 23224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#ifdef DB_PTHREAD_LOG_EVENTS 23322f44d5f0a70e43825abadcc8f475ea4b4353509Enrico Granata printf("%s (bits = 0x%8.8x), m_value = 0x%8.8x, returning 0x%8.8x\n", __FUNCTION__, bits, m_value, m_value & bits); 23424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#endif 23524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 23624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return m_value & bits; 23724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 23824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 23924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner //------------------------------------------------------------------ 24024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// Wait for bits to be reset in \a m_value. 24124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// 24224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// Waits in a thread safe way for any bits in \a bits to get 24324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// logically reset in \a m_value. If all bits are already reset in 24424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// \a m_value, this function will return without waiting. 24524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// 24651d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// It is possible for the value to be changed between the time 24751d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// the bits are reset and the time the waiting thread wakes up. 24851d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// If the bits are no set when the waiting thread wakes up, it will 24951d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// go back into a wait state. It may be necessary for the calling 25051d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// code to use additional thread synchronization methods to detect 25151d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// transitory states. 25251d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// 25324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// @param[in] bits 25424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// The bits we are waiting to be reset in \a m_value. 25524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// 25624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// @param[in] abstime 25724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// If non-NULL, the absolute time at which we should stop 25824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// waiting, else wait an infinite amount of time. 25924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// 26024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// @return 26124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// Zero on successful waits, or non-zero if a timeout or 26224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// unrecoverable error occurs. 26324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner //------------------------------------------------------------------ 26424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner T 26524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner WaitForResetValueBits (T bits, const TimeValue *abstime = NULL) 26624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 26724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner int err = 0; 26824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 26924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // pthread_cond_timedwait() or pthread_cond_wait() will atomically 27024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // unlock the mutex and wait for the condition to be set. When either 27124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // function returns, they will re-lock the mutex. We use an auto lock/unlock 27224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // class (Mutex::Locker) to allow us to return at any point in this 27324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // function and not have to worry about unlocking the mutex. 27424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Mutex::Locker locker(m_mutex); 27524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 27624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#ifdef DB_PTHREAD_LOG_EVENTS 27722f44d5f0a70e43825abadcc8f475ea4b4353509Enrico Granata printf("%s (bits = 0x%8.8x, abstime = %p), m_value = 0x%8.8x\n", __FUNCTION__, bits, abstime, m_value); 27824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#endif 279f8e98a6e4560c632a9c0373abee247e747097845Greg Clayton while (err == 0 && ((m_value & bits) != 0)) 28024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 2818533e994d3076ef517e2cf7f3030bbc6a7273a9bJim Ingham err = m_condition.Wait (m_mutex, abstime); 28224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 28324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 28424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#ifdef DB_PTHREAD_LOG_EVENTS 28522f44d5f0a70e43825abadcc8f475ea4b4353509Enrico Granata printf("%s (bits = 0x%8.8x), m_value = 0x%8.8x, returning 0x%8.8x\n", __FUNCTION__, bits, m_value, m_value & bits); 28624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#endif 28724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return m_value & bits; 28824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 28924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 29024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner //------------------------------------------------------------------ 29124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// Wait for \a m_value to be equal to \a value. 29224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// 29324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// Waits in a thread safe way for \a m_value to be equal to \a 29424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// value. If \a m_value is already equal to \a value, this 29524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// function will return without waiting. 29624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// 29751d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// It is possible for the value to be changed between the time 29851d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// the value is set and the time the waiting thread wakes up. 29951d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// If the value no longer matches the requested value when the 30051d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// waiting thread wakes up, it will go back into a wait state. It 30151d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// may be necessary for the calling code to use additional thread 30251d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// synchronization methods to detect transitory states. 30351d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// 30424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// @param[in] value 30524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// The value we want \a m_value to be equal to. 30624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// 30724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// @param[in] abstime 30824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// If non-NULL, the absolute time at which we should stop 30924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// waiting, else wait an infinite amount of time. 31024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// 31124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// @param[out] timed_out 31224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// If not null, set to true if we return because of a time out, 31324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// and false if the value was set. 31424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// 31524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// @return 31624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// @li \b true if the \a m_value is equal to \a value 31724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// @li \b false otherwise 31824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner //------------------------------------------------------------------ 31924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner bool 32024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner WaitForValueEqualTo (T value, const TimeValue *abstime = NULL, bool *timed_out = NULL) 32124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 32224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner int err = 0; 32324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // pthread_cond_timedwait() or pthread_cond_wait() will atomically 32424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // unlock the mutex and wait for the condition to be set. When either 32524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // function returns, they will re-lock the mutex. We use an auto lock/unlock 32624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // class (Mutex::Locker) to allow us to return at any point in this 32724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // function and not have to worry about unlocking the mutex. 32824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Mutex::Locker locker(m_mutex); 32924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 33024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#ifdef DB_PTHREAD_LOG_EVENTS 33122f44d5f0a70e43825abadcc8f475ea4b4353509Enrico Granata printf("%s (value = 0x%8.8x, abstime = %p), m_value = 0x%8.8x\n", __FUNCTION__, value, abstime, m_value); 33224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#endif 33331ab22bfc055d8bd088ae4d8002ad281f929e60dGreg Clayton if (timed_out) 33431ab22bfc055d8bd088ae4d8002ad281f929e60dGreg Clayton *timed_out = false; 33531ab22bfc055d8bd088ae4d8002ad281f929e60dGreg Clayton 33624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner while (err == 0 && m_value != value) 33724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 3381b584ebc1de8b50fe375cffb5fb33ad13be10046Jim Ingham err = m_condition.Wait (m_mutex, abstime, timed_out); 33924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 34024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 34124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return m_value == value; 34224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 34324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 34451d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor //------------------------------------------------------------------ 34551d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// Wait for \a m_value to be equal to \a value and then set it to 34651d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// a new value. 34751d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// 34851d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// Waits in a thread safe way for \a m_value to be equal to \a 34951d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// value and then sets \a m_value to \a new_value. If \a m_value 35051d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// is already equal to \a value, this function will immediately 35151d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// set \a m_value to \a new_value and return without waiting. 35251d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// 35351d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// It is possible for the value to be changed between the time 35451d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// the value is set and the time the waiting thread wakes up. 35551d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// If the value no longer matches the requested value when the 35651d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// waiting thread wakes up, it will go back into a wait state. It 35751d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// may be necessary for the calling code to use additional thread 35851d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// synchronization methods to detect transitory states. 35951d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// 36051d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// @param[in] value 36151d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// The value we want \a m_value to be equal to. 36251d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// 36351d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// @param[in] new_value 36451d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// The value to which \a m_value will be set if \b true is 36551d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// returned. 36651d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// 36751d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// @param[in] abstime 36851d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// If non-NULL, the absolute time at which we should stop 36951d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// waiting, else wait an infinite amount of time. 37051d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// 37151d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// @param[out] timed_out 37251d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// If not null, set to true if we return because of a time out, 37351d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// and false if the value was set. 37451d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// 37551d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// @return 37651d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// @li \b true if the \a m_value became equal to \a value 37751d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// @li \b false otherwise 37851d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor //------------------------------------------------------------------ 37991da7493de9a6d3ba2ae2bbaddbfff0f5d52a3cbGreg Clayton bool 38091da7493de9a6d3ba2ae2bbaddbfff0f5d52a3cbGreg Clayton WaitForValueEqualToAndSetValueTo (T wait_value, T new_value, const TimeValue *abstime = NULL, bool *timed_out = NULL) 38191da7493de9a6d3ba2ae2bbaddbfff0f5d52a3cbGreg Clayton { 38291da7493de9a6d3ba2ae2bbaddbfff0f5d52a3cbGreg Clayton int err = 0; 38391da7493de9a6d3ba2ae2bbaddbfff0f5d52a3cbGreg Clayton // pthread_cond_timedwait() or pthread_cond_wait() will atomically 38491da7493de9a6d3ba2ae2bbaddbfff0f5d52a3cbGreg Clayton // unlock the mutex and wait for the condition to be set. When either 38591da7493de9a6d3ba2ae2bbaddbfff0f5d52a3cbGreg Clayton // function returns, they will re-lock the mutex. We use an auto lock/unlock 38691da7493de9a6d3ba2ae2bbaddbfff0f5d52a3cbGreg Clayton // class (Mutex::Locker) to allow us to return at any point in this 38791da7493de9a6d3ba2ae2bbaddbfff0f5d52a3cbGreg Clayton // function and not have to worry about unlocking the mutex. 38891da7493de9a6d3ba2ae2bbaddbfff0f5d52a3cbGreg Clayton Mutex::Locker locker(m_mutex); 38991da7493de9a6d3ba2ae2bbaddbfff0f5d52a3cbGreg Clayton 39091da7493de9a6d3ba2ae2bbaddbfff0f5d52a3cbGreg Clayton#ifdef DB_PTHREAD_LOG_EVENTS 39122f44d5f0a70e43825abadcc8f475ea4b4353509Enrico Granata printf("%s (wait_value = 0x%8.8x, new_value = 0x%8.8x, abstime = %p), m_value = 0x%8.8x\n", __FUNCTION__, wait_value, new_value, abstime, m_value); 39291da7493de9a6d3ba2ae2bbaddbfff0f5d52a3cbGreg Clayton#endif 39391da7493de9a6d3ba2ae2bbaddbfff0f5d52a3cbGreg Clayton if (timed_out) 39491da7493de9a6d3ba2ae2bbaddbfff0f5d52a3cbGreg Clayton *timed_out = false; 39591da7493de9a6d3ba2ae2bbaddbfff0f5d52a3cbGreg Clayton 39691da7493de9a6d3ba2ae2bbaddbfff0f5d52a3cbGreg Clayton while (err == 0 && m_value != wait_value) 39791da7493de9a6d3ba2ae2bbaddbfff0f5d52a3cbGreg Clayton { 3981b584ebc1de8b50fe375cffb5fb33ad13be10046Jim Ingham err = m_condition.Wait (m_mutex, abstime, timed_out); 39991da7493de9a6d3ba2ae2bbaddbfff0f5d52a3cbGreg Clayton } 40091da7493de9a6d3ba2ae2bbaddbfff0f5d52a3cbGreg Clayton 40191da7493de9a6d3ba2ae2bbaddbfff0f5d52a3cbGreg Clayton if (m_value == wait_value) 40291da7493de9a6d3ba2ae2bbaddbfff0f5d52a3cbGreg Clayton { 40391da7493de9a6d3ba2ae2bbaddbfff0f5d52a3cbGreg Clayton m_value = new_value; 40491da7493de9a6d3ba2ae2bbaddbfff0f5d52a3cbGreg Clayton return true; 40591da7493de9a6d3ba2ae2bbaddbfff0f5d52a3cbGreg Clayton } 40691da7493de9a6d3ba2ae2bbaddbfff0f5d52a3cbGreg Clayton 40791da7493de9a6d3ba2ae2bbaddbfff0f5d52a3cbGreg Clayton return false; 40891da7493de9a6d3ba2ae2bbaddbfff0f5d52a3cbGreg Clayton } 40991da7493de9a6d3ba2ae2bbaddbfff0f5d52a3cbGreg Clayton 41091da7493de9a6d3ba2ae2bbaddbfff0f5d52a3cbGreg Clayton 41124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner //------------------------------------------------------------------ 41224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// Wait for \a m_value to not be equal to \a value. 41324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// 41424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// Waits in a thread safe way for \a m_value to not be equal to \a 41524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// value. If \a m_value is already not equal to \a value, this 41624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// function will return without waiting. 41724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// 41851d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// It is possible for the value to be changed between the time 41951d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// the value is set and the time the waiting thread wakes up. 42051d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// If the value is equal to the test value when the waiting thread 42151d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// wakes up, it will go back into a wait state. It may be 42251d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// necessary for the calling code to use additional thread 42351d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// synchronization methods to detect transitory states. 42451d7a39dca300a7fa90a44a0fc5338048b49ac20Andrew Kaylor /// 42524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// @param[in] value 42624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// The value we want \a m_value to not be equal to. 42724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// 42824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// @param[out] new_value 42924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// The new value if \b true is returned. 43024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// 43124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// @param[in] abstime 43224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// If non-NULL, the absolute time at which we should stop 43324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// waiting, else wait an infinite amount of time. 43424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// 43524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// @return 43624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// @li \b true if the \a m_value is equal to \a value 43724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// @li \b false otherwise 43824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner //------------------------------------------------------------------ 43924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner bool 44024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner WaitForValueNotEqualTo (T value, T &new_value, const TimeValue *abstime = NULL) 44124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 44224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner int err = 0; 44324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // pthread_cond_timedwait() or pthread_cond_wait() will atomically 44424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // unlock the mutex and wait for the condition to be set. When either 44524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // function returns, they will re-lock the mutex. We use an auto lock/unlock 44624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // class (Mutex::Locker) to allow us to return at any point in this 44724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // function and not have to worry about unlocking the mutex. 44824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Mutex::Locker locker(m_mutex); 44924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#ifdef DB_PTHREAD_LOG_EVENTS 45022f44d5f0a70e43825abadcc8f475ea4b4353509Enrico Granata printf("%s (value = 0x%8.8x, abstime = %p), m_value = 0x%8.8x\n", __FUNCTION__, value, abstime, m_value); 45124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#endif 45224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner while (err == 0 && m_value == value) 45324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 4548533e994d3076ef517e2cf7f3030bbc6a7273a9bJim Ingham err = m_condition.Wait (m_mutex, abstime); 45524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 45624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 45724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (m_value != value) 45824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 45924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner new_value = m_value; 46024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return true; 46124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 46224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return false; 46324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 46424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 46524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerprotected: 46624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner //---------------------------------------------------------------------- 46724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // pthread condition and mutex variable to controll access and allow 46824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // blocking between the main thread and the spotlight index thread. 46924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner //---------------------------------------------------------------------- 47024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner T m_value; ///< The templatized value T that we are protecting access to 47124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner mutable Mutex m_mutex; ///< The mutex to use when accessing the data 47224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Condition m_condition; ///< The pthread condition variable to use for signaling that data available or changed. 47324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 47424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerprivate: 47524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 47624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner //------------------------------------------------------------------ 47724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// Broadcast if needed. 47824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// 47924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// Check to see if we need to broadcast to our condition variable 48024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// depedning on the \a old_value and on the \a broadcast_type. 48124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// 48224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// If \a broadcast_type is eBroadcastNever, no broadcast will be 48324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// sent. 48424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// 48524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// If \a broadcast_type is eBroadcastAlways, the condition variable 48624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// will always be broadcast. 48724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// 48824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// If \a broadcast_type is eBroadcastOnChange, the condition 48924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// variable be broadcast if the owned value changes. 49024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner //------------------------------------------------------------------ 49124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner void 49224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Broadcast (T old_value, PredicateBroadcastType broadcast_type) 49324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 49424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner bool broadcast = (broadcast_type == eBroadcastAlways) || ((broadcast_type == eBroadcastOnChange) && old_value != m_value); 49524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#ifdef DB_PTHREAD_LOG_EVENTS 49622f44d5f0a70e43825abadcc8f475ea4b4353509Enrico Granata printf("%s (old_value = 0x%8.8x, broadcast_type = %i) m_value = 0x%8.8x, broadcast = %u\n", __FUNCTION__, old_value, broadcast_type, m_value, broadcast); 49724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#endif 49824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (broadcast) 49924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_condition.Broadcast(); 50024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 50124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 50224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 50324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DISALLOW_COPY_AND_ASSIGN(Predicate); 50424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}; 50524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 50624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} // namespace lldb_private 50724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 50824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#endif // #if defined(__cplusplus) 50924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#endif // #ifndef liblldb_Predicate_h_ 510