1254721Semaste//===-- Condition.cpp -------------------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#include <errno.h>
11254721Semaste
12254721Semaste#include "lldb/Host/Condition.h"
13254721Semaste#include "lldb/Host/TimeValue.h"
14254721Semaste
15254721Semaste
16254721Semasteusing namespace lldb_private;
17254721Semaste
18263363Semaste#ifndef _WIN32
19263363Semaste
20254721Semaste//----------------------------------------------------------------------
21254721Semaste// Default constructor
22254721Semaste//
23254721Semaste// The default constructor will initialize a new pthread condition
24254721Semaste// and maintain the condition in the object state.
25254721Semaste//----------------------------------------------------------------------
26254721SemasteCondition::Condition () :
27254721Semaste    m_condition()
28254721Semaste{
29254721Semaste    ::pthread_cond_init (&m_condition, NULL);
30254721Semaste}
31254721Semaste
32254721Semaste//----------------------------------------------------------------------
33254721Semaste// Destructor
34254721Semaste//
35254721Semaste// Destroys the pthread condition that the object owns.
36254721Semaste//----------------------------------------------------------------------
37254721SemasteCondition::~Condition ()
38254721Semaste{
39254721Semaste    ::pthread_cond_destroy (&m_condition);
40254721Semaste}
41254721Semaste
42254721Semaste//----------------------------------------------------------------------
43254721Semaste// Unblock all threads waiting for a condition variable
44254721Semaste//----------------------------------------------------------------------
45254721Semasteint
46254721SemasteCondition::Broadcast ()
47254721Semaste{
48254721Semaste    return ::pthread_cond_broadcast (&m_condition);
49254721Semaste}
50254721Semaste
51254721Semaste//----------------------------------------------------------------------
52254721Semaste// Unblocks one thread waiting for the condition variable
53254721Semaste//----------------------------------------------------------------------
54254721Semasteint
55254721SemasteCondition::Signal ()
56254721Semaste{
57254721Semaste    return ::pthread_cond_signal (&m_condition);
58254721Semaste}
59254721Semaste
60263363Semaste/* convert struct timeval to ms(milliseconds) */
61263363Semastestatic unsigned long int tv2ms(struct timeval a) {
62263363Semaste    return ((a.tv_sec * 1000) + (a.tv_usec / 1000));
63263363Semaste}
64263363Semaste
65254721Semaste//----------------------------------------------------------------------
66254721Semaste// The Wait() function atomically blocks the current thread
67254721Semaste// waiting on the owned condition variable, and unblocks the mutex
68254721Semaste// specified by "mutex".  The waiting thread unblocks only after
69254721Semaste// another thread calls Signal(), or Broadcast() with the same
70254721Semaste// condition variable, or if "abstime" is valid (non-NULL) this
71254721Semaste// function will return when the system time reaches the time
72254721Semaste// specified in "abstime". If "abstime" is NULL this function will
73254721Semaste// wait for an infinite amount of time for the condition variable
74254721Semaste// to be signaled or broadcasted.
75254721Semaste//
76254721Semaste// The current thread re-acquires the lock on "mutex".
77254721Semaste//----------------------------------------------------------------------
78254721Semasteint
79254721SemasteCondition::Wait (Mutex &mutex, const TimeValue *abstime, bool *timed_out)
80254721Semaste{
81254721Semaste    int err = 0;
82254721Semaste    do
83254721Semaste    {
84254721Semaste        if (abstime && abstime->IsValid())
85254721Semaste        {
86254721Semaste            struct timespec abstime_ts = abstime->GetAsTimeSpec();
87254721Semaste            err = ::pthread_cond_timedwait (&m_condition, mutex.GetMutex(), &abstime_ts);
88254721Semaste        }
89254721Semaste        else
90254721Semaste            err = ::pthread_cond_wait (&m_condition, mutex.GetMutex());
91254721Semaste    } while (err == EINTR);
92254721Semaste
93254721Semaste    if (timed_out != NULL)
94254721Semaste    {
95254721Semaste        if (err == ETIMEDOUT)
96254721Semaste            *timed_out = true;
97254721Semaste        else
98254721Semaste            *timed_out = false;
99254721Semaste    }
100254721Semaste
101254721Semaste    return err;
102254721Semaste}
103254721Semaste
104263363Semaste#endif
105263363Semaste
106263363Semaste//----------------------------------------------------------------------
107263363Semaste// Get accessor to the pthread condition object
108263363Semaste//----------------------------------------------------------------------
109263363Semastelldb::condition_t *
110263363SemasteCondition::GetCondition()
111263363Semaste{
112263363Semaste    return &m_condition;
113263363Semaste}
114