hardirq.h
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:3k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * BK Id: %F% %I% %G% %U% %#%
  3.  */
  4. #ifdef __KERNEL__
  5. #ifndef __ASM_HARDIRQ_H
  6. #define __ASM_HARDIRQ_H
  7. #include <linux/config.h>
  8. #include <asm/smp.h>
  9. /* entry.S is sensitive to the offsets of these fields */
  10. /* The __last_jiffy_stamp field is needed to ensure that no decrementer 
  11.  * interrupt is lost on SMP machines. Since on most CPUs it is in the same 
  12.  * cache line as local_irq_count, it is cheap to access and is also used on UP 
  13.  * for uniformity.
  14.  */
  15. typedef struct {
  16. unsigned long __softirq_pending; /* set_bit is used on this */
  17. unsigned int __local_irq_count;
  18. unsigned int __local_bh_count;
  19. unsigned int __syscall_count;
  20. struct task_struct * __ksoftirqd_task;
  21. unsigned int __last_jiffy_stamp;
  22. unsigned int __heartbeat_count;
  23. unsigned int __heartbeat_reset;
  24. } ____cacheline_aligned irq_cpustat_t;
  25. #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
  26. #define last_jiffy_stamp(cpu) __IRQ_STAT((cpu), __last_jiffy_stamp)
  27. #define heartbeat_count(cpu) __IRQ_STAT((cpu), __heartbeat_count)
  28. #define heartbeat_reset(cpu) __IRQ_STAT((cpu), __heartbeat_reset)
  29. /*
  30.  * Are we in an interrupt context? Either doing bottom half
  31.  * or hardware interrupt processing?
  32.  */
  33. #define in_interrupt() ({ int __cpu = smp_processor_id(); 
  34. (local_irq_count(__cpu) + local_bh_count(__cpu) != 0); })
  35. #define in_irq() (local_irq_count(smp_processor_id()) != 0)
  36. #ifndef CONFIG_SMP
  37. #define hardirq_trylock(cpu) (local_irq_count(cpu) == 0)
  38. #define hardirq_endlock(cpu) do { } while (0)
  39. #define hardirq_enter(cpu) (local_irq_count(cpu)++)
  40. #define hardirq_exit(cpu) (local_irq_count(cpu)--)
  41. #define synchronize_irq() do { } while (0)
  42. #else /* CONFIG_SMP */
  43. #include <asm/atomic.h>
  44. extern unsigned char global_irq_holder;
  45. extern unsigned volatile long global_irq_lock;
  46. extern atomic_t global_irq_count;
  47. static inline void release_irqlock(int cpu)
  48. {
  49. /* if we didn't own the irq lock, just ignore.. */
  50. if (global_irq_holder == (unsigned char) cpu) {
  51. global_irq_holder = NO_PROC_ID;
  52. clear_bit(0,&global_irq_lock);
  53. }
  54. }
  55. static inline void hardirq_enter(int cpu)
  56. {
  57. unsigned int loops = 10000000;
  58. ++local_irq_count(cpu);
  59. atomic_inc(&global_irq_count);
  60. while (test_bit(0,&global_irq_lock)) {
  61. if (cpu == global_irq_holder) {
  62. printk("uh oh, interrupt while we hold global irq lock! (CPU %d)n", cpu);
  63. #ifdef CONFIG_XMON
  64. xmon(0);
  65. #endif
  66. break;
  67. }
  68. if (loops-- == 0) {
  69. printk("do_IRQ waiting for irq lock (holder=%d)n", global_irq_holder);
  70. #ifdef CONFIG_XMON
  71. xmon(0);
  72. #endif
  73. }
  74. }
  75. }
  76. static inline void hardirq_exit(int cpu)
  77. {
  78. atomic_dec(&global_irq_count);
  79. --local_irq_count(cpu);
  80. }
  81. static inline int hardirq_trylock(int cpu)
  82. {
  83. return !atomic_read(&global_irq_count) && !test_bit(0,&global_irq_lock);
  84. }
  85. #define hardirq_endlock(cpu) do { } while (0)
  86. extern void synchronize_irq(void);
  87. #endif /* CONFIG_SMP */
  88. #endif /* __ASM_HARDIRQ_H */
  89. #endif /* __KERNEL__ */