Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.8.
  1.. SPDX-License-Identifier: GPL-2.0
  2
  3Delay and sleep mechanisms
  4==========================
  5
  6This document seeks to answer the common question: "What is the
  7RightWay (TM) to insert a delay?"
  8
  9This question is most often faced by driver writers who have to
 10deal with hardware delays and who may not be the most intimately
 11familiar with the inner workings of the Linux Kernel.
 12
 13The following table gives a rough overview about the existing function
 14'families' and their limitations. This overview table does not replace the
 15reading of the function description before usage!
 16
 17.. list-table::
 18   :widths: 20 20 20 20 20
 19   :header-rows: 2
 20
 21   * -
 22     - `*delay()`
 23     - `usleep_range*()`
 24     - `*sleep()`
 25     - `fsleep()`
 26   * -
 27     - busy-wait loop
 28     - hrtimers based
 29     - timer list timers based
 30     - combines the others
 31   * - Usage in atomic Context
 32     - yes
 33     - no
 34     - no
 35     - no
 36   * - precise on "short intervals"
 37     - yes
 38     - yes
 39     - depends
 40     - yes
 41   * - precise on "long intervals"
 42     - Do not use!
 43     - yes
 44     - max 12.5% slack
 45     - yes
 46   * - interruptible variant
 47     - no
 48     - yes
 49     - yes
 50     - no
 51
 52A generic advice for non atomic contexts could be:
 53
 54#. Use `fsleep()` whenever unsure (as it combines all the advantages of the
 55   others)
 56#. Use `*sleep()` whenever possible
 57#. Use `usleep_range*()` whenever accuracy of `*sleep()` is not sufficient
 58#. Use `*delay()` for very, very short delays
 59
 60Find some more detailed information about the function 'families' in the next
 61sections.
 62
 63`*delay()` family of functions
 64------------------------------
 65
 66These functions use the jiffy estimation of clock speed and will busy wait for
 67enough loop cycles to achieve the desired delay. udelay() is the basic
 68implementation and ndelay() as well as mdelay() are variants.
 69
 70These functions are mainly used to add a delay in atomic context. Please make
 71sure to ask yourself before adding a delay in atomic context: Is this really
 72required?
 73
 74.. kernel-doc:: include/asm-generic/delay.h
 75	:identifiers: udelay ndelay
 76
 77.. kernel-doc:: include/linux/delay.h
 78	:identifiers: mdelay
 79
 80
 81`usleep_range*()` and `*sleep()` family of functions
 82----------------------------------------------------
 83
 84These functions use hrtimers or timer list timers to provide the requested
 85sleeping duration. In order to decide which function is the right one to use,
 86take some basic information into account:
 87
 88#. hrtimers are more expensive as they are using an rb-tree (instead of hashing)
 89#. hrtimers are more expensive when the requested sleeping duration is the first
 90   timer which means real hardware has to be programmed
 91#. timer list timers always provide some sort of slack as they are jiffy based
 92
 93The generic advice is repeated here:
 94
 95#. Use `fsleep()` whenever unsure (as it combines all the advantages of the
 96   others)
 97#. Use `*sleep()` whenever possible
 98#. Use `usleep_range*()` whenever accuracy of `*sleep()` is not sufficient
 99
100First check fsleep() function description and to learn more about accuracy,
101please check msleep() function description.
102
103
104`usleep_range*()`
105~~~~~~~~~~~~~~~~~
106
107.. kernel-doc:: include/linux/delay.h
108	:identifiers: usleep_range usleep_range_idle
109
110.. kernel-doc:: kernel/time/sleep_timeout.c
111	:identifiers: usleep_range_state
112
113
114`*sleep()`
115~~~~~~~~~~
116
117.. kernel-doc:: kernel/time/sleep_timeout.c
118       :identifiers: msleep msleep_interruptible
119
120.. kernel-doc:: include/linux/delay.h
121	:identifiers: ssleep fsleep