hardirq.h
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:3k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * BK Id: SCCS/s.hardirq.h 1.12 07/10/01 11:26:58 trini
  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. } ____cacheline_aligned irq_cpustat_t;
  23. #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
  24. #define last_jiffy_stamp(cpu) __IRQ_STAT((cpu), __last_jiffy_stamp)
  25. /*
  26.  * Are we in an interrupt context? Either doing bottom half
  27.  * or hardware interrupt processing?
  28.  */
  29. #define in_interrupt() ({ int __cpu = smp_processor_id(); 
  30. (local_irq_count(__cpu) + local_bh_count(__cpu) != 0); })
  31. #define in_irq() (local_irq_count(smp_processor_id()) != 0)
  32. #ifndef CONFIG_SMP
  33. #define hardirq_trylock(cpu) (local_irq_count(cpu) == 0)
  34. #define hardirq_endlock(cpu) do { } while (0)
  35. #define hardirq_enter(cpu) (local_irq_count(cpu)++)
  36. #define hardirq_exit(cpu) (local_irq_count(cpu)--)
  37. #define synchronize_irq() do { } while (0)
  38. #else /* CONFIG_SMP */
  39. #include <asm/atomic.h>
  40. extern unsigned char global_irq_holder;
  41. extern unsigned volatile long global_irq_lock;
  42. extern atomic_t global_irq_count;
  43. static inline void release_irqlock(int cpu)
  44. {
  45. /* if we didn't own the irq lock, just ignore.. */
  46. if (global_irq_holder == (unsigned char) cpu) {
  47. global_irq_holder = NO_PROC_ID;
  48. clear_bit(0,&global_irq_lock);
  49. }
  50. }
  51. static inline void hardirq_enter(int cpu)
  52. {
  53. unsigned int loops = 10000000;
  54. ++local_irq_count(cpu);
  55. atomic_inc(&global_irq_count);
  56. while (test_bit(0,&global_irq_lock)) {
  57. if (cpu == global_irq_holder) {
  58. printk("uh oh, interrupt while we hold global irq lock! (CPU %d)n", cpu);
  59. #ifdef CONFIG_XMON
  60. xmon(0);
  61. #endif
  62. break;
  63. }
  64. if (loops-- == 0) {
  65. printk("do_IRQ waiting for irq lock (holder=%d)n", global_irq_holder);
  66. #ifdef CONFIG_XMON
  67. xmon(0);
  68. #endif
  69. }
  70. }
  71. }
  72. static inline void hardirq_exit(int cpu)
  73. {
  74. atomic_dec(&global_irq_count);
  75. --local_irq_count(cpu);
  76. }
  77. static inline int hardirq_trylock(int cpu)
  78. {
  79. return !atomic_read(&global_irq_count) && !test_bit(0,&global_irq_lock);
  80. }
  81. #define hardirq_endlock(cpu) do { } while (0)
  82. extern void synchronize_irq(void);
  83. #endif /* CONFIG_SMP */
  84. #endif /* __ASM_HARDIRQ_H */
  85. #endif /* __KERNEL__ */