RobotCore
1.0
WPILib port to raspberry Pi
Toggle main menu visibility
Loading...
Searching...
No Matches
PiSignals.java
1
package
org.wpilib.hardware.hal.PiNotifier;
2
3
import
java.util.ArrayList;
4
import
java.util.HashMap;
5
import
java.util.List;
6
import
java.util.Map;
7
import
java.util.concurrent.atomic.AtomicInteger;
8
import
java.util.concurrent.locks.Condition;
9
import
java.util.concurrent.locks.ReentrantLock;
10
20
public
final
class
PiSignals {
22
public
static
final
int
TYPE_EVENT
= 0x01;
23
25
public
static
final
int
TYPE_SEMAPHORE
= 0x02;
26
28
public
static
final
int
TYPE_NOTIFIER
= 0x13;
29
30
private
static
final
int
ERROR_BIT = 0x80000000;
31
32
private
static
final
class
State {
33
int
signaled;
34
boolean
autoReset;
35
int
maxCount;
// semaphores only
36
final
List<Condition> waiters =
new
ArrayList<>(2);
37
}
38
39
private
static
final
ReentrantLock s_lock =
new
ReentrantLock();
40
private
static
final
Map<Integer, State> s_states =
new
HashMap<>();
41
private
static
final
Map<Integer, AtomicInteger> s_nextIndex =
new
HashMap<>();
42
43
private
PiSignals
() {}
44
45
// ---------------------------------------------------------------- handles
46
53
public
static
int
allocateHandle
(
int
type) {
54
AtomicInteger counter;
55
s_lock.lock();
56
try
{
57
counter = s_nextIndex.computeIfAbsent(type, t ->
new
AtomicInteger());
58
}
finally
{
59
s_lock.unlock();
60
}
61
int
index = counter.incrementAndGet() & 0xFFFFFF;
62
if
(index == 0) {
63
index = counter.incrementAndGet() & 0xFFFFFF;
// skip 0 on wraparound
64
}
65
return
((type & 0x7F) << 24) | index;
66
}
67
68
// ---------------------------------------------------------- signal objects
69
77
public
static
void
createSignalObject
(
int
handle,
boolean
manualReset,
boolean
initialState) {
78
s_lock.lock();
79
try
{
80
State s = s_states.computeIfAbsent(handle, h ->
new
State());
81
s.signaled = initialState ? 1 : 0;
82
s.autoReset = !manualReset;
83
}
finally
{
84
s_lock.unlock();
85
}
86
}
87
93
public
static
void
setSignalObject
(
int
handle) {
94
s_lock.lock();
95
try
{
96
State s = s_states.get(handle);
97
if
(s ==
null
) {
98
return
;
99
}
100
s.signaled = 1;
101
// Wake everyone; with auto-reset only the first to re-check consumes it, the rest re-wait.
102
for
(Condition c : s.waiters) {
103
c.signalAll();
104
}
105
}
finally
{
106
s_lock.unlock();
107
}
108
}
109
115
public
static
void
resetSignalObject
(
int
handle) {
116
s_lock.lock();
117
try
{
118
State s = s_states.get(handle);
119
if
(s !=
null
) {
120
s.signaled = 0;
121
}
122
}
finally
{
123
s_lock.unlock();
124
}
125
}
126
133
public
static
void
destroySignalObject
(
int
handle) {
134
s_lock.lock();
135
try
{
136
State s = s_states.remove(handle);
137
if
(s !=
null
) {
138
for
(Condition c : s.waiters) {
139
c.signalAll();
140
}
141
}
142
}
finally
{
143
s_lock.unlock();
144
}
145
}
146
147
// ------------------------------------------------------------------ events
148
156
public
static
int
makeEvent
(
boolean
manualReset,
boolean
initialState) {
157
int
handle =
allocateHandle
(
TYPE_EVENT
);
158
createSignalObject
(handle, manualReset, initialState);
159
return
handle;
160
}
161
167
public
static
void
destroyEvent
(
int
handle) {
168
if
((handle >>> 24) ==
TYPE_EVENT
) {
169
destroySignalObject
(handle);
170
}
171
}
172
178
public
static
void
setEvent
(
int
handle) {
179
if
((handle >>> 24) ==
TYPE_EVENT
) {
180
setSignalObject
(handle);
181
}
182
}
183
189
public
static
void
resetEvent
(
int
handle) {
190
if
((handle >>> 24) ==
TYPE_EVENT
) {
191
resetSignalObject
(handle);
192
}
193
}
194
195
// -------------------------------------------------------------- semaphores
196
204
public
static
int
makeSemaphore
(
int
initialCount,
int
maximumCount) {
205
int
handle =
allocateHandle
(
TYPE_SEMAPHORE
);
206
s_lock.lock();
207
try
{
208
State s =
new
State();
209
s.signaled = initialCount;
210
s.autoReset =
true
;
211
s.maxCount = maximumCount;
212
s_states.put(handle, s);
213
}
finally
{
214
s_lock.unlock();
215
}
216
return
handle;
217
}
218
224
public
static
void
destroySemaphore
(
int
handle) {
225
if
((handle >>> 24) ==
TYPE_SEMAPHORE
) {
226
destroySignalObject
(handle);
227
}
228
}
229
237
public
static
boolean
releaseSemaphore
(
int
handle,
int
releaseCount) {
238
if
((handle >>> 24) !=
TYPE_SEMAPHORE
|| releaseCount <= 0) {
239
return
false
;
240
}
241
s_lock.lock();
242
try
{
243
State s = s_states.get(handle);
244
if
(s ==
null
|| (s.maxCount - s.signaled) < releaseCount) {
245
return
false
;
246
}
247
s.signaled += releaseCount;
248
for
(Condition c : s.waiters) {
249
c.signalAll();
250
}
251
return
true
;
252
}
finally
{
253
s_lock.unlock();
254
}
255
}
256
257
// ------------------------------------------------------------------ waits
258
// These four match the WPIUtilJNI Java signatures and exception behavior.
259
266
public
static
void
waitForObject
(
int
handle)
throws
InterruptedException {
267
int
[] r = waitCore(
new
int
[] {handle}, -1,
null
);
268
if
(r.length == 0 || (r[0] & ERROR_BIT) != 0) {
269
throw
new
InterruptedException(
"WaitForObject interrupted"
);
270
}
271
}
272
281
public
static
boolean
waitForObjectTimeout
(
int
handle,
double
timeout)
282
throws
InterruptedException {
283
boolean
[] timedOut =
new
boolean
[1];
284
int
[] r = waitCore(
new
int
[] {handle}, timeout, timedOut);
285
if
(timedOut[0]) {
286
return
true
;
287
}
288
if
(r.length == 0 || (r[0] & ERROR_BIT) != 0) {
289
throw
new
InterruptedException(
"WaitForObject interrupted"
);
290
}
291
return
false
;
292
}
293
301
public
static
int
[]
waitForObjects
(
int
[] handles)
throws
InterruptedException {
302
int
[] r = waitCore(handles, -1,
null
);
303
if
(r.length == 0) {
304
throw
new
InterruptedException(
"WaitForObjects interrupted"
);
305
}
306
return
r;
307
}
308
317
public
static
int
[]
waitForObjectsTimeout
(
int
[] handles,
double
timeout)
318
throws
InterruptedException {
319
boolean
[] timedOut =
new
boolean
[1];
320
int
[] r = waitCore(handles, timeout, timedOut);
321
if
(r.length == 0 && !timedOut[0]) {
322
throw
new
InterruptedException(
"WaitForObjects interrupted"
);
323
}
324
return
r;
325
}
326
327
private
static
int
[] waitCore(
int
[] handles,
double
timeout,
boolean
[] timedOutOut)
328
throws
InterruptedException {
329
s_lock.lock();
330
Condition cond =
null
;
331
try
{
332
long
deadline = timeout >= 0 ? System.nanoTime() + (long) (timeout * 1e9) : 0;
333
boolean
timedOut =
false
;
334
int
[] out =
new
int
[handles.length];
335
int
count;
336
for
(;;) {
337
count = 0;
338
for
(
int
h : handles) {
339
State s = s_states.get(h);
340
if
(s ==
null
) {
341
out[count++] = h | ERROR_BIT;
// non-existent/destroyed handle counts as signaled+error
342
}
else
if
(s.signaled > 0) {
343
out[count++] = h;
344
if
(s.autoReset) {
345
s.signaled--;
346
}
347
}
348
}
349
if
(count != 0 || timedOut) {
350
break
;
351
}
352
if
(timeout == 0) {
353
timedOut =
true
;
354
break
;
355
}
356
if
(cond ==
null
) {
357
cond = s_lock.newCondition();
358
for
(
int
h : handles) {
359
State s = s_states.get(h);
360
if
(s !=
null
) {
361
s.waiters.add(cond);
362
}
363
}
364
}
365
if
(timeout < 0) {
366
cond.await();
367
}
else
{
368
long
remaining = deadline - System.nanoTime();
369
if
(remaining <= 0 || cond.awaitNanos(remaining) <= 0) {
370
timedOut =
true
;
// loop once more: a signal may have raced the timeout
371
}
372
}
373
}
374
if
(timedOutOut !=
null
) {
375
timedOutOut[0] = timedOut && count == 0;
376
}
377
int
[] result =
new
int
[count];
378
System.arraycopy(out, 0, result, 0, count);
379
return
result;
380
}
finally
{
381
if
(cond !=
null
) {
382
for
(
int
h : handles) {
383
State s = s_states.get(h);
384
if
(s !=
null
) {
385
s.waiters.remove(cond);
386
}
387
}
388
}
389
s_lock.unlock();
390
}
391
}
392
}
org.wpilib.hardware.hal.PiNotifier.PiSignals
Definition
PiSignals.java:20
org.wpilib.hardware.hal.PiNotifier.PiSignals.setSignalObject
static void setSignalObject(int handle)
Definition
PiSignals.java:93
org.wpilib.hardware.hal.PiNotifier.PiSignals.createSignalObject
static void createSignalObject(int handle, boolean manualReset, boolean initialState)
Definition
PiSignals.java:77
org.wpilib.hardware.hal.PiNotifier.PiSignals.destroyEvent
static void destroyEvent(int handle)
Definition
PiSignals.java:167
org.wpilib.hardware.hal.PiNotifier.PiSignals.destroySignalObject
static void destroySignalObject(int handle)
Definition
PiSignals.java:133
org.wpilib.hardware.hal.PiNotifier.PiSignals.makeEvent
static int makeEvent(boolean manualReset, boolean initialState)
Definition
PiSignals.java:156
org.wpilib.hardware.hal.PiNotifier.PiSignals.destroySemaphore
static void destroySemaphore(int handle)
Definition
PiSignals.java:224
org.wpilib.hardware.hal.PiNotifier.PiSignals.allocateHandle
static int allocateHandle(int type)
Definition
PiSignals.java:53
org.wpilib.hardware.hal.PiNotifier.PiSignals.makeSemaphore
static int makeSemaphore(int initialCount, int maximumCount)
Definition
PiSignals.java:204
org.wpilib.hardware.hal.PiNotifier.PiSignals.resetSignalObject
static void resetSignalObject(int handle)
Definition
PiSignals.java:115
org.wpilib.hardware.hal.PiNotifier.PiSignals.waitForObjects
static int[] waitForObjects(int[] handles)
Definition
PiSignals.java:301
org.wpilib.hardware.hal.PiNotifier.PiSignals.waitForObject
static void waitForObject(int handle)
Definition
PiSignals.java:266
org.wpilib.hardware.hal.PiNotifier.PiSignals.waitForObjectTimeout
static boolean waitForObjectTimeout(int handle, double timeout)
Definition
PiSignals.java:281
org.wpilib.hardware.hal.PiNotifier.PiSignals.setEvent
static void setEvent(int handle)
Definition
PiSignals.java:178
org.wpilib.hardware.hal.PiNotifier.PiSignals.releaseSemaphore
static boolean releaseSemaphore(int handle, int releaseCount)
Definition
PiSignals.java:237
org.wpilib.hardware.hal.PiNotifier.PiSignals.TYPE_NOTIFIER
static final int TYPE_NOTIFIER
Definition
PiSignals.java:28
org.wpilib.hardware.hal.PiNotifier.PiSignals.TYPE_SEMAPHORE
static final int TYPE_SEMAPHORE
Definition
PiSignals.java:25
org.wpilib.hardware.hal.PiNotifier.PiSignals.waitForObjectsTimeout
static int[] waitForObjectsTimeout(int[] handles, double timeout)
Definition
PiSignals.java:317
org.wpilib.hardware.hal.PiNotifier.PiSignals.TYPE_EVENT
static final int TYPE_EVENT
Definition
PiSignals.java:22
org.wpilib.hardware.hal.PiNotifier.PiSignals.resetEvent
static void resetEvent(int handle)
Definition
PiSignals.java:189
org
wpilib
hardware
hal
PiNotifier
PiSignals.java
Generated by
1.18.0