A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
unix-system-condition.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2008 University of Washington
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  */
18 
19 #include <pthread.h>
20 #include <cerrno> // for ETIMEDOUT
21 #include <sys/time.h>
22 
23 #include "fatal-error.h"
24 #include "system-condition.h"
25 #include "log.h"
26 
27 
28 NS_LOG_COMPONENT_DEFINE ("SystemCondition");
29 
30 namespace ns3 {
31 
33 public:
34  static const uint64_t NS_PER_SEC = (uint64_t)1000000000;
35 
38 
39  void SetCondition (bool condition);
40  bool GetCondition (void);
41  void Signal (void);
42  void Broadcast (void);
43  void Wait (void);
44  bool TimedWait (uint64_t ns);
45 
46 private:
47  pthread_mutex_t m_mutex;
48  pthread_cond_t m_cond;
50 };
51 
53 {
54  NS_LOG_FUNCTION (this);
55 
56  m_condition = false;
57 
58  pthread_mutexattr_t mAttr;
59  pthread_mutexattr_init (&mAttr);
60 //
61 // Linux and OS X (at least) have, of course chosen different names for the
62 // error checking flags just to make life difficult.
63 //
64 #if defined (PTHREAD_MUTEX_ERRORCHECK_NP)
65  pthread_mutexattr_settype (&mAttr, PTHREAD_MUTEX_ERRORCHECK_NP);
66 #else
67  pthread_mutexattr_settype (&mAttr, PTHREAD_MUTEX_ERRORCHECK);
68 #endif
69  pthread_mutex_init (&m_mutex, &mAttr);
70 
71  pthread_condattr_t cAttr;
72  pthread_condattr_init (&cAttr);
73  pthread_condattr_setpshared (&cAttr, PTHREAD_PROCESS_PRIVATE);
74  pthread_cond_init (&m_cond, &cAttr);
75 }
76 
78 {
79  NS_LOG_FUNCTION (this);
80  pthread_mutex_destroy (&m_mutex);
81  pthread_cond_destroy (&m_cond);
82 }
83 
84 void
86 {
87  NS_LOG_FUNCTION (this << condition);
88  m_condition = condition;
89 }
90 
91 bool
93 {
94  NS_LOG_FUNCTION (this);
95  return m_condition;
96 }
97 
98 void
100 {
101  NS_LOG_FUNCTION (this);
102 
103  pthread_mutex_lock (&m_mutex);
104  pthread_cond_signal (&m_cond);
105  pthread_mutex_unlock (&m_mutex);
106 }
107 
108 void
110 {
111  NS_LOG_FUNCTION (this);
112 
113  pthread_mutex_lock (&m_mutex);
114  pthread_cond_broadcast (&m_cond);
115  pthread_mutex_unlock (&m_mutex);
116 }
117 
118 void
120 {
121  NS_LOG_FUNCTION (this);
122 
123  pthread_mutex_lock (&m_mutex);
124  m_condition = false;
125  while (m_condition == false)
126  {
127  pthread_cond_wait (&m_cond, &m_mutex);
128  }
129  pthread_mutex_unlock (&m_mutex);
130 }
131 
132 bool
134 {
135  NS_LOG_FUNCTION (this << ns);
136 
137  struct timespec ts;
138  ts.tv_sec = ns / NS_PER_SEC;
139  ts.tv_nsec = ns % NS_PER_SEC;
140 
141  struct timeval tv;
142  gettimeofday (&tv, NULL);
143 
144  ts.tv_sec += tv.tv_sec;
145  ts.tv_nsec += tv.tv_usec * 1000;
146  if (ts.tv_nsec > (int64_t)NS_PER_SEC)
147  {
148  ++ts.tv_sec;
149  ts.tv_nsec %= NS_PER_SEC;
150  }
151 
152  int rc;
153 
154  pthread_mutex_lock (&m_mutex);
155  while (m_condition == false)
156  {
157  rc = pthread_cond_timedwait (&m_cond, &m_mutex, &ts);
158  if (rc == ETIMEDOUT)
159  {
160  pthread_mutex_unlock (&m_mutex);
161  return true;
162  }
163  }
164  pthread_mutex_unlock (&m_mutex);
165  return false;
166 }
167 
169  : m_priv (new SystemConditionPrivate ())
170 {
171  NS_LOG_FUNCTION (this);;
172 }
173 
175 {
176  NS_LOG_FUNCTION (this);
177  delete m_priv;
178 }
179 
180 void
182 {
183  NS_LOG_FUNCTION (this << condition);
184  m_priv->SetCondition (condition);
185 }
186 
187 bool
189 {
190  NS_LOG_FUNCTION (this);
191  return m_priv->GetCondition ();
192 }
193 
194 void
196 {
197  NS_LOG_FUNCTION (this);
198  m_priv->Signal ();
199 }
200 
201 void
203 {
204  NS_LOG_FUNCTION (this);
205  m_priv->Broadcast ();
206 }
207 
208 void
210 {
211  NS_LOG_FUNCTION (this);
212  m_priv->Wait ();
213 }
214 
215 bool
217 {
218  NS_LOG_FUNCTION (this << ns);
219  return m_priv->TimedWait (ns);
220 }
221 
222 } // namespace ns3
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:345
void Signal(void)
Release one thread if waiting for the condition to be true.
void Broadcast(void)
Release all threads waiting for the condition to be true.
void Wait(void)
Wait, possibly forever, for the condition to be true.
void SetCondition(bool condition)
Set the value of the underlying condition.
bool GetCondition(void)
Get the value of the underlying condition.
bool TimedWait(uint64_t ns)
Wait a maximum of ns nanoseconds for the condition to be true.
NS_LOG_COMPONENT_DEFINE("SystemCondition")
SystemConditionPrivate * m_priv
static const uint64_t NS_PER_SEC