include/asm-i386/softirq.h
12472 #ifndef __ASM_SOFTIRQ_H
12473 #define __ASM_SOFTIRQ_H
12474
12475 #include <asm/atomic.h>
12476 #include <asm/hardirq.h>
12477
12478 extern unsigned int local_bh_count[NR_CPUS];
12479
12480 #define get_active_bhs() (bh_mask & bh_active)
12481 #define clear_active_bhs(x) \
12482 atomic_clear_mask((x),&bh_active)
12483
12484 extern inline void init_bh(int nr, void (*routine)(void))
12485 {
12486 bh_base[nr] = routine;
12487 atomic_set(&bh_mask_count[nr], 0);
12488 bh_mask |= 1 << nr;
12489 }
12490
12491 extern inline void remove_bh(int nr)
12492 {
12493 bh_mask &= ~(1 << nr);
12494 mb();
12495 bh_base[nr] = NULL;
12496 }
12497
12498 extern inline void mark_bh(int nr)
12499 {
12500 set_bit(nr, &bh_active);
12501 }
12502
12503 #ifdef __SMP__
12504
12505 /* The locking mechanism for base handlers, to prevent
12506 * re-entrancy, is entirely private to an implementation,
12507 * it should not be referenced at all outside of this
12508 * file. */
12509 extern atomic_t global_bh_lock;
12510 extern atomic_t global_bh_count;
12511
12512 extern void synchronize_bh(void);
12513
12514 static inline void start_bh_atomic(void)
12515 {
12516 atomic_inc(&global_bh_lock);
12517 synchronize_bh();
12518 }
12519
12520 static inline void end_bh_atomic(void)
12521 {
12522 atomic_dec(&global_bh_lock);
12523 }
12524
12525 /* These are for the IRQs testing the lock */
12526 static inline int softirq_trylock(int cpu)
12527 {
12528 if (!test_and_set_bit(0,&global_bh_count)) {
12529 if (atomic_read(&global_bh_lock) == 0) {
12530 ++local_bh_count[cpu];
12531 return 1;
12532 }
12533 clear_bit(0,&global_bh_count);
12534 }
12535 return 0;
12536 }
12537
12538 static inline void softirq_endlock(int cpu)
12539 {
12540 local_bh_count[cpu]--;
12541 clear_bit(0,&global_bh_count);
12542 }
12543
12544 #else
12545
12546 extern inline void start_bh_atomic(void)
12547 {
12548 local_bh_count[smp_processor_id()]++;
12549 barrier();
12550 }
12551
12552 extern inline void end_bh_atomic(void)
12553 {
12554 barrier();
12555 local_bh_count[smp_processor_id()]--;
12556 }
12557
12558 /* These are for the irq's testing the lock */
12559 #define softirq_trylock(cpu) (local_bh_count[cpu] \
12560 ? 0 : (local_bh_count[cpu]=1))
12561 #define softirq_endlock(cpu) (local_bh_count[cpu] = 0)
12562 #define synchronize_bh() barrier()
12563
12564 #endif /* SMP */
12565
12566 /* These use a mask count to correctly handle nested
12567 * disable/enable calls */
12568 extern inline void disable_bh(int nr)
12569 {
12570 bh_mask &= ~(1 << nr);
12571 atomic_inc(&bh_mask_count[nr]);
12572 synchronize_bh();
12573 }
12574
12575 extern inline void enable_bh(int nr)
12576 {
12577 if (atomic_dec_and_test(&bh_mask_count[nr]))
12578 bh_mask |= 1 << nr;
12579 }
12580
12581 #endif /* __ASM_SOFTIRQ_H */
Сайт управляется системой
uCoz