€• oŒsphinx.addnodes”Œdocument”“”)”}”(Œ rawsource”Œ”Œchildren”]”(Œ translations”Œ LanguagesNode”“”)”}”(hhh]”(hŒ pending_xref”“”)”}”(hhh]”Œdocutils.nodes”ŒText”“”ŒChinese (Simplified)”…””}”Œparent”hsbaŒ attributes”}”(Œids”]”Œclasses”]”Œnames”]”Œdupnames”]”Œbackrefs”]”Œ refdomain”Œstd”Œreftype”Œdoc”Œ reftarget”Œ#/translations/zh_CN/timers/hrtimers”Œmodname”NŒ classname”NŒ refexplicit”ˆuŒtagname”hhh ubh)”}”(hhh]”hŒChinese (Traditional)”…””}”hh2sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ#/translations/zh_TW/timers/hrtimers”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒItalian”…””}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ#/translations/it_IT/timers/hrtimers”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒJapanese”…””}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ#/translations/ja_JP/timers/hrtimers”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒKorean”…””}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ#/translations/ko_KR/timers/hrtimers”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒPortuguese (Brazilian)”…””}”hh‚sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ#/translations/pt_BR/timers/hrtimers”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒSpanish”…””}”hh–sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ#/translations/sp_SP/timers/hrtimers”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubeh}”(h]”h ]”h"]”h$]”h&]”Œcurrent_language”ŒEnglish”uh1h hhŒ _document”hŒsource”NŒline”NubhŒsection”“”)”}”(hhh]”(hŒtitle”“”)”}”(hŒ6hrtimers - subsystem for high-resolution kernel timers”h]”hŒ6hrtimers - subsystem for high-resolution kernel timers”…””}”(hh¼h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhh·h²hh³Œ=/var/lib/git/docbuild/linux/Documentation/timers/hrtimers.rst”h´KubhŒ paragraph”“”)”}”(hŒHThis patch introduces a new subsystem for high-resolution kernel timers.”h]”hŒHThis patch introduces a new subsystem for high-resolution kernel timers.”…””}”(hhÍh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khh·h²hubhÌ)”}”(hX©One might ask the question: we already have a timer subsystem (kernel/timers.c), why do we need two timer subsystems? After a lot of back and forth trying to integrate high-resolution and high-precision features into the existing timer framework, and after testing various such high-resolution timer implementations in practice, we came to the conclusion that the timer wheel code is fundamentally not suitable for such an approach. We initially didn't believe this ('there must be a way to solve this'), and spent a considerable effort trying to integrate things into the timer wheel, but we failed. In hindsight, there are several reasons why such integration is hard/impossible:”h]”hX¯One might ask the question: we already have a timer subsystem (kernel/timers.c), why do we need two timer subsystems? After a lot of back and forth trying to integrate high-resolution and high-precision features into the existing timer framework, and after testing various such high-resolution timer implementations in practice, we came to the conclusion that the timer wheel code is fundamentally not suitable for such an approach. We initially didn’t believe this (‘there must be a way to solve this’), and spent a considerable effort trying to integrate things into the timer wheel, but we failed. In hindsight, there are several reasons why such integration is hard/impossible:”…””}”(hhÛh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khh·h²hubhŒ bullet_list”“”)”}”(hhh]”(hŒ list_item”“”)”}”(hXvthe forced handling of low-resolution and high-resolution timers in the same way leads to a lot of compromises, macro magic and #ifdef mess. The timers.c code is very "tightly coded" around jiffies and 32-bitness assumptions, and has been honed and micro-optimized for a relatively narrow use case (jiffies in a relatively narrow HZ range) for many years - and thus even small extensions to it easily break the wheel concept, leading to even worse compromises. The timer wheel code is very good and tight code, there's zero problems with it in its current usage - but it is simply not suitable to be extended for high-res timers. ”h]”hÌ)”}”(hXuthe forced handling of low-resolution and high-resolution timers in the same way leads to a lot of compromises, macro magic and #ifdef mess. The timers.c code is very "tightly coded" around jiffies and 32-bitness assumptions, and has been honed and micro-optimized for a relatively narrow use case (jiffies in a relatively narrow HZ range) for many years - and thus even small extensions to it easily break the wheel concept, leading to even worse compromises. The timer wheel code is very good and tight code, there's zero problems with it in its current usage - but it is simply not suitable to be extended for high-res timers.”h]”hX{the forced handling of low-resolution and high-resolution timers in the same way leads to a lot of compromises, macro magic and #ifdef mess. The timers.c code is very “tightly coded†around jiffies and 32-bitness assumptions, and has been honed and micro-optimized for a relatively narrow use case (jiffies in a relatively narrow HZ range) for many years - and thus even small extensions to it easily break the wheel concept, leading to even worse compromises. The timer wheel code is very good and tight code, there’s zero problems with it in its current usage - but it is simply not suitable to be extended for high-res timers.”…””}”(hhôh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khhðubah}”(h]”h ]”h"]”h$]”h&]”uh1hîhhëh²hh³hÊh´Nubhï)”}”(hXœthe unpredictable [O(N)] overhead of cascading leads to delays which necessitate a more complex handling of high resolution timers, which in turn decreases robustness. Such a design still leads to rather large timing inaccuracies. Cascading is a fundamental property of the timer wheel concept, it cannot be 'designed out' without inevitably degrading other portions of the timers.c code in an unacceptable way. ”h]”hÌ)”}”(hX›the unpredictable [O(N)] overhead of cascading leads to delays which necessitate a more complex handling of high resolution timers, which in turn decreases robustness. Such a design still leads to rather large timing inaccuracies. Cascading is a fundamental property of the timer wheel concept, it cannot be 'designed out' without inevitably degrading other portions of the timers.c code in an unacceptable way.”h]”hXŸthe unpredictable [O(N)] overhead of cascading leads to delays which necessitate a more complex handling of high resolution timers, which in turn decreases robustness. Such a design still leads to rather large timing inaccuracies. Cascading is a fundamental property of the timer wheel concept, it cannot be ‘designed out’ without inevitably degrading other portions of the timers.c code in an unacceptable way.”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khjubah}”(h]”h ]”h"]”h$]”h&]”uh1hîhhëh²hh³hÊh´Nubhï)”}”(hXRthe implementation of the current posix-timer subsystem on top of the timer wheel has already introduced a quite complex handling of the required readjusting of absolute CLOCK_REALTIME timers at settimeofday or NTP time - further underlying our experience by example: that the timer wheel data structure is too rigid for high-res timers. ”h]”hÌ)”}”(hXQthe implementation of the current posix-timer subsystem on top of the timer wheel has already introduced a quite complex handling of the required readjusting of absolute CLOCK_REALTIME timers at settimeofday or NTP time - further underlying our experience by example: that the timer wheel data structure is too rigid for high-res timers.”h]”hXQthe implementation of the current posix-timer subsystem on top of the timer wheel has already introduced a quite complex handling of the required readjusting of absolute CLOCK_REALTIME timers at settimeofday or NTP time - further underlying our experience by example: that the timer wheel data structure is too rigid for high-res timers.”…””}”(hj$h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K$hj ubah}”(h]”h ]”h"]”h$]”h&]”uh1hîhhëh²hh³hÊh´Nubhï)”}”(hX™the timer wheel code is most optimal for use cases which can be identified as "timeouts". Such timeouts are usually set up to cover error conditions in various I/O paths, such as networking and block I/O. The vast majority of those timers never expire and are rarely recascaded because the expected correct event arrives in time so they can be removed from the timer wheel before any further processing of them becomes necessary. Thus the users of these timeouts can accept the granularity and precision tradeoffs of the timer wheel, and largely expect the timer subsystem to have near-zero overhead. Accurate timing for them is not a core purpose - in fact most of the timeout values used are ad-hoc. For them it is at most a necessary evil to guarantee the processing of actual timeout completions (because most of the timeouts are deleted before completion), which should thus be as cheap and unintrusive as possible. ”h]”hÌ)”}”(hX˜the timer wheel code is most optimal for use cases which can be identified as "timeouts". Such timeouts are usually set up to cover error conditions in various I/O paths, such as networking and block I/O. The vast majority of those timers never expire and are rarely recascaded because the expected correct event arrives in time so they can be removed from the timer wheel before any further processing of them becomes necessary. Thus the users of these timeouts can accept the granularity and precision tradeoffs of the timer wheel, and largely expect the timer subsystem to have near-zero overhead. Accurate timing for them is not a core purpose - in fact most of the timeout values used are ad-hoc. For them it is at most a necessary evil to guarantee the processing of actual timeout completions (because most of the timeouts are deleted before completion), which should thus be as cheap and unintrusive as possible.”h]”hXœthe timer wheel code is most optimal for use cases which can be identified as “timeoutsâ€. Such timeouts are usually set up to cover error conditions in various I/O paths, such as networking and block I/O. The vast majority of those timers never expire and are rarely recascaded because the expected correct event arrives in time so they can be removed from the timer wheel before any further processing of them becomes necessary. Thus the users of these timeouts can accept the granularity and precision tradeoffs of the timer wheel, and largely expect the timer subsystem to have near-zero overhead. Accurate timing for them is not a core purpose - in fact most of the timeout values used are ad-hoc. For them it is at most a necessary evil to guarantee the processing of actual timeout completions (because most of the timeouts are deleted before completion), which should thus be as cheap and unintrusive as possible.”…””}”(hj<h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K+hj8ubah}”(h]”h ]”h"]”h$]”h&]”uh1hîhhëh²hh³hÊh´Nubeh}”(h]”h ]”h"]”h$]”h&]”Œbullet”Œ-”uh1héh³hÊh´Khh·h²hubhÌ)”}”(hX=The primary users of precision timers are user-space applications that utilize nanosleep, posix-timers and itimer interfaces. Also, in-kernel users like drivers and subsystems which require precise timed events (e.g. multimedia) can benefit from the availability of a separate high-resolution timer subsystem as well.”h]”hX=The primary users of precision timers are user-space applications that utilize nanosleep, posix-timers and itimer interfaces. Also, in-kernel users like drivers and subsystems which require precise timed events (e.g. multimedia) can benefit from the availability of a separate high-resolution timer subsystem as well.”…””}”(hjXh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K:hh·h²hubhÌ)”}”(hX˜While this subsystem does not offer high-resolution clock sources just yet, the hrtimer subsystem can be easily extended with high-resolution clock capabilities, and patches for that exist and are maturing quickly. The increasing demand for realtime and multimedia applications along with other potential users for precise timers gives another reason to separate the "timeout" and "precise timer" subsystems.”h]”hX While this subsystem does not offer high-resolution clock sources just yet, the hrtimer subsystem can be easily extended with high-resolution clock capabilities, and patches for that exist and are maturing quickly. The increasing demand for realtime and multimedia applications along with other potential users for precise timers gives another reason to separate the “timeout†and “precise timer†subsystems.”…””}”(hjfh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K@hh·h²hubhÌ)”}”(hXAnother potential benefit is that such a separation allows even more special-purpose optimization of the existing timer wheel for the low resolution and low precision use cases - once the precision-sensitive APIs are separated from the timer wheel and are migrated over to hrtimers. E.g. we could decrease the frequency of the timeout subsystem from 250 Hz to 100 HZ (or even smaller).”h]”hXAnother potential benefit is that such a separation allows even more special-purpose optimization of the existing timer wheel for the low resolution and low precision use cases - once the precision-sensitive APIs are separated from the timer wheel and are migrated over to hrtimers. E.g. we could decrease the frequency of the timeout subsystem from 250 Hz to 100 HZ (or even smaller).”…””}”(hjth²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KGhh·h²hubh¶)”}”(hhh]”(h»)”}”(hŒ(hrtimer subsystem implementation details”h]”hŒ(hrtimer subsystem implementation details”…””}”(hj…h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhj‚h²hh³hÊh´KOubhÌ)”}”(hŒ%the basic design considerations were:”h]”hŒ%the basic design considerations were:”…””}”(hj“h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KQhj‚h²hubhê)”}”(hhh]”(hï)”}”(hŒ simplicity ”h]”hÌ)”}”(hŒ simplicity”h]”hŒ simplicity”…””}”(hj¨h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KShj¤ubah}”(h]”h ]”h"]”h$]”h&]”uh1hîhj¡h²hh³hÊh´Nubhï)”}”(hŒŒdata structure not bound to jiffies or any other granularity. All the kernel logic works at 64-bit nanoseconds resolution - no compromises. ”h]”hÌ)”}”(hŒ‹data structure not bound to jiffies or any other granularity. All the kernel logic works at 64-bit nanoseconds resolution - no compromises.”h]”hŒ‹data structure not bound to jiffies or any other granularity. All the kernel logic works at 64-bit nanoseconds resolution - no compromises.”…””}”(hjÀh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KUhj¼ubah}”(h]”h ]”h"]”h$]”h&]”uh1hîhj¡h²hh³hÊh´Nubhï)”}”(hŒ7simplification of existing, timing related kernel code ”h]”hÌ)”}”(hŒ6simplification of existing, timing related kernel code”h]”hŒ6simplification of existing, timing related kernel code”…””}”(hjØh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KXhjÔubah}”(h]”h ]”h"]”h$]”h&]”uh1hîhj¡h²hh³hÊh´Nubeh}”(h]”h ]”h"]”h$]”h&]”jVjWuh1héh³hÊh´KShj‚h²hubhÌ)”}”(hX%another basic requirement was the immediate enqueueing and ordering of timers at activation time. After looking at several possible solutions such as radix trees and hashes, we chose the red black tree as the basic data structure. Rbtrees are available as a library in the kernel and are used in various performance-critical areas of e.g. memory management and file systems. The rbtree is solely used for time sorted ordering, while a separate list is used to give the expiry code fast access to the queued timers, without having to walk the rbtree.”h]”hX%another basic requirement was the immediate enqueueing and ordering of timers at activation time. After looking at several possible solutions such as radix trees and hashes, we chose the red black tree as the basic data structure. Rbtrees are available as a library in the kernel and are used in various performance-critical areas of e.g. memory management and file systems. The rbtree is solely used for time sorted ordering, while a separate list is used to give the expiry code fast access to the queued timers, without having to walk the rbtree.”…””}”(hjòh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KZhj‚h²hubhÌ)”}”(hŒ±(This separate list is also useful for later when we'll introduce high-resolution clocks, where we need separate pending and expired queues while keeping the time-order intact.)”h]”hŒ³(This separate list is also useful for later when we’ll introduce high-resolution clocks, where we need separate pending and expired queues while keeping the time-order intact.)”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kchj‚h²hubhÌ)”}”(hX Time-ordered enqueueing is not purely for the purposes of high-resolution clocks though, it also simplifies the handling of absolute timers based on a low-resolution CLOCK_REALTIME. The existing implementation needed to keep an extra list of all armed absolute CLOCK_REALTIME timers along with complex locking. In case of settimeofday and NTP, all the timers (!) had to be dequeued, the time-changing code had to fix them up one by one, and all of them had to be enqueued again. The time-ordered enqueueing and the storage of the expiry time in absolute time units removes all this complex and poorly scaling code from the posix-timer implementation - the clock can simply be set without having to touch the rbtree. This also makes the handling of posix-timers simpler in general.”h]”hX Time-ordered enqueueing is not purely for the purposes of high-resolution clocks though, it also simplifies the handling of absolute timers based on a low-resolution CLOCK_REALTIME. The existing implementation needed to keep an extra list of all armed absolute CLOCK_REALTIME timers along with complex locking. In case of settimeofday and NTP, all the timers (!) had to be dequeued, the time-changing code had to fix them up one by one, and all of them had to be enqueued again. The time-ordered enqueueing and the storage of the expiry time in absolute time units removes all this complex and poorly scaling code from the posix-timer implementation - the clock can simply be set without having to touch the rbtree. This also makes the handling of posix-timers simpler in general.”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kghj‚h²hubhÌ)”}”(hXThe locking and per-CPU behavior of hrtimers was mostly taken from the existing timer wheel code, as it is mature and well suited. Sharing code was not really a win, due to the different data structures. Also, the hrtimer functions now have clearer behavior and clearer names - such as hrtimer_try_to_cancel() and hrtimer_cancel() [which are roughly equivalent to timer_delete() and timer_delete_sync()] - so there's no direct 1:1 mapping between them on the algorithmic level, and thus no real potential for code sharing either.”h]”hXThe locking and per-CPU behavior of hrtimers was mostly taken from the existing timer wheel code, as it is mature and well suited. Sharing code was not really a win, due to the different data structures. Also, the hrtimer functions now have clearer behavior and clearer names - such as hrtimer_try_to_cancel() and hrtimer_cancel() [which are roughly equivalent to timer_delete() and timer_delete_sync()] - so there’s no direct 1:1 mapping between them on the algorithmic level, and thus no real potential for code sharing either.”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kthj‚h²hubhÌ)”}”(hX©Basic data types: every time value, absolute or relative, is in a special nanosecond-resolution 64bit type: ktime_t. (Originally, the kernel-internal representation of ktime_t values and operations was implemented via macros and inline functions, and could be switched between a "hybrid union" type and a plain "scalar" 64bit nanoseconds representation (at compile time). This was abandoned in the context of the Y2038 work.)”h]”hX±Basic data types: every time value, absolute or relative, is in a special nanosecond-resolution 64bit type: ktime_t. (Originally, the kernel-internal representation of ktime_t values and operations was implemented via macros and inline functions, and could be switched between a “hybrid union†type and a plain “scalar†64bit nanoseconds representation (at compile time). This was abandoned in the context of the Y2038 work.)”…””}”(hj*h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K}hj‚h²hubeh}”(h]”Œ(hrtimer-subsystem-implementation-details”ah ]”h"]”Œ(hrtimer subsystem implementation details”ah$]”h&]”uh1hµhh·h²hh³hÊh´KOubh¶)”}”(hhh]”(h»)”}”(hŒ#hrtimers - rounding of timer values”h]”hŒ#hrtimers - rounding of timer values”…””}”(hjCh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhj@h²hh³hÊh´K†ubhÌ)”}”(hŒŠthe hrtimer code will round timer events to lower-resolution clocks because it has to. Otherwise it will do no artificial rounding at all.”h]”hŒŠthe hrtimer code will round timer events to lower-resolution clocks because it has to. Otherwise it will do no artificial rounding at all.”…””}”(hjQh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kˆhj@h²hubhÌ)”}”(hŒÖone question is, what resolution value should be returned to the user by the clock_getres() interface. This will return whatever real resolution a given clock has - be it low-res, high-res, or artificially-low-res.”h]”hŒÖone question is, what resolution value should be returned to the user by the clock_getres() interface. This will return whatever real resolution a given clock has - be it low-res, high-res, or artificially-low-res.”…””}”(hj_h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K‹hj@h²hubeh}”(h]”Œ!hrtimers-rounding-of-timer-values”ah ]”h"]”Œ#hrtimers - rounding of timer values”ah$]”h&]”uh1hµhh·h²hh³hÊh´K†ubh¶)”}”(hhh]”(h»)”}”(hŒ#hrtimers - testing and verification”h]”hŒ#hrtimers - testing and verification”…””}”(hjxh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjuh²hh³hÊh´KubhÌ)”}”(hŒõWe used the high-resolution clock subsystem on top of hrtimers to verify the hrtimer implementation details in praxis, and we also ran the posix timer tests in order to ensure specification compliance. We also ran tests on low-resolution clocks.”h]”hŒõWe used the high-resolution clock subsystem on top of hrtimers to verify the hrtimer implementation details in praxis, and we also ran the posix timer tests in order to ensure specification compliance. We also ran tests on low-resolution clocks.”…””}”(hj†h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K’hjuh²hubhÌ)”}”(hŒNThe hrtimer patch converts the following kernel functionality to use hrtimers:”h]”hŒNThe hrtimer patch converts the following kernel functionality to use hrtimers:”…””}”(hj”h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K—hjuh²hubhŒ block_quote”“”)”}”(hŒ%- nanosleep - itimers - posix-timers ”h]”hê)”}”(hhh]”(hï)”}”(hŒ nanosleep”h]”hÌ)”}”(hj­h]”hŒ nanosleep”…””}”(hj¯h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kšhj«ubah}”(h]”h ]”h"]”h$]”h&]”uh1hîhj¨ubhï)”}”(hŒitimers”h]”hÌ)”}”(hjÄh]”hŒitimers”…””}”(hjÆh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K›hjÂubah}”(h]”h ]”h"]”h$]”h&]”uh1hîhj¨ubhï)”}”(hŒ posix-timers ”h]”hÌ)”}”(hŒ posix-timers”h]”hŒ posix-timers”…””}”(hjÝh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KœhjÙubah}”(h]”h ]”h"]”h$]”h&]”uh1hîhj¨ubeh}”(h]”h ]”h"]”h$]”h&]”jVjWuh1héh³hÊh´Kšhj¤ubah}”(h]”h ]”h"]”h$]”h&]”uh1j¢h³hÊh´Kšhjuh²hubhÌ)”}”(hŒfThe conversion of nanosleep and posix-timers enabled the unification of nanosleep and clock_nanosleep.”h]”hŒfThe conversion of nanosleep and posix-timers enabled the unification of nanosleep and clock_nanosleep.”…””}”(hjýh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kžhjuh²hubhÌ)”}”(hŒ?The code was successfully compiled for the following platforms:”h]”hŒ?The code was successfully compiled for the following platforms:”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K¡hjuh²hubj£)”}”(hŒ$i386, x86_64, ARM, PPC, PPC64, IA64 ”h]”hÌ)”}”(hŒ#i386, x86_64, ARM, PPC, PPC64, IA64”h]”hŒ#i386, x86_64, ARM, PPC, PPC64, IA64”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K£hjubah}”(h]”h ]”h"]”h$]”h&]”uh1j¢h³hÊh´K£hjuh²hubhÌ)”}”(hŒ3The code was run-tested on the following platforms:”h]”hŒ3The code was run-tested on the following platforms:”…””}”(hj1h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K¥hjuh²hubj£)”}”(hŒ'i386(UP/SMP), x86_64(UP/SMP), ARM, PPC ”h]”hÌ)”}”(hŒ&i386(UP/SMP), x86_64(UP/SMP), ARM, PPC”h]”hŒ&i386(UP/SMP), x86_64(UP/SMP), ARM, PPC”…””}”(hjCh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K§hj?ubah}”(h]”h ]”h"]”h$]”h&]”uh1j¢h³hÊh´K§hjuh²hubhÌ)”}”(hŒ¼hrtimers were also integrated into the -rt tree, along with a hrtimers-based high-resolution clock implementation, so the hrtimers code got a healthy amount of testing and use in practice.”h]”hŒ¼hrtimers were also integrated into the -rt tree, along with a hrtimers-based high-resolution clock implementation, so the hrtimers code got a healthy amount of testing and use in practice.”…””}”(hjWh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K©hjuh²hubj£)”}”(hŒThomas Gleixner, Ingo Molnar”h]”hÌ)”}”(hjgh]”hŒThomas Gleixner, Ingo Molnar”…””}”(hjih²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K­hjeubah}”(h]”h ]”h"]”h$]”h&]”uh1j¢h³hÊh´K­hjuh²hubeh}”(h]”Œ!hrtimers-testing-and-verification”ah ]”h"]”Œ#hrtimers - testing and verification”ah$]”h&]”uh1hµhh·h²hh³hÊh´Kubeh}”(h]”Œ4hrtimers-subsystem-for-high-resolution-kernel-timers”ah ]”h"]”Œ6hrtimers - subsystem for high-resolution kernel timers”ah$]”h&]”uh1hµhhh²hh³hÊh´Kubeh}”(h]”h ]”h"]”h$]”h&]”Œsource”hÊuh1hŒcurrent_source”NŒ current_line”NŒsettings”Œdocutils.frontend”ŒValues”“”)”}”(hºNŒ generator”NŒ datestamp”NŒ source_link”NŒ source_url”NŒ toc_backlinks”Œentry”Œfootnote_backlinks”KŒ sectnum_xform”KŒstrip_comments”NŒstrip_elements_with_classes”NŒ strip_classes”NŒ report_level”KŒ halt_level”KŒexit_status_level”KŒdebug”NŒwarning_stream”NŒ traceback”ˆŒinput_encoding”Œ utf-8-sig”Œinput_encoding_error_handler”Œstrict”Œoutput_encoding”Œutf-8”Œoutput_encoding_error_handler”j¯Œerror_encoding”Œutf-8”Œerror_encoding_error_handler”Œbackslashreplace”Œ language_code”Œen”Œrecord_dependencies”NŒconfig”NŒ id_prefix”hŒauto_id_prefix”Œid”Œ dump_settings”NŒdump_internals”NŒdump_transforms”NŒdump_pseudo_xml”NŒexpose_internals”NŒstrict_visitor”NŒ_disable_config”NŒ_source”hÊŒ _destination”NŒ _config_files”]”Œ7/var/lib/git/docbuild/linux/Documentation/docutils.conf”aŒfile_insertion_enabled”ˆŒ raw_enabled”KŒline_length_limit”M'Œpep_references”NŒ pep_base_url”Œhttps://peps.python.org/”Œpep_file_url_template”Œpep-%04d”Œrfc_references”NŒ rfc_base_url”Œ&https://datatracker.ietf.org/doc/html/”Œ tab_width”KŒtrim_footnote_reference_space”‰Œsyntax_highlight”Œlong”Œ smart_quotes”ˆŒsmartquotes_locales”]”Œcharacter_level_inline_markup”‰Œdoctitle_xform”‰Œ docinfo_xform”KŒsectsubtitle_xform”‰Œ image_loading”Œlink”Œembed_stylesheet”‰Œcloak_email_addresses”ˆŒsection_self_link”‰Œenv”NubŒreporter”NŒindirect_targets”]”Œsubstitution_defs”}”Œsubstitution_names”}”Œrefnames”}”Œrefids”}”Œnameids”}”(j‰j†j=j:jrjojj~uŒ nametypes”}”(j‰‰j=‰jr‰j‰uh}”(j†h·j:j‚joj@j~juuŒ footnote_refs”}”Œ citation_refs”}”Œ autofootnotes”]”Œautofootnote_refs”]”Œsymbol_footnotes”]”Œsymbol_footnote_refs”]”Œ footnotes”]”Œ citations”]”Œautofootnote_start”KŒsymbol_footnote_start”KŒ id_counter”Œ collections”ŒCounter”“”}”…”R”Œparse_messages”]”Œtransform_messages”]”Œ transformer”NŒ include_log”]”Œ decoration”Nh²hub.