Upload
jack-kirby
View
221
Download
0
Embed Size (px)
Citation preview
8/10/2019 7. the Real-Time Clock API
1/14
The
Reol-Tme
ClockAPl
"All
my
possessionsfor
amoment
of time."
-Elizabeth
I
Tr
chapter
explores
the
implementation
of
the RTSJ
def,nition
of
clocks
and
timers within
Java
RTS. The
classes
explored
in
detail
provide
jitter-free
time
operations,
and
access
to a high-resolution
clock for
timer
objects for
different
types
of
timers. For
instance,
you
can
create
timer
objects
that
cause
time-related
events to fire
either
periodically,
or for
one-time
use.
The
ClockAPl
Java RTS
implements
the RTSJ
Clock
API,
which
defines real-time
clock
and
timer facilities. These
classes
should
be used in
place
of
calls
to
System.cur-
rentTimeMilf
is,
System.nanoTime,
and the
java.util.Date
class. They
rep-
resent
points
in time
with the
best
possible
accuracy
and
precision
the
underlying
hardware
can
support,
and
distinguish
between
absolute
points
in time,
and those
relative
to a starting
point.
Additionally,
these classes
allow
the creation
of timers
that
f,re
either
periodically,
or
for
one
time
only, deterministically.
Finally,
the
Java RTS
implementation
of these
classes
satisfles
the
POSIX
real-time require-
ment
of
providing
access
to
high-resolution
timers. For instance,
the code in List-
ingT-l
checks
and
displays
the
resolution
of
the real-time
clock
the system
it's
executed on.
223
8/10/2019 7. the Real-Time Clock API
2/14
224
Crupron
7 Trun
Rott-Tttp
CtocxAPI
Listing 7-1
Output
the RT
clock
accuracy
i mport
javax.
real
ti
me.
*;
publ
i
c
cl
ass
Mai n
{
public
static
void main(String[] args)
{
RelativeTime t
-
C'l
ock.
getRea'l
timeCl
ockO
.
getResol
utionO
;
System. out
.
pri
ntl
n
(
"Real-time
clock
resolution
=
"
+
t.toStringO);
)
]
Since
timer
resolution
is
hardware-dependent,
you're
likely to
get
different
results
on
different
systems
you
run
Java
RTS
on.
When
the code
in Listing
7-1
is
exe-
cuted on SunFire
v240, the accuracy output
is: a
Real-time
clock resolution =
(0
ms, 200 ns)
Clearly,
the timer resolution
for
Java
RTS applications
on
this machine is 200
nanoseconds. Keep in mind
that the
system
you
run
Java
RTS
on
must
provide
access to
high-resolution timers, and the user
account
you
execute
your
applica-
tion
with must
have
privilege
to access
the
high-resolution timer implementation.
To
use
the
RTSJ
Clock
API
(see
Figure
7-1)
to
create timestamps or
high-
resolution timings, begin by
gaining
a
reference to the singleton real-time clock
object
via
the
getReal
ti meCl
ock
O
method call
on
the
j
avax
.
real
ti me . Cl ock
object,
as
seen
in
the
previous example.
To
calculate
a
timestamp
with
nanosecond
resolution
(on
hardware that
supports it), use code similar to that
in Listing
7-2.
Listing 7-2
Real-time clock
timestamp code
javax.
realtime.Clock
rtClock
=
javax.
realtime.Clock.
getRealtimeClockO
;
javax.
realtime.Absol uteTime
begi
nTime
;
j
avax
.
real
ti
me .
Absol
uteTi
me endTi me
;
//
get
start
time
and
convert
to
nanoseconds
begi
nTim
=
rtClock.
getTimeO
;
long lBegin
=
(beg'inTime.getMillisecondsO
o
1000000L) +
rtt^/al I
Cl
ockTi meBefore
.
getNanoseconds
O
;
//
do
process'ing
here..
.
//
gel.
end time
and
convert
to
nanoseconds
endTift
=
rtClock.
getTimeO
;
long
lEnd
=
(beginTime.getMillisecondsO
o
1000000L) +
rtL\,al
I Cl
ockTi
meBefore. getNanoseconds
O
;
8/10/2019 7. the Real-Time Clock API
3/14
Tttr
CtocxAPI
In
addition
to the
high-resolution
timing
shown
in Listing
7-2, tluotgh
a
combination
of
the Clock
and Absol
uteTime
classes,
you
can
perform
date
and
time
operations.
This includes gaining
access
to
java.util.Date
objects.
The
complete
class
diagram
for
the
RTSJ
time
operations
is
shown inFigweT-2.
javax.
realtime.Clock
+getEpochOffset0
+getRealtimeClock0
+getResolution0
+getTime0
+setResolution0
Figure
7-1.
The
Java
RTS Clock
class.
i HignResolutionTime
i
r---------
------l
i
+absolute$
i
l
^r^-^/\
I
;
+ctoneQ
,
i
+compareTo$
i
i
+equatsQ
i
i
+gerCtockQ
i
i
+getMittisecondsQ
I
I
+getNanosecondsfl
I
,
l
+hashCode
I
+relative0
+set$
+waitFor0bject0
22
+add0
+getDate0
+relative0
+set$
+subtractfl
+tostring0
+add0
+relative0
+subtract0
+tostring0
Figure
7-2
The
Java
RTS time
operations.
8/10/2019 7. the Real-Time Clock API
4/14
226
CrutprnnT
Tnr
RmuTtun
CrccxAPI
+destroyO
i
+disableQ
I
+enableO
i
+fireO
i
+getClockQ
i
+getFireTime$
i
+handledBY$
I
I
+
isRunningQ
,
+removeHanter1
i
+reschedulefl i
+setHandleO
i
Figure 7-3 The Java RTS
timer
operations.
We'll take
a look at how to use these classes
shortly.
As
mentioned earlier,
the
Cl ock
API
provides
access
to timers that can be set to
expire
periodically,
or one
time only.
These
classes
are
Peri odi
cTi
mer and OneShotTi mer, respectively
(see
Figure 7-3).
Since
these classes
extend
AsynchEvent,
we'11
examine
these classes
in
detail
in
Chapter 8.
Jovo
RTS
High-Resolution
Time
+getlnterval0
+setlnterval0
Operotions
In
Java
RTS, real-time
time
objects
are
instances
of
either
the
Absol
uteTi
me
or
RelativeTime
classes,
and associated
with
a
singleton real-time
clock.
In
fact,
we've already seen these
classes used
with
setting
the
release
parameters
for
8/10/2019 7. the Real-Time Clock API
5/14
J
u, RTS
H
rcn-
Resotuno,t
Ttrun,
O
pnntnoN
s
periodic
Real
ti
meTh
read
objects
in
Chapter
5. However,
there
are
more
details
to these classes
that need
to be
examined.
The Absol
uteTi
me
class
represents
a
specific
point
in
time. It's
specif,ed
and
measured
in
a combination
of
milliseconds
and nanoseconds.
Here
are
the
Abso-
I
uteTi
me
class
constructors:
Absol
uteTimeO---{reates
a
new
object representing
a time
of 0
milliseconds
and nanoseconds.
Absol
uteTime(Absol
uteTime)----creates
a new
object
with
the
same
starting
time
as
the
given
object.
Absol
uteTime(Clock)-creates
a new
object
associated
with
the
given
RTSJ
Cl ock
object.
AbsouteTime(AbsoluteTime, Clock)-creates
a new
object
with
the same
starting
time
as
the
given
object,
and associated
with
the
given
RTSJ
Clock
object.
AbsoluteTime(Date)-creates
a
new
object with
a
starting
time of
Date.
getTi
me.
AbsoluteTime(Date,
Clock)-creates
a
new
object
with
a stafing
time of
Date.
getTi
me,
and
associated
with
the
given
RTSJ
Cl
ock
object.
Absol
uteTi
me
(l
ong
mi
1
I
i
s
,
i
nt
nanos)-creates
a
new object
with
a
start-
ing
time represented
by the
given
millisecond
and nanosecond
components.
AbsoluteTime(long
millis,
int nanos,
clock)---creates
a new
object
with
a starting
time represented
by
the
given
millisecond
and
nanosecond
com-
ponents,
and associated
with
the
given
RTSJ
Cl
ock object.
The
Rel
ati
veTi
me
class
represents
a time interval,
such
as
a
period
of time rela-
tive to the
current
time. It's frequently
used
when
specifying
a
periodic
real-time
thread's
period,
a
parameter
to
a Real
ti
meTh
read
.
si
eep
call, or
a
call
to
a
form
of
the wai
t
method
when
synchronizing
on
shared
objects. The
constructors
for
the Rel
ati
meTi me
class are:
RelativeTime(Iong
mil
I is,
int
nanos)-creates
a
new
object
that repre-
sents
the interval
based on
the
provided
milliseconds parameter,
plus
the
pro-
vided
nanosecond parameter.
In
this case,
the real-time
clock
is used
by
default.
Re'lativeTime(long
miI'lis,
int
nanos,
clock)---creates
a
new
object
that represents
the
interval
based
on the
provided
milliseconds
parameter,
plus
22
8/10/2019 7. the Real-Time Clock API
6/14
228
Cruprnn7
Tnn
Rnr-Ttur CrccxAPI
the
provided
nanosecond
parameter.
In this
case,
the
provided
clock
is
used;
if
null,
then the
real-time
clock
is
used by
default.
Re'lativeTimeO----creates
a
new object
with zeros
for both the
milliseconds
and
nanoseconds
parameter.
The real-time
clock
is used by default.
Rel
ati
veTi
me
(Cl
ock)--creates
a
new object
with
zeros
for
both
the
millisec-
onds and
nanoseconds
parameter.
In this
case,
the
provided
clock
is used; if
null,
then the
real-time
clock
is
used by
default.
Rel ativeTime(ReI
ativeTime)-creates
a
new
object
from
the one
provided.
RelativeTime(RelativeTime,
Clock)----creates
a
new object
from the one
provided,
using
the
clock
provided.
Both
Hi
ghResol
uti
onTi
me
classes
allow
you
to
perform
time arithmetic,
where
you
can add and subtract
different
time
objects
to
derive new time
objects.
For
instance, the code
in Listing
7-3
is
a
very
easy
way
to determine
the amount of
time a
particular
operation
takes to execute.
Listing 7-3
Timing a
real-time operation
i mport
j
avax . real ti
me.
*
;
public
class
Main
{
public
static
void
main(String[]
args)
{
//
Create the objects
beforehand; eliminates
jitter
AbsoluteTime
before;
AbsoluteTime after;
RelativeTime elapsed;
before
=
Clock.getReal
timeClockO
.getTimeO
;
//
perform
operation
here...
after
=
Clock.getReal
timeClockO
.getTimeO
;
elapsed
=
after.subtract(before)
;
System.out.println("Elapsed
time:
"
+ elapsed)
;
)
]
As the comment at the
beginning of the
code
says,
we
declare
the time objects
before the timed
operation
so
that
the
object
creating time doesn't
get
factored
into
the
measurement. Since
Cl
ock
operations
are bounded and deterministic
in
Java
RTS, the
calls to
getTi
me are efflcient,
and
consistent, in terms of execution
time.
In
fact, due to inherent
jitter
in the
j
ava. uti
I
.
Date
class,
you
should
use Cl
ock
.
getRealtimeClockO.getTime
and
the
AbsoluteTime
it
returns
for
all
time-
stamping operations,
such
as
that shown in
Listing
7-4.
8/10/2019 7. the Real-Time Clock API
7/14
A
Cotptrno
SrocxDnt
Fsr
Ex*tptn
Listing
7-4
Jitter-free
Date code
22
AbsoluteTime
current
=
clock.
getRealtimeclockO
.
getTimeO
;
Date
tifi
=
current.getDateO;
System.out.println("Current
date/t'ime: "
+
time)
;
Let's
take
a
look
at
more
involved example
of
how
to
use
both
the Absol
uteTime
and
Rel
ati veTi
me
classes.
A
Confloled
Stock
Doto
Feed
Exomple
Let's
examine
a situation
where
we want
to send
conflated
stock
price
data
to
cli-
ent
applications.
The requirement
is
to
gather
all updates
for
a
particular
stock
ticker
as
they occur in real-time, but
send
them no
less
than ten
milliseconds
apart.
This
means
that for
all
updates
that
occur
within each
ten-millisecond
period,
the
updates
must
be added
together
to form
one
overall
update
that is
sent to
the cli-
ents
(see
Figure
7-4). However,
if
more
than
ten milliseconds
elapses
between
single
updates,
the
update
data
gets
transmitted
immediately
(there's
no
need
to
delay
any
longer).
In
the examples
shown
in
this
flgure,
the
stock
price
starts
at a
value
of
10.00.
Before
the
first
ten-millisecond
conflation period
(where
an update
to clients
will
be sent)
four
individual
price
updates
are received
from
the
external
data
feed
for
the
stock
being
watched.
Each
price
update
is
applied
to
the
stock
price,
but
the
result
is
not
sent until
the conflation
period
expires.
At that
time,
the stock
price
is
9.48,
which
is
the
value
sent
in
the
update
to the
client
applications.
Stock
start
price:
10.00
Notify
Clients
Stock:
9.37
il
Notify
Clients
Stock:9.48
.'i'Il
9.98
9.48
9.37
0
*--ro-r;poateliola-t.ro--'
}0,
*-----;upout-,,;------'
i:
One update
(past
conflation time)
Figure
7-4
Conflated stock
ticker
updates.
8/10/2019 7. the Real-Time Clock API
8/14
230
Csprnn7 Tan Rp,r-TtusCtocxAPI
However,
during
the
next conflation
period
(another
ten
milliseconds)
no
price
updates
are
received.
Therefore,
no conflated
price
update
needs to
be
sent since
the value
hasn't changed.
However,
as
soon
as
the
next
price
update does
occur,
the
resulting
price
will be sent
out
immediately
(which
is
9.37
in this example).
At this
point,
the conflation
timer
is reset,
and
updates
will
be
conflated
for the
next ten
milliseconds.
The description
and
diagram
above
lay the
groundwork
for
our sample
applica-
tion.
There's
no need to
create
a
periodic
RTT;
we'll
simply
use
a
starting
time
(an
Absol uteTi
me
object)
and
wait on an
object
that will be signaled
when
an update
occurs.
However, we'Il
use
the
H'i
ghResol
uti onTi me
.
wai
tFo rObj
ect
method,
which
allows
us to
provide
a
maximum
amount of
time
to
wait. Therefore,
with
each
update,
the code
will check
the
time
elapsed,
and if
it's
still
within
the
confla-
tion time
period,
the code
will
again
wait
but
for
the time
remaining
in the
period.
Implementing
it
this way allows
us
to demonstrate the
use
of
Absol
uteTi
me
and
Rel ati
veTi me objects,
as
well
as Hi
ghResol
uti onTi
me arithmetic
in
one
mean-
ingful
example.
In Chapter
8,
we'11
modify
this application
to use
a
Ti mer
object
instead. For
now,
let's
begin
looking
at Listing
7-5.
Listing 7-5
The
conflated
stock
update
application
i mport
javax.
real
ti
me.
*;
pubf
ic
class
MyApp
{
Object
lock
=
new
ObjectO;
double
update
=
0.00;
final
RelativeTime
PERI0D
=
nw
RelativeTime(L0,0);
//
L0ms
class Conflater
extends
RealtimeThread
{
boolean
updateOccured
=
false;
RelativeTime
timeout
=
PERIOD;
AbsoluteT'ime
startTime
=
null;
double
pri
ce
=
0.00i
public
void runO
{
// ...
)
private
vojd updatecl
i
ents(
double
newPrice,
RelativeTime
lastUpdate)
//
...
]
]
class
DataFeed
extends
RealtimeThread
{
private
Object
privlock
=
new
ObjectO;
pubf
ic
void
runO
{
8/10/2019 7. the Real-Time Clock API
9/14
A
Conrtrt
SrocxDtr
Fnto
Exuptz,
//
...
]
private
void
send(int
interval,
double
change)
{
//
...
]
]
pub'lic
MyAppO
{
Conflater
conflater
=
w
ConflaterO;
DataFeed
datafeed
=
hw
DataFeedo;
conflater.
startO
;
datafeed.
startO
;
]
public
static
void main(String[]
args)
{
MYAPP
PP
=
new
MyAppO;
]
From
this
code,
you
can
see
that
there
are
two
RealtimeThread
classes:
Con-
flater,
and
DataFeed.
The
Conflater
class
object
listens
for
updates
from
the
DataFeed
class object,
and
sends
conflated
updates
to its
clients
at
least
every
PERIOD
amount
of time. Both
RTTs
share
the
object 1ock,
and each
change
to
the
stock is
communicated
through
update.
The
Confloter
Closs
Let's
take
a
look
at
class
Conflater
in
more
detail-see
Listing
7-6-as
that's
where
the
interesting
code is.
Listing
7-6
The
Conflater
class
class
Conflater
extends
RealtimeThread
{
boolean
updateOccured
=
false;
RelativeTime
timeout
=
pERIOD;
AbsoluteTime
startTime
=
null;
double
pri
ce
=
0.00i
Clock rtClock
=
Clock.getRealtimeClockO
;
public
void
runO
{
try
{
//
Walt
to
receive
start
pr-ice,
and
begin
conflation
synchronized(lock){
lock.waitO;
]
Ltinued
23
8/10/2019 7. the Real-Time Clock API
10/14
232
CrutprnnT
Tae Rott-Tmr
CucxAPI
//
Ihe first update
is
the
starting
price
price
=
update;
startTirx
=
FtClock.
getTimeO
;
System.
out
.
pri
ntl
n
(
"Conflater received starting
price")
;
//
Now
wa'it
for
updates,
apply
them,
and
send
//
updated
price
to
clients
after conflated
period
while(true){
synchroni
zed
(
lock
)
{
//
wait
for
update
or
period
to
expire
update
=
0.00
Hi
ghReso'l
utionTime.waitForobject(l
ock, timeout)
;
AbsoluteTime
current
=
rtClock.getTimeO;
RelativeTime elapsed
=
cu
r rent
.
subt
ract
(startTi
me)
;
//
Check
for update or timeout
if
(
update
=
0.OO
) {
//
Apply
update,
and
check time
updateoccured
=
true;
price
+= updti
System.
out .
pri
ntl n
(
"Conflater:
update
"
+ update +
",
El
apsed="
+
el
apsed)
;
timeout
=
PERIOD.subtract(
elapsed
);
//
First update
since
previous
period
if
(
elapsed.getMillisecondsO
>
PERIOD.
getMi
I
I i secondsO
)
{
//
Send
update,
start
new
conflation
period
updateCl
i
ents(pri
ce, e1 apsed)
;
startTiffi
=
rtClock.
getTimeO
;
]
]
else
{
/
/
Conflati
on
period
expi red
if
(
updateOccured
)
t
//
Send
update, start
new conflation
period
updateCl
i ents(pri
ce, e1 apsed)
;
startTifi
=
FtClock.
getT'imeo
;
]
]
8/10/2019 7. the Real-Time Clock API
11/14
A
C
o,t
p
trno
Srocx Dm
F nno
E xrup
to
]
catch(Exceptione){
e
.
pri
ntstackTrace
O ;
)
]
private
void
updateclients(
double newprice,
RelativeTime
lastUpdate)
{
System.out.println("Conflater:
Updating
clients:
")
;
System.out.print1n("Conflater:
price="
+ newprice);
System.out.println("Conflater:
Time
since last:,'
+
1 astUpdate)
;
Send
update
//
Reset
some values
timeout
=
PERIOD;
updateOccured
=
false;
The
first
update
received
is
the
starting price.
From
that
point
on, the
thread
enters
an
inf,nite
loop
waiting
for an
update,
or
the
period
to expire-whichever
comes
first.
In
the
whi 1e
loop,
wai
tForobject
is called
with
a
timeout
value,
which
is
initially
set
to
the
full ten-millisecond
period.
Therefore,
one
of
two things
can
occur:
an update
arrives,
which
results
in
the
wait
call
returning
when
the
lock
object
is
signaled,
or the
timeout period
expires.
When
execution
continues
after
wai
tFor0bject,
the
elapsed
time
since
the
start
of
the
conflation
period
is
determined,
and
a check
is
made
to
see
if
a data feed
update has
arrived.
This is
simple-if
the
update
price
is
non-zero,
an update
occurred.
Otherwise
the
timeout
value
has
expired.
In
the
case
of a
price
update,
a
flag
is
set
(to
be
checked
later, when the period expires),
the
price
is
adjusted
accordingly,
and the
timeout
value
is
set
to the
time remaining
in
the current
period.
However,
if
the
elapsed
time
since the
beginning
of the
period
is
greater
than
the
period
itself,
then we
know
that
a
data
feed
update hasn't
been received
in
the
current
period
and this
update
needs
to be
sent to
clients right
away. The
updateCl
i
ents
method is
called
to
perform
this.
In
the
case
of
a
period
timeout,
a
check is
made
to see if
any
data feed
updates
have
occurred
in
the
current
period.
If not,
then
nothing
special is
done,
and
the
23
8/10/2019 7. the Real-Time Clock API
12/14
234
Cru*rr,n7
Tnr
Rn.r-Ttur
CtocxAPI
code
again
calls
wai
tFor0bject.
If an
update
has occurred, then
a call
is made to
updateCf
ients,
where
all clients are
given
the
new
conflated stock
price.
Also,
the
period
start time
is
reset
to the current
time
in
preparation
of
the new confla-
tion
period. The updatecl
i ents method also
resets
the
timeout
to be
equal to the
full
period,
and
resets the flag that
indicates
a
data feed
update
has occurred.
The
code is
now ready to call
wai
tForObj
ect
again.
The
DotoFeed
Closs
The
DataFeed
class
is
simple,
but
since
it
uses RelativeTime to
create
pauses
between
updates
(to
simulate
updates arriving
aperiodically) let's explore
it
now
(see
ListingT-7).
Listing
7-7 The
DataFeed
class
class
DataFeed
extends
RealtimeThread
{
private
Object
privlock
=
w
ObjectO;
public
void
runO
{
//
begin
first
period
send(O,
L0.00);
//
starting
price
send(2
,
-.02);
send(1
,
-.0L);
send
(1-
,
+
.0L)
;
send(2,
-.50)
;
send(4, O.0O);
//
tust
sleep
for
4ms
//
begin second
period
send(12,
-.11);
//
update
well
after
period
]
private
void send(int
interval, double change)
{
if(interval>0){
//
Wait
for
elapsed
time
try
{
RelativeTime
elaPsed
=
new Rel ativeTime(interval,
0)
;
synchron'i
zed
(
privlock
) {
Hi
ghResol
uti onTi
me . wai tFor0bj ect
(
privlock,
elapsed);
]
]
catch(Exceptione){}
]
if
(
change
=
O.OO
)
{
update
=
change;
8/10/2019 7. the Real-Time Clock API
13/14
A
Co,tpttrs,o
SrocxDm,
Fm
Ex,lturpm
synchronized(1ock){
lock.notifyO;
]
This
contrived
code
simulates
sending
the
updates,
perperiod,
as
shown
in Figure
7-4.The
first
parameter
in
the
send
method
is the
amount
of
time in milliseconds
the
code
waits
before
sending
the update.
The
second
parameter
is
the amount
the
stock
price
has
moved,
up or
down
(a
delta value).
If
the
update
value
passed
is
zeto,the
method
effectively
acts
as
a
high-resolution
call
to
s'leep. If
the
interval
is
set to
zeo,
the
price
update
is
sent
immediately.
Sending
a
price
update is
a
simple
operation;
the
global update
delta value is
set,
and the
shared
lock
object
is
signaled
(informing
the
Conflater
class
that
the
update
is
available).
The
succession
of
calls
to send
is meant
to simulate
a
random
pattern
of
updates
with
varying
amounts
of time
between
them,
such
that
they
recreate
the scenario
in
Figure
7-4.
Applicotion
Output
When
executed
with
Java
RTS
on
a uniprocessor,
the following
output
will
be
observed:
Conflater
started...
Conflate
r recei
ved
start'i ng
pr.i
ce
Conflater:
update
-0.02,
Elapsed=(2
ms,
2484
ns)
Conflater:
update
-0.0L,
Elapsed=(3
ms,
5276
ns)
Conflater:
update
0.01-,
Elapsed=(5
ms,
3099 ns)
Conflater:
update
-0.5,
E'lapsed=(7
ms,
3104
ns)
Conflater:
Updati
ng
c'li ents:
Conflater:
pri
c=9.48
Conflater:
Time
since
last
update:(10
ms,
0
ns)
Conflater:
update
-0.LL,
E'lapsed=(13
ms,
5331 ns)
Conflater:
update
after
period
Conflater:
Updating
clients:
Conflater:
pri
ce=9.
37
Conflater:
Time
since last
update:(13
ms,
5331 ns)
Atthe
verybeginning
(r=
0),
the
stock
startprice
is
received
andthewai
tForobject
loop
begins. You
can
see
in
the output
above
that four
data
feed
updates
are
conflated
into
the
first
price
update
sent
out
to
the simulated
clients.
The
time
elapsed
when
each update
is
received
is relative
to
the
start
of
the
current period (not
to
each
23
8/10/2019 7. the Real-Time Clock API
14/14
236
Cu.prnn7
Trun
Rn,uTt*t
CtocxAPI
individual
update).
Therefore, the
first
update
to clients
is triggered
by the
period
timeout
att+
l0
milliseconds.
However,
during the
second
ten-millisecond
period,
no
data
feed
updates occur.
Therefore,
when the
period
expires,
nothing
is done. When
an
update
finally does
arrive
13
milliseconds
after the
beginning
of
the
second
period (t +
23
millisec-
onds), the
new
price
is
sent
to clients
immediately,
and
the
cycle
repeats.