Ядро Linux в комментариях

       

Kernel/softirq.c


29070 /* 29071 * linux/kernel/softirq.c 29072 * 29073 * Copyright (C) 1992 Linus Torvalds 29074 * 29075 * do_bottom_half() runs at normal kernel priority: all 29076 * interrupts enabled. do_bottom_half() is atomic with 29077 * respect to itself: a bottom_half handler need not be 29078 * re-entrant. 29079 * 29080 * Fixed a disable_bh()/enable_bh() race (was causing a 29081 * console lockup) due bh_mask_count not atomic 29082 * handling. Copyright (C) 1998 Andrea Arcangeli 29083 */ 29084 29085 #include <linux/mm.h> 29086 #include <linux/kernel_stat.h> 29087 #include <linux/interrupt.h> 29088 #include <linux/smp_lock.h> 29089 29090 #include <asm/io.h> 29091 29092 /* intr_count died a painless death... -DaveM */ 29093 29094 atomic_t bh_mask_count[32]; 29095 unsigned long bh_active = 0; 29096 unsigned long bh_mask = 0; 29097 void (*bh_base[32])(void); 29098 29099 /* This needs to make sure that only one bottom half 29100 * handler is ever active at a time. We do this without 29101 * locking by doing an atomic increment on the 29102 * intr_count, and checking (nonatomically) against 29103 * 1. Only if it's 1 do we schedule the bottom half. 29104 * 29105 * Note that the non-atomicity of the test (as opposed to 29106 * the actual update) means that the test may fail, and 29107 * _nobody_ runs the handlers if there is a race that 29108 * makes multiple CPU's get here at the same time. That's 29109 * ok, we'll run them next time around. */

29110 static inline void run_bottom_halves(void) 29111 { 29112 unsigned long active; 29113 void (**bh)(void); 29114 29115 active = get_active_bhs(); 29116 clear_active_bhs(active); 29117 bh = bh_base;

29118 do { 29119 if (active & 1) 29120 (*bh)(); 29121 bh++; 29122 active >>= 1; 29123 } while (active); 29124 } 29125

29126 asmlinkage void do_bottom_half(void) 29127 { 29128 int cpu = smp_processor_id(); 29129 29130 if (softirq_trylock(cpu)) { 29131 if (hardirq_trylock(cpu)) { 29132 __sti(); 29133 run_bottom_halves(); 29134 __cli(); 29135 hardirq_endlock(cpu); 29136 } 29137 softirq_endlock(cpu); 29138 } 29139 }



Содержание раздела