欢迎来到天天文库
浏览记录
ID:61499525
大小:36.00 KB
页数:5页
时间:2021-02-07
《嵌入式操作系统内核原理和开发(线程切换).doc》由会员上传分享,免费在线阅读,更多相关内容在应用文档-天天文库。
1、嵌入式操作系统内核原理和开发(线程切换)在操作系统中,线程切换是很重要的一个环节。如果没有线程的切换,我们如何才能实现多线程的并发运行呢?既然要实现切换,那么一方面,我们需要对原来的寄存器进行保存,另外一方面我们还要压入新堆栈的寄存器,这样才能实现线程切换的效果。在x86下面,因为切换线程的ip地址是固定的,所以切换所需要的寄存器也是固定的,一般来说保存eax、ebx、ecx、edx、esi、edi、ebp和esp即可。比如说,像这样,[cpp]viewplaincopy1voidswap(UINT32*prev,UI
2、NT32*next)2{3__asm("push%%eaxt"4"push%%ebxt"5"push%%ecxt"6"push%%edxt"7"push%%esit"8"push%%edit"9"push%%ebpt"10"push%%espt"1112"lea0x8(%%ebp),%%eaxt"13"mov(%%eax),%%eaxt"14"mov%%esp,(%%eax)t"1516"lea0xc(%%ebp),%%eaxt"17"mov(%%
3、eax),%%eaxt"18"mov(%%eax),%%espt"1920"pop%%espt"21"pop%%ebpt"22"pop%%edit"23"pop%%esit"24"pop%%edxt"25"pop%%ecxt"26"pop%%ebxt"27"pop%%eaxt"28::);29}上面说的都是对已经运行的线程进行切换。那么刚刚创建的线程怎么进行切换呢?一个不错的方法就是仿真出栈的处理流程。把初始状态的寄存器放在堆栈里面,模仿线程的出栈过程,设置好
4、线程的初始寄存器数值即可。比如说,像这样,[cpp]viewplaincopy1voidsignal_handler(intm)2{3UINT32*data;4UINT32unit;56if(count!=0)7{8printf("count=%d",count++);9return;10}1112printf("count=%d",count++);13data=(UINT32*)malloc(STACK_LENGTH);14unit=STACK_LENGTH>>2;1516if(NULL==data)17r
5、eturn;1819memset(data,0,STACK_LENGTH);20data[unit-1]=(UINT32)hello;21data[unit-2]=0;22data[unit-3]=0;23data[unit-4]=0;24data[unit-5]=0;25data[unit-6]=0;26data[unit-7]=0;27data[unit-8]=0;28data[unit-9]=0;29data[unit-10]=(UINT32)&data[unit-9];3031new=(UINT32)&data
6、[unit-10];32swap(&old,&new);33free(data);34}最后,我们给出一份完整的代码。在程序收到第一个signal的时候,我们发现代码不仅申请了内存,还初始化成了堆栈的格式,完美地解决了堆栈切换的问题。当然在hello处理结束后,代码又恢复成了原来的格式,而且内存正常释放,一切就像没有发生过一样。试想,如果每一次处理的都是一个function和stack,那基本上就可以模仿线程的运行过程了。[cpp]viewplaincopy1#include2#include7、e.h>3#include4#include5#include67#defineUINT32unsignedint8#defineSTACK_LENGTH1024910staticstructitimervaloldtv;11UINT32old=0;12UINT32new=0;13UINT32count=0;1415voidset_timer()16{17structitimervalitv;18itv.it_interval.tv_sec=1;19itv8、.it_interval.tv_usec=0;20itv.it_value.tv_sec=1;21itv.it_value.tv_usec=0;22setitimer(ITIMER_REAL,&itv,&oldtv);23}2425voidswap(UINT32*prev,UINT32*next)26{27__asm("push%
7、e.h>3#include4#include5#include67#defineUINT32unsignedint8#defineSTACK_LENGTH1024910staticstructitimervaloldtv;11UINT32old=0;12UINT32new=0;13UINT32count=0;1415voidset_timer()16{17structitimervalitv;18itv.it_interval.tv_sec=1;19itv
8、.it_interval.tv_usec=0;20itv.it_value.tv_sec=1;21itv.it_value.tv_usec=0;22setitimer(ITIMER_REAL,&itv,&oldtv);23}2425voidswap(UINT32*prev,UINT32*next)26{27__asm("push%
此文档下载收益归作者所有