Threadx 線程調度

Threadx os 線程調度方法:
1,基於優先級的調度,高優先級線程搶佔低優先級線程
2,同一優先級線程可以採用基於時間片輪轉調度方式
3,線程主動掛起,其他線程獲得調度執行
幾種方式同時採用,聯合進行線程調度。
通過創建線程時設置時間片爲0,可以禁止基於時間片輪轉調度。

基於優先級搶佔調度

通過中斷或消息驅動進行調度。
1,高優先級線程搶佔低優先級線程
2,只要有高優先級線程執行,低優先級線程無法執行
3,高優先級線程可以主動掛起,低優先級線程恢復執行
4,系統中所有線程優先級相同,需要執行線程主動掛起,下一就緒線程纔有機會得到調度執行。
舉例:
1,線程a執行,發送消息給線程b,線程b優先級高,保證實時性,線程b立即搶佔線程a,獲得處理器執行
2,線程b執行過程中,發生硬件中斷,進行中斷處理。中斷處理中喚醒了線程c。
3,中斷處理完成返回時,由於線程c優先級最高,切換到線程c執行。
4,線程c處理完,主動掛起,由於之前線程b被搶佔,並且是系統中優先級最高線程,線程b獲取執行權限。
5,線程b給線程a發送消息,這是線程a並沒有立即執行。因爲線程a優先級低於線程b。
6,線程b處理完,主動掛起。線程a成爲系統中優先級最高線程,切換到線程a執行。

在這裏插入圖片描述## 基於時間片輪轉調度方式
針對相同優先級線程進行調度,需要時鐘中斷進行驅動。一般設置週期性定時器,中斷處理時,計算執行線程時間片是否用盡,如果時間片用盡,切換到下一個線程執行。相當於相同優先級幾個線程平均分配處理器資源。

在這裏插入圖片描述

VOID   _tx_timer_interrupt(VOID)
{
    _tx_timer_system_clock++;                                           /*  系統滴答時間加              */
    if (_tx_timer_time_slice) {                                         /*  如果有剩餘的時間片          */
		_tx_timer_time_slice--;                                         /*  時間片調整、減一            */
		if (_tx_timer_time_slice == 0) {                                /*  如果當前時間片耗盡          */
			_tx_timer_expired_time_slice =  TX_TRUE;                    /*  設置標識                    */
		}
    }

    if (*_tx_timer_current_ptr) {                                       /*  是否有定時器需要處理        */
        _tx_timer_expired =  TX_TRUE;
    } else {
        _tx_timer_current_ptr++;                                        /*  指向下一時刻定時器就緒鏈表頭*/
        if (_tx_timer_current_ptr == _tx_timer_list_end){
            _tx_timer_current_ptr =  _tx_timer_list_start;
		}
    }

    if ((_tx_timer_expired_time_slice) || (_tx_timer_expired)) {        /*  有事情要做                  */
		if (_tx_timer_expired) {
		    _tx_timer_expired   = TX_FALSE;
			_tx_thread_preempt_disable++;
	
			_tx_thread_resume(&_tx_timer_thread);                       /*  回覆定時器線程              */
		}
		/* 時間片用盡 */
		if (_tx_timer_expired_time_slice) {
    		_tx_timer_expired_time_slice    = TX_FALSE;
			if (_tx_thread_time_slice() == TX_FALSE) {                  /*  不需要切換,載入分配的時間片*/
				_tx_timer_time_slice =  _tx_thread_current_ptr -> tx_time_slice;
			}
		 } 
    }
}

執行線程時間片用盡,調用_tx_thread_time_slice判斷是否進行線程切換。

UINT    _tx_thread_time_slice(VOID)
{

TX_INTERRUPT_SAVE_AREA
REG_1 UINT          status;             /* Time-slice status flag	    */
REG_2 TX_THREAD     *thread_ptr;        /* Thread priority head pointer */


    /* Pickup the current thread pointer.  */
    thread_ptr =  _tx_thread_current_ptr;

    /* Default time-slice status to false.  A true value indicates this
       routine did indeed perform a time-slice.  */
    status =  TX_FALSE;

    /* Lockout interrupts while thread attempts to relinquish control.  */
    TX_DISABLE

    /* Make sure the thread is still active, i.e. not suspended.  */
    if (thread_ptr -> tx_state == TX_READY)
    {

        /* Setup a fresh time-slice for the thread.  */
        thread_ptr -> tx_time_slice =  thread_ptr -> tx_new_time_slice;

        /* Check to make sure preemption is enabled.  */
        if (_tx_thread_preempt_disable)
        {

            /* Preemption is disabled by the system, set time-slice to 1 for retry.  */
            thread_ptr -> tx_time_slice =  1;

            /* Set status to false.  */
            status =  TX_FALSE;
        }

        /* Determine if there is another thread at the same priority.  */
        #def 同優先級就緒隊列有其他線程,那麼進行切換
        else if ((thread_ptr -> tx_ready_next != thread_ptr) &&
                 (thread_ptr -> tx_priority == thread_ptr -> tx_preempt_threshold))
        {
        
            /* There is another thread at this priority, make it the highest at
               this priority level.  */
               #def 就緒隊列頭部指向下一個線程,同時相當於當前執行線程移動到了隊列尾部
            _tx_thread_priority_list[thread_ptr -> tx_priority] =  thread_ptr -> tx_ready_next;
	
            /* Designate the highest priority thread as the one to execute.  Don't use this 
               thread's priority as an index just in case a higher priority thread is now 
               ready!  */
               #def 選出新的執行線程
            _tx_thread_execute_ptr =  _tx_thread_priority_list[_tx_thread_highest_priority];

            /* Set the status to true to indicate a preemption is going to take
               place.  */
            status =  TX_TRUE;
        }
    }

    /* Restore previous interrupt posture.  */
    TX_RESTORE

    /* Return to caller.  */
    return(status);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章