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

📄 sche.c

📁 深圳市微逻辑电子有限公司 巨果&#8226 Kingmos&reg 系统核心
💻 C
📖 第 1 页 / 共 3 页
字号:
/******************************************************
Copyright(c) 版权所有,1998-2005微逻辑。保留所有权利。
******************************************************/

/*****************************************************
文件说明:调度管理
版本号:2.0.0
开发时期:2000
作者:李林
修改记录:
	2004-09-29, 修改 Schedule
    2004-08-24, 08-14的修改导致事件无法激活
    2004-08-14, __DownSemphores INTR_ON();  //2004-08-14, add by lilin
	2004-08-11, 不是用动态分配( WaitForSingleObject。WaitMultiSingleObject  ) 信号量,涉及到 semaphpor.c thread.c sche.c
    2003-08-30: timeout 清0
    2003-08-21:LN, WakeupThread,当唤醒线程时,将被唤醒的
	           优先级提高一个点。
    2003-04-24:LN,增加supend and resume 功能
******************************************************/

#include <eframe.h>
#include <eobjtype.h>
#include <eassert.h>
#include <epcore.h>
#include <sysintr.h>
#include <coresrv.h>
#include <epalloc.h>
#include <oemfunc.h>

//1024 for USE_THREAD_PAGE_TABLE
struct {
	THREAD thread;
	BYTE   dump[THREAD_STRUCT_SIZE - sizeof(THREAD) + 1024];
}_InitKernelThread = { INIT_THREAD, };
const LPTHREAD lpInitKernelThread = (LPTHREAD)&_InitKernelThread;

PROCESS InitKernelProcess = INIT_PROCESS;

HANDLEDATA InitKernelProcessHandle = { { OBJ_PROCESS, NULL, NULL, (DWORD)&InitKernelProcessHandle, 1 }, (HANDLE)&InitKernelProcessHandle, &InitKernelProcess  };
HANDLEDATA InitKernelThreadHandle = { { OBJ_THREAD, NULL, NULL, (DWORD)&InitKernelProcessHandle, 1 }, (HANDLE)&InitKernelThreadHandle, &InitKernelProcess  };
DWORD InitKernelThreadTLS[TLS_MAX_INDEXS];
LPTHREAD lpCurThread = (LPTHREAD)&_InitKernelThread;//lpInitKernelThread;//lpInitKernelThread;

LPPROCESS_SEGMENTS lppProcessSegmentSlots[MAX_PROCESS_ID];
LPPROCESS lppProcessPtr[MAX_PROCESS_ID];

#ifdef VIRTUAL_MEM
//LPPROCESS_SEGMENTS KernelSegment;   // virtual = KERNEL_SEGMENT = 0xC0000000
#endif

static void SetPriorityBitmap( UINT uPriority );
static void ClearPriorityBitmap( UINT uPriority );

//	重调度标志
BOOL bNeedResched = 0;
//	当前处于运行态的线程数
int nCountRunning = 0;
//	时间片
volatile DWORD dwJiffies = 0;

// 优先级映射表
// 系统将256个优先级分为8分组,用uPriorityGroup表示, 
// uPriorityGroup的每个bit表示一个分组(0表示该分组没有运行线程,1表示有)
// bRTIndexTable用于查找uPriorityGroup最高优先级分组
static const BYTE bRTIndexTable[] = 
{ 
    0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,   // 0x00 - 0x0f(15)
	4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,   // 0x10
    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,   // 0x20
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,   // 0x30

    6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,   // 0x40
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,   // 0x50
    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,   // 0x60
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,    // 0x70   - 0x7f

    7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,   // 0x80
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,   // 0x90
    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,   // 0xa0
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,   // 0xb0

    6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,   // 0xc0
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,   // 0xd0
    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,   // 0xe0
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0    // 0xf0  - 0xff
};

// 8个优先级分组 * 32 个优先级
static UINT uPriorityGroup;
// 256个bits, 每个DWORD表示一个分组
static DWORD dwPriorityBitmap[8];
// 用于得到数0-32在一个DWORD所对应的bits位
static const DWORD bitMask[] = { 0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010, 0x00000020, 0x00000040, 0x00000080,
                                 0x00000100, 0x00000200, 0x00000400, 0x00000800, 0x00001000, 0x00002000, 0x00004000, 0x00008000,
								 0x00010000, 0x00020000, 0x00040000, 0x00080000, 0x00100000, 0x00200000, 0x00400000, 0x00800000,
								 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000 };

//	256级优先级线程对列,所有具有相同优先级[pri]的可运行线程都放在lpThreadList[pri]里组成链表
static LPTHREAD lpThreadList[256];


// ********************************************************************
//声明: int KL_GetCountRunning( void )
//参数:
//	无
//返回值:
//	返回当前可运行线程数
//功能描述:
//	得到系统当前可运行线程数
//引用:
//	系统API
// ********************************************************************
int KL_GetCountRunning( void )
{
	return nCountRunning;
}
/*
// ********************************************************************
//声明: int GetRuningThreadList( void )
//参数:
//	无
//返回值:
//	返回当前可运行线程数
//功能描述:
//	得到系统当前可运行线程数
//引用:
//	系统API
// ********************************************************************
LPTHREAD * GetRuningThreadList( void )
{
	return lpThreadList;
}
*/
// ********************************************************************
//声明:void __AddWaitQueue( LPWAITQUEUE * lppQueue, LPWAITQUEUE lpWait ) 
//参数:
//	IN lppQueue - LPWAITQUEUE指针,指向队列头的地址
//	IN lpWait - WAITQUEUE结构指针,需要加入的等待节点
//返回值:
//	无
//功能描述:
//	将一个等待线程加入等待队列的首位置
//引用:
//	
// ********************************************************************

static void __AddWaitQueue( LPWAITQUEUE * lppQueue, LPWAITQUEUE lpWait )
{
	UINT uiSave;
	LPWAITQUEUE lpHead;
	LPWAITQUEUE lpNext;
		
	LockIRQSave( &uiSave ); // 保存 & 关中断
	
	lpHead = *lppQueue;
	
	if ( lpHead )
		lpNext = lpHead;
	else
	    lpNext = WAIT_QUEUE_HEAD( lppQueue );

	//加入首位置
	*lppQueue = lpWait;
	lpWait->lpNext = lpNext;
	
	UnlockIRQRestore( &uiSave );  // 恢复
}

// ********************************************************************
//声明:void __RemoveWaitQueue( LPWAITQUEUE *lppQueue, LPWAITQUEUE lpWait ) 
//参数:
//	IN lppQueue - LPWAITQUEUE指针,指向队列头的地址
//	IN lpWait - WAITQUEUE结构指针,需要移出的等待节点
//返回值:
//	无
//功能描述:
//	将一个等待线程移出等待队列
//引用:
//	
// ********************************************************************

void __RemoveWaitQueue( LPWAITQUEUE *lppQueue, LPWAITQUEUE lpWait )
{
	UINT uiSave;
	LPWAITQUEUE lpNext;
	LPWAITQUEUE lpHead;
	
	LockIRQSave( &uiSave );// 保存 & 关中断

	lpNext = lpWait->lpNext;
	lpHead = lpNext;
	
	while( 1 ) 
	{
		LPWAITQUEUE lpNextList = lpHead->lpNext;
		if ( lpNextList == lpWait )
			break;  // 找到
		lpHead = lpNextList;
	}
	//移出
	lpHead->lpNext = lpNext;

	UnlockIRQRestore( &uiSave );// 恢复
}

// ********************************************************************
//声明:LPTHREAD GetHighestPriority( LPUINT lpPriority ) 
//参数:
//	OUT lpPriority - 用于接受当前最高优先级的级数(可以为NULL)
//返回值:
//	返回线程指针
//功能描述:
//	得到当前最高优先级线程
//引用:
//	
// ********************************************************************

static LPTHREAD GetHighestPriority( LPUINT lpPriority )
{
	UINT uIndex;
    DWORD dwBitmap;
	LPTHREAD lpThread = NULL;
    UINT uiSave;

	LockIRQSave( &uiSave );// 保存 & 关中断
	//得到最高分组
	uIndex = bRTIndexTable[uPriorityGroup];
	//得到该分组的优先级位图
	dwBitmap = dwPriorityBitmap[uIndex];
	//该分组的第一个优先级基
	uIndex <<= 5;
	while( dwBitmap )
	{
		UINT bit = dwBitmap & 0xff; // 8个优先级
		if( bit )
		{	//存在,得到最高的
			uIndex += bRTIndexTable[bit];
			if( lpPriority )
				*lpPriority = uIndex;
			lpThread = lpThreadList[uIndex];
			break;
		}
		//没有,取下一个八位
		dwBitmap >>= 8;//
		uIndex += 8;
	}

    UnlockIRQRestore( &uiSave );// 恢复
	return lpThread;
}

// ********************************************************************
//声明:LPTHREAD GetHigherPriority( UINT uiHighestPriority, LPUINT lpPriority ) 
//参数:
//	IN uiHighestPriority - 最高优先级
//	OUT lpPriority - 用于接受次优先级的级数
//返回值:
//	假如成功,返回当前次高优先级线程指针,*lpPriority为次高优先级级数;假如没有,返回NULL
//功能描述:
//	得到当前次高优先级线程及其级数
//引用:
//	
// ********************************************************************

static LPTHREAD GetHigherPriority( UINT uiHighestPriority, LPUINT lpPriority )
{
	LPTHREAD lpThread;
    UINT uiSave;

	LockIRQSave( &uiSave );// 保存 & 关中断

	// 清除最高优先级
	ClearPriorityBitmap( uiHighestPriority );
	// 得到最高优先级
    lpThread = GetHighestPriority( lpPriority );
	// 恢复最高优先级
	SetPriorityBitmap( uiHighestPriority );

    UnlockIRQRestore( &uiSave );// 恢复
	return lpThread;
}

// ********************************************************************
//声明:static void SetPriorityBitmap( UINT uPriority ) 
//参数:
//	IN uPriority - 优先级
//返回值:
//	无
//功能描述:
//	设置优先级位图
//引用:
//	
// ********************************************************************

static void SetPriorityBitmap( UINT uPriority )
{
    UINT uiSave;

	LockIRQSave( &uiSave );// 保存 & 关中断
	// 设置分组
	uPriorityGroup |= bitMask[uPriority >> 5];
	//	设置该组的位图
	dwPriorityBitmap[uPriority >> 5] |= bitMask[uPriority & 0X1F];

    UnlockIRQRestore( &uiSave );// 恢复
}

// ********************************************************************
//声明:void ClearPriorityBitmap( UINT uPriority ) 
//参数:
//	IN uPriority - 优先级
//返回值:
//	无
//功能描述:
//	清除优先级位图
//引用:
//	
// ********************************************************************

static void ClearPriorityBitmap( UINT uPriority )
{
    UINT uiSave;

	LockIRQSave( &uiSave );// 保存 & 关中断
	
	if( ( dwPriorityBitmap[uPriority >> 5] &= ~(bitMask[uPriority & 0X1F]) ) == 0 )
	    uPriorityGroup &= ~bitMask[uPriority >> 5];

    UnlockIRQRestore( &uiSave );// 恢复
}

// ********************************************************************
//声明:void SetThreadCurrentPriority( LPTHREAD lpThread, UINT lPriority ) 
//参数:
//	IN lpThread - THREAD 结构指针
//	IN lPriority - 优先级
//返回值:
//	无
//功能描述:
//	设置线程的当前优先级
//引用:
//	
// ********************************************************************

void SetThreadCurrentPriority( LPTHREAD lpThread, UINT lPriority )
{
    UINT uiSave;

	LockIRQSave( &uiSave );// 保存 & 关中断
//    ASSERT( lpThread != lpInitKernelThread );
	if( lpThread->dwState == THREAD_RUNNING )
	{	//可运行线程
		//从运行队列先移出
		RemoveFromRunQueue( lpThread );
		//设置新的优先级并将其放入运行队列
		lpThread->nCurPriority = lPriority;
		AddToRunQueue( lpThread );
	}
	else
		lpThread->nCurPriority = lPriority;
	
	UnlockIRQRestore( &uiSave );// 恢复
}

// ********************************************************************
//声明:void AddToRunQueue( LPTHREAD lpThread ) 
//参数:
//	IN lpThread - THREAD结构指针
//返回值:
//	无
//功能描述:
//	将线程加入运行队列
//引用:
//	
// ********************************************************************

void AddToRunQueue( LPTHREAD lpThread )
{
    UINT uiSave;
	UINT uPri;
	LPTHREAD lpList;

	LockIRQSave( &uiSave );// 保存 & 关中断


	if( lpThread->nSuspendCount ) //2003-04-24:LN,增加
	{  //仍然挂起
		lpThread->dwState = THREAD_SUSPENDED;//2003-04-24:LN,增加
		goto _ADD_RET; //2003-04-24:LN,增加
	}  //2003-04-24:LN,增加

	if( lpThread->lpNextRun || lpThread->lpPrevRun )
	{	
		goto _ADD_RET;
	}
	//得到当前优先级所在的可运行对列
	uPri = lpThread->nCurPriority;
	lpList = lpThreadList[uPri];
	//放到队列头
	if( lpList )
	{	
		( lpThread->lpPrevRun = lpList->lpPrevRun )->lpNextRun = lpThread;
		lpThread->lpNextRun = lpList;
		lpList->lpPrevRun = lpThread;
	}
	else
	{	//
		lpThread->lpPrevRun = lpThread->lpNextRun = lpThread;
		//设置优先级位图
	    SetPriorityBitmap( uPri );
	}
	lpThreadList[uPri] = lpThread;	
	//是否请求重调度	
	if( uPri <= lpCurThread->nCurPriority )
		bNeedResched = 1;//是
	nCountRunning++;   // 增加运行线程数

_ADD_RET:

	UnlockIRQRestore( &uiSave );// 恢复
}

// ********************************************************************
//声明:void RemoveFromRunQueue( LPTHREAD lpThread ) 
//参数:
//	IN lpThread - THREAD结构指针
//返回值:
//	无
//功能描述:
//	将线程移出运行队列
//引用:
//	
// ********************************************************************

void RemoveFromRunQueue( LPTHREAD lpThread )
{
	LPTHREAD lpNext;
	LPTHREAD lpPrev;
	UINT uiSave;

	LockIRQSave( &uiSave );// 保存 & 关中断
     
	if( lpThread != lpInitKernelThread )
	{	//
		UINT uPri = lpThread->nCurPriority;

		lpNext = lpThread->lpNextRun;
		lpPrev = lpThread->lpPrevRun;
		//ASSERT( lpNext && lpPrev );
		
		//移出
		if( lpNext == lpThread )
		{	//该优先级队列仅仅一个
			//ASSERT(lpPrev == lpThread);
			lpThreadList[uPri] = NULL;
			//清除优先级位图
			ClearPriorityBitmap(uPri);
		}
		else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -