Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. #ifndef LINUX_PREEMPT_MASK_H
  2. #define LINUX_PREEMPT_MASK_H
  3.  
  4. #include <linux/preempt.h>
  5.  
  6. /*
  7.  * We put the hardirq and softirq counter into the preemption
  8.  * counter. The bitmask has the following meaning:
  9.  *
  10.  * - bits 0-7 are the preemption count (max preemption depth: 256)
  11.  * - bits 8-15 are the softirq count (max # of softirqs: 256)
  12.  *
  13.  * The hardirq count could in theory be the same as the number of
  14.  * interrupts in the system, but we run all interrupt handlers with
  15.  * interrupts disabled, so we cannot have nesting interrupts. Though
  16.  * there are a few palaeontologic drivers which reenable interrupts in
  17.  * the handler, so we need more than one bit here.
  18.  *
  19.  * PREEMPT_MASK:        0x000000ff
  20.  * SOFTIRQ_MASK:        0x0000ff00
  21.  * HARDIRQ_MASK:        0x000f0000
  22.  *     NMI_MASK:        0x00100000
  23.  * PREEMPT_ACTIVE:      0x00200000
  24.  */
  25. #define PREEMPT_BITS    8
  26. #define SOFTIRQ_BITS    8
  27. #define HARDIRQ_BITS    4
  28. #define NMI_BITS        1
  29.  
  30. #define PREEMPT_SHIFT   0
  31. #define SOFTIRQ_SHIFT   (PREEMPT_SHIFT + PREEMPT_BITS)
  32. #define HARDIRQ_SHIFT   (SOFTIRQ_SHIFT + SOFTIRQ_BITS)
  33. #define NMI_SHIFT       (HARDIRQ_SHIFT + HARDIRQ_BITS)
  34.  
  35. #define __IRQ_MASK(x)   ((1UL << (x))-1)
  36.  
  37. #define PREEMPT_MASK    (__IRQ_MASK(PREEMPT_BITS) << PREEMPT_SHIFT)
  38. #define SOFTIRQ_MASK    (__IRQ_MASK(SOFTIRQ_BITS) << SOFTIRQ_SHIFT)
  39. #define HARDIRQ_MASK    (__IRQ_MASK(HARDIRQ_BITS) << HARDIRQ_SHIFT)
  40. #define NMI_MASK        (__IRQ_MASK(NMI_BITS)     << NMI_SHIFT)
  41.  
  42. #define PREEMPT_OFFSET  (1UL << PREEMPT_SHIFT)
  43. #define SOFTIRQ_OFFSET  (1UL << SOFTIRQ_SHIFT)
  44. #define HARDIRQ_OFFSET  (1UL << HARDIRQ_SHIFT)
  45. #define NMI_OFFSET      (1UL << NMI_SHIFT)
  46.  
  47. #define SOFTIRQ_DISABLE_OFFSET  (2 * SOFTIRQ_OFFSET)
  48.  
  49. #define PREEMPT_ACTIVE_BITS     1
  50. #define PREEMPT_ACTIVE_SHIFT    (NMI_SHIFT + NMI_BITS)
  51. #define PREEMPT_ACTIVE  (__IRQ_MASK(PREEMPT_ACTIVE_BITS) << PREEMPT_ACTIVE_SHIFT)
  52.  
  53. #define hardirq_count() (preempt_count() & HARDIRQ_MASK)
  54. #define softirq_count() (preempt_count() & SOFTIRQ_MASK)
  55. #define irq_count()     (preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK \
  56.                                  | NMI_MASK))
  57.  
  58. /*
  59.  * Are we doing bottom half or hardware interrupt processing?
  60.  * Are we in a softirq context? Interrupt context?
  61.  * in_softirq - Are we currently processing softirq or have bh disabled?
  62.  * in_serving_softirq - Are we currently processing softirq?
  63.  */
  64. #define in_irq()                (hardirq_count())
  65. #define in_softirq()            (softirq_count())
  66. #define in_interrupt()          (irq_count())
  67. #define in_serving_softirq()    (softirq_count() & SOFTIRQ_OFFSET)
  68.  
  69. /*
  70.  * Are we in NMI context?
  71.  */
  72. #define in_nmi()        (preempt_count() & NMI_MASK)
  73.  
  74. #if defined(CONFIG_PREEMPT_COUNT)
  75. # define PREEMPT_CHECK_OFFSET 1
  76. #else
  77. # define PREEMPT_CHECK_OFFSET 0
  78. #endif
  79.  
  80. /*
  81.  * The preempt_count offset needed for things like:
  82.  *
  83.  *  spin_lock_bh()
  84.  *
  85.  * Which need to disable both preemption (CONFIG_PREEMPT_COUNT) and
  86.  * softirqs, such that unlock sequences of:
  87.  *
  88.  *  spin_unlock();
  89.  *  local_bh_enable();
  90.  *
  91.  * Work as expected.
  92.  */
  93. #define SOFTIRQ_LOCK_OFFSET (SOFTIRQ_DISABLE_OFFSET + PREEMPT_CHECK_OFFSET)
  94.  
  95. /*
  96.  * Are we running in atomic context?  WARNING: this macro cannot
  97.  * always detect atomic context; in particular, it cannot know about
  98.  * held spinlocks in non-preemptible kernels.  Thus it should not be
  99.  * used in the general case to determine whether sleeping is possible.
  100.  * Do not use in_atomic() in driver code.
  101.  */
  102. #define in_atomic()     ((preempt_count() & ~PREEMPT_ACTIVE) != 0)
  103.  
  104. /*
  105.  * Check whether we were atomic before we did preempt_disable():
  106.  * (used by the scheduler, *after* releasing the kernel lock)
  107.  */
  108. #define in_atomic_preempt_off() \
  109.                 ((preempt_count() & ~PREEMPT_ACTIVE) != PREEMPT_CHECK_OFFSET)
  110.  
  111. #ifdef CONFIG_PREEMPT_COUNT
  112. # define preemptible()  (preempt_count() == 0 && !irqs_disabled())
  113. #else
  114. # define preemptible()  0
  115. #endif
  116.  
  117. #endif /* LINUX_PREEMPT_MASK_H */
  118.