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