1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
/*************************************************************************
* *
* JCSP ("CSP for Java") libraries *
* Copyright (C) 1996-2008 Peter Welch and Paul Austin. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public *
* License as published by the Free Software Foundation; either *
* version 2.1 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, *
* USA. *
* *
* Author contact: P.H.Welch@ukc.ac.uk *
* *
*************************************************************************/
// package org.jcsp.plugNplay;
//
// This class *is* in the above package. It is reproduced here because
// this source is quoted in the documentation of org.jcsp.lang.Alternative.
// The above package declaration is commented out since, otherwise,
// compiling the *java files in this directory would fail (because of
// an attempt to duplicate Regulate in org.jcsp.plugNplay).
//{{{ javadoc
/**
* This process controls the flow of traffic from its in to out channels.
* <H2>Description</H2>
* <tt>Regulate</tt> produces a constant rate of output flow, regardless of
* the rate of its input. At the end of each timeslice defined by the required
* output rate, it outputs the last object input during that timeslice.
* If nothing has come in during a timeslice, the previous output will be repeated
* (note: this will be a null if nothing has ever arrived).
* If the input flow is greater than the required output flow, data will be discarded.
* <P>
* The interval (in msecs) defining the output flow rate is given by a constructor
* argument; but this can be changed at any time by sending a new interval (as a <tt>Long</tt>)
* down its <tt>reset</tt> channel.
* <H2>Description</H2>
* See {@link Alternative#STFR here}.
*
* @see org.jcsp.plugNplay.FixedDelay
* @see org.jcsp.plugNplay.Regular
*
* @author P.H.Welch
*
*/
//}}}
import org.jcsp.lang.*;
public class Regulate implements CSProcess {
private final AltingChannelInput in, reset;
private final ChannelOutput out;
private final long initialInterval;
/**
* Construct the process.
*
* @param in the input channel
* @param out the output channel
* @param initialInterval the initial interval between outputs (in milliseconds)
* @param reset send a <tt>Long</tt> down this to change the interval between outputs (in milliseconds)
*/
public Regulate (final AltingChannelInput in, final AltingChannelInput reset,
final ChannelOutput out, final long initialInterval) {
this.in = in;
this.reset = reset;
this.out = out;
this.initialInterval = initialInterval;
}
/**
* The main body of this process.
*/
public void run () {
final CSTimer tim = new CSTimer ();
final Guard[] guards = {reset, tim, in}; // prioritised order
final int RESET = 0; // index into guards
final int TIM = 1; // index into guards
final int IN = 2; // index into guards
final Alternative alt = new Alternative (guards);
Object x = null; // holding object
long interval = initialInterval;
long timeout = tim.read () + interval;
tim.setAlarm (timeout);
while (true) {
switch (alt.priSelect ()) {
case RESET:
interval = ((Long) reset.read ()).longValue ();
timeout = tim.read (); // fall through
case TIM:
out.write (x);
timeout += interval;
tim.setAlarm (timeout);
break;
case IN:
x = in.read ();
break;
}
}
}
}
|