学习网考试学习资料

Gzu521.com

Linux操作系统内核抢占补丁的基本原理(1)

LINUX教程   点击:次   发布时间:2006-11-15   【字体: 】   来源:Gzu521.com
Gzu521.com学习网
cpu在内核中运行时并不是处处不可抢占的,内核中存在一些空隙,在这时进行抢占是安全的,内核抢占补丁的基本原理就是将smp可并行的代码段看成是可以进行内核抢占的区域。  

lm6 ,/ [ 此文转贴于 贵 州 学 习 网 电脑课堂LINUX教程 http://WWW.gzu521.COM ] lm6 ,/


  2.4内核正好细化了多cpu下的内核线程同步机构,对不可并行的指令块用spinlock和rwlock作了细致的表示,该补丁的实现可谓水到渠成。具体的方法就是在进程的任务结构上增加一个preempt_count变量作为内核抢占锁,它随着spinlock和rwlock一起加锁和解锁。当preempt_count为0时表示可以进行内核调度。内核调度器的入口为preempt_schedule(),它将当前进程标记为task_preempted状态再调用schedule(),在task_preempted状态,schedule()不会将进程从运行队列中删除。  

  下面是内核抢占补丁的主要代码示意:  


arch/i386/kernel/entry.s: 
preempt_count = 4 # 将task_struct中的flags用作preempt_count,flags被移到了别 
的位置 
ret_from_exception: # 从异常返回 
#ifdef config_smp 
get_current(%ebx) 
movl processor(%ebx),%eax 
shll $config_x86_l1_cache_shift,%eax 
movl symbol_name(irq_stat)(,%eax),%ecx # softirq_active 
testl symbol_name(irq_stat)+4(,%eax),%ecx # softirq_mask 
#else 
movl symbol_name(irq_stat),%ecx # softirq_active 
testl symbol_name(irq_stat)+4,%ecx # softirq_mask 
#endif 
jne handle_softirq 
#ifdef config_preempt 
cli 
incl preempt_count(%ebx) # 异常的入口没有禁止内核调度的指令,与ret_from_intr 
匹配一下 
#endif 
entry(ret_from_intr) # 硬件中断的返回 
get_current(%ebx) 
#ifdef config_preempt 
cli 
decl preempt_count(%ebx) # 恢复内核抢占标志 
#endif 
movl eflags(%esp),%eax # mix eflags and cs 
movb cs(%esp),%al 
testl $(vm_mask | 3),%eax # return to vm86 mode or non-supervisor? 
jne ret_with_reschedule 
#ifdef config_preempt 
cmpl $0,preempt_count(%ebx) 
jnz restore_all # 如果preempt_count非零则表示禁止内核抢占 
cmpl $0,need_resched(%ebx) 
jz restore_all # 
movl symbol_name(irq_stat)+irq_stat_local_bh_count cpu_indx,%ecx 
addl symbol_name(irq_stat)+irq_stat_local_irq_count cpu_indx,%ecx 
jnz restore_all 
incl preempt_count(%ebx) 
sti 
call symbol_name(preempt_schedule) 
jmp ret_from_intr # 新进程返回,返回ret_from_intr恢复抢占标志后再返回 
#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_unlock(lock) \ 
do { \ 
_raw_spin_unlock(lock); \ 
ctx_sw_on(); \ 离开自旋锁时允许并完成内核抢占 
} while (0) 
#define read_lock(lock) ({ctx_sw_off(); _raw_read_lock(lock);}) 
#define read_unlock(lock) ({_raw_read_unlock(lock); ctx_sw_on();}) 
#define write_lock(lock) ({ctx_sw_off(); _raw_write_lock(lock);}) 
#define write_unlock(lock) ({_raw_write_unlock(lock); ctx_sw_on();}) 
#define write_trylock(lock) ({ctx_sw_off(); _raw_write_trylock(lock) ? \ 
1 : ({ctx_sw_on(); 0;});}) 
... 

本文共3页:上一页123下一页

责任编辑:gzu521

电脑课堂分类
Windows 2000教程
Windows XP教程
Windows 2003教程
Windows Vista教程
LINUX教程
软件教学
办公软件
硬件DIY
分类推荐信息
更多...
大类最新文章
更多...