📄 sche.c
字号:
{ //是否在队列头 ?
if( lpThreadList[uPri] == lpThread )
{ //是
lpThreadList[uPri] = lpNext;
}
lpNext->lpPrevRun = lpPrev;
lpPrev->lpNextRun = lpNext;
}
lpThread->lpNextRun = NULL;
lpThread->lpPrevRun = NULL;
lpThread->nBoost = 0;
nCountRunning--;
}
else
{ //决不应该到这里!!!
ASSERT(0);
}
UnlockIRQRestore( &uiSave );// 恢复
}
// ********************************************************************
//声明:void MoveToEndOfRunQueue( LPTHREAD lpThread )
//参数:
// IN lpThread - THREAD结构指针
//返回值:
// 无
//功能描述:
// 将线程移到本运行队列尾部
//引用:
//
// ********************************************************************
void MoveToEndOfRunQueue( LPTHREAD lpThread )
{
UINT uiSave;
LPTHREAD lpNext;
LPTHREAD lpPrev;
UINT uPri;
LPTHREAD lpList;
LockIRQSave( &uiSave );// 保存 & 关中断
lpNext = lpThread->lpNextRun;
lpPrev = lpThread->lpPrevRun;
uPri = lpThread->nCurPriority;
lpList = lpThreadList[uPri];
//是否在队列头 ?
if( lpList == lpThread )
{ //是
lpThreadList[uPri] = lpNext;
}
// 移出
lpNext->lpPrevRun = lpPrev;
lpPrev->lpNextRun = lpNext;
// 放到尾部
lpThread->lpNextRun = lpList;
lpPrev = lpList;
lpList->lpPrevRun = lpThread;
lpThread->lpPrevRun = lpPrev;
lpPrev->lpNextRun = lpThread;
UnlockIRQRestore( &uiSave );// 恢复
}
// ********************************************************************
//声明:void _LinkThread( LPTHREAD lpThread )
//参数:
// IN lpThread - THREAD结构指针
//返回值:
// 无
//功能描述:
// 将线程加入到线程双链表
//引用:
//
// ********************************************************************
void _LinkThread( LPTHREAD lpThread )
{
UINT uiSave;
LockIRQSave( &uiSave );// 保存 & 关中断
// 连接到链表
lpThread->lpNextThread = lpInitKernelThread;
lpThread->lpPrevThread = lpInitKernelThread->lpPrevThread;
lpInitKernelThread->lpPrevThread->lpNextThread = lpThread;
lpInitKernelThread->lpPrevThread = lpThread;
UnlockIRQRestore( &uiSave );// 恢复
}
// ********************************************************************
//声明:void _RemoveThread( LPTHREAD lpThread )
//参数:
// IN lpThread - THREAD结构指针
//返回值:
// 无
//功能描述:
// 与_LinkThread对应,该功能将线程从线程双链表移出
//引用:
//
// ********************************************************************
void _RemoveThread( LPTHREAD lpThread )
{
UINT uiSave;
LockIRQSave( &uiSave );// 保存 & 关中断
// 移出系统链表
ASSERT( lpThread->dwMagic == THREAD_MAGIC );
lpThread->lpNextThread->lpPrevThread = lpThread->lpPrevThread;
lpThread->lpPrevThread->lpNextThread = lpThread->lpNextThread;
UnlockIRQRestore( &uiSave );// 恢复
}
// ********************************************************************
//声明:void _WakeupThread( LPTHREAD lpThread, BOOL bHighLevel )
//参数:
// IN lpThread - THREAD结构指针
// IN bHighLevel - 是否增加一个点,假如TRUE,则增加nBoost一个点
//返回值:
// 无
//功能描述:
// 唤醒线程
//引用:
//
// ********************************************************************
void _WakeupThread( LPTHREAD lpThread, BOOL bHighLevel )
{
UINT uiSave;
LockIRQSave( &uiSave );// 保存 & 关中断
lpThread->dwState = THREAD_RUNNING;
if ( !lpThread->lpNextRun )
{
if( bHighLevel )
lpThread->nBoost++; //临时增加 1 tick
//加入到可运行对列
AddToRunQueue( lpThread );
}
UnlockIRQRestore( &uiSave );// 恢复
}
// ********************************************************************
//声明:static void ThreadTimeout( DWORD dwData )
//参数:
// IN dwData - THREAD结构指针
//返回值:
// 无
//功能描述:
// 睡眠到期回调函数。当线程睡眠到期时,会调用该函数去唤醒该线程
//引用:
//
// ********************************************************************
static void ThreadTimeout( DWORD dwData )
{
((LPTHREAD)dwData)->dwTimeout = 0;
if( ((LPTHREAD)dwData)->dwState == THREAD_INTERRUPTIBLE ||
((LPTHREAD)dwData)->dwState == THREAD_UNINTERRUPTIBLE )
_WakeupThread( (LPTHREAD)dwData, FALSE );//唤醒该线程
else
{
;
}
}
// ********************************************************************
//声明: static LPTHREAD GetNextRun( LPTHREAD lpPrev, DWORD dwTimeout )
//参数:
// IN lpPrev - THREAD结构指针
// IN dwTimeout - 前一个线程是否是需要睡眠
//返回值:
// THREAD指针
//功能描述:
// 得到需要调度的线程。该功能遍历所有的可运行线程并返回优先级最高的一个或
// 同级优先级中最需要运行的一个
//引用:
//
// ********************************************************************
static LPTHREAD GetNextRun( LPTHREAD lpPrev, DWORD dwTimeout )
{
{
LONG lCount;
LPTHREAD p, lpNext;
LPTHREAD lpHeadList = GetHighestPriority( NULL );//得到最高优先级队列
//ASSERT( lpHeadList );
//先初始化一个
lCount = lpHeadList->nTickCount + lpHeadList->nBoost;
p = lpHeadList->lpNextRun;
lpNext = lpHeadList;
//遍历同级优先级的所有线程
while( p != lpHeadList )
{
LONG lCurCount;
lCurCount = p->nTickCount + p->nBoost;
if( lCurCount )
{
if( p == lpPrev ) //是否是前一个?
{ //是
if( dwTimeout ) //前一个是否需要睡眠
lCurCount = -1000; //是,不需要运行
else
lCurCount++; //否,提高一个点
}
}
//选择具有最大的lCurCount值的线程
if( lCount < lCurCount )
{
lCount = lCurCount;
lpNext = p;
}
p = p->lpNextRun;
}
// 假如本优先级的所有线程的counter值都为0,则重新初始化他们
if( !lCount )
{ //都为0
p = lpHeadList;
do{
p->nTickCount = (short)p->nRotate;
p = p->lpNextRun;
}while( p != lpHeadList );
}
if( lpNext->nBoost ) //假如可能,减去临时爆发值
lpNext->nBoost--;
return lpNext;
}
}
// ********************************************************************
//声明: void CALLBACK Schedule(void)
//参数:
// 无
//返回值:
// 无
//功能描述:
// 调度函数。当线程需要放弃CPU或调度时间片到期时会调用该函数来选择一个新的线程去运行
//引用:
//
// ********************************************************************
void CALLBACK Schedule(void)
{
LPTHREAD lpPrev, lpNext;
DWORD dwTimeout = 0;
INTR_OFF(); //关掉中断
//2004-09-29, remove by lilin, 因为 ISR_Handler 会打开中断 并且该功能在 DefaultHandler 也有处理
if( iISRActiveCount ) //是否有激活的中断例程
{ // 是处理它们
ISR_Handler( ISR_ALL_INTRS );
}
//2004-09-29
//
bNeedResched = 0;
lpPrev = lpCurThread;
// 轮转策略
if( lpPrev->nTickCount != 0 && lpPrev->fPolicy == THREAD_POLICY_ROTATION )
{ //
lpPrev->nTickCount = (short)lpPrev->nRotate;
//移到对列尾
MoveToEndOfRunQueue( lpPrev );
}
//2004-09-29, remove by lilin, 因为 HandleSignal 会打开中断
//我将其放到末尾,今后我觉得应该同时 DefaultHandler
if( lpPrev->dwSignal & ~lpPrev->dwBlocked ) //是否有信号
{ //是,处理信号
HandleSignal();
}
//2004-09-29
//检查当前线程
switch( lpPrev->dwState )
{
case THREAD_INTERRUPTIBLE:
if( lpPrev->dwSignal & ~lpPrev->dwBlocked )
{
lpPrev->dwState = THREAD_RUNNING;
break;
}
if( lpPrev->dwTimeout && lpPrev->dwTimeout <= dwJiffies )
{ // continue, but 放弃一次CPU
dwTimeout = lpPrev->dwTimeout;
lpPrev->dwTimeout = 0;
lpPrev->nBoost = 0;
lpPrev->dwState = THREAD_RUNNING;
break;
}
default:
RemoveFromRunQueue( lpPrev );//移出可运行队列
break;
case THREAD_RUNNING:
break;
}
//遍历所有可运行线程,得到一个最优的线程去运行
lpNext = GetNextRun( lpPrev, dwTimeout );
if( lpPrev != lpNext )
{
//lpCurThread = lpNext;
//#ifdef VIRTUAL_MEM
//假如有MMU管理,设置新的进程空间
if( lpPrev->lpCurProcess != lpNext->lpCurProcess ||
lpPrev->akyAccessKey != lpNext->akyAccessKey )
GetMMUContext( lpNext, 0, lpNext->lpCurProcess );
//#endif
//切换
SwitchTo( lpPrev, lpNext );
}
INTR_ON();
return;
}
// ********************************************************************
//声明:static void WakeupWaitQueue( LPWAITQUEUE *lppQueue )
//参数:
// IN lppQueue - LPWAITQUEUE指针
//返回值:
// 无
//功能描述:
// 唤醒所有在该队列的等待线程
//引用:
//
// ********************************************************************
static void WakeupWaitQueue( LPWAITQUEUE *lppQueue )
{
LPWAITQUEUE lpNext;
LPWAITQUEUE lpHead;
UINT uiSave;
if( !lppQueue || !(lpNext = *lppQueue) )
{
RETAILMSG( 1, ("error at WakeupWaitQueue: lppQueue(0x%x),lpNext(0x%x).\r\n", lppQueue, lpNext ) );
return;
}
LockIRQSave( &uiSave );// 保存 & 关中断
lpHead = WAIT_QUEUE_HEAD( lppQueue );
while( lpNext != lpHead )
{
LPTHREAD lpThread = lpNext->lpThread;
LPWAITQUEUE lpCur = lpNext;
lpNext = lpNext->lpNext;
if ( lpThread )
{
if ( lpThread->dwState == THREAD_UNINTERRUPTIBLE ||
lpThread->dwState == THREAD_INTERRUPTIBLE )
{
if( lpThread->lpRouser == NULL )
lpThread->lpRouser = lpCur;
_WakeupThread( lpThread, TRUE ); //唤醒他
}
}
if ( !lpNext )
{
RETAILMSG( 1, ("error at WakeupWaitQueue: lpNext==NULL!.\r\n" ) );
break;
}
}
UnlockIRQRestore( &uiSave );//恢复
return;
}
// ********************************************************************
//声明:void __Up( LPSEMAPHORE lpsem )
//参数:
// IN lpsem - SEMAPHORE结构指针
//返回值:
// 无
//功能描述:
// 释放等待信号量的线程
//引用:
//
// ********************************************************************
void __Up( LPSEMAPHORE lpsem )
{
WakeupWaitQueue( &lpsem->lpWaitQueue );
}
// ********************************************************************
//声明:DWORD __DownSemphores( LPSEMAPHORE * lppsem, DWORD nCount, DWORD dwTimeout )
//参数:
// IN lppsem - LPSEMAPHORE指针数组
// IN nCount - 保存在LPSEMAPHORE指针数组里的指针数 <= MAX_WAITOBJS
// IN dwTimeout - 超时等待时间(已毫秒为单位)
//返回值:
// 假如成功,返回 WAIT_OBJECT_0+n (假如有一个对象有信号) 或 WAIT_TIMEOUT(没有任何对象有信号并且等待时间到);
// 否则,返回 WAIT_FAILED
//功能描述:
//
//引用:
// 请求信号量
// ********************************************************************
DWORD __DownSemphores( LPSEMAPHORE * lppsem, DWORD nCount, DWORD dwTimeout )
{
LPTHREAD lpThread = lpCurThread;
//WAITQUEUE waitQueue[MAX_WAITOBJS];
WAITQUEUE * lpWaitQueue;
//TIMERLIST timer;
DWORD dwExpire;
DWORD dwRetv = WAIT_OBJECT_0;
DWORD i;
//2004-08-11,如果用动态分配的方法,则需要在HandleThreadExit做对应的释放处理
//lpWaitQueue = &waitQueue[0];
lpWaitQueue = (WAITQUEUE *)KHeap_Alloc( nCount * sizeof( WAITQUEUE ) );
if( lpWaitQueue == NULL )
return WAIT_FAILED;
INTR_OFF();
lpThread->nsemRet = WAIT_OBJECT_0;
// 初始化每一个等待队列
for( i = 0; i < nCount; i++ )
{
lpWaitQueue[i].lpThread = lpThread;
lpWaitQueue[i].lpNext = NULL;
__AddWaitQueue( &lppsem[i]->lpWaitQueue, &lpWaitQueue[i] );
lpThread->lppsemWait[i] = lppsem[i]; //2005-01-29, add
}
// 设定该线程的等待事件
//lpThread->lppsemWait = lppsem; //2005-01-29, remove
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -