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
35namespace ns3 {
36
37NS_LOG_COMPONENT_DEFINE ("SystemCondition");
38
44{
45public:
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
84private:
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
125void
127{
128 NS_LOG_FUNCTION (this << condition);
129 m_condition = condition;
130}
131
132bool
134{
135 NS_LOG_FUNCTION (this);
136 return m_condition;
137}
138
139void
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
149void
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
159void
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
173bool
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
221void
223{
224 NS_LOG_FUNCTION (this << condition);
225 m_priv->SetCondition (condition);
226}
227
228bool
230{
231 NS_LOG_FUNCTION (this);
232 return m_priv->GetCondition ();
233}
234
235void
237{
238 NS_LOG_FUNCTION (this);
239 m_priv->Signal ();
240}
241
242void
244{
245 NS_LOG_FUNCTION (this);
246 m_priv->Broadcast ();
247}
248
249void
251{
252 NS_LOG_FUNCTION (this);
253 m_priv->Wait ();
254}
255
256bool
258{
259 NS_LOG_FUNCTION (this << ns);
260 return m_priv->TimedWait (ns);
261}
262
263} // namespace ns3
void Signal(void)
Release one thread if waiting for the condition to be true.
bool GetCondition(void)
Get the value of the underlying condition.
void SetCondition(bool condition)
Set the value of the underlying condition.
void Broadcast(void)
Release all threads waiting for the condition to be true.
SystemConditionPrivate * m_priv
The (system-dependent) implementation.
void Wait(void)
Wait, possibly forever, for the condition to be true.
bool TimedWait(uint64_t ns)
Wait a maximum of ns nanoseconds for the condition to be true.
Implementation of SystemCondition for Unix-like systems.
void Signal(void)
Signal the condition.
void SetCondition(bool condition)
Set the condition.
bool GetCondition(void)
Get the condition value.
static const uint64_t NS_PER_SEC
Conversion from ns to s.
pthread_cond_t m_cond
The pthread condition variable.
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...
void Broadcast(void)
Broadcast the condition.
bool m_condition
The condition state.
pthread_mutex_t m_mutex
Mutex controlling access to the condition.
void Wait(void)
Unset the condition, then wait for another thread to set it with SetCondition.
NS_FATAL_x macro definitions.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Debug message logging.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
ns3::SystemCondition declaration.