Subversion Repositories HelenOS-doc

Compare Revisions

Ignore whitespace Rev 84 → Rev 85

/design/trunk/src/ch_time.xml
144,11 → 144,11
<title>Time source for userspace</title>
 
<para>In HelenOS, userspace tasks don't communicate with the kernel in
order to read system time. Instead, a mechanism that shares kernel time of
the day counters with userspace address spaces is deployed. On the kernel
side, during system initialization, HelenOS allocates a frame of physical
memory and stores the time of the day counters there. The counters have
the following structure:</para>
order to read the system time. Instead, a mechanism that shares kernel
time of the the day counters with userspace address spaces is deployed. On
the kernel side, during system initialization, HelenOS allocates a frame
of physical memory and stores the time of the day counters there. The
counters have the following structure:</para>
 
<itemizedlist>
<listitem>
165,36 → 165,37
</itemizedlist>
 
<para>One of the userspace tasks with capabilities of memory manager (e.g.
ns) asks the kernel to map this frame into its address space. Other,
non-privileged, tasks then use IPC to communicate read-only sharing of
this memory. Reading time in a userspace task is therefore just a matter
of reading memory.</para>
ns) asks the kernel to map this frame into its address space. Other
non-privileged tasks then use IPC to receive read-only share of this
memory. Reading time in a userspace task is therefore just a matter of
reading memory.</para>
 
<para>There are two interesting points about this. First, the counters are
32-bit even on 64-bit machines. The goal is to provide subsecond precision
with the possibility to span roughly 136 years. Note that a single 64-bit
microsecond counter could not be usually read atomically on 32-bit
platforms. Now the second point is that 32-bit platforms cannot atomically
read two 32-bit counters either. However, a generic protocol is used to
guarantee that sequentially read times will create a non-decreasing
sequence.</para>
platforms. Unfortunately, on 32-bit platforms it is usually impossible to
read atomically two 32-bit counters either. However, a generic protocol is
used to guarantee that sequentially read times will create a
non-decreasing sequence.</para>
 
<para>The problematic part is updating both seconds and microseconds once
in a second. Seconds must be incremented and microseconds must be reset.
However, without any synchronization, the two kernel stores and the two
userspace reads can arbitrarily interleave. Furthemore, the reader has no
chance to detect that the counters were updated only from half. Therefore
three counters are used in HelenOS.</para>
<para>The problematic part is incrementing seconds counter and clearing
microseconds counter together once every second. Seconds must be
incremented and microseconds must be reset. However, without any
synchronization, the two kernel stores and the two userspace reads can
arbitrarily interleave. Furthemore, the reader has no chance to detect
that the counters were updated only paritally. Therefore three counters
are used in HelenOS.</para>
 
<para>If seconds need to be updated, the kernel increments the first
second counter, issues a write memory barrier operation, updates the
microsecond counter, issues another write memory barrier operation and
increments the second second counter. When only microseconds need to be
increments the second second counter. When only microseconds needs to be
updated, no special action is taken by the kernel. On the other hand, the
userspace task must always read all three counters and in reversed order.
A read memory barrier operation must be issued between each two reads. A
userspace task must always read all three counters in reversed order. A
read memory barrier operation must be issued between each two reads. A
non-atomic read is detected when the two second counters differ. The
userspace library solves this situation by returning zero instead of the
value read from the microsecond counter.</para>
userspace library solves this situation by returning higher of them with
microseconds set to zero.</para>
</section>
</chapter>