ns-3 Direct Code Execution
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
dce-pthread-cond.cc
Go to the documentation of this file.
1 #include "dce-pthread.h"
2 #include "process.h"
3 #include "utils.h"
4 #include "dce-manager.h"
5 #include "ns3/log.h"
6 #include "ns3/assert.h"
7 #include <errno.h>
8 
9 NS_LOG_COMPONENT_DEFINE ("SimuPthreadCond");
10 
11 using namespace ns3;
12 
13 
14 static uint32_t
15 CondToCid (const pthread_cond_t *cond)
16 {
17  NS_ASSERT (sizeof (pthread_cond_t) >= 4);
18  if (cond != 0)
19  {
20  const uint32_t *pcid = (const uint32_t *)cond;
21  return *pcid;
22  }
23  return 0;
24 }
25 static void
26 CidToCond (uint32_t cid, pthread_cond_t *cond)
27 {
28  uint32_t *pcid = (uint32_t *)cond;
29  *pcid = cid;
30 }
31 static struct Condition *
32 PthreadCondInitStatic (pthread_cond_t *cond)
33 {
34  Thread *current = Current ();
35  NS_LOG_FUNCTION (cond);
36  // This method initializes the condition variable fully when it has been
37  // initialized with PTHREAD_COND_INITIALIZER.
38  struct Condition *condition = new Condition ();
39  condition->cid = current->process->nextCid;
40  current->process->nextCid++;
41  current->process->conditions.push_back (condition);
42  CidToCond (condition->cid, cond);
43  return condition;
44 }
45 
46 static struct Condition *
47 SearchCondition (pthread_cond_t *cond)
48 {
49  Thread *current = Current ();
50  if (cond == 0)
51  {
52  return 0;
53  }
54  uint32_t cid = CondToCid (cond);
55  if (cid == 0)
56  {
57  struct Condition *condition = PthreadCondInitStatic (cond);
58  return condition;
59  }
60  for (uint32_t i = 0; i < current->process->conditions.size (); ++i)
61  {
62  struct Condition *condition = current->process->conditions[i];
63  if (condition->cid == cid)
64  {
65  return condition;
66  }
67  }
68  return 0;
69 }
70 
71 
72 int dce_pthread_cond_init (pthread_cond_t *cond,
73  const pthread_condattr_t *attr)
74 {
75  NS_LOG_FUNCTION (Current () << UtilsGetNodeId () << cond << attr);
76  NS_ASSERT (Current () != 0);
77 
78  if (cond == 0)
79  {
80  return EINVAL;
81  }
82  PthreadCondInitStatic (cond);
83 
84  return 0;
85 }
86 int dce_pthread_cond_destroy (pthread_cond_t *cond)
87 {
88  NS_LOG_FUNCTION (Current () << UtilsGetNodeId () << cond);
89  NS_ASSERT (Current () != 0);
90  Thread *current = Current ();
91 
92  struct Condition *condition = SearchCondition (cond);
93  if (condition == 0)
94  {
95  return EINVAL;
96  }
97 
98  for (std::vector<struct Condition *>::iterator i = current->process->conditions.begin ();
99  i != current->process->conditions.end (); ++i)
100  {
101  if (condition == *i)
102  {
103  delete condition;
104  condition = 0;
105  current->process->conditions.erase (i);
106  break;
107  }
108  }
109  NS_ASSERT (condition == 0);
110  CidToCond (2, cond);
111 
112  return 0;
113 }
114 int dce_pthread_cond_broadcast (pthread_cond_t *cond)
115 {
116  NS_LOG_FUNCTION (Current () << UtilsGetNodeId () << cond);
117  NS_ASSERT (Current () != 0);
118  Thread *current = Current ();
119 
120  struct Condition *condition = SearchCondition (cond);
121  if (condition == 0)
122  {
123  return EINVAL;
124  }
125 
126  for (std::list<Thread *>::const_iterator i = condition->waiting.begin ();
127  i != condition->waiting.end (); i++)
128  {
129  current->process->manager->Wakeup (*i);
130  }
131  condition->waiting.clear ();
132  return 0;
133 }
134 int dce_pthread_cond_signal (pthread_cond_t *cond)
135 {
136  NS_LOG_FUNCTION (Current () << UtilsGetNodeId () << cond);
137  NS_ASSERT (Current () != 0);
138  Thread *current = Current ();
139 
140  struct Condition *condition = SearchCondition (cond);
141  if (condition == 0)
142  {
143  return EINVAL;
144  }
145  if (!condition->waiting.empty ())
146  {
147  Thread *thread = condition->waiting.front ();
148  current->process->manager->Wakeup (thread);
149  condition->waiting.pop_front ();
150  }
151  return 0;
152 }
153 int dce_pthread_cond_timedwait (pthread_cond_t * cond,
154  pthread_mutex_t * mutex,
155  const struct timespec * abstime)
156 {
157  NS_LOG_FUNCTION (Current () << UtilsGetNodeId () << cond << mutex);
158  NS_ASSERT (Current () != 0);
159  Thread *current = Current ();
160 
161  struct Condition *condition = SearchCondition (cond);
162  if (condition == 0)
163  {
164  return EINVAL;
165  }
166  Time timeout = UtilsTimeToSimulationTime (UtilsTimespecToTime (*abstime));
167  timeout -= Simulator::Now ();
168  timeout = Max (Seconds (0.0), timeout);
169 
170  dce_pthread_mutex_unlock (mutex);
171  condition->waiting.push_back (current);
172  Time timeLeft = current->process->manager->Wait (timeout);
173  dce_pthread_mutex_lock (mutex);
174  if (timeLeft.IsZero ())
175  {
176  return ETIMEDOUT;
177  }
178  return 0;
179 }
180 int dce_pthread_cond_wait (pthread_cond_t * cond,
181  pthread_mutex_t * mutex)
182 {
183  NS_LOG_FUNCTION (Current () << UtilsGetNodeId () << cond << mutex);
184  NS_ASSERT (Current () != 0);
185  Thread *current = Current ();
186 
187  struct Condition *condition = SearchCondition (cond);
188  if (condition == 0)
189  {
190  return EINVAL;
191  }
192  dce_pthread_mutex_unlock (mutex);
193  condition->waiting.push_back (current);
194  current->process->manager->Wait ();
195  dce_pthread_mutex_lock (mutex);
196  return 0;
197 }
198 
199 // we don't implement any attribute for condition variables
200 int dce_pthread_condattr_init (pthread_condattr_t *attr)
201 {
202  return 0;
203 }
204 int dce_pthread_condattr_destroy (pthread_condattr_t *attr)
205 {
206  return 0;
207 }