kernel/eka/nkern/win32/ncthrd.cpp
author hgs
Tue, 26 Oct 2010 12:49:20 +0100
changeset 297 b2826f67641f
parent 279 957c583b417b
permissions -rw-r--r--
201043_03
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
273
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
     1
// Copyright (c) 1998-2010 Nokia Corporation and/or its subsidiary(-ies).
0
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
     2
// All rights reserved.
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
     3
// This component and the accompanying materials are made available
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
     4
// under the terms of the License "Eclipse Public License v1.0"
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
     5
// which accompanies this distribution, and is available
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
     7
//
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
     8
// Initial Contributors:
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
     9
// Nokia Corporation - initial contribution.
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    10
//
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    11
// Contributors:
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    12
//
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    13
// Description:
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    14
// e32\nkern\win32\ncthrd.cpp
273
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    15
//
0
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    16
//
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    17
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    18
// NThreadBase member data
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    19
#define __INCLUDE_NTHREADBASE_DEFINES__
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    20
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    21
#include "nk_priv.h"
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    22
#include <emulator.h>
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    23
273
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    24
#if		defined(__CW32__) && defined(__MWERKS__) && (__MWERKS__ < 0x3200)
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    25
// Early versions didn't support try/except :(
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    26
#error	"This compiler is no longer supported, because it doesn't provide C++ exception generation and handling"
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    27
#endif
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    28
0
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    29
extern "C" void ExcFault(TAny*);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    30
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    31
// initial Win32 thread stack size
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    32
const TInt KInitialStackSize = 0x1000;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    33
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    34
// maximum size of the parameter block passed to a new thread
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    35
const TInt KMaxParameterBlock = 512;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    36
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    37
// data passed to new thread to enable hand-off of the parameter block
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    38
struct SCreateThread
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    39
	{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    40
	const SNThreadCreateInfo* iInfo;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    41
	NFastMutex iHandoff;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    42
	};
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    43
273
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    44
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    45
/** Set some global properties of the emulator
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    46
	Called by the Win32 base port during boot.
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    47
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    48
	@param	aTrace TRUE means trace Win32 thread ID for every thread created
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    49
	@param	aSingleCpu TRUE means lock the emulator process to a single CPU
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    50
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    51
	@internalTechnology
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    52
 */
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    53
EXPORT_C void NThread::SetProperties(TBool aTrace, TInt aSingleCpu)
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    54
	{
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    55
	Win32TraceThreadId = aTrace;
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    56
	Win32SingleCpu = aSingleCpu;
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    57
	}
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    58
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    59
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    60
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    61
void NThread__HandleException(TWin32ExcInfo aExc)
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    62
//
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    63
// Final stage NKern exception handler.
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    64
//
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    65
// The first stage of exception processing (in ExceptionHandler()) entered the
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    66
// kernel and locked it, so we have to undo those two operations before returning.
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    67
// However, if the kernel was already locked when the exception occurred, it is
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    68
// a fatal condition and the system will be faulted.
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    69
//
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    70
// Note that the parameter struct is passed by value, this allows for direct
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    71
// access to the exception context created on the call stack by NThread::Exception().
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    72
//
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    73
	{
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    74
	NKern::Unlock();
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    75
	if (TheScheduler.iKernCSLocked)
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    76
		ExcFault(&aExc);
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    77
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    78
	// Complete the exception data. Note that the call to EnterKernel() in
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    79
	// ExceptionHandler() will have incremented iInKernel after the exception
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    80
	// occurred.
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    81
	NThread* me = static_cast<NThread*>(TheScheduler.iCurrentThread);
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    82
	__NK_ASSERT_DEBUG(me->iInKernel);
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    83
	aExc.iFlags = me->iInKernel == 1 ? 0 : TWin32ExcInfo::EExcInKernel;
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    84
	aExc.iHandler = NULL;
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    85
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    86
	// run NThread exception handler in 'kernel' mode
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    87
	me->iHandlers->iExceptionHandler(&aExc, me);
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    88
	LeaveKernel();
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    89
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    90
	// If a 'user' handler is set by the kernel handler, run it
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    91
	if (aExc.iHandler)
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    92
		aExc.iHandler(aExc.iParam[0], aExc.iParam[1]);
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    93
	}
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    94
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    95
__NAKED__ void NThread::Exception()
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    96
//
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    97
// Trampoline to nKern exception handler
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    98
// Must preserve all registers in the structure defined by TWin32Exc
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
    99
//
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   100
// This is an intermediate layer, to which control has been diverted by
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   101
// NThread::ExceptionHandler(). It constructs a TWin32Exc structure on
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   102
// the stack and passes it NThread__ExceptionHandler().
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   103
//
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   104
// At this point we are no longer in Win32 exception context.
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   105
//
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   106
	{
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   107
	// this is the TWin32Exc structure
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   108
	__asm push Win32ExcAddress			// save return address followed by EBP first to help debugger
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   109
	__asm push ebp
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   110
	__asm mov ebp, esp
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   111
	__asm push cs
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   112
	__asm pushfd
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   113
	__asm push gs
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   114
	__asm push fs
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   115
	__asm push es
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   116
	__asm push ds
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   117
	__asm push ss
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   118
	__asm push edi
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   119
	__asm push esi
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   120
	__asm lea esi, [ebp+8]
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   121
	__asm push esi						// original esp
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   122
	__asm push ebx
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   123
	__asm push edx
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   124
	__asm push ecx
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   125
	__asm push eax
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   126
	__asm push Win32ExcDataAddress
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   127
	__asm push Win32ExcCode
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   128
	__asm sub esp, 20					// struct init completed by NThread__HandleException()
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   129
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   130
	__asm call NThread__HandleException
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   131
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   132
	__asm add esp, 28
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   133
	__asm pop eax
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   134
	__asm pop ecx
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   135
	__asm pop edx
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   136
	__asm pop ebx
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   137
	__asm pop esi						// original ESP - ignore
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   138
	__asm pop esi
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   139
	__asm pop edi
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   140
	__asm pop ebp						// original SS - ignore
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   141
	__asm pop ds
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   142
	__asm pop es
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   143
	__asm pop fs
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   144
	__asm pop gs
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   145
	__asm popfd
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   146
	__asm pop ebp						// original CS - ignore
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   147
	__asm pop ebp
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   148
	__asm ret
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   149
	}
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   150
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   151
// From e32/commmon/win32/seh.cpp
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   152
extern DWORD CallFinalSEHHandler(EXCEPTION_RECORD* aException, CONTEXT* aContext);
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   153
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   154
extern void DivertHook();
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   155
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   156
DWORD NThread::ExceptionHandler(EXCEPTION_RECORD* aException, CONTEXT* aContext)
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   157
//
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   158
// Win32 exception handler for EPOC threads
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   159
//
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   160
// This is the outermost wrapper, called from ExceptionFilter() of via manual
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   161
// interception of the Win32 exception mechanism if using a really old compiler
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   162
//
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   163
	{
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   164
	if (aException->ExceptionCode == EXCEPTION_BREAKPOINT)
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   165
		{
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   166
		// Hardcoded breakpoint
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   167
		//
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   168
		// Jump directly to NT's default unhandled exception handler which will
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   169
		// either display a dialog, directly invoke the JIT debugger or do nothing
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   170
		// dependent upon the AeDebug and ErrorMode registry settings.
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   171
		//
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   172
		// Note this handler is always installed on the SEH chain and is always
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   173
		// the last handler on this chain, as it is installed by NT in kernel32.dll
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   174
		// before invoking the Win32 thread function.
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   175
		return CallFinalSEHHandler(aException, aContext);
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   176
		}
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   177
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   178
	// deal with conflict between preemption and diversion
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   179
	// the diversion will have been applied to the pre-exception context, not
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   180
	// the current context, and thus will get 'lost'. Wake-up of a pre-empted
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   181
	// thread with a diversion will not unlock the kernel, so we need to deal
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   182
	// with the possibility that the kernel may be locked if a diversion exists
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   183
	NThread& me = *static_cast<NThread*>(TheScheduler.iCurrentThread);
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   184
	if (me.iDiverting && me.iDivertFn)
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   185
		{
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   186
		// The thread is being forced to exit - run the diversion outside of Win32 exception handler
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   187
		__NK_ASSERT_ALWAYS(TheScheduler.iKernCSLocked == 1);
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   188
		aContext->Eip = (TUint32)&DivertHook;
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   189
		}
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   190
	else
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   191
		{
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   192
		if (me.iDiverting)
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   193
			{
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   194
			// The thread is being prodded to pick up its callbacks.  This will happen when the
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   195
			// exception handler calls LeaveKernel(), so we can remove the diversion
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   196
			__NK_ASSERT_ALWAYS(TheScheduler.iKernCSLocked == 1);
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   197
			if (aException->ExceptionAddress == &DivertHook)
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   198
				aException->ExceptionAddress = me.iDivertReturn;
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   199
			me.iDivertReturn = NULL;
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   200
			me.iDiverting = EFalse;
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   201
			EnterKernel(TRUE);
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   202
			}
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   203
		else
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   204
			{
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   205
			EnterKernel();
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   206
			TheScheduler.iKernCSLocked = 1;	// prevent pre-emption
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   207
			}
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   208
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   209
		// If the kernel was already locked, this will be detected in the next stage handler
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   210
		// (NThread::Exception()), which we arrange to run outside the Win32 exception context
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   211
		Win32ExcAddress = aException->ExceptionAddress;
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   212
		Win32ExcDataAddress = (TAny*)aException->ExceptionInformation[1];
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   213
		Win32ExcCode = aException->ExceptionCode;
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   214
		aContext->Eip = (TUint32)&Exception;
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   215
		}
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   216
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   217
	return ExceptionContinueExecution;
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   218
	}
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   219
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   220
LONG WINAPI NThread::ExceptionFilter(EXCEPTION_POINTERS* aExc)
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   221
//
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   222
// Filter wrapper for main Win32 exception handler
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   223
//
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   224
	{
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   225
	LONG ret = EXCEPTION_CONTINUE_SEARCH;
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   226
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   227
	switch (ExceptionHandler(aExc->ExceptionRecord, aExc->ContextRecord))
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   228
		{
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   229
	case ExceptionContinueExecution:
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   230
		ret = EXCEPTION_CONTINUE_EXECUTION;
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   231
		break;
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   232
		
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   233
	case ExceptionContinueSearch:
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   234
	default:
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   235
		break;
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   236
		}
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   237
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   238
	return ret;
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   239
	}
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   240
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   241
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   242
DWORD WINAPI NThread::StartThread(LPVOID aParam)
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   243
//
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   244
// Win32 thread function for nKern threads.
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   245
//
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   246
// The thread first enters this function after the nScheduler has resumed
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   247
// it, following the context switch induced by the hand-off mutex.
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   248
//
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   249
// The parameter block for this thread needs to be copied into its
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   250
// own context, before releasing the mutex and handing control back to
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   251
// the creating thread.
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   252
//
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   253
	{
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   254
	SCreateThread* init = static_cast<SCreateThread*>(aParam);
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   255
	NThread& me = *static_cast<NThread*>(init->iHandoff.iHoldingThread);
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   256
	me.iWinThreadId = GetCurrentThreadId();
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   257
	SchedulerRegister(me);
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   258
#ifdef BTRACE_FAST_MUTEX
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   259
	BTraceContext4(BTrace::EFastMutex, BTrace::EFastMutexWait, &init->iHandoff);
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   260
#endif
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   261
	NKern::Unlock();
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   262
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   263
	// intercept win32 exceptions in a debuggabble way
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   264
	__try
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   265
		{
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   266
		// save the thread entry point and parameter block
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   267
		const SNThreadCreateInfo& info = *init->iInfo;
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   268
		NThreadFunction threadFunction = info.iFunction;
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   269
		TUint8 parameterBlock[KMaxParameterBlock];
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   270
		TAny* parameter = (TAny*)info.iParameterBlock;
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   271
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   272
		if (info.iParameterBlockSize)
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   273
			{
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   274
			__NK_ASSERT_DEBUG(TUint(info.iParameterBlockSize) <= TUint(KMaxParameterBlock));
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   275
			memcpy(parameterBlock, info.iParameterBlock, info.iParameterBlockSize);
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   276
			parameter = parameterBlock;
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   277
			}
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   278
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   279
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   280
		// Calculate stack base
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   281
		me.iUserStackBase = (((TLinAddr)&parameterBlock) + 0xfff) & ~0xfff;
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   282
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   283
		// some useful diagnostics for debugging
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   284
		if (Win32TraceThreadId)
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   285
			KPrintf("Thread %T created @ 0x%x - Win32 Thread ID 0x%x", init->iHandoff.iHoldingThread, init->iHandoff.iHoldingThread, GetCurrentThreadId());
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   286
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   287
#ifdef MONITOR_THREAD_CPU_TIME
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   288
		me.iLastStartTime = 0;  // Don't count NThread setup in cpu time
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   289
#endif
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   290
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   291
		// start-up complete, release the handoff mutex, which will re-suspend us
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   292
		NKern::FMSignal(&init->iHandoff);
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   293
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   294
		// thread has been resumed: invoke the thread function
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   295
		threadFunction(parameter);
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   296
		}
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   297
	__except (ExceptionFilter(GetExceptionInformation()))
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   298
		{
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   299
		// Do nothing - filter does all the work and hooks into EPOC
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   300
		// h/w exception mechanism if necessary by thread diversion
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   301
		}
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   302
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   303
	NKern::Exit();
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   304
	return 0;
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   305
	}
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   306
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   307
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   308
0
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   309
/**
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   310
 * Set the Win32 thread priority based on the thread type.
273
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   311
 * Interrupt/Event threads must be able to preempt normal
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   312
 * nKern threads, so they get a higher (Win32) priority.
0
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   313
 */
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   314
static void SetPriority(HANDLE aThread, TEmulThreadType aType)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   315
	{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   316
	TInt p;
273
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   317
0
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   318
	switch (aType)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   319
		{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   320
	default:
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   321
		FAULT();
273
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   322
0
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   323
	case EThreadEvent:
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   324
		p = THREAD_PRIORITY_ABOVE_NORMAL;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   325
		break;
273
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   326
0
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   327
	case EThreadNKern:
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   328
		p = THREAD_PRIORITY_NORMAL;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   329
		break;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   330
		}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   331
273
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   332
	CheckedSetThreadPriority(aThread, p);
0
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   333
	SetThreadPriorityBoost(aThread, TRUE);		// disable priority boost (for NT)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   334
	}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   335
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   336
/**	Create a Win32 thread for use in the emulator.
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   337
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   338
	@param	aType Type of thread (Event or NKern) - determines Win32 priority
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   339
	@param	aThreadFunc Entry point of thread
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   340
	@param	aPtr Argument passed to entry point
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   341
	@param	aRun TRUE if thread should be resumed immediately
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   342
	@return	The Win32 handle to the thread, 0 if an error occurred
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   343
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   344
	@pre    Call either in thread context.
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   345
	@pre	Do not call from bare Win32 threads.
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   346
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   347
	@see TEmulThreadType
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   348
 */
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   349
EXPORT_C HANDLE CreateWin32Thread(TEmulThreadType aType, LPTHREAD_START_ROUTINE aThreadFunc, LPVOID aPtr, TBool aRun)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   350
	{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   351
	__NK_ASSERT_DEBUG(!TheScheduler.iCurrentThread || NKern::CurrentContext() == NKern::EThread);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   352
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   353
	__LOCK_HOST;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   354
	
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   355
	DWORD id;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   356
	HANDLE handle = CreateThread(NULL , KInitialStackSize, aThreadFunc, aPtr, CREATE_SUSPENDED, &id);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   357
	if (handle)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   358
		{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   359
		SetPriority(handle, aType);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   360
		if (aRun)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   361
			ResumeThread(handle);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   362
		}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   363
	return handle;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   364
	}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   365
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   366
static HANDLE InitThread()
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   367
//
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   368
// Set up the initial thread and return the thread handle
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   369
//
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   370
	{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   371
	HANDLE p = GetCurrentProcess();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   372
	HANDLE me;
273
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   373
	DWORD r = DuplicateHandle(p, GetCurrentThread(), p, &me, 0, FALSE, DUPLICATE_SAME_ACCESS);
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   374
	__NK_ASSERT_ALWAYS(r != 0);						// r is zero on error
0
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   375
	SetPriority(me, EThreadNKern);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   376
	return me;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   377
	}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   378
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   379
TInt NThread::Create(SNThreadCreateInfo& aInfo, TBool aInitial)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   380
	{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   381
	iWinThread = NULL;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   382
	iWinThreadId = 0;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   383
	iScheduleLock = NULL;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   384
	iInKernel = 1;
273
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   385
	iDivertFn = NULL;
0
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   386
	iWakeup = aInitial ? ERelease : EResumeLocked;	// mark new threads as created (=> win32 suspend)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   387
273
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   388
	TInt r = NThreadBase::Create(aInfo, aInitial);
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   389
	if (r != KErrNone)
0
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   390
		return r;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   391
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   392
	// the rest has to be all or nothing, we must complete it
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   393
	iScheduleLock = CreateEventA(NULL, FALSE, FALSE, NULL);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   394
	if (iScheduleLock == NULL)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   395
		return Emulator::LastError();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   396
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   397
	if (aInitial)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   398
		{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   399
		iWinThread = InitThread();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   400
		FastCounterInit();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   401
#ifdef MONITOR_THREAD_CPU_TIME
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   402
		iLastStartTime = NKern::FastCounter();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   403
#endif
273
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   404
		iUserStackBase = (((TLinAddr)&r) + 0xfff) & ~0xfff; // base address of stack
0
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   405
		SchedulerInit(*this);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   406
		return KErrNone;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   407
		}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   408
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   409
	// create the thread proper
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   410
	//
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   411
	SCreateThread start;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   412
	start.iInfo = &aInfo;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   413
	iWinThread = CreateWin32Thread(EThreadNKern, &StartThread, &start, FALSE);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   414
	if (iWinThread == NULL)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   415
		{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   416
		r = Emulator::LastError();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   417
		CloseHandle(iScheduleLock);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   418
		return r;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   419
		}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   420
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   421
#ifdef BTRACE_THREAD_IDENTIFICATION
273
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   422
	BTrace4(BTrace::EThreadIdentification, BTrace::ENanoThreadCreate, this);
0
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   423
#endif
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   424
	// switch to the new thread to hand over the parameter block
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   425
	NKern::Lock();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   426
	ForceResume();	// mark the thread as ready
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   427
	// give the thread ownership of the handoff mutex
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   428
	start.iHandoff.iHoldingThread = this;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   429
	iHeldFastMutex = &start.iHandoff;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   430
	Suspend(1);		// will defer as holding a fast mutex (implicit critical section)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   431
	// do the hand-over
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   432
	start.iHandoff.Wait();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   433
	start.iHandoff.Signal();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   434
	NKern::Unlock();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   435
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   436
	return KErrNone;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   437
	}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   438
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   439
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   440
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   441
void NThread::Diverted()
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   442
//
273
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   443
// This function is called in the context of a thread that is being diverted.
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   444
// This can be for either of two reasons: if iDivertFn has been set, that
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   445
// function will be called and is not expected to return i.e.  it should force
279
957c583b417b 201039_07
hgs
parents: 273
diff changeset
   446
// the thread to exit (in this case, the thread may already be in the kernel,
957c583b417b 201039_07
hgs
parents: 273
diff changeset
   447
// but only at a place where it's safe for it to be killed).  Otherwise, the
957c583b417b 201039_07
hgs
parents: 273
diff changeset
   448
// thread must be in user mode, and it's forced to make a null trip through
957c583b417b 201039_07
hgs
parents: 273
diff changeset
   449
// the kernel, causing it to run pending user-mode callbacks on the way out.
273
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   450
//
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   451
// On entry, the kernel is locked and interrupts enabled
0
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   452
//
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   453
	{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   454
	NThread& me = *static_cast<NThread*>(TheScheduler.iCurrentThread);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   455
	__NK_ASSERT_ALWAYS(TheScheduler.iKernCSLocked == 1);
273
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   456
	__NK_ASSERT_ALWAYS(me.iDiverting);
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   457
	NThread::TDivert divertFn = me.iDivertFn;
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   458
	me.iDivertFn = NULL;
0
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   459
	me.iDivertReturn = NULL;
273
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   460
	me.iDiverting = EFalse;
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   461
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   462
	EnterKernel(TRUE);
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   463
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   464
	if (divertFn)
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   465
		divertFn();					// does not return
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   466
0
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   467
	NKern::Unlock();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   468
	LeaveKernel();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   469
	}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   470
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   471
void NThread__Diverted()
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   472
	{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   473
	NThread::Diverted();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   474
	}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   475
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   476
__NAKED__ void DivertHook()
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   477
	{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   478
	// The stack frame is set up like this:
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   479
	//
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   480
	//		| return address |
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   481
	//		| frame pointer  |
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   482
	//		| flags			 |
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   483
	//		| saved eax		 |
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   484
	//		| saved ecx		 |
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   485
	//      | saved edx		 |
273
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   486
	//
0
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   487
	__asm push eax					// reserve word for return address
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   488
	__asm push ebp
273
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   489
	__asm mov ebp, esp
0
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   490
	__asm pushfd
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   491
	__asm push eax
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   492
	__asm push ecx
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   493
	__asm push edx
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   494
	__asm mov eax, [TheScheduler.iCurrentThread]
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   495
	__asm mov eax, [eax]NThread.iDivertReturn
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   496
	__asm mov [esp + 20], eax		// store return address
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   497
	__asm call NThread__Diverted
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   498
	__asm pop edx
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   499
	__asm pop ecx
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   500
	__asm pop eax
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   501
	__asm popfd
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   502
	__asm pop ebp
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   503
	__asm ret
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   504
	}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   505
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   506
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   507
void NThread::ApplyDiversion()
273
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   508
//
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   509
// Arrange that the thread will be diverted when next it runs.
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   510
// This can be for either of two reasons: if iDivertFn has been set,
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   511
// that function will be called and is not expected to return i.e.
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   512
// it should force the thread to exit. Otherwise, the thread will
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   513
// make a null trip through the kernel, causing it to run pending
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   514
// user-mode callbacks on the way out.
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   515
//
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   516
// This uses the Win32 CONTEXT functions to change the thread's PC
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   517
// so that execution restarts at DivertHook ...
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   518
//
0
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   519
	{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   520
	// Called with interrupts disabled and kernel locked
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   521
	__NK_ASSERT_ALWAYS(TheScheduler.iKernCSLocked == 1);
273
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   522
	__NK_ASSERT_ALWAYS(iDivertReturn == NULL || iDiverting);
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   523
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   524
	if (iDiverting)
0
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   525
		return;
273
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   526
0
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   527
	CONTEXT c;
273
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   528
	c.ContextFlags = CONTEXT_CONTROL;
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   529
	CheckedGetThreadContext(iWinThread, &c);
0
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   530
	iDivertReturn = (TAny*)c.Eip;
273
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   531
	c.Eip = (TUint32)&DivertHook;
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   532
	c.ContextFlags = CONTEXT_CONTROL;
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   533
	CheckedSetThreadContext(iWinThread, &c);
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   534
	iDiverting = ETrue;
0
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   535
	}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   536
273
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   537
void NThread::Divert(TDivert aDivertFn)
0
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   538
//
273
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   539
// Arrange that the thread will exit by calling aDivertFn when next
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   540
// it runs.  The diversion function will be called with the kernel
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   541
// locked and interrupts enabled.  It is not expected to return.
0
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   542
//
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   543
	{
273
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   544
	iDivertFn = aDivertFn;
0
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   545
	if (iWakeup == EResume)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   546
		iWakeup = EResumeDiverted;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   547
	else
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   548
		__NK_ASSERT_ALWAYS(iWakeup == ERelease);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   549
	}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   550
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   551
void NThread::ExitSync()
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   552
//
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   553
// Diversion used to terminate 'stillborn' threads.
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   554
// On entry, kernel is locked, interrupts are enabled and we hold an interlock mutex
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   555
//
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   556
	{
273
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   557
	NThreadBase& me = *TheScheduler.iCurrentThread;
0
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   558
	me.iHeldFastMutex->Signal();	// release the interlock
273
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   559
	me.iNState = EDead;				// mark ourselves as dead which will take thread out of scheduler
0
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   560
	TheScheduler.Remove(&me);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   561
	RescheduleNeeded();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   562
	TScheduler::Reschedule();	// this won't return
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   563
	FAULT();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   564
	}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   565
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   566
void NThread::Stillborn()
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   567
//
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   568
// Called if the new thread creation was aborted - so it will not be killed in the usual manner
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   569
//
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   570
// This function needs to exit the thread synchronously as on return we will destroy the thread control block
273
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   571
// Thus we need to use an interlock that ensure that the target thread runs the exit handler before we continue
0
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   572
//
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   573
	{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   574
	// check if the Win32 thread was created
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   575
	if (!iWinThread)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   576
		return;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   577
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   578
	NKern::Lock();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   579
	Divert(&ExitSync);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   580
	ForceResume();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   581
	// create and assign mutex to stillborn thread
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   582
	NFastMutex interlock;
273
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   583
	interlock.iHoldingThread = this;
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   584
	iHeldFastMutex = &interlock;
0
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   585
	interlock.Wait();			// interlock on thread exit handler
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   586
	interlock.Signal();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   587
	NKern::Unlock();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   588
	}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   589
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   590
void NThread::ExitAsync()
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   591
//
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   592
// Diversion used to terminate 'killed' threads.
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   593
// On entry, kernel is locked and interrupts are enabled
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   594
//
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   595
	{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   596
	NThreadBase& me = *TheScheduler.iCurrentThread;
273
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   597
	__NK_ASSERT_ALWAYS(static_cast<NThread&>(me).iInKernel > 0);
0
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   598
	me.iCsCount = 0;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   599
	me.Exit();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   600
	}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   601
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   602
inline void NThread::DoForceExit()
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   603
	{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   604
	__NK_ASSERT_DEBUG(TheScheduler.iKernCSLocked);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   605
	Divert(&ExitAsync);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   606
	}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   607
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   608
void NThreadBase::ForceExit()
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   609
//
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   610
// Called to force the thread to exit when it resumes
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   611
//
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   612
	{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   613
	static_cast<NThread*>(this)->DoForceExit();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   614
	}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   615
273
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   616
void NThreadBase::OnExit()
0
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   617
	{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   618
	}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   619
273
6a75fa55495f 201037_09
hgs
parents: 0
diff changeset
   620
void NThreadBase::OnKill()
0
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   621
	{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   622
	}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   623