⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sche.c

📁 深圳市微逻辑电子有限公司 巨果&#8226 Kingmos&reg 系统核心
💻 C
📖 第 1 页 / 共 3 页
字号:
		{	//是否在队列头 ?
		    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 + -