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 <sys/time.h>
22 
23 #include "fatal-error.h"
24 #include "system-condition.h"
25 #include "log.h"
26 
27 
34 namespace ns3 {
35 
36 NS_LOG_COMPONENT_DEFINE ("SystemCondition");
37 
43 public:
45  static const uint64_t NS_PER_SEC = (uint64_t)1000000000;
46 
51 
57  void SetCondition (bool condition);
63  bool GetCondition (void);
65  void Signal (void);
67  void Broadcast (void);
71  void Wait (void);
80  bool TimedWait (uint64_t ns);
81 
82 private:
84  pthread_mutex_t m_mutex;
86  pthread_cond_t m_cond;
89 };
90 
92 {
93  NS_LOG_FUNCTION (this);
94 
95  m_condition = false;
96 
97  pthread_mutexattr_t mAttr;
98  pthread_mutexattr_init (&mAttr);
99 //
100 // Linux and OS X (at least) have, of course chosen different names for the
101 // error checking flags just to make life difficult.
102 //
103 #if defined (PTHREAD_MUTEX_ERRORCHECK_NP)
104  pthread_mutexattr_settype (&mAttr, PTHREAD_MUTEX_ERRORCHECK_NP);
105 #else
106  pthread_mutexattr_settype (&mAttr, PTHREAD_MUTEX_ERRORCHECK);
107 #endif
108  pthread_mutex_init (&m_mutex, &mAttr);
109 
110  pthread_condattr_t cAttr;
111  pthread_condattr_init (&cAttr);
112  pthread_condattr_setpshared (&cAttr, PTHREAD_PROCESS_PRIVATE);
113  pthread_cond_init (&m_cond, &cAttr);
114 }
115 
117 {
118  NS_LOG_FUNCTION (this);
119  pthread_mutex_destroy (&m_mutex);
120  pthread_cond_destroy (&m_cond);
121 }
122 
123 void
125 {
126  NS_LOG_FUNCTION (this << condition);
127  m_condition = condition;
128 }
129 
130 bool
132 {
133  NS_LOG_FUNCTION (this);
134  return m_condition;
135 }
136 
137 void
139 {
140  NS_LOG_FUNCTION (this);
141 
142  pthread_mutex_lock (&m_mutex);
143  pthread_cond_signal (&m_cond);
144  pthread_mutex_unlock (&m_mutex);
145 }
146 
147 void
149 {
150  NS_LOG_FUNCTION (this);
151 
152  pthread_mutex_lock (&m_mutex);
153  pthread_cond_broadcast (&m_cond);
154  pthread_mutex_unlock (&m_mutex);
155 }
156 
157 void
159 {
160  NS_LOG_FUNCTION (this);
161 
162  pthread_mutex_lock (&m_mutex);
163  m_condition = false;
164  while (m_condition == false)
165  {
166  pthread_cond_wait (&m_cond, &m_mutex);
167  }
168  pthread_mutex_unlock (&m_mutex);
169 }
170 
171 bool
173 {
174  NS_LOG_FUNCTION (this << ns);
175 
176  struct timespec ts;
177  ts.tv_sec = ns / NS_PER_SEC;
178  ts.tv_nsec = ns % NS_PER_SEC;
179 
180  struct timeval tv;
181  gettimeofday (&tv, NULL);
182 
183  ts.tv_sec += tv.tv_sec;
184  ts.tv_nsec += tv.tv_usec * 1000;
185  if (ts.tv_nsec > (int64_t)NS_PER_SEC)
186  {
187  ++ts.tv_sec;
188  ts.tv_nsec %= NS_PER_SEC;
189  }
190 
191  int rc;
192 
193  pthread_mutex_lock (&m_mutex);
194  while (m_condition == false)
195  {
196  rc = pthread_cond_timedwait (&m_cond, &m_mutex, &ts);
197  if (rc == ETIMEDOUT)
198  {
199  pthread_mutex_unlock (&m_mutex);
200  return true;
201  }
202  }
203  pthread_mutex_unlock (&m_mutex);
204  return false;
205 }
206 
208  : m_priv (new SystemConditionPrivate ())
209 {
210  NS_LOG_FUNCTION (this);;
211 }
212 
214 {
215  NS_LOG_FUNCTION (this);
216  delete m_priv;
217 }
218 
219 void
221 {
222  NS_LOG_FUNCTION (this << condition);
223  m_priv->SetCondition (condition);
224 }
225 
226 bool
228 {
229  NS_LOG_FUNCTION (this);
230  return m_priv->GetCondition ();
231 }
232 
233 void
235 {
236  NS_LOG_FUNCTION (this);
237  m_priv->Signal ();
238 }
239 
240 void
242 {
243  NS_LOG_FUNCTION (this);
244  m_priv->Broadcast ();
245 }
246 
247 void
249 {
250  NS_LOG_FUNCTION (this);
251  m_priv->Wait ();
252 }
253 
254 bool
256 {
257  NS_LOG_FUNCTION (this << ns);
258  return m_priv->TimedWait (ns);
259 }
260 
261 } // 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:201
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.