File: /usr/src/linux/include/asm/hardirq.h

1     #ifndef __ASM_HARDIRQ_H
2     #define __ASM_HARDIRQ_H
3     
4     #include <linux/config.h>
5     #include <linux/threads.h>
6     #include <linux/irq.h>
7     
8     /* assembly code in softirq.h is sensitive to the offsets of these fields */
9     typedef struct {
10     	unsigned int __softirq_pending;
11     	unsigned int __local_irq_count;
12     	unsigned int __local_bh_count;
13     	unsigned int __syscall_count;
14     	struct task_struct * __ksoftirqd_task; /* waitqueue is too large */
15     	unsigned int __nmi_count;	/* arch dependent */
16     } ____cacheline_aligned irq_cpustat_t;
17     
18     #include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
19     
20     /*
21      * Are we in an interrupt context? Either doing bottom half
22      * or hardware interrupt processing?
23      */
24     #define in_interrupt() ({ int __cpu = smp_processor_id(); \
25     	(local_irq_count(__cpu) + local_bh_count(__cpu) != 0); })
26     
27     #define in_irq() (local_irq_count(smp_processor_id()) != 0)
28     
29     #ifndef CONFIG_SMP
30     
31     #define hardirq_trylock(cpu)	(local_irq_count(cpu) == 0)
32     #define hardirq_endlock(cpu)	do { } while (0)
33     
34     #define irq_enter(cpu, irq)	(local_irq_count(cpu)++)
35     #define irq_exit(cpu, irq)	(local_irq_count(cpu)--)
36     
37     #define synchronize_irq()	barrier()
38     
39     #else
40     
41     #include <asm/atomic.h>
42     #include <asm/smp.h>
43     
44     extern unsigned char global_irq_holder;
45     extern unsigned volatile long global_irq_lock; /* long for set_bit -RR */
46     
47     static inline int irqs_running (void)
48     {
49     	int i;
50     
51     	for (i = 0; i < smp_num_cpus; i++)
52     		if (local_irq_count(i))
53     			return 1;
54     	return 0;
55     }
56     
57     static inline void release_irqlock(int cpu)
58     {
59     	/* if we didn't own the irq lock, just ignore.. */
60     	if (global_irq_holder == (unsigned char) cpu) {
61     		global_irq_holder = NO_PROC_ID;
62     		clear_bit(0,&global_irq_lock);
63     	}
64     }
65     
66     static inline void irq_enter(int cpu, int irq)
67     {
68     	++local_irq_count(cpu);
69     
70     	while (test_bit(0,&global_irq_lock)) {
71     		/* nothing */;
72     	}
73     }
74     
75     static inline void irq_exit(int cpu, int irq)
76     {
77     	--local_irq_count(cpu);
78     }
79     
80     static inline int hardirq_trylock(int cpu)
81     {
82     	return !local_irq_count(cpu) && !test_bit(0,&global_irq_lock);
83     }
84     
85     #define hardirq_endlock(cpu)	do { } while (0)
86     
87     extern void synchronize_irq(void);
88     
89     #endif /* CONFIG_SMP */
90     
91     #endif /* __ASM_HARDIRQ_H */
92