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

📄 sche.c

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