Rev 58 | Rev 127 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 58 | Rev 85 | ||
---|---|---|---|
Line 142... | Line 142... | ||
142 | 142 | ||
143 | <section> |
143 | <section> |
144 | <title>Time source for userspace</title> |
144 | <title>Time source for userspace</title> |
145 | 145 | ||
146 | <para>In HelenOS, userspace tasks don't communicate with the kernel in |
146 | <para>In HelenOS, userspace tasks don't communicate with the kernel in |
147 | order to read system time. Instead, a mechanism that shares kernel time of |
147 | order to read the system time. Instead, a mechanism that shares kernel |
148 | the day counters with userspace address spaces is deployed. On the kernel |
148 | time of the the day counters with userspace address spaces is deployed. On |
149 | side, during system initialization, HelenOS allocates a frame of physical |
149 | the kernel side, during system initialization, HelenOS allocates a frame |
150 | memory and stores the time of the day counters there. The counters have |
150 | of physical memory and stores the time of the day counters there. The |
151 | the following structure:</para> |
151 | counters have the following structure:</para> |
152 | 152 | ||
153 | <itemizedlist> |
153 | <itemizedlist> |
154 | <listitem> |
154 | <listitem> |
155 | <para>first 32-bit counter for seconds,</para> |
155 | <para>first 32-bit counter for seconds,</para> |
156 | </listitem> |
156 | </listitem> |
Line 163... | Line 163... | ||
163 | <para>second 32-bit counter for seconds.</para> |
163 | <para>second 32-bit counter for seconds.</para> |
164 | </listitem> |
164 | </listitem> |
165 | </itemizedlist> |
165 | </itemizedlist> |
166 | 166 | ||
167 | <para>One of the userspace tasks with capabilities of memory manager (e.g. |
167 | <para>One of the userspace tasks with capabilities of memory manager (e.g. |
168 | ns) asks the kernel to map this frame into its address space. Other, |
168 | ns) asks the kernel to map this frame into its address space. Other |
169 | non-privileged, tasks then use IPC to communicate read-only sharing of |
169 | non-privileged tasks then use IPC to receive read-only share of this |
170 | this memory. Reading time in a userspace task is therefore just a matter |
170 | memory. Reading time in a userspace task is therefore just a matter of |
171 | of reading memory.</para> |
171 | reading memory.</para> |
172 | 172 | ||
173 | <para>There are two interesting points about this. First, the counters are |
173 | <para>There are two interesting points about this. First, the counters are |
174 | 32-bit even on 64-bit machines. The goal is to provide subsecond precision |
174 | 32-bit even on 64-bit machines. The goal is to provide subsecond precision |
175 | with the possibility to span roughly 136 years. Note that a single 64-bit |
175 | with the possibility to span roughly 136 years. Note that a single 64-bit |
176 | microsecond counter could not be usually read atomically on 32-bit |
176 | microsecond counter could not be usually read atomically on 32-bit |
177 | platforms. Now the second point is that 32-bit platforms cannot atomically |
177 | platforms. Unfortunately, on 32-bit platforms it is usually impossible to |
178 | read two 32-bit counters either. However, a generic protocol is used to |
178 | read atomically two 32-bit counters either. However, a generic protocol is |
179 | guarantee that sequentially read times will create a non-decreasing |
179 | used to guarantee that sequentially read times will create a |
180 | sequence.</para> |
180 | non-decreasing sequence.</para> |
181 | 181 | ||
182 | <para>The problematic part is updating both seconds and microseconds once |
182 | <para>The problematic part is incrementing seconds counter and clearing |
183 | in a second. Seconds must be incremented and microseconds must be reset. |
183 | microseconds counter together once every second. Seconds must be |
- | 184 | incremented and microseconds must be reset. However, without any |
|
184 | However, without any synchronization, the two kernel stores and the two |
185 | synchronization, the two kernel stores and the two userspace reads can |
185 | userspace reads can arbitrarily interleave. Furthemore, the reader has no |
186 | arbitrarily interleave. Furthemore, the reader has no chance to detect |
186 | chance to detect that the counters were updated only from half. Therefore |
187 | that the counters were updated only paritally. Therefore three counters |
187 | three counters are used in HelenOS.</para> |
188 | are used in HelenOS.</para> |
188 | 189 | ||
189 | <para>If seconds need to be updated, the kernel increments the first |
190 | <para>If seconds need to be updated, the kernel increments the first |
190 | second counter, issues a write memory barrier operation, updates the |
191 | second counter, issues a write memory barrier operation, updates the |
191 | microsecond counter, issues another write memory barrier operation and |
192 | microsecond counter, issues another write memory barrier operation and |
192 | increments the second second counter. When only microseconds need to be |
193 | increments the second second counter. When only microseconds needs to be |
193 | updated, no special action is taken by the kernel. On the other hand, the |
194 | updated, no special action is taken by the kernel. On the other hand, the |
194 | userspace task must always read all three counters and in reversed order. |
195 | userspace task must always read all three counters in reversed order. A |
195 | A read memory barrier operation must be issued between each two reads. A |
196 | read memory barrier operation must be issued between each two reads. A |
196 | non-atomic read is detected when the two second counters differ. The |
197 | non-atomic read is detected when the two second counters differ. The |
197 | userspace library solves this situation by returning zero instead of the |
198 | userspace library solves this situation by returning higher of them with |
198 | value read from the microsecond counter.</para> |
199 | microseconds set to zero.</para> |
199 | </section> |
200 | </section> |
200 | </chapter> |
201 | </chapter> |
201 | 202 |