ns-3 Direct Code Execution
Home
Tutorials ▼
Docs ▼
Wiki
Manual
Develop ▼
API
Bugs
API
Main Page
Related Pages
Namespaces
Classes
Files
File List
File Members
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Friends
Macros
Pages
dce-semaphore.cc
Go to the documentation of this file.
1
#include "
dce-semaphore.h
"
2
#include "
process.h
"
3
#include "
dce-manager.h
"
4
#include "
utils.h
"
5
#include <stdint.h>
6
#include <errno.h>
7
#include "ns3/log.h"
8
#include "ns3/assert.h"
9
#include "ns3/fatal-error.h"
10
#include "ns3/simulator.h"
11
12
NS_LOG_COMPONENT_DEFINE
(
"Semaphore"
);
13
14
using namespace
ns3;
15
16
17
static
uint32_t
AllocateSid
(
struct
Process
*process)
18
{
19
// check that semaphore structure is big enough to store our semaphore id
20
NS_ASSERT (
sizeof
(sem_t) >
sizeof
(uint16_t));
21
uint32_t sid = process->
nextSid
;
22
process->
nextSid
++;
23
return
sid;
24
}
25
static
void
SidToSem
(uint32_t sid, sem_t *sem)
26
{
27
uint32_t *psid = (uint32_t *)sem;
28
*psid = sid;
29
}
30
static
uint32_t
SemToSid
(
const
sem_t *sem)
31
{
32
if
(sem == 0)
33
{
34
return
0;
35
}
36
const
uint32_t *psid = (
const
uint32_t *)sem;
37
return
*psid;
38
}
39
static
struct
Semaphore
*
40
SearchSemaphore
(
const
sem_t *sem)
41
{
42
Thread
*current =
Current
();
43
if
(sem == 0)
44
{
45
return
0;
46
}
47
uint32_t sid =
SemToSid
(sem);
48
for
(uint32_t i = 0; i < current->
process
->
semaphores
.size (); ++i)
49
{
50
struct
Semaphore
*semaphore = current->
process
->
semaphores
[i];
51
if
(semaphore->
sid
== sid)
52
{
53
return
semaphore;
54
}
55
}
56
return
0;
57
}
58
59
int
dce_sem_init
(sem_t *sem,
int
pshared,
unsigned
int
value)
60
{
61
Thread
*current =
Current
();
62
NS_LOG_FUNCTION (current << sem << pshared << value);
63
NS_ASSERT (current != 0);
64
65
if
(pshared != 0)
66
{
67
current->
err
= ENOSYS;
68
return
-1;
69
}
70
Semaphore
*semaphore =
new
Semaphore
();
71
semaphore->
sid
=
AllocateSid
(current->
process
);
72
semaphore->
count
= value;
73
semaphore->
waiting
.clear ();
74
current->
process
->
semaphores
.push_back (semaphore);
75
SidToSem
(semaphore->
sid
, sem);
76
return
0;
77
}
78
int
dce_sem_destroy
(sem_t *sem)
79
{
80
Thread
*current =
Current
();
81
NS_LOG_FUNCTION (current <<
UtilsGetNodeId
() << sem);
82
NS_ASSERT (current != 0);
83
struct
Semaphore
*semaphore =
SearchSemaphore
(sem);
84
if
(semaphore == 0)
85
{
86
current->
err
= EINVAL;
87
return
-1;
88
}
89
if
(!semaphore->
waiting
.empty ())
90
{
91
NS_FATAL_ERROR (
"Trying to destroy a semaphore on which someone else is waiting."
);
92
}
93
for
(std::vector<struct Semaphore *>::iterator i = current->
process
->
semaphores
.begin ();
94
i != current->
process
->
semaphores
.end (); ++i)
95
{
96
if
(semaphore == *i)
97
{
98
delete
semaphore;
99
semaphore = 0;
100
current->
process
->
semaphores
.erase (i);
101
break
;
102
}
103
}
104
NS_ASSERT (semaphore == 0);
105
SidToSem
(2, sem);
106
return
0;
107
}
108
int
dce_sem_post
(sem_t *sem)
109
{
110
Thread
*current =
Current
();
111
NS_LOG_FUNCTION (current <<
UtilsGetNodeId
() << sem);
112
NS_ASSERT (current != 0);
113
114
struct
Semaphore
*semaphore =
SearchSemaphore
(sem);
115
if
(semaphore == 0)
116
{
117
current->
err
= EINVAL;
118
return
-1;
119
}
120
121
semaphore->
count
++;
122
123
if
(!semaphore->
waiting
.empty ())
124
{
125
// FIFO order for threads blocked on the semaphore waiting for it.
126
Thread
*waiting = semaphore->
waiting
.front ();
127
current->
process
->
manager
->
Wakeup
(waiting);
128
// give them a chance to run.
129
current->
process
->
manager
->
Yield
();
130
}
131
132
return
0;
133
}
134
int
dce_sem_wait
(sem_t *sem)
135
{
136
Thread
*current =
Current
();
137
NS_LOG_FUNCTION (current <<
UtilsGetNodeId
() << sem);
138
NS_ASSERT (current != 0);
139
140
struct
Semaphore
*semaphore =
SearchSemaphore
(sem);
141
if
(semaphore == 0)
142
{
143
current->
err
= EINVAL;
144
return
-1;
145
}
146
while
(semaphore->
count
== 0)
147
{
148
semaphore->
waiting
.push_back (current);
149
current->
process
->
manager
->
Wait
();
150
semaphore->
waiting
.remove (current);
151
}
152
semaphore->
count
--;
153
return
0;
154
}
155
int
dce_sem_trywait
(sem_t *sem)
156
{
157
Thread
*current =
Current
();
158
NS_LOG_FUNCTION (current <<
UtilsGetNodeId
() << sem);
159
NS_ASSERT (current != 0);
160
161
struct
Semaphore
*semaphore =
SearchSemaphore
(sem);
162
if
(semaphore == 0)
163
{
164
current->
err
= EINVAL;
165
return
-1;
166
}
167
if
(semaphore->
count
== 0)
168
{
169
current->
err
= EAGAIN;
170
return
-1;
171
}
172
semaphore->
count
--;
173
return
0;
174
}
175
int
dce_sem_timedwait
(sem_t *sem,
const
struct
timespec *abs_timeout)
176
{
177
Thread
*current =
Current
();
178
NS_LOG_FUNCTION (current <<
UtilsGetNodeId
() << sem);
179
NS_ASSERT (current != 0);
180
181
struct
Semaphore
*semaphore =
SearchSemaphore
(sem);
182
if
(semaphore == 0)
183
{
184
current->
err
= EINVAL;
185
return
-1;
186
}
187
188
if
(semaphore->
count
> 0)
189
{
190
// fast path
191
semaphore->
count
--;
192
return
0;
193
}
194
Time expirationTime =
UtilsTimeToSimulationTime
(
UtilsTimespecToTime
(*abs_timeout));
195
if
(expirationTime <= Simulator::Now ())
196
{
197
// timer already expired when we start.
198
current->
err
= ETIMEDOUT;
199
return
-1;
200
}
201
// setup timer.
202
Time timeoutLeft = expirationTime - Simulator::Now ();
203
while
(semaphore->
count
== 0)
204
{
205
semaphore->
waiting
.push_back (current);
206
timeoutLeft = current->
process
->
manager
->
Wait
(timeoutLeft);
207
semaphore->
waiting
.remove (current);
208
if
(timeoutLeft.IsZero ())
209
{
210
// timer expired
211
current->
err
= ETIMEDOUT;
212
return
-1;
213
}
214
}
215
semaphore->
count
--;
216
return
0;
217
}
218
int
dce_sem_getvalue
(sem_t *sem,
int
*sval)
219
{
220
Thread
*current =
Current
();
221
NS_LOG_FUNCTION (current <<
UtilsGetNodeId
() << sem);
222
NS_ASSERT (current != 0);
223
224
struct
Semaphore
*semaphore =
SearchSemaphore
(sem);
225
if
(semaphore == 0)
226
{
227
current->
err
= EINVAL;
228
return
-1;
229
}
230
*sval = semaphore->
count
;
231
return
0;
232
}
model
dce-semaphore.cc
Generated on Fri Aug 30 2013 13:57:55 for ns-3-dce by
1.8.1.2