kvm線程-001

KVM具有獨立於機器的、可移植的線程模型,可以獨立於Java語言運行.

其變化如下:

1.0之前

使用了一個簡單的循環調度模型,其中系統中的所有活動線程都存儲在循環列表中.

列表中的線程根據每個任務的Java級優先級,一個接一個地執行。在實現級別,線程優先級只是一個整數,它告訴解釋器在下一個線程切換髮生之前,線程可以執行多少原語。在每個字節碼執行之後,線程的“Timeslice”計數器將遞減。當時間片變爲零時,將強制執行線程切換。一些I/O原語也可以啓動線程切換。

1.0

加入了異步(非阻塞)I/O。

另一個目標是引入輕鬆實現替代調度機制的能力,但不太徹底地改變現有系統。

在最初的系統環境中,許多地方發生了切換。現在,它只在解釋器調度循環的頂部完成。在原始版本中,可運行的線程與當前正在執行的線程一起保存在循環列表中。現在,當線程開始執行時,每個線程都會從可運行線程的循環列表中刪除,當線程被阻塞時,會返回到循環列表中。

變量up已重命名爲當前線程,並指向當前正在執行的線程。一個新的變量runnable threads指向可運行線程的循環列表。

suspendThread() 方法有所改變.

它以前有一個要掛起哪個線程的參數,但在任何情況下都不能掛起,所以該參數已被刪除。這個例程用於執行上下文切換,但現在它只將currentThread置零,並調用一個名爲signalTimeToReschedule()的新函數,該函數向解釋器發出信號,表示在執行下一個字節碼之前應該重新調度VM。

爲解釋器提供了一個新的函數istimeToReschedule()來測試這種情況,並調用了一個新的函數reschedule()來測試這種情況。解釋器字節碼調度循環頂部的代碼現在是:

if (isTimeToReshedule()) {
         reschedule();
   }

isTimeToReshedule() 爲宏,宏展開後爲: Timeslice-- == 0.signalTimeToReschedule()也會宏,其只是將Timeslice 設置爲0.

並定義瞭如下方法:

  1. startThread()

    標記線程存活,但是是暫停狀態

  2. resumeThread()

    此函數將線程放回可運行線程列表(runnablethreads),如果激活的線程的優先級高於當前執行的線程的優先級,也將調用signalTimeToReschedule()。

  3. BuildThread()

    現在,這會將所有新線程添加到另一個名爲all threads的活動線程列表中。此列表由垃圾收集器使用。

  4. DismantleThread()

    從AllThreads 中移除

  5. stopThread()

    此函數與buildThread()的邏輯相反。它掛起線程並調用Dismantlethread()。

  6. resumeThread()

    這將替換使用ActivateThread()重新啓動掛起的線程。

  7. isActivated()

    在調用這個例程之前,必須測試currentThread是否爲非空

  8. HandleEvent()

    因爲原始handleEvent例程調用了ActivateThread,所以它不需要任何更改(isActivated()的調用約定除外)。 但是,返回參數的含義現在略有不同,這意味着向runnablethreads添加了一個新線程,而不是它只是切換了上下文。

  9. SwitchThread()

    switchthread現在只從reschedule()調用。當前線程可以指向線程,也可以不指向線程。如果這樣,我們會像以前一樣通過runnablethreads列表旋轉線程。如果它爲空並且runnablethreads列表爲空,則函數返回false,並且reschedule()必須決定要做什麼。

  10. JLT_Yield()

只在signalTimeToReschedule()中調用

此外,還支持了異步i/0.

1.0.3

kvm 1.0.3有一個新的monitor/synchronization實現。


線程模型

在kvm中內部,爲每個線程實例化以下結構之一:

  • THREAD : 是一種內部(VM級)結構,用於存儲獨立於Java級的東西來實現搶佔任務切換的必要信息。活動線程單獨鏈接到包含系統中所有活動線程的線性列表。
  • JAVATHREAD: JAVATHREAD被映射到Java類“Thread.java”中定義的實例結構。它是從線程引用的。

爲什麼定義這兩個結構? 其原因是爲了便於移植,kvm希望保持線程系統實現與Java語言無關。

其中THREAD定義如下:

struct threadQueue {
    THREAD nextAliveThread;  /*  alive線程隊列 */
    THREAD nextThread;       /*  運行或等待線程隊列 */
    JAVATHREAD javaThread;   /*  包含java 級別的線程信息 */
    long   timeslice;        /*  從Java級線程優先級計算而來*/
    STACK stack;             /*   該線程的執行棧*/

    /*
     * 以下四個變量用於在線程可運行時存儲線程的虛擬機寄存器(=active,但不是當前給定的處理器時間)。
     * 爲了方便垃圾收集,我們將指向執行堆棧的指針存儲爲偏移量,而不是實際指針。
     * */
    BYTE* ipStore;           /*   程序計數器*/
    FRAME fpStore;           /*  幀*/
    cell* spStore;           /*  sp*/
    cell* nativeLp;          /* 在KNI的調用中用來訪問本地變量*/

    MONITOR monitor;         /* 當前線程的monitor*/
    short monitor_depth;

    THREAD nextAlarmThread;  /* 在當前隊列中的下一個線程 */
    long   wakeupTime[2];    /*  我們不能要求堆對象的8字節對齊 */
    void (*wakeupCall)(THREAD); /*  線程喚醒時調用 */
    struct {
        int depth;
        long hashCode;
    } extendedLock;          /*  在FASTLOCK時使用*/

    char* pendingException;  /* 線程將要拋出異常的類名 */
    char* exceptionMessage;  /*  要拋出異常的信息 */

    enum {
        THREAD_JUST_BORN = 1,     /* 還沒有啓動 */
        THREAD_ACTIVE = 2,        /* 當前正在運行,或者在等待運行的隊列中 */
        THREAD_SUSPENDED = 4,     /* 等待monitor或者alarm */
        THREAD_DEAD = 8,          /* 線程退出 */
        THREAD_MONITOR_WAIT = 16,
        THREAD_CONVAR_WAIT = 32,
        THREAD_DBG_SUSPENDED = 64
    } state; // 線程狀態定義
    bool_t isPendingInterrupt;    /* Don't perform next sleep or wait */

#if ENABLE_JAVA_DEBUGGER
    bool_t isStepping;      
    bool_t isAtBreakpoint;
    bool_t needEvent;
    CEModPtr debugEvent;

    ByteCode nextOpcode;
    struct singleStep_mod stepInfo;
    int debugSuspendCount; 
#endif /* ENABLE_JAVA_DEBUGGER */

};

JAVATHREAD定義如下:

struct javaThreadStruct {    /* (A true Java object instance) */

    COMMON_OBJECT_INFO(INSTANCE_CLASS)
    long       priority;     /*  線程的優先級*/
    THREAD     VMthread;     /* 執行vm thread  */
    INSTANCE   target;       /* 執行run的對象 */
    SHORTARRAY name;         /*  線程名稱*/
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章