专利名称:保存多个执行上下文的方法和装置的制作方法
技术领域:
本发明实施例的方面涉及执行与两个或两个以上线程相关联的指令的领域,具体而言,本发明实施例的方面涉及保存与那些线程相关联的执行上下文。
背景技术:
在单任务操作系统中,通常在单任务操作环境中每次允许执行一个线程。
图1说明了在单任务操作环境中传统函数调用如何工作。该系统包括调用程序函数、被调用程序函数以及与被调用程序函数和调用程序函数中的数据(如数据和参数)相关联的公共堆栈。将项(如数据,参数等)加入堆栈中称为压栈。从堆栈中移出项称为弹出。应用程序执行指令。公共堆栈保存与执行的指令相关联的数据。指令之一可为函数调用。在传统函数调用中,在阶段1结束时,当调用被调用程序函数时,调用程序函数会将控制传递给被调用程序函数。被调用程序函数将其执行上下文放入堆栈。被调用程序函数的执行上下文被置于调用程序函数执行上下文之上。当被调用程序函数完成与该函数相关联的全部指令时,调用程序函数收回控制,如图1中阶段2所指示的。在被调用程序函数已完成其全部指令的处理时,被调用程序函数负责将控制返回调用程序函数。在阶段3,调用程序函数然后重新开始与调用程序函数相关联的指令的执行并完成与调用程序函数相关联的剩余的指令。
图1还说明了堆栈中的执行上下文在不同阶段的改变。该系统保存公共堆栈的一组执行上下文。调用程序函数和被调用程序函数能共享公共堆栈来保存它们的堆栈框架。在阶段2,执行被调用程序函数中的指令。在公共堆栈中,被调用程序函数的执行上下文被堆在调用程序函数的执行上下文之上。与公共堆栈相关联的单个堆栈指针通常指向被放在堆栈顶部的项。在传统函数调用中,被调用程序函数有效阻塞其调用程序函数直到被调用程序函数执行完其全部指令。
本发明的实施例参照如下附图图1说明了在单任务操作环境中传统函数调用如何工作。
图2说明了在任何给定时间点只能执行一个线程的操作环境中运行的多个执行上下文例程的实施例的示意图。
图3a和3b说明了在给定时间点只能执行一个线程的操作环境中允许两个或两个以上线程同时操作的多个执行上下文例程的实施例的流程图。
图4说明了一示范性计算机系统的框图,该系统可使用例程的实施例使用堆栈切换同时保存线程的两个或两个以上执行上下文。
虽然会对本发明进行各种更改和选择形式,但是其中特定实施例通过附图中的例子进行了描述并将在本文中详细描述。本发明的实施例应不应被理解成限于公开的特定形式,而是相反,本发明要覆盖落入本发明精神和范围内的所有更改、等同和可选形式。
具体实施例方式
在下面描述中,为提供对本发明实施例的充分理解,说明了大量特定细节,如称为组件的特定函数的例子等。然而,本领域技术人员显见,本发明的实施例能在没有这些特定细节的条件下实施。此外,特定数字参照不应被解释为字面上的顺序,而是应解释为第一线程不同于第二线程。因此,所说明的特定细节只是示范性的。特定细节可根据本发明的精神和范围进行改变,并且仍被认为是在本发明精神和范围内。
总之,对实现多个执行上下文例程的各种方法和装置进行了描述。在给定时间点只能执行一个线程的执行环境中,多个执行上下文例程使用堆栈切换同时保存线程的两个或两个以上执行上下文。被调用程序线程可显式地挂起其指令的执行。当执行调用程序线程中的指令时,多个执行上下文例程仍保存包含被调用程序堆栈的指针的返回地址位置的执行上下文。
图2说明了在任何给定时间点只能执行一个线程的操作环境中运行的多个执行上下文例程的实施例的示意图。系统包括调用程序线程202、被调用程序线程204以及专用于存储调用程序线程202的第一执行上下文的第一存储区、专用于存储被调用程序线程204的第一执行上下文的第二存储区。第一存储区是调用程序堆栈206。第二存储区是被调用程序堆栈208。
被调用程序线程204和调用程序线程202可利用嵌入在固件中的以软件、以有限状态机的逻辑或其他类似机制实现的例程。注意,在下面描述中,将使用以软件实现的例程来帮助理解该例程。在给定时间点只能执行一个线程的操作环境中,该例程使用堆栈切换同时保存线程的两个或两个以上执行上下文。被调用程序线程204可显式地挂起其指令的执行。当执行调用程序线程202中的指令时,多个执行上下文例程仍保存包含被调用程序堆栈208的指针的返回地址位置的执行上下文。同样,调用程序线程202可显式地挂起其指令的执行。当执行被调用程序线程204中的指令时,多个执行上下文例程仍保存包含调用程序堆栈206的指针的返回地址位置的执行上下文。
线程可为由CPU(中央处理器),ASIC(专用集成电路)或类似的处理设备顺序执行的、以便完成任务或任务的至少特定方面的指令序列。两个或两个以上线程可协作完成单个任务。任务的独立性和完成任务的各个方面的独立性是多任务操作系统中的关键。
因此,调用程序线程202和被调用程序线程204可合作单个任务,但负责该任务不同的不同部分。调用程序线程202和被调用程序线程204还可各自实现单独的任务。无论何时只要线程发起对其他线程的调用,则发起该调用的线程挂起其指令的执行。
例程分配第一存储区作为调用程序线程202的调用程序堆栈206。当执行调用程序线程202中的指令时,该例程将调用程序线程202的第一执行上下文存储在调用程序堆栈206中。所存储的调用程序线程的执行上下文可包含数据,如调用程序的本地数据、需要传到被调用程序的参数、和与调用程序堆栈206相关联的指针的返回地址。应用软件在执行指令时可将该指针与调用程序线程202一起使用。调用程序线程202中的指令可能到达一点,在该点调用程序线程202希望挂起并显式地放弃指令的执行。调用程序线程202可能希望与另一线程进行通信,或调用程序线程202知道它将空闲很长一段时间来等待对具有很长响应时间的请求的响应等。当调用程序线程202调用被调用程序线程204时,调用程序线程202挂起并显式地放弃调用程序堆栈206中的指令的执行。该例程然后存储调用程序线程202的包括调用程序堆栈206中的当前指针的地址的执行上下文。
在时刻2,该例程分配第二存储区作为被调用程序线程204的被调用程序堆栈208。当执行被调用程序线程204中的指令时,该例程将被调用程序线程204的第二执行上下文存储在被调用程序堆栈208中。所存储的被调用程序线程的执行上下文可包含数据,如被调用程序的本地数据、需要传递到调用程序的参数、和与调用程序堆栈206相关联的指针的返回地址。应用软件可在执行指令时将调用程序的执行上下文上的指针与被调用程序线程204一起使用。
在该时间点,在给定时间点只能执行一个线程能的操作环境中,该例程同时保存被调用程序线程204和调用程序线程202的执行上下文(包括这两个堆栈上的指针的地址)。当应用软件使用活动的被调用程序堆栈208上的指针的位置时,非活动的调用程序堆栈206上的指针210的地址被存储。硬件寄存器可用于存储当前活动的堆栈的指针的地址位置。
因此,当堆栈切换发生时,该例程将应用软件指引到当前存储的执行上下文。应用询问硬件寄存器来确定指针位于堆栈上的什么位置。该例程控制什么地址存储在该硬件寄存器中。
该例程允许多个任务以及单个任务的多个方面同时运行在单任务操作环境中。然而,在任何给定时间点,在执行线程中的指令时仅活动地操纵一个堆栈,而另一个堆栈只简单地保存所存储的与另一个线程相关联的执行上下文。此外,与被调用程序线程相关联的被调用程序堆栈中执行上下文的存储独立于与调用程序线程相关联的调用程序堆栈中执行上下文的存储,因为这两个执行上下文被保存在单独的存储区中。将两个或两个以上执行上下文保存在单独的存储区中消除了执行上下文中一个堆在另一个之上的情况并自动改变指针的位置。
堆栈可为一组硬件寄存器或用于跟踪内部操作的保留的一定量的存储器。堆栈通常以后进先出(LIFO)的方式操作,该方式使压入堆栈的最后一组数据成为最先从堆栈中弹出的一组数据。
被调用程序线程204可在指令执行时到达一点,在该点,被调用程序线程204希望与另一线程进行通信,或由于某种其他原因放弃执行其指令。在时刻3,例程恢复所存储的执行上下文和调用程序堆栈206上的指针位置,同时被调用程序线程204挂起其指令的执行。例程通过将应用软件切换到其他线程指令和存储的上下文来恢复所存储的执行上下文。该例程将硬件寄存器中存储的指针的地址改变为调用程序线程的指针地址。调用程序线程202从当调用程序线程202显式地挂起其指令执行时指针停在的地址处开始执行指令。
该例程允许执行的指令的挂起和线程之间的执行上下文堆栈切换,直到全部线程已完成所有与那些线程相关联的指令的执行。此外,在完成与被调用程序线程204相关联的所有指令之前,该例程恢复所存储的调用程序线程202的执行上下文和调用程序堆栈206上的指针位置。当被调用程序线程显式地将控制返还给调用程序线程202时,该例程恢复所存储的调用程序线程202的执行上下文和调用程序堆栈206上的指针位置。
当协作完成单个任务的不同部分时,被调用程序线程204和调用程序线程202可使用执行指令的挂起和堆栈切换来同步。各线程能独立于该单任务环境中其他线程的完成来开始或关闭。除了线程有时用函数调来显式地放弃指令的控制和执行之外,各线程执行指令就如同该线程是唯一在该系统中执行的线程一样。该例程允许所有线程在互不影响指令执行顺序或与那些指令相关联的执行上下文的情况下同时运行。
该例程用堆栈切换来保存多个执行上下文,这使多个线程能够在单线程环境中同时保存。
总之,被调用程序线程204能在某点将自身显式地挂起并稍后由调用程序线程202重新开始。一另外的堆栈专用于存储各新的被调用程序线程204的执行上下文以避免线程之间的干扰。同样,调用程序线程202能在某点将自身显式地挂起并稍后由被调用程序线程204重新开始。
下面是例程的实现堆栈切换功能的伪码。
typedef struct_EXEC_CTXjmp_buf*retCtx;jmp_buf threadCtx;unsigned long*stack;}EXEC_CTX;//ExecCtx是指向EXEC_CTX结构的指针//EntryPoint是指向线程入口函数(对应于下面伪码中的MAIN函数)
的指针//Arg是传递到EntryPoint的参数(其对应于下面伪码中的Command函数)Function StartExecCtx(ExecCtx,EntryPoint,Arg){SuspendExecCtx(ExecCtx);(*EntryPoint)(Arg);longjmp(Exec->retCtx,2);//返回调度程序}Function InitExecCtx(ExecCtx,EntryPoint,Arg)jmp_buf thisCtx;ExecCtx->stack=malloc(STACK_SIZE);//分配线程的堆栈ExecCtx->retCtx=&thisCtx;if(!setjmp(ExecCtx->retCtx))_asm mov esp,stack+STACK_SIZE;//这里切换到新堆栈StartExecCtx(ExecCtx,EntryPoint,Arg);}}Function RunExecCtx(ExecCtx){jmp)buf thisCtx;ExecCtx->retCtx=&thisCtx;switch(setjmp(ExecCtx->retCtx))case 0:
longimp(&ExecCtx->threadCtx,1);//切换到线程case 1: return false;//EntryPoint尚未完成case 2: return ture;//EntryPoint已完成}}Function ReleaseExecCtx(ExecCtx)
free(ExecCtx->stack);}Function SuspendExecCtx(ExecCtx){if(!setjmp(&ExecCtx->thread))longjmp(ExecCtx->retCtx,1);//切换到调度程序}setjmp、longjmp、malloc和free是由大多数编译程序提供的标准C程序设计语言函数。函数调用是试图与另一子例程、线程或程序通信或从另一子例程、线程或程序请求服务的语句。通过分支指令或由汇编程序、编译程序或解释程序创建的某些其他连接方法物理进行对线程的调用。
setjmp()函数将其堆栈环境保存在参数中以供稍后由longjmp()函数使用。longjmp()函数用对应的参数来恢复由setjmp()函数的上一次调用所保存的环境。在longjmp()函数完成后,程序执行继续,就象对setjmp()函数的对应调用刚返回值val一样。在从setjmp()函数返回的时刻,所有外部和静态数据变量具有longjmp()函数被调用时的值。longjmp()函数完成后,程序执行继续,就象setjmp()函数的对应启用刚返回由val表示的值一样。
malloc()和free()函数提供了简单通用的存储器分配包。malloc()函数返回指向适于堆栈排列的至少字节大小的存储器块的指针。free()函数的参数是指向之前由malloc()函数分配的块的指针。在执行free()函数后,该空间可供线程进行另外的分配,尽管没有返还给系统。在线程一终止执行,就将存储器返还给系统。
InitExecCtx是内联汇编程序函数,该函数允许直接操作堆栈指针。InitExecCtx可全部用汇编程序编写以避免非预期结果。术语“线程”指在伪码中定义的执行上下文。术语“调度”指调用InitExecCtx函数和RunExecCtx函数来运行该“线程”的代码。
下面是例程和对应的伪码的示范性应用。
客户机可扩展固件接口(EFI)代理是运行在客户机预启动阶段的EFI应用。代理的任务是接收来自服务器的命令并依次执行这些命令。当执行一命令时,该代理应及时向服务器报告进度,否则该客户机将被认为失效。
代理可在逻辑上分成两个或两个以上线程部分,称为“核心”和“单元”。核心的任务是接收来自服务器的命令,将接收的命令分派给合适的单元,并将单元的进度报告给服务器。“单元”是能完成特定任务的一组函数。为了精确,各单元提供给该核心如下四个函数以供调用“support”,“init”, “exec”和“final”。下面的伪码说明了该核心如何找到合适的单元并执行该命令。
Unit=getNextUnit(NULL);//获得第一登记的单元while(Unit!=NULL){if(Unit->Support(Command)){Unit->Init(Command);//找到合适的单元,调用Initwhile(!Unit->Exec(Command))//对Exec进行需要次数的调用ReportCommandProgress(Command);Unit->Final(Command);//调用FinalReportCommandDone(Command);//告诉服务器该命令完成break;}Unit=getNextUnit(Unit);}单元的伪码如下。
Function Main(Command){//将单元做什么设置在产生明确输出的该函数中...
SuspendExecCtx(ExecCtx);//显式地放弃执行
...//继续处理SuspendExecCtx(ExecCtx);//再次放弃执行...
}Function Init(Command){InitExecCtx(ExecCtx,Main,Command);//初始化执行上下文}Function Exec(Command)return RunExecCtx(ExecCtx);//重新开始执行Main}Function Final(Command)ReleaseExecCtx(ExecCtx);//清除}该例程的SuspendExecCtx、InitExecCtx、RunExecCtx和ReleaseExecCtx函数实现了任务的独立性。函数Main实现单元的逻辑。函数Main可被编码为具有一些对SuspendExecCtx函数的插入调用的普通函数。开发者能在一段中保存该逻辑而不是必需将逻辑分成多个段。为了说明的目的,SuspendExecCtx函数在Main函数中出现两次。实际上,对SuspendExecCtx函数可出现的位置和次数没有限制。SuspendExecCtx函数还可出现在除了Main函数之外的其他函数中,但应由Main函数直接或间接调用。应在对给定执行上下文对象执行任何其他操作执行之前调用InitExecCtx函数。可通过调用SuspendExecCtx函数来挂起执行上下文对象。该执行上下文对象然后处于挂起状态并且在返回运行状态前不能再被挂起。该执行上下文对象可通过调用RunExecCtx函数再次运行。该执行上下文对象处于运行状态并且不能在返回挂起状态之前再次运行。前面列出的堆栈伪码还在SuspendExecCtx、InitExecCtx、RunExecCtx和ReleaseExecCtx函数的实现细节方面进行了详细阐述。
图3a和3b说明了在给定时间点只能执行一个线程的操作环境中允许两个或两个以上线程同时操作的多个执行上下文例程的实施例的流程图。
在步骤302,多个执行上下文例程分配第一存储区作为调用程序线程的堆栈。第一存储区成为专用于存储调用程序线程的执行上下文的堆栈,即调用程序堆栈。
在步骤306,应用软件开始调用程序线程中的指令的执行。
在步骤308,多个执行上下文例程保存与其指令被执行的调用程序线程相关联的执行上下文。所存储的调用程序线程的执行上下文可包含数据,如调用程序的本地数据、需要传递到被调用程序的参数和与调用程序堆栈相关联的指针的当前地址。
在步骤310,调用程序线程调用另一线程、即被调用程序线程来显式地放弃指令的执行。调用程序线程挂起执行的指令并显式地放弃指令执行控制。调用程序线程和被调用程序线程可合作单个任务但负责该任务的不同部分。无论何时一线程发起对另一线程的调用,发起该调用的线程挂起其指令的执行。调用程序线程挂起指令的执行,因为调用程序线程可能等待对请求的长响应时段,等待与其他线程同步,或其他类似的空闲时段。
过程是执行特定任务程序的程序段。过程可为线程。因此,无论何时合作一个任务但负责该任务的不同部分的过程需要互相通信,这些过程将挂起它们自己,并将放弃系统控制,然后让另一个过程继续运行。
在步骤312,多个执行上下文例程存储调用程序堆栈中的指针的当前地址以及与调用程序线程相关联的执行上下文。所存储的执行上下文包括在切换点调用程序堆栈中的指针的返回地址。
在步骤314,多个执行上下文例程分配第二存储区作为被调用程序线程的堆栈。第二存储区成为专用于存储被调用程序线程的执行上下文的堆栈,即被调用程序堆栈。
在步骤318,多个执行上下文例程将应用软件从调用程序线程中执行的指令切换到被调用程序线程中执行的指令。多个执行上下文例程也将应用软件切换到使用存储在被调用程序堆栈中的执行上下文。
在步骤320,应用软件开始被调用程序线程中的指令的执行。
在步骤322,多个执行上下文例程保存与其指令被执行的被调用程序线程相关联的执行上下文。从而,在给定时间点只能执行一个线程的操作环境中,该系统使用堆栈切换同时保存线程的两个或两个以上执行上下文。例程挂起与调用程序线程相关联的指令的执行,并在执行与调用程序线程相关联的指令时仍保存包括返回地址位置(被调用程序堆栈上的指针地址)的执行上下文。
在步骤324,通过挂起被调用程序线程中指令的执行或通过完成被调用程序线程中的所有指令,被调用程序线程停止执行的指令。
在步骤326,被调用程序线程放弃对指令的执行的控制,返回调用程序线程。被调用程序线程调用调用程序线程来放弃对指令执行的控制,返回调用程序线程。在有些情况下,两个或两个以上线程有时需要完成单个任务。因此,现在各线程能独立于与其他线程相关联的指令的完成来开始或关闭。
在步骤328,多个执行上下文例程初始化来恢复所存储的执行上下文和调用程序堆栈上的指针位置。
在步骤330,多个执行上下文例程将应用软件指引到重新开始执行调用程序线程中的指令。从而,多个任务能相互独立地开始或关闭,然而,与在某些多任务操作环境中一样,运行在该操作环境中的任务不在相同时刻运行,而是在同一时间段内同时运行。使用堆栈切换的例程可以是用于需要在单线程环境中并行操作的任务的解决方案。
在步骤332,多个执行上下文例程继续执行的指令和执行上下文堆栈切换的挂起,直到这两个线程都完成了执行与那些线程相关联的所有指令。具有多个执行上下文例程的应用软件允许称为线程的一个或多个程序的不同部分来同时执行。多个执行上下文例程允许线程在基本上不互相影响指令执行顺序或执行上下文的条件下于相同的时间段运行。
在步骤334,在一些实施例中,当运行预启动应用程序或装载操作系统软件的启动操作时,多个执行上下文例程执行执行的指令和堆栈切换的挂起。当运行预启动应用程序或装载操作系统软件的启动操作时,多个执行上下文例程可被嵌入到固件中,使得可利用多个同时任务的运行。
多个执行上下文例程可在单任务操作环境(如启动和预启动操作环境)中来实现,以达到如在多任务环境中看到的任务的并行性和灵活性。该例程可存储在嵌入固件中的基础代码中。
图4说明了示范性计算机系统的框图,该系统可使用例程的实施例使用堆栈切换同时保存线程的两个或两个以上执行上下文。在一实施例中,计算机系统400包括用于传送信息的通信机构或总线411、和与总线411连接的用于处理信息的集成电路部件(如处理器412)。计算机系统400中部件或设备中的一个或多个(如处理器412或芯片组436)可使用该例程的实施例来同时运行多个任务。
计算机系统400还包括连接到总线411的用于存储信息和要由处理器412执行的指令的随机存取存储器(RAM)或其他动态存储设备404(称为主存)。主存404还可用于存储在处理器412执行指令期间的临时变量或其他中间信息。
固件403可为软件和硬件的结合,如具有记录在EPROM上的例程的操作的电可编程只读存储器(EPROM)。固件403可嵌入基础代码、基本输入/输出系统代码(BIOS)或其他类似的代码。固件403使计算机系统400的自身启动成为可能。计算机开始工作称为启动,这包括装载操作系统和其他基本软件。固件403可为可扩展固件接口(EFI)。EFI提供对操作系统及其装载程序可用的启动和运行时服务调用。这为启动操作系统和运行预启动应用程序提供了标准的环境。
计算机系统400还包括连接到总线411用于存储静态信息和用于处理器412的指令的只读存储器(ROM)和/或其他静态存储设备406。
计算机系统400还可连接到显示设备421,如阴极射线管(CRT)或液晶显示器(LCD),显示设备连接到总线411用于显示信息给计算机用户。文字数字输入设备(键盘)422,包括文字数字和其他键,也可被连接到总线411用于传送信息和命令选择给处理器412。一种另外的用户输入设备是光标控制设备423,如鼠标、跟踪球、轨迹板、指示笔或光标方向键,所述光标控制设备连接到总线411来将方向信息和命令选择传送到处理器412并控制显示设备421上的光标移动。
可连接到总线411的另一设备是硬拷贝设备424,它可用于在介质(如纸、薄膜或类似形式的介质)上印刷指令、数据或其它信息。此外,声音录制和回放设备(如扬声器和/或麦克风(图中未显示)可选地连接到总线411来与计算机系统400用音频接口连接。连接到总线411的另一设备可为有线/无线通信能力425。
在一实施例中,软件用于使例程能更容易地嵌入到机器可读介质上。机器可读介质包括提供(即,存储和/或传输)以机器(例如,计算机、网络设备、个人数字助理、制造工具、任何具有一个或多个处理器组的设备等)可访问形式的信息的任何机构。例如,机器可读介质包括可记录/不可记录介质(例如,包括固件的只读存储器(ROM)、随机存取存储器(RAM)、磁盘存储介质、光存储器介质、闪存设备等),以及电、光、声或其它形式的传播信号(例如,载波、红外线信号、数字信号等)等。
虽然已对本发明的一些特定实施例进行了说明,但是本发明不限于这些实施例。例如,用软件代码执行的操作可同样用配置成在有限状态机中执行那些操作的逻辑电路来实现。上面在EFI代理中讨论的示范性通信线程能作为主线程来实现。主线程响应服务器发出的进度查询。各工作者线程将内部状态视为输入,进行一些操作,更新其内部状态并在输出中告诉通信线程它的进度。无论何时返回由工作线程提供的函数,通信线程保持调用工作线程并响应服务器查询。所有工作者线程能共享同一通信线程。工作线程和通信线程能与该例程保存独立。本发明要被理解成不限于本文描述的特定实施例,其范围只由附加的权利要求来确定。
权利要求
1.一种方法,包括在给定时间点只能执行一个线程的操作环境中使用堆栈切换同时保存线程的两个或两个以上执行上下文;以及当执行调用程序线程中的指令时,挂起被调用程序线程中的指令的执行并仍保存包括被调用程序堆栈的指针的返回地址位置的执行上下文。
2.如权利要求1所述的方法,还包括在所述调用程序线程完成其全部指令的执行之前,挂起所述调用程序线程中的指令的执行并将对指令的执行的控制返还给所述被调用程序线程。
3.如权利要求1所述的方法,其中所述调用程序线程和所述被调用程序线程合作单个任务但负责所述任务的不同部分,并且无论何时所述线程发起对另一线程的调用,发起所述调用的线程挂起其指令的执行。
4.一种计算机可读介质,所述介质存储使机器执行如权利要求1所述的方法的指令。
5.一种有限状态机,所述有限状态机具有配置为实现如权利要求1所述的方法的逻辑。
6.如权利要求1所述的方法,还包括当运行预启动应用程序时,执行如权利要求1所述的方法。
7.如权利要求1所述的方法,还包括在装载操作系统软件的启动操作期间,执行如权利要求1所述的方法。
8.一种存储使机器执行如下操作的指令的计算机可读介质,包括当第一线程调用第二线程时,挂起并显式地放弃第一线程中的指令的执行;以及当执行第二线程中的指令时,存储第一线程的包括数据、参数和第一堆栈上的指针的地址的执行上下文。
9.如权利要求8所述的制品,其中第一线程是被调用程序线程,而第一堆栈专用于存储所述被调用程序线程的执行上下文。
10.如权利要求8所述的制品,其中所述存储和所述挂起发生在在给定时间点只能执行一个线程的操作环境中。
11.如权利要求8所述的制品,其中所述计算机可读介质存储使机器执行如下操作的额外指令,包括分配第一存储区作为调用程序线程的堆栈,其中所述第一存储区专用于存储所述调用程序线程的第一执行上下文;以及分配第二存储区作为被调用程序线程的堆栈,其中所述第二存储区专用于存储所述被调用程序线程的第二执行上下文。
12.如权利要求9所述的制品,其中所述计算机可读介质存储使机器执行如下操作的额外指令,包括在给定时间点只能执行一个线程的操作环境中,同时保存所述被调用程序线程和第二线程的包括两个堆栈上的指针的地址的执行上下文。
13.如权利要求9所述的制品,其中所述计算机可读介质存储使机器执行如下操作的额外指令,包括当第二线程挂起其指令的执行时,恢复所存储的执行上下文和所述被调用程序堆栈上的指针位置。
14.如权利要求9所述的制品,其中所述计算机可读介质是固件。
15.如权利要求9所述的制品,其中所述计算机可读介质存储使机器执行如下操作的额外指令,包括将应用软件从使用第二堆栈中的执行上下文切换到使用第一堆栈中的执行上下文。
16.如权利要求9所述的制品,其中与所述被调用程序线程相关联的第一堆栈中执行上下文的存储独立于与所述调用程序线程相关联的第二堆栈中执行上下文的存储。
17.如权利要求9所述的制品,其中所述被调用程序线程和第二线程合作单个任务但负责所述任务的不同部分。
18.一种系统,包括第一存储区,专用于存储第一线程的第一执行上下文;第二存储区,专用于存储第二线程的第二执行上下文;以及嵌入有例程的固件,用于指引存储第一线程的包括第一存储区上的指针的地址的执行上下文,在第一线程发起对第二线程的调用时发起第二线程中的指令的执行,并且指引存储第二线程的包括第二存储区上的指针的地址的执行上下文。
19.如权利要求18所述的系统,其中嵌入有所述例程的固件还在与第二线程相关联的全部指令的完成之前,恢复所存储的第一线程的执行上下文和第一存储区上的指针位置。
20.如权利要求18所述的系统,还包括与所述固件协同工作的处理器。
全文摘要
一种方法、装置和系统,其中在给定时间点只能执行一个线程的操作环境中使用堆栈切换同时保存线程的两个或两个以上执行上下文。当调用程序线程中的指令被执行时,被调用程序线程中的指令的执行被挂起,并且包括被调用程序堆栈的指针的返回地址位置的执行上下文被保存。
文档编号G06F12/00GK101091166SQ200480044782
公开日2007年12月19日 申请日期2004年12月30日 优先权日2004年12月30日
发明者B·邢, Y·程 申请人:英特尔公司