📄 sche.c
字号:
/******************************************************
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 + -