|
#else jmp restore_all #endif ALIGN handle_softirq: #ifdef CONFIG_PREEMPT cli GET_CURRENT(%ebx) incl preempt_count(%ebx) sti #endif call SYMBOL_NAME(do_softirq) jmp ret_from_intr ALIGN reschedule: call SYMBOL_NAME(schedule) # test jmp ret_from_sys_call include/asm/hw_irq.h: ... #ifdef CONFIG_PREEMPT #define BUMP_CONTEX_SWITCH_LOCK \ GET_CURRENT \ "incl 4(%ebx)\n\t" #else #define BUMP_CONTEX_SWITCH_LOCK #endif #define SAVE_ALL \ 硬件中断保护入口现场 "cld\n\t" \ "pushl %es\n\t" \ "pushl %ds\n\t" \ "pushl %eax\n\t" \ "pushl %ebp\n\t" \ "pushl %edi\n\t" \ "pushl %esi\n\t" \ "pushl %edx\n\t" \ "pushl %ecx\n\t" \ "pushl %ebx\n\t" \ "movl $" STR(__KERNEL_DS) ",%edx\n\t" \ "movl %edx,%ds\n\t" \ "movl %edx,%es\n\t" \ BUMP_CONTEX_SWITCH_LOCK # 硬件中断的入口禁止内核抢占 include/Linux/spinlock.h: #ifdef CONFIG_PREEMPT #define switch_lock_count() current->preempt_count #define in_ctx_sw_off() (switch_lock_count().counter) 判断当前进程的抢占计数 是否非零 #define atomic_ptr_in_ctx_sw_off() (&switch_lock_count()) #define ctx_sw_off() \ 禁止内核抢占 do { \ atomic_inc(atomic_ptr_in_ctx_sw_off()); \ 当前进程的内核抢占计数增1 } while (0) #define ctx_sw_on_no_preempt() \ 允许内核抢占 do { \ atomic_dec(atomic_ptr_in_ctx_sw_off()); \ 当前进程的内核抢占计数减1 } while (0) #define ctx_sw_on() \ 允许并完成内核抢占 do { \ if (atomic_dec_and_test(atomic_ptr_in_ctx_sw_off()) && \ current->need_resched) \ preempt_schedule(); \ } while (0) #define spin_lock(lock) \ do { \ ctx_sw_off(); \ 进入自旋锁时禁止抢占 _raw_spin_lock(lock); \ } while(0) #define spin_trylock(lock) ({ctx_sw_off(); _raw_spin_trylock(lock) ? \锁定并 测试原来是否上锁 1 : ({ctx_sw_on(); 0;});}) #define spin_unl上一页 [1] [2] [3] [4] [5] [6] 下一页 |
|
|
|
|
|
|
|