A Discrete-Event Network Simulator
API
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 <time.h> // for timespec
22 #include <sys/time.h> // for timeval, gettimeofday
23 
24 #include "fatal-error.h"
25 #include "system-condition.h"
26 #include "log.h"
27 
28 
35 namespace ns3 {
36 
37 NS_LOG_COMPONENT_DEFINE ("SystemCondition");
38 
44 {
45 public:
47  static const uint64_t NS_PER_SEC = (uint64_t)1000000000;
48 
53 
59  void SetCondition (bool condition);
65  bool GetCondition (void);
67  void Signal (void);
69  void Broadcast (void);
73  void Wait (void);
82  bool TimedWait (uint64_t ns);
83 
84 private:
86  pthread_mutex_t m_mutex;
88  pthread_cond_t m_cond;
91 };
92 
94 {
95  NS_LOG_FUNCTION (this);
96 
97  m_condition = false;
98 
99  pthread_mutexattr_t mAttr;
100  pthread_mutexattr_init (&mAttr);
101 //
102 // Linux and OS X (at least) have, of course chosen different names for the
103 // error checking flags just to make life difficult.
104 //
105 #if defined (PTHREAD_MUTEX_ERRORCHECK_NP)
106  pthread_mutexattr_settype (&mAttr, PTHREAD_MUTEX_ERRORCHECK_NP);
107 #else
108  pthread_mutexattr_settype (&mAttr, PTHREAD_MUTEX_ERRORCHECK);
109 #endif
110  pthread_mutex_init (&m_mutex, &mAttr);
111 
112  pthread_condattr_t cAttr;
113  pthread_condattr_init (&cAttr);
114  pthread_condattr_setpshared (&cAttr, PTHREAD_PROCESS_PRIVATE);
115  pthread_cond_init (&m_cond, &cAttr);
116 }
117 
119 {
120  NS_LOG_FUNCTION (this);
121  pthread_mutex_destroy (&m_mutex);
122  pthread_cond_destroy (&m_cond);
123 }
124 
125 void
127 {
128  NS_LOG_FUNCTION (this << condition);
129  m_condition = condition;
130 }
131 
132 bool
134 {
135  NS_LOG_FUNCTION (this);
136  return m_condition;
137 }
138 
139 void
141 {
142  NS_LOG_FUNCTION (this);
143 
144  pthread_mutex_lock (&m_mutex);
145  pthread_cond_signal (&m_cond);
146  pthread_mutex_unlock (&m_mutex);
147 }
148 
149 void
151 {
152  NS_LOG_FUNCTION (this);
153 
154  pthread_mutex_lock (&m_mutex);
155  pthread_cond_broadcast (&m_cond);
156  pthread_mutex_unlock (&m_mutex);
157 }
158 
159 void
161 {
162  NS_LOG_FUNCTION (this);
163 
164  pthread_mutex_lock (&m_mutex);
165  m_condition = false;
166  while (m_condition == false)
167  {
168  pthread_cond_wait (&m_cond, &m_mutex);
169  }
170  pthread_mutex_unlock (&m_mutex);
171 }
172 
173 bool
175 {
176  NS_LOG_FUNCTION (this << ns);
177 
178  struct timespec ts;
179  ts.tv_sec = ns / NS_PER_SEC;
180  ts.tv_nsec = ns % NS_PER_SEC;
181 
182  struct timeval tv;
183  gettimeofday (&tv, NULL);
184 
185  ts.tv_sec += tv.tv_sec;
186  ts.tv_nsec += tv.tv_usec * 1000;
187  if (ts.tv_nsec > (int64_t)NS_PER_SEC)
188  {
189  ++ts.tv_sec;
190  ts.tv_nsec %= NS_PER_SEC;
191  }
192 
193  int rc;
194 
195  pthread_mutex_lock (&m_mutex);
196  while (m_condition == false)
197  {
198  rc = pthread_cond_timedwait (&m_cond, &m_mutex, &ts);
199  if (rc == ETIMEDOUT)
200  {
201  pthread_mutex_unlock (&m_mutex);
202  return true;
203  }
204  }
205  pthread_mutex_unlock (&m_mutex);
206  return false;
207 }
208 
210  : m_priv (new SystemConditionPrivate ())
211 {
212  NS_LOG_FUNCTION (this);
213 }
214 
216 {
217  NS_LOG_FUNCTION (this);
218  delete m_priv;
219 }
220 
221 void
223 {
224  NS_LOG_FUNCTION (this << condition);
225  m_priv->SetCondition (condition);
226 }
227 
228 bool
230 {
231  NS_LOG_FUNCTION (this);
232  return m_priv->GetCondition ();
233 }
234 
235 void
237 {
238  NS_LOG_FUNCTION (this);
239  m_priv->Signal ();
240 }
241 
242 void
244 {
245  NS_LOG_FUNCTION (this);
246  m_priv->Broadcast ();
247 }
248 
249 void
251 {
252  NS_LOG_FUNCTION (this);
253  m_priv->Wait ();
254 }
255 
256 bool
258 {
259  NS_LOG_FUNCTION (this << ns);
260  return m_priv->TimedWait (ns);
261 }
262 
263 } // namespace ns3
NS_FATAL_x macro definitions.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
void Signal(void)
Signal the condition.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
ns3::SystemCondition declaration.
bool TimedWait(uint64_t ns)
Unset the condition, then wait for a limited amount of wall-clock time for another thread to set it w...
pthread_cond_t m_cond
The pthread condition variable.
void Signal(void)
Release one thread if waiting for the condition to be true.
void Broadcast(void)
Broadcast the condition.
void Broadcast(void)
Release all threads waiting for the condition to be true.
void SetCondition(bool condition)
Set the condition.
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.
void Wait(void)
Unset the condition, then wait for another thread to set it with SetCondition.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
bool TimedWait(uint64_t ns)
Wait a maximum of ns nanoseconds for the condition to be true.
bool m_condition
The condition state.
Implementation of SystemCondition for Unix-like systems.
SystemConditionPrivate * m_priv
The (system-dependent) implementation.
static const uint64_t NS_PER_SEC
Conversion from ns to s.
pthread_mutex_t m_mutex
Mutex controlling access to the condition.
Debug message logging.
bool GetCondition(void)
Get the condition value.