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 public:
46  static const uint64_t NS_PER_SEC = (uint64_t)1000000000;
47 
52 
58  void SetCondition (bool condition);
64  bool GetCondition (void);
66  void Signal (void);
68  void Broadcast (void);
72  void Wait (void);
81  bool TimedWait (uint64_t ns);
82 
83 private:
85  pthread_mutex_t m_mutex;
87  pthread_cond_t m_cond;
90 };
91 
93 {
94  NS_LOG_FUNCTION (this);
95 
96  m_condition = false;
97 
98  pthread_mutexattr_t mAttr;
99  pthread_mutexattr_init (&mAttr);
100 //
101 // Linux and OS X (at least) have, of course chosen different names for the
102 // error checking flags just to make life difficult.
103 //
104 #if defined (PTHREAD_MUTEX_ERRORCHECK_NP)
105  pthread_mutexattr_settype (&mAttr, PTHREAD_MUTEX_ERRORCHECK_NP);
106 #else
107  pthread_mutexattr_settype (&mAttr, PTHREAD_MUTEX_ERRORCHECK);
108 #endif
109  pthread_mutex_init (&m_mutex, &mAttr);
110 
111  pthread_condattr_t cAttr;
112  pthread_condattr_init (&cAttr);
113  pthread_condattr_setpshared (&cAttr, PTHREAD_PROCESS_PRIVATE);
114  pthread_cond_init (&m_cond, &cAttr);
115 }
116 
118 {
119  NS_LOG_FUNCTION (this);
120  pthread_mutex_destroy (&m_mutex);
121  pthread_cond_destroy (&m_cond);
122 }
123 
124 void
126 {
127  NS_LOG_FUNCTION (this << condition);
128  m_condition = condition;
129 }
130 
131 bool
133 {
134  NS_LOG_FUNCTION (this);
135  return m_condition;
136 }
137 
138 void
140 {
141  NS_LOG_FUNCTION (this);
142 
143  pthread_mutex_lock (&m_mutex);
144  pthread_cond_signal (&m_cond);
145  pthread_mutex_unlock (&m_mutex);
146 }
147 
148 void
150 {
151  NS_LOG_FUNCTION (this);
152 
153  pthread_mutex_lock (&m_mutex);
154  pthread_cond_broadcast (&m_cond);
155  pthread_mutex_unlock (&m_mutex);
156 }
157 
158 void
160 {
161  NS_LOG_FUNCTION (this);
162 
163  pthread_mutex_lock (&m_mutex);
164  m_condition = false;
165  while (m_condition == false)
166  {
167  pthread_cond_wait (&m_cond, &m_mutex);
168  }
169  pthread_mutex_unlock (&m_mutex);
170 }
171 
172 bool
174 {
175  NS_LOG_FUNCTION (this << ns);
176 
177  struct timespec ts;
178  ts.tv_sec = ns / NS_PER_SEC;
179  ts.tv_nsec = ns % NS_PER_SEC;
180 
181  struct timeval tv;
182  gettimeofday (&tv, NULL);
183 
184  ts.tv_sec += tv.tv_sec;
185  ts.tv_nsec += tv.tv_usec * 1000;
186  if (ts.tv_nsec > (int64_t)NS_PER_SEC)
187  {
188  ++ts.tv_sec;
189  ts.tv_nsec %= NS_PER_SEC;
190  }
191 
192  int rc;
193 
194  pthread_mutex_lock (&m_mutex);
195  while (m_condition == false)
196  {
197  rc = pthread_cond_timedwait (&m_cond, &m_mutex, &ts);
198  if (rc == ETIMEDOUT)
199  {
200  pthread_mutex_unlock (&m_mutex);
201  return true;
202  }
203  }
204  pthread_mutex_unlock (&m_mutex);
205  return false;
206 }
207 
209  : m_priv (new SystemConditionPrivate ())
210 {
211  NS_LOG_FUNCTION (this);
212 }
213 
215 {
216  NS_LOG_FUNCTION (this);
217  delete m_priv;
218 }
219 
220 void
222 {
223  NS_LOG_FUNCTION (this << condition);
224  m_priv->SetCondition (condition);
225 }
226 
227 bool
229 {
230  NS_LOG_FUNCTION (this);
231  return m_priv->GetCondition ();
232 }
233 
234 void
236 {
237  NS_LOG_FUNCTION (this);
238  m_priv->Signal ();
239 }
240 
241 void
243 {
244  NS_LOG_FUNCTION (this);
245  m_priv->Broadcast ();
246 }
247 
248 void
250 {
251  NS_LOG_FUNCTION (this);
252  m_priv->Wait ();
253 }
254 
255 bool
257 {
258  NS_LOG_FUNCTION (this << ns);
259  return m_priv->TimedWait (ns);
260 }
261 
262 } // 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:204
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.