專利名稱:基于操作棧記錄的恢復(fù)的Java線程遷移的方法
技術(shù)領(lǐng)域:
基于操作棧記錄的恢復(fù)的Java線程遷移的方法屬于線程遷移技術(shù)領(lǐng)域,尤其涉及Java線程遷移技術(shù)。
Java線程遷移(Java Thread Migration)指的是,將在我們的系統(tǒng)中運(yùn)行的線程(Thread),以線程(Thread)為最小單位,從正在運(yùn)行的節(jié)點(diǎn)(node)暫停執(zhí)行,將該線程的代碼(code)以及數(shù)據(jù)(data)傳輸?shù)较到y(tǒng)中其他的可運(yùn)行節(jié)點(diǎn),繼續(xù)執(zhí)行的過程。通常,我們所說的透明遷移(transparent migration),指的是,系統(tǒng)在捕捉和恢復(fù)線程的代碼以及數(shù)據(jù)的過程中,沒有外部的介入,這個(gè)外部指的是用戶。
目前,Java線程遷移領(lǐng)域里,由于java虛擬機(jī)沒有相應(yīng)的接口,不能提供給外部程序使其得到正在運(yùn)行的線程的各種狀態(tài),其中包括PC(指令指針)以及操作棧內(nèi)的內(nèi)容,公認(rèn)的可行的方法有兩種第一種直接修改虛擬機(jī)代碼,這樣的處理方法很直接,但是帶來的問題也是很明顯的,這種不透明的處理方法會(huì)產(chǎn)生很嚴(yán)重的兼容性問題,眾所周知,擁有Java虛擬機(jī)版權(quán)的SUNMicrosystems(太陽微系統(tǒng))公司對(duì)版權(quán)問題是很敏感而且很嚴(yán)格控制其版本的。
第二種不涉及到修改虛擬機(jī)的任何代碼,根據(jù)Java代碼的執(zhí)行特點(diǎn),在代碼動(dòng)態(tài)加載的時(shí)候,動(dòng)態(tài)的修改需要執(zhí)行的代碼,在目標(biāo)代碼中增加所需要的代碼段,記錄所需要的環(huán)境變量包括PC(指令指針)的值,同時(shí)利用Java提供的調(diào)試工具JPDA(Java Platform DebugArchitecture Java調(diào)試平臺(tái)體系結(jié)構(gòu)),抽取java虛擬機(jī)中的操作棧中的內(nèi)容。
我們闡述的重點(diǎn)將放在第二種方案,針對(duì)Java線程(Thread)中的PC(Program Counter程序指針計(jì)數(shù)器)值以及Local Variables(局部變量)的恢復(fù),目前有一些研究機(jī)構(gòu)提出了自己的策略,如比利時(shí)的KULEUVEN研究院采用了Java線程序列化策略,以色列技術(shù)學(xué)院采用了重新改裝Java編譯器的策略。我們沿用了利用JPDA捕捉PC以及Local Variables的數(shù)值,采用了Java線程序列化來保存,并利用插入Byte Code(字節(jié)碼)來恢復(fù)這些值的狀態(tài)的方案。
雖然很多研究機(jī)構(gòu)對(duì)上述的兩種PC和Local Varaiables的捕捉和恢復(fù),有很多方案,但是很少提及對(duì)Thread的Operand Stack(操作棧)的捕捉和恢復(fù),并且沒有研究機(jī)構(gòu)能發(fā)表出明確可行的方案,這一點(diǎn)是我們參考的文獻(xiàn)中沒有任何一家研究提到過的。
針對(duì)這個(gè)線程遷移中的重點(diǎn)和難點(diǎn),我們提出了自己的可行方案,實(shí)現(xiàn)了Java Thread線程中的Operand Stack(操作棧)的恢復(fù),我們的策略可以很安全有效地實(shí)現(xiàn)。
使用證明它同時(shí)保證了線程遷移的正確性和Java線程遷移的效率。
Java本質(zhì)上是一種面向堆棧的語言,這種特點(diǎn)決定了,Java里面任何與數(shù)值有關(guān)的操作比如賦值,表達(dá)式的計(jì)算都需要借助棧來完成,而我們的目的是要在目標(biāo)代碼計(jì)算的同時(shí),記錄和保存操作棧中的內(nèi)容,以便于在程序遷移到其他的目標(biāo)節(jié)點(diǎn)的時(shí)候能夠恢復(fù)操作棧的內(nèi)容。
我們針對(duì)不同的程序操作進(jìn)行了不同的處理。第一種賦值操作,我們的策略是將相應(yīng)的代碼段隔離,當(dāng)執(zhí)行到這些隔離代碼段的時(shí)候,不進(jìn)行遷移,這樣也就不用對(duì)操作棧中的內(nèi)容進(jìn)行隔離了。第二種情況是我們需要進(jìn)行操作棧內(nèi)容保存的,在載入目標(biāo)字節(jié)碼的過程中,如果遇到了下面這樣類型的語句賦值、表達(dá)式運(yùn)算(形如以下的表達(dá)式代碼段)x=y(tǒng)+z;我們要插入相應(yīng)的處理代碼。
下面,我們針對(duì)這兩種不同的處理過程,給出兩個(gè)簡(jiǎn)單的例子A)賦值操作的處理。。。。。。。
x=100;//X變量的值設(shè)置成100。。。。。。。
普通匯編的結(jié)果是0bipush100 //常數(shù)100進(jìn)入操作棧(0perand stack)2istore_1//將操作棧頂?shù)臄?shù)值彈出并設(shè)置變量X我們的處理,在該代碼段的前后都插入我們的代碼隔離標(biāo)志,向系統(tǒng)表明,該代碼段不可以打斷,只有執(zhí)行完畢才可以遷移。
處理的結(jié)果的代碼是0 iconst_1//插入的代碼隔離段開始部分標(biāo)志1 istore_2//插入的代碼隔離段開始部分標(biāo)志2 bipush100//原來的代碼段4 istore_1//原來的代碼段5 iconst 0//插入的代碼隔離段結(jié)束部分結(jié)束標(biāo)志6 istore_2//插入的代碼隔離段結(jié)束部分標(biāo)志B)表達(dá)式操作的處理。 。 。 。 。 。 。
×=y(tǒng)+z;//將y,z相加并將結(jié)果賦值給X普通匯編的結(jié)果是8 iload_2 //將變量y的值壓入操作棧9 iload_3 //將變量z的值壓入操作棧10 iadd //將操作棧頂?shù)膬蓚€(gè)值相加并將結(jié)果放入棧頂11 istore_1 //將操作棧頂?shù)臄?shù)值彈出并設(shè)置變量X我們的處理是針對(duì)每一次出棧入棧操作,都用插入相應(yīng)的byte code來記錄相應(yīng)的操作,針對(duì)上面第8條語句就處理成如下結(jié)果26 iconst_1 //插入的代碼隔離段開始部分標(biāo)志27 istore%4 //插入的代碼隔離段開始部分標(biāo)志29 iload_2 //原來的代碼段30 iinc%5 -1 //記錄操作棧中的內(nèi)容計(jì)數(shù)器+133 dup //復(fù)制操作棧頂?shù)膬?nèi)容34 istore%6//彈出并保存操作棧頂?shù)膬?nèi)容到新插入的變量中36 iconst_0 //插入的代碼隔離段結(jié)束部分標(biāo)志37 istore%4 //插入的代碼隔離段結(jié)束部分標(biāo)志經(jīng)過針對(duì)每條語句的類似的處理,結(jié)果的代碼如下//對(duì)第8條語句iload_2的修改26 iconst_1 //插入的代碼隔離段開始部分標(biāo)志27 istore%4 //插入的代碼隔離段開始部分標(biāo)志29 iload_2 //原來的代碼段30 iinc %5 -1 //記錄操作棧中的內(nèi)容計(jì)數(shù)器+1(操作棧為1個(gè)值)33 dup//復(fù)制操作棧頂?shù)膬?nèi)容34 istore%6//彈出并保存操作棧頂?shù)膬?nèi)容到新插入的變量中36 iconst_0 //插入的代碼隔離段結(jié)束部分標(biāo)志37 istore%4//插入的代碼隔離段結(jié)束部分標(biāo)志//對(duì)第9條語句iload_3的修改39 iconst_1 //插入的代碼隔離段開始部分標(biāo)志40 istore%4//插入的代碼隔離段開始部分標(biāo)志42 iload_3//原來的代碼段43 iinc %5 -1 //記錄操作棧中的內(nèi)容計(jì)數(shù)器+1(操作棧為2個(gè)值)46 dup //復(fù)制操作棧頂?shù)膬?nèi)容47 istore%7 //彈出并保存操作棧頂?shù)膬?nèi)容到新插入的變量49 iconst_0 //插入的代碼隔離段結(jié)束部分標(biāo)志50 istore%4//插入的代碼隔離段結(jié)束部分標(biāo)志//對(duì)第10條語句iadd的修改52 iconst_1//插入的代碼隔離段開始部分標(biāo)志53 istore%4//插入的代碼隔離段開始部分標(biāo)志55 iadd //原來的代碼段56 iinc%5 1 //記錄操作棧中的內(nèi)容計(jì)數(shù)器-1(此時(shí)操作棧數(shù)為1)59 dup //復(fù)制操作棧頂?shù)膬?nèi)容60 istore%6//彈出并保存操作棧頂?shù)膬?nèi)容到新插入的變量62 iconst_0//插入的代碼隔離段結(jié)束部分標(biāo)志63 istore%4 //插入的代碼隔離段結(jié)束部分標(biāo)志//對(duì)第11條語句istore_1的修改65 iconst_1//插入的代碼隔離段開始部分標(biāo)志66 istore%4//插入的代碼隔離段開始部分標(biāo)志68 istore_1 //原來的代碼段69 iinc%5 1 //記錄操作棧中的內(nèi)容計(jì)數(shù)器-1(此時(shí)操作棧為空)
72 iconst_0//插入的代碼隔離段結(jié)束部分標(biāo)志73 istore%4//插入的代碼隔離段結(jié)束部分標(biāo)志綜上所述,針對(duì)我們的目標(biāo),保證Java線程遷移的過程中的棧能夠被正確的恢復(fù),同時(shí)考慮到遷移過程中的效率問題,我們采用的策略是分析目標(biāo)代碼的類型,采用了對(duì)賦值表達(dá)式利用類似數(shù)據(jù)庫中的事務(wù)處理(transention)進(jìn)行隔離,也就是說把賦值表達(dá)式的目標(biāo)代碼看作一個(gè)整體,進(jìn)行原子操作。而同時(shí)針對(duì)Java線程中的表達(dá)式操作,我們則采用了上面所描述的方法,同時(shí)上面也展示了被我們的策略修改前和修改之后的目標(biāo)代碼。
經(jīng)過測(cè)試,我們的策略能夠保證Java線程在遷移過程棧能夠正確的恢復(fù),從而保證了線程遷移的正確性,同時(shí)我們的策略也保證了Java線程遷移的效率。
相應(yīng)的一般性的程序流程框圖見
圖1。
首先,需要指出和說明的是,本文中的算法采用的機(jī)制是對(duì)透明的算法,這里透明的含義是指,本文上面流程中闡述的,針對(duì)用戶提交程序遷移的過程中所需要的,捕捉用戶程序的程序指針,程序的變量的數(shù)值,和用戶程序操作棧的內(nèi)容,并且在目標(biāo)代碼遷移到目標(biāo)代碼之后,針對(duì)用戶程序指針,程序的變量的數(shù)值,和用戶程序操作棧的內(nèi)容的恢復(fù)工作,所有的上面的工作,都是在用戶透明的情況下進(jìn)行的,也就是說,用戶不需要對(duì)上面所闡述的種種工作進(jìn)行參與和操作,這些工作都是由,元計(jì)算系統(tǒng)中的線程遷移模塊來完成的。
因此,鑒于上面的闡述,擁有本文中的所描述的線程遷移的算法的元計(jì)算系統(tǒng)中,如果需要遷移用戶提交的任務(wù)到目標(biāo)節(jié)點(diǎn),用戶無需做出額外的動(dòng)作。
權(quán)利要求
1.基于操作棧紀(jì)錄的恢復(fù)的Java線程遷移的方法,其特征在于它通過動(dòng)態(tài)地解釋載入的字節(jié)碼,使得在載入目標(biāo)字節(jié)碼的同時(shí),動(dòng)態(tài)地修改載入的目標(biāo)字節(jié)碼;它對(duì)下述不同的程序操作進(jìn)行不同的處理(1).賦值操作把相應(yīng)的代碼段隔離,以便當(dāng)執(zhí)行到這些隔離代碼段時(shí)去阻止遷移,以此代替對(duì)操作棧中的內(nèi)容進(jìn)行隔離;(2).操作棧內(nèi)容保存的操作在載入目標(biāo)字節(jié)碼的過程中,插入相應(yīng)的處理代碼,及時(shí)對(duì)每一次出棧入棧的操作,都用插入相應(yīng)的字節(jié)碼的方法來記錄相應(yīng)的操作。
全文摘要
基于操作棧記錄與恢復(fù)的Java線程遷移的方法屬于線程遷移技術(shù)領(lǐng)域,其特征在于它通過動(dòng)態(tài)的解釋載入的字節(jié)碼,使得在載入目標(biāo)字節(jié)碼的同時(shí),動(dòng)態(tài)地修改插入的目標(biāo)字節(jié)碼。對(duì)于賦值操作,它把相應(yīng)的代碼段隔離,以此代替對(duì)操作棧中的內(nèi)容進(jìn)行隔離;對(duì)于保存操作棧內(nèi)容的操作,針對(duì)每一次出棧入棧的操作,都用插入相應(yīng)的字節(jié)碼的方法來記錄相應(yīng)的操作,它操作安全效率也高。
文檔編號(hào)G06F9/45GK1438576SQ0312103
公開日2003年8月27日 申請(qǐng)日期2003年3月21日 優(yōu)先權(quán)日2003年3月21日
發(fā)明者楊廣文, 馬聰鵬, 陳明 申請(qǐng)人:清華大學(xué)