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

📄 schedule.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 5 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
/*
 *              NK Kernel scheduler code
 *
 *
 * Module Name:
 *
 *              schedule.c
 *
 * Abstract:
 *
 *              This file implements the scheduler for the NK kernel
 *
 *
 */

/* @doc EXTERNAL KERNEL */
/* @topic Kernel Entrypoints | Kernel Entrypoints */

#include "kernel.h"
#ifdef ARM
#include "nkarm.h"
#endif
#include <kitlpriv.h>
#include <psapi.h>
#include <altimports.h>
#include <tokpriv.h>

#ifndef _PREFAST_
#pragma warning(disable: 4068) // Disable pragma warnings
#endif

BOOL PageOutForced, bLastIdle;

DWORD dwDefaultThreadQuantum;

extern PFN_SHIMCLOSEPROCESS g_pfnShimCloseProcess;

/* General design: 
    There are many queues in the system, for all categories of processes.  All
    processes are on exactly one queue, with the exception of the currently
    running process (if any) which is on the NULL queue.  Runnable processes are
    on one of the run queues (there are several, one for each priority).  Examples
    of other queues are for sleeping, blocked on a critical section (one per
    critical section), etc.  Preemption grabs the current thread (if any) and puts
    it at the end of the queue for that thread's priority, and then grabs the
    highest priority thread (which should, by definition, always be at the same
    priority as the preempted thread, else the other thread would have been
    running [in the case of a higher prio], or we would have continued running
    the preempted thread [in the case of a lower prio].  Kernel routines take
    threads off of queues and put them on other queues.  NextThread finds the
    next thread to run, or returns 0 if there are no runnable threads.  We preempt
    with a fixed timeslice (probably 10ms).
*/

CRITICAL_SECTION csDbg, DbgApiCS, NameCS, CompCS, LLcs, ModListcs, WriterCS, MapCS, PagerCS, EventCS, MutexCS, SemCS;
CRITICAL_SECTION MapNameCS, PhysCS, ODScs, RFBcs, VAcs, rtccs, PageOutCS;
CRITICAL_SECTION DirtyPageCS, WDcs;

#ifdef DEBUG
CRITICAL_SECTION EdbgODScs, TimerListCS;
#endif
BOOL fKITLcsInitialized;
CRITICAL_SECTION KITLcs;

THREADTIME *TTList;

#if defined(x86)
extern PTHREAD g_CurFPUOwner;
#endif

RunList_t RunList;
PTHREAD SleepList;
HANDLE hEventList;
HANDLE hMutexList;
HANDLE hSemList;
DWORD dwReschedTime;

DWORD currmaxprio = MAX_PRIORITY_LEVELS - 1;
DWORD CurrTime;
DWORD dwPrevReschedTime;
PTHREAD pOOMThread;

SYSTEMTIME CurAlarmTime;
DWORD dwNKAlarmResolutionMSec = 10 * 1000;      // 10 seconds
#define MIN_NKALARMRESOLUTION_MSEC      1000    // 1 second
#define MAX_NKALARMRESOLUTION_MSEC      60000   // 60 seconds

HANDLE hAlarmEvent, hAlarmThreadWakeup; 
PTHREAD pCleanupThread;

#define THREAD_PWR_GUARD_PRIORITY       1
HANDLE hEvtPwrHndlr;

PROCESS ProcArray[MAX_PROCESSES];
PROCESS *kdProcArray = ProcArray;
struct KDataStruct *kdpKData = &KData;

HANDLE hCoreDll;
void (*TBFf)(LPVOID, ulong);
void (*MTBFf)(LPVOID, ulong, ulong, ulong, ulong);
void (*CTBFf)(LPVOID, ulong, ulong, ulong, ulong);
BOOL (*KSystemTimeToFileTime)(LPSYSTEMTIME, LPFILETIME);
LONG (*KCompareFileTime)(LPFILETIME, LPFILETIME);
BOOL (*KLocalFileTimeToFileTime)(const FILETIME *, LPFILETIME);
BOOL (*KFileTimeToSystemTime)(const FILETIME *, LPSYSTEMTIME);
void (*pPSLNotify)(DWORD, DWORD, DWORD);
void (*pSignalStarted)(DWORD);
BOOL (*pGetHeapSnapshot)(THSNAP *pSnap, BOOL bMainOnly, LPVOID *pDataPtr, HANDLE hProc);

LPVOID pExitThread;
LPVOID pExcpExitThread;
LPDWORD pIsExiting;
extern Name *pDebugger;
LPVOID pCaptureDumpFileOnDevice;

void DoPageOut(void);
extern DWORD PageOutNeeded;
BYTE GetHighPos(DWORD);

// idle thread for cleaning dirty pages
void CleanDirtyPagesThread(LPVOID pv);

// for save/restore CoProcRegister
DWORD cbNKCoProcRegSize;
DWORD fNKSaveCoProcReg;
void (*pOEMSaveCoProcRegister) (LPBYTE pArea);
void (*pOEMRestoreCoProcRegister) (LPBYTE pArea);
void (*pOEMInitCoProcRegisterSavedArea) (LPBYTE pArea);

// for variable tick scheduler
void (*pOEMUpdateRescheduleTime) (DWORD dwTick);

static DWORD FakedOEMIntrOccurs (DWORD dwSysIntr)
{
    return dwSysIntr;
}

// for OEM schedule hook
void (*pfnOEMReschedule) (DWORD dwThrdId, DWORD dwPrio, DWORD dwQuantum, DWORD dwFlags);
DWORD (*pfnOEMIntrOccurs) (DWORD dwSysIntr) = FakedOEMIntrOccurs;   // set to faked function to simplify assembly


static BYTE W32PrioMap[MAX_WIN32_PRIORITY_LEVELS] = {
    MAX_PRIORITY_LEVELS-8,
    MAX_PRIORITY_LEVELS-7,
    MAX_PRIORITY_LEVELS-6,
    MAX_PRIORITY_LEVELS-5,
    MAX_PRIORITY_LEVELS-4,
    MAX_PRIORITY_LEVELS-3,
    MAX_PRIORITY_LEVELS-2,
    MAX_PRIORITY_LEVELS-1,
};

void (*pfnOEMMapW32Priority) (int nPrios, LPBYTE pPrioMap);

typedef struct RTs {
    PTHREAD pHelper;    // must be first
    DWORD dwBase, dwLen;// if we're freeing the stack
    DWORD dwOrigBase;   // if we are on a fiber stack, we need to free the original
    PPROCESS pProc;     // if we're freeing the proc
    LPTHRDDBG pThrdDbg; // if we're freeing a debug structure
    HANDLE hThread;     // if we're freeing a handle / threadtime
    PTHREAD pThread;    // if we're freeing a thread structure
    CLEANEVENT *lpce1;
    CLEANEVENT *lpce2;
    CLEANEVENT *lpce3;
    LPDWORD pdwDying;
} RTs;

const PFNVOID ThrdMthds[] = {
    (PFNVOID)SC_ThreadCloseHandle,
    (PFNVOID)0,
    (PFNVOID)UB_ThreadSuspend,
    (PFNVOID)SC_ThreadResume,
    (PFNVOID)SC_ThreadSetPrio,
    (PFNVOID)SC_ThreadGetPrio,
    (PFNVOID)SC_ThreadGetCode,
    (PFNVOID)SC_ThreadGetContext,
    (PFNVOID)SC_ThreadSetContext,
    (PFNVOID)SC_ThreadTerminate,
    (PFNVOID)SC_CeGetThreadPriority,
    (PFNVOID)SC_CeSetThreadPriority,
    (PFNVOID)SC_CeGetThreadQuantum,
    (PFNVOID)SC_CeSetThreadQuantum,
};

BOOL SC_ProcGetModInfo (HANDLE hProcess, HMODULE hModule, LPMODULEINFO lpmodinfo, DWORD cb);
BOOL SC_ProcSetVer (HANDLE hProcess, DWORD dwVersion);

const PFNVOID ProcMthds[] = {
    (PFNVOID)SC_ProcCloseHandle,
    (PFNVOID)0,
    (PFNVOID)SC_ProcTerminate,
    (PFNVOID)SC_ProcGetCode,
    (PFNVOID)0,
    (PFNVOID)SC_ProcFlushICache,
    (PFNVOID)SC_ProcReadMemory,
    (PFNVOID)SC_ProcWriteMemory,
    (PFNVOID)SC_ProcDebug,
    (PFNVOID)SC_ProcGetModInfo,
    (PFNVOID)SC_ProcSetVer,
};

const PFNVOID EvntMthds[] = {
    (PFNVOID)SC_EventCloseHandle,
    (PFNVOID)0,
    (PFNVOID)SC_EventModify,
    (PFNVOID)SC_EventAddAccess,
    (PFNVOID)SC_EventGetData,
    (PFNVOID)SC_EventSetData,
};

const PFNVOID MutxMthds[] = {
    (PFNVOID)SC_MutexCloseHandle,
    (PFNVOID)0,
    (PFNVOID)SC_ReleaseMutex,
};

const PFNVOID SemMthds[] = {
    (PFNVOID)SC_SemCloseHandle,
    (PFNVOID)0,
    (PFNVOID)SC_ReleaseSemaphore,
};

const CINFO cinfThread = {
    "THRD",
    DISPATCH_KERNEL_PSL,
    SH_CURTHREAD,
    sizeof(ThrdMthds)/sizeof(ThrdMthds[0]),
    ThrdMthds
};

const CINFO cinfProc = {
    "PROC",
    DISPATCH_KERNEL_PSL,
    SH_CURPROC,
    sizeof(ProcMthds)/sizeof(ProcMthds[0]),
    ProcMthds
};

const CINFO cinfEvent = {
    "EVNT",
    DISPATCH_KERNEL_PSL,
    HT_EVENT,
    sizeof(EvntMthds)/sizeof(EvntMthds[0]),
    EvntMthds
};

const CINFO cinfMutex = {
    "MUTX",
    DISPATCH_KERNEL_PSL,
    HT_MUTEX,
    sizeof(MutxMthds)/sizeof(MutxMthds[0]),
    MutxMthds
};

const CINFO cinfSem = {
    "SEMP",
    DISPATCH_KERNEL_PSL,
    HT_SEMAPHORE,
    sizeof(SemMthds)/sizeof(SemMthds[0]),
    SemMthds
};

ERRFALSE(offsetof(EVENT, pProxList) == offsetof(PROCESS, pProxList));
ERRFALSE(offsetof(EVENT, pProxList) == offsetof(THREAD, pProxList));
ERRFALSE(offsetof(EVENT, pProxList) == offsetof(STUBEVENT, pProxList));

ERRFALSE(offsetof(CRIT, pProxList) == offsetof(SEMAPHORE, pProxList));
ERRFALSE(offsetof(CRIT, pProxList) == offsetof(MUTEX, pProxList));
ERRFALSE(offsetof(CRIT, pProxList) == offsetof(EVENT, pProxList));
ERRFALSE(offsetof(CRIT, pProxHash) == offsetof(SEMAPHORE, pProxHash));
ERRFALSE(offsetof(CRIT, pProxHash) == offsetof(MUTEX, pProxHash));
ERRFALSE(offsetof(CRIT, pProxHash) == offsetof(EVENT, pProxHash));

ERRFALSE(offsetof(CRIT, bListed) == offsetof(MUTEX, bListed));
ERRFALSE(offsetof(CRIT, bListedPrio) == offsetof(MUTEX, bListedPrio));
ERRFALSE(offsetof(CRIT, pPrevOwned) == offsetof(MUTEX, pPrevOwned));
ERRFALSE(offsetof(CRIT, pNextOwned) == offsetof(MUTEX, pNextOwned));
ERRFALSE(offsetof(CRIT, pUpOwned) == offsetof(MUTEX, pUpOwned));
ERRFALSE(offsetof(CRIT, pDownOwned) == offsetof(MUTEX, pDownOwned));


#define MAX_SECURE_STACK    100         // max # of secure stack
LONG    g_CntSecureStk;

extern DWORD   ROMDllLoadBase;     // this is the low water mark for DLL loaded into per-process's slot
extern DWORD   SharedDllBase;      // base of dlls loaded in slot 1
extern int kstrncmpi(LPCWSTR str1, LPCWSTR str2, int count);

extern BOOL FreePSD (HANDLE hObj);
extern BOOL ACLCheck (HANDLE hObj);
extern DWORD AllocPSD (LPSECURITY_ATTRIBUTES lpsa, LPName *psd);


//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void DbgrNotifyProcCreate (PTHREAD pth, PPROCESS pproc, BOOL fWait)
{
    LPTHRDDBG pThrdDbg = pth->pThrdDbg;
    LPCREATE_PROCESS_DEBUG_INFO pInfo = &pThrdDbg->dbginfo.u.CreateProcessInfo;

    DEBUGCHK (pth == pproc->pMainTh);
    pThrdDbg->dbginfo.dwProcessId = (DWORD)pproc->hProc;
    pThrdDbg->dbginfo.dwThreadId = (DWORD)pth->hTh;
    pThrdDbg->dbginfo.dwDebugEventCode = CREATE_PROCESS_DEBUG_EVENT;
    pInfo->hFile = NULL;
    pInfo->hProcess = pproc->hProc;
    pInfo->hThread = pth->hTh;
    pInfo->lpStartAddress = (LPVOID) pth->dwStartAddr;
    pInfo->lpBaseOfImage = (LPVOID)pproc->dwVMBase;
    pInfo->dwDebugInfoFileOffset = 0;
    pInfo->nDebugInfoSize = 0;
    pInfo->lpThreadLocalBase = pth->tlsPtr;
    pInfo->lpImageName = pproc->lpszProcName;
    pInfo->fUnicode = 1;

    if (fWait) {
        SetEvent (pThrdDbg->hEvent);
        SC_WaitForMultiple (1, &pThrdDbg->hBlockEvent, FALSE, INFINITE);
    }
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void DbgrNotifyThrdCreate (PTHREAD pth, PPROCESS pproc, BOOL fWait, LPTHREAD_START_ROUTINE lpStartAddress)
{
    LPTHRDDBG pThrdDbg = pth->pThrdDbg;
    LPCREATE_THREAD_DEBUG_INFO pInfo = &pThrdDbg->dbginfo.u.CreateThread;

    pThrdDbg->dbginfo.dwProcessId = (DWORD)pproc->hProc;
    pThrdDbg->dbginfo.dwThreadId = (DWORD)pth->hTh;
    pThrdDbg->dbginfo.dwDebugEventCode = CREATE_THREAD_DEBUG_EVENT;

    pInfo->hThread = pth->hTh;
    pInfo->lpStartAddress = lpStartAddress;
    pInfo->lpThreadLocalBase = pth->tlsPtr;

    if (fWait) {
        SetEvent (pThrdDbg->hEvent);
        SC_WaitForMultiple (1, &pThrdDbg->hBlockEvent, FALSE, INFINITE);
    }
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void DbgrNotifyExit (PTHREAD pth, PPROCESS pproc, DWORD dwCode, DWORD dwData)
{
    LPDEBUG_EVENT pDbgInfo = &pth->pThrdDbg->dbginfo;
    LPDWORD pdwCode = (EXIT_PROCESS_DEBUG_EVENT == dwCode)
        ? &pDbgInfo->u.ExitProcess.dwExitCode
        : &pDbgInfo->u.ExitThread.dwExitCode;

    pDbgInfo->dwProcessId = (DWORD)pproc->hProc;
    pDbgInfo->dwThreadId = (DWORD)pth->hTh;
    pDbgInfo->dwDebugEventCode = dwCode;
    *pdwCode = GET_DYING(pth) ? GetUserInfo(pth->hTh) : dwData;
}


//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void DbgrNotifyDllLoad (PTHREAD pth, PPROCESS pproc, BOOL fWait, PMODULE pMod)
{
    LPTHRDDBG pThrdDbg = pth->pThrdDbg;
    LPLOAD_DLL_DEBUG_INFO pInfo = &pThrdDbg->dbginfo.u.LoadDll;
    
    pThrdDbg->dbginfo.dwProcessId = (DWORD)pproc->hProc;
    pThrdDbg->dbginfo.dwThreadId = (DWORD)pth->hTh;
    pThrdDbg->dbginfo.dwDebugEventCode = LOAD_DLL_DEBUG_EVENT;
    pInfo->hFile = NULL;
    pInfo->lpBaseOfDll = (LPVOID)ZeroPtr(pMod->BasePtr);
    pInfo->dwDebugInfoFileOffset = 0;
    pInfo->nDebugInfoSize = 0;
    pInfo->lpImageName = pMod->lpszModName;
    pInfo->fUnicode = 1;

    if (fWait) {
        SetEvent(pth->pThrdDbg->hEvent);
        SC_WaitForMultiple(1,&pth->pThrdDbg->hBlockEvent,FALSE,INFINITE);
    }
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void DbgrNotifyDllUnload (PTHREAD pth, PPROCESS pproc, BOOL fWait, PMODULE pMod)
{
    LPTHRDDBG pThrdDbg = pth->pThrdDbg;
    
    pThrdDbg->dbginfo.dwProcessId = (DWORD)pproc->hProc;
    pThrdDbg->dbginfo.dwThreadId = (DWORD)pth->hTh;
    pThrdDbg->dbginfo.dwDebugEventCode = UNLOAD_DLL_DEBUG_EVENT;

⌨️ 快捷键说明

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