📄 sche.c
字号:
lpThread->nWaitCount = (WORD)nCount;
lpThread->lpWaitQueue = lpWaitQueue;
if( dwTimeout == INFINITE )
{ //无超时要求,死等
lpThread->dwState = THREAD_UNINTERRUPTIBLE;
}
else
{ // 需要超时处理,这里增加一个timer
dwExpire = dwTimeout + dwJiffies;
lpCurThread->dwTimeout = dwExpire;//dwTimeout;
lpThread->dwState = THREAD_INTERRUPTIBLE;
INIT_TIMER_LIST( &lpCurThread->timer );
lpCurThread->timer.dwExpires = dwExpire;
lpCurThread->timer.dwData = (DWORD)lpCurThread;
lpCurThread->timer.lpFunction = ThreadTimeout;
_AddTimerList(&lpCurThread->timer);
//lpCurThread->lpTimer = &timer;
}
while( 1 )
{ //是否有信号?
for( i = 0; i < nCount; i++ )
{
if( lppsem[i]->nCount )
{
dwRetv = WAIT_OBJECT_0 + i;//有,返回
while( i-- )
{
lppsem[i]->nWaiting--; // 清除之前增加的等待计数
}
lpThread->nsemRet = (WORD)dwRetv;
goto _return;
}
lppsem[i]->nWaiting++;
}
// 没有任何对象有信号
if( dwTimeout != INFINITE && lpCurThread->dwTimeout == 0 )
{// 需要超时处理但超时时间为0,返回
i = nCount;
while( i-- )
{
lppsem[i]->nWaiting--; // 清除之前增加的等待计数
}
dwRetv = WAIT_TIMEOUT;
break;
}
//放弃CPU并等待信号
//INTR_ON(); //2004-08-14, add by lilin
Schedule();
INTR_OFF();
if( lpThread->lpRouser )
{
i = (WAITQUEUE*)lpThread->lpRouser - lpWaitQueue;
ASSERT( i < nCount );
if( i < nCount )
{
if( lppsem[i]->nCount ||
(lpThread->flag & FLAG_PULSE_EVENTING) )
{
dwRetv = WAIT_OBJECT_0 + i;//有,返回
lpThread->nsemRet = (WORD)dwRetv;
lpThread->lpRouser = NULL;
goto _return;
}
}
else
{
ERRORMSG( 1, ( "__DownSemphores: error lpRouser(0x%x),lpWaitQueue(0x%x),i( %d )", lpThread->lpRouser, lpWaitQueue, i ) );
}
lpThread->lpRouser = NULL;
}
if( dwTimeout == INFINITE )
lpThread->dwState = THREAD_UNINTERRUPTIBLE;
else
lpThread->dwState = THREAD_INTERRUPTIBLE;
}
_return:
//ASSERT( lpThread == lpCurThread );
//
lpThread->dwTimeout = 0;
lpThread->dwState = THREAD_RUNNING;
// lpThread->lpTimer = NULL;
// lpThread->lppsemWait = NULL; //2005-01-29, remove
lpThread->nWaitCount = 0;
lpThread->lpWaitQueue = NULL;
INTR_ON();
if( dwTimeout != INFINITE )
{ //删除timer
_DelTimerList(&lpCurThread->timer);
}
//清除
for( i = 0; i < nCount; i++ )
{
__RemoveWaitQueue( &lppsem[i]->lpWaitQueue, &lpWaitQueue[i] );
}
KHeap_Free( lpWaitQueue, nCount * sizeof( WAITQUEUE ) );
return dwRetv;
}
// ********************************************************************
//声明:DWORD ScheduleTimeout( DWORD dwTimeout )
//参数:
// IN dwTimeout - 延迟时间(以毫秒为单位)
//返回值:
// 返回实际等待的时间
//功能描述:
// 让线程延迟一段时间
//引用:
//
// ********************************************************************
DWORD ScheduleTimeout( DWORD dwTimeout )
{
//TIMERLIST timer;
DWORD dwExpire;
DWORD dwNeedJiffies;
if( dwTimeout == INFINITE )
{ //死等
lpCurThread->dwState = THREAD_UNINTERRUPTIBLE;
Schedule();
return dwTimeout;
}
else
{ //
dwNeedJiffies = OEM_TimeToJiffies( dwTimeout, 0 ); // 得到毫秒数对应的时间片
INTR_OFF();
//初始化timer
dwExpire = dwNeedJiffies + dwJiffies;
lpCurThread->dwTimeout = dwExpire;
// 2004-05-13, lilin,如果时间太短,无法实现Sleep的功能
// 导致其它线程得不到时间
//lpCurThread->dwState = THREAD_INTERRUPTIBLE;
if( dwTimeout )
{ //必须切换(从运行线程中移出)
lpCurThread->dwState = THREAD_UNINTERRUPTIBLE;
}
else
{ //如果同优先级的线程存在,则切换到同优先级的其它线程
//否则直接返回
lpCurThread->dwState = THREAD_INTERRUPTIBLE;
}
//
INIT_TIMER_LIST( &lpCurThread->timer );
lpCurThread->timer.dwExpires = dwExpire;
lpCurThread->timer.dwData = (DWORD)lpCurThread;
lpCurThread->timer.lpFunction = ThreadTimeout;//唤醒线程的回调函数
//插入timer列式
_AddTimerList(&lpCurThread->timer);
//lpCurThread->lpTimer = &timer;
INTR_ON();
//放弃CPU
Schedule();
//移出
_DelTimerList(&lpCurThread->timer);
//lpCurThread->lpTimer = NULL;
//实际超时
dwTimeout = dwExpire - dwJiffies;
}
return dwTimeout;
}
static TIMERLIST timerHead = { &timerHead, &timerHead, ~0, 0, NULL };
// ********************************************************************
//声明:void _AddTimerList( LPTIMERLIST lpTimer )
//参数:
// IN lpTimer - TIMERLIST结构指针
//返回值:
// 无
//功能描述:
// 将一个定时器对象插入timerHead链表
//引用:
//
// ********************************************************************
void _AddTimerList( LPTIMERLIST lpTimer )
{
LPTIMERLIST p;
UINT uiSave;
p = &timerHead;
LockIRQSave( &uiSave );// 保存 & 关中断
//按定时时间从小到大连接
do {
p = p->lpNext;
} while ( lpTimer->dwExpires > p->dwExpires );
lpTimer->lpNext = p;
lpTimer->lpPrev = p->lpPrev;
p->lpPrev = lpTimer;
lpTimer->lpPrev->lpNext = lpTimer;
UnlockIRQRestore( &uiSave );//恢复
}
// ********************************************************************
//声明:int _DelTimerList( LPTIMERLIST lpTimer )
//参数:
// IN lpTimer - TIMERLIST结构指针
//返回值:
// 假如成功,返回1;否则,返回0
//功能描述:
// 与_AddTimerList对应,该功能从timerHead链表移出一个定时器对象
//引用:
//
// ********************************************************************
int _DelTimerList( LPTIMERLIST lpTimer )
{
int ret = 0;
UINT uiSave;
LockIRQSave( &uiSave );// 保存 & 关中断
if ( lpTimer->lpNext ) //合法?
{ //是
LPTIMERLIST lpNext;
if ( ( lpNext = lpTimer->lpNext ) != NULL ) //合法?
{ //是,移出
( lpNext->lpPrev = lpTimer->lpPrev )->lpNext = lpNext;
lpTimer->lpNext = lpTimer->lpPrev = NULL;
ret = 1;
}
}
UnlockIRQRestore( &uiSave );//恢复
return ret;
}
// ********************************************************************
//声明:static void RunTimerList( void )
//参数:
// 无
//返回值:
// 无
//功能描述:
// 遍历在timerHead链表里的所有定时器对象,如果有到期的,移出它并回调定时器功能
//引用:
//
// ********************************************************************
static void RunTimerList( void )
{
LPTIMERLIST lpTimer;
INTR_OFF();//关掉中断
while( (lpTimer = timerHead.lpNext) != &timerHead &&
lpTimer->dwExpires <= dwJiffies )
{
// 移出,remove lpTimer from list
lpTimer->lpNext->lpPrev = lpTimer->lpPrev;
lpTimer->lpPrev->lpNext = lpTimer->lpNext;
lpTimer->lpNext = lpTimer->lpPrev = NULL;
INTR_ON();//打开中断
//调用定时器功能
lpTimer->lpFunction( lpTimer->dwData );
INTR_OFF();//关掉中断
}
INTR_ON();//打开中断
}
// ********************************************************************
//声明:static void UpdateThreadTimes( DWORD dwTicks, DWORD dwSystem )
//参数:
// IN dwTicks - 系统时间片
// IN dwSystem - 系统内部已经使用的时间片
//返回值:
// 无
//功能描述:
// 更新当前线程所消耗的时间片
//引用:
//
// ********************************************************************
static void UpdateThreadTimes( DWORD dwTicks, DWORD dwSystem )
{
LPTHREAD lpThread = lpCurThread;
if( lpThread->fPolicy != THREAD_POLICY_FIFO ) //调度策略为FIFO吗?
{ //否,FIFO调度策略不需要修改时间片
int nUser = dwTicks - dwSystem; //nUser为用户使用的时间片
if( nUser > 0 )
{
int nTick = lpThread->nTickCount - nUser;
if( nTick < 0 )
{ //消耗完,请求重调度
lpThread->nTickCount = 0;
bNeedResched = 1;
}
else
lpThread->nTickCount = nTick; //修改为新的
lpThread->dwTimerCount += nUser;
}
}
}
static DWORD dwLostTicks = 0; //系统时间片,当系统启动时,该值不断增加
static DWORD dwLostTicksSystem = 0; //当系统在处理事务时所消耗的时间片
// ********************************************************************
//声明:static void UpdateTimes(void)
//参数:
// 无
//返回值:
// 无
//功能描述:
// 更新当前线程所消耗的时间片
//引用:
//
// ********************************************************************
static void UpdateTimes(void)
{
DWORD dwTicks;
dwTicks = KL_InterlockedExchange( (LPLONG)&dwLostTicks, 0 );
if ( dwTicks )
{
DWORD dwSystem;
dwSystem = KL_InterlockedExchange( (LPLONG)&dwLostTicksSystem, 0 );
UpdateThreadTimes( dwTicks, dwSystem );
}
}
// ********************************************************************
//声明:void DoTimer( void * lp )
//参数:
// IN lp - 保留
//返回值:
// 无
//功能描述:
// 系统timer处理
//引用:
//
// ********************************************************************
void DoTimer( void * lp )
{
dwJiffies++;
dwLostTicks++;
//UpdateTimes();
ISR_Active( SYSINTR_TIMING );
if ( 0 )//!IS_USER_MODE( lp ) )
{
dwLostTicksSystem++;
}
}
// ********************************************************************
//声明:static void CALLBACK TimerISR( DWORD dwISRHandle )
//参数:
// IN dwISRHandle - 调用 ISR_RegisterServer 时所传递的参数
//返回值:
// 无
//功能描述:
// timer中断服务例程,处理与时间有关的事务,如 定时器,唤醒功能等
//引用:
//
// ********************************************************************
static void CALLBACK TimerISR( DWORD dwISRHandle )
{
UpdateTimes();
RunTimerList();
}
// ********************************************************************
//声明:BOOL InitScheduler(void)
//参数:
// 无
//返回值:
// 假如成功,返回TRUE;否则,返回FALSE
//功能描述:
// 初始化调度器
//引用:
// call by start.c
// ********************************************************************
BOOL InitScheduler(void)
{
int i = sizeof( THREAD );
memset( lpThreadList, 0, sizeof(lpThreadList) );
memset( dwPriorityBitmap, 0, sizeof(dwPriorityBitmap) );
uPriorityGroup = 0;
memset( lppProcessSegmentSlots, 0, sizeof( lppProcessSegmentSlots ) );
memset( lppProcessPtr, 0, sizeof( lppProcessPtr ) );
InitKernelProcess.lpCpuPTS = AllocCPUPTS();
//初始化内核线程
lpInitKernelThread->dwThreadId = (DWORD)MAKE_HANDLE( lpInitKernelThread );
lpInitKernelThread->nCurPriority = lpInitKernelThread->nOriginPriority = IDLE_PRIORITY;
lpCurThread = lpInitKernelThread;
lpThreadList[IDLE_PRIORITY] = lpCurThread;
uPriorityGroup = 0x80;
dwPriorityBitmap[7] = 0x80000000;
//注册timer中断服务例程
ISR_RegisterServer( SYSINTR_TIMING, TimerISR, 0 );
lpCurThread->nLockScheCount = 0;
INIT_TIMER_LIST( &lpCurThread->timer );
//test only
// InitKernelProcess.akyAccessKey = -1;//
//
#ifdef VIRTUAL_MEM
lppProcessSegmentSlots[SHARE_SEGMENT_INDEX] = AllocSegmentIndexAndSegment(SHARE_MEM_BASE);//(DWORD)Seg_Alloc();
//memset( &KernelSegment, 0, sizeof(KernelSegment) );
//KernelSegment.dwSegBaseAddress = KERNEL_SEGMENT_BASE;
//KernelSegment.lpSeg = Seg_Alloc();
//InitKernelProcess.lpProcessSegments = &KernelSegment;
InitKernelProcess.lpProcessSegments = AllocSegmentIndexAndSegment(KERNEL_SEGMENT_BASE);
//InitKernelProcess.lpProcessSegments->dwSegBaseAddress = KERNEL_SEGMENT_BASE;
#endif
#ifdef USE_THREAD_PAGE_TABLE
InitThreadPageTable( lpInitKernelThread );
// lpInitKernelThread->pageTable.lpdwVirtualPageTable = ( ( ( (DWORD)lpInitKernelThread + (3 * 1024) ) + (1024-1) ) & ~(1024-1) );//ALIGN_PAGE_UP( (DWORD)lpInitKernelThread + (3 * 1024) );
// lpInitKernelThread->pageTable.lpdwPhyPageTable = _GetPhysicalPageAdr(lpInitKernelThread->pageTable.lpdwVirtualPageTable);
// lpInitKernelThread->pageTable.lpdwVirtualPageTable = CACHE_TO_UNCACHE(lpInitKernelThread->pageTable.lpdwVirtualPageTable);
// RETAILMSG( 1, ("lpInitKernelThread=0x%x,V=0x%x,P=0x%x.\r\n", lpInitKernelThread, lpInitKernelThread->pageTable.lpdwVirtualPageTable, lpInitKernelThread->pageTable.lpdwPhyPageTable ) );
#endif
// RETAILMSG( 1, ("lpInitKernelThread->lpCpuPTS=0x%x.\r\n", lpCurThread->lpCpuPTS ) );
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -