mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
2002-08-09 David Welch <welch@computer2.darkstar.org>
* ntoskrnl/ps/create.c (NtCreateThread): Call PsSuspendThread if NtCreateThread has CreateSuspended as TRUE. * ntoskrnl/ps/suspend.c (PsSuspendThread, PsResumeThread, PiSuspendThreadKernelRoutine): Fixed suspend functionality. 2002-08-09 David Welch <welch@computer2.darkstar.org> * ntoskrnl/ke/i386/usertrap.c (print_user_address): Copy the LDR variable from the right address. 2002-08-09 David Welch <welch@computer2.darkstar.org> * ntoskrnl/ke/apc.c (KiDeliverNormalApc): Check for kernel APCs pending on exit from the kernel. * ntoskrnl/ke/apc.c (KiDeliverNormalApc, KiDeliverUserApc, KiDeliverApc): Set the APC's inserted flag to FALSE after removing it from the thread's queue. 2002-08-09 David Welch <welch@computer2.darkstar.org> * lib/kernel32/thread/thread.c (ThreadStartup): Don't call DLL entrypoints; this is done by LdrInitializeThunk. * lib/ntdll/ldr/startup.c (LdrInitializeThunk): Call DLLs in initialization order; take the loader lock before calling. 2002-08-09 David Welch <welch@computer2.darkstar.org> * apps/tests/thread/thread.c (main): Test suspend and resume functionality. svn path=/trunk/; revision=3324
This commit is contained in:
parent
5a801d58c3
commit
95fbecfd46
12 changed files with 165 additions and 126 deletions
|
@ -1,3 +1,36 @@
|
|||
2002-08-09 David Welch <welch@computer2.darkstar.org>
|
||||
|
||||
* ntoskrnl/ps/create.c (NtCreateThread): Call PsSuspendThread
|
||||
if NtCreateThread has CreateSuspended as TRUE.
|
||||
* ntoskrnl/ps/suspend.c (PsSuspendThread, PsResumeThread,
|
||||
PiSuspendThreadKernelRoutine): Fixed suspend functionality.
|
||||
|
||||
2002-08-09 David Welch <welch@computer2.darkstar.org>
|
||||
|
||||
* ntoskrnl/ke/i386/usertrap.c (print_user_address): Copy
|
||||
the LDR variable from the right address.
|
||||
|
||||
2002-08-09 David Welch <welch@computer2.darkstar.org>
|
||||
|
||||
* ntoskrnl/ke/apc.c (KiDeliverNormalApc): Check for
|
||||
kernel APCs pending on exit from the kernel.
|
||||
* ntoskrnl/ke/apc.c (KiDeliverNormalApc, KiDeliverUserApc,
|
||||
KiDeliverApc): Set the APC's inserted flag to FALSE after
|
||||
removing it from the thread's queue.
|
||||
|
||||
2002-08-09 David Welch <welch@computer2.darkstar.org>
|
||||
|
||||
* lib/kernel32/thread/thread.c (ThreadStartup): Don't
|
||||
call DLL entrypoints; this is done by LdrInitializeThunk.
|
||||
* lib/ntdll/ldr/startup.c (LdrInitializeThunk): Call
|
||||
DLLs in initialization order; take the loader lock before
|
||||
calling.
|
||||
|
||||
2002-08-09 David Welch <welch@computer2.darkstar.org>
|
||||
|
||||
* apps/tests/thread/thread.c (main): Test suspend and
|
||||
resume functionality.
|
||||
|
||||
2002-08-08 David Welch <welch@computer2.darkstar.org>
|
||||
|
||||
* ntoskrnl/mm/section (NtQuerySection): Return the
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: thread.c,v 1.7 2001/02/06 00:11:17 dwelch Exp $
|
||||
/* $Id: thread.c,v 1.8 2002/08/09 17:23:56 dwelch Exp $
|
||||
*
|
||||
*
|
||||
*
|
||||
|
@ -44,7 +44,7 @@ int main (int argc, char* argv[])
|
|||
DWORD i=0;
|
||||
DWORD id;
|
||||
ULONG nr;
|
||||
|
||||
HANDLE ThreadHandle[NR_THREADS];
|
||||
|
||||
// The user must supply one argument (the seed). if he/she doesn't
|
||||
// then we show the help.
|
||||
|
@ -60,16 +60,30 @@ int main (int argc, char* argv[])
|
|||
printf("Creating %d threads...\n",NR_THREADS*2);
|
||||
for (i=0;i<NR_THREADS;i++)
|
||||
{
|
||||
CreateThread(NULL,
|
||||
ThreadHandle[i] = CreateThread(NULL,
|
||||
0,
|
||||
thread_main1,
|
||||
(LPVOID)i,
|
||||
0,
|
||||
CREATE_SUSPENDED,
|
||||
&id);
|
||||
|
||||
}
|
||||
|
||||
for (i=0;i<NR_THREADS;i++)
|
||||
{
|
||||
ResumeThread(ThreadHandle[i]);
|
||||
}
|
||||
|
||||
for (i=0;i<NR_THREADS;i++)
|
||||
{
|
||||
SuspendThread(ThreadHandle[i]);
|
||||
}
|
||||
|
||||
for (i=0;i<NR_THREADS;i++)
|
||||
{
|
||||
ResumeThread(ThreadHandle[i]);
|
||||
}
|
||||
|
||||
printf("All threads created...\n");
|
||||
for(;;);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: thread.c,v 1.26 2001/08/15 20:35:39 ea Exp $
|
||||
/* $Id: thread.c,v 1.27 2002/08/09 17:23:56 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
|
@ -26,16 +26,6 @@
|
|||
|
||||
static VOID ThreadAttachDlls (VOID);
|
||||
|
||||
/* Type for a DLL's entry point */
|
||||
typedef
|
||||
WINBOOL
|
||||
STDCALL
|
||||
(* PDLLMAIN_FUNC) (
|
||||
HANDLE hInst,
|
||||
ULONG ul_reason_for_call,
|
||||
LPVOID lpReserved
|
||||
);
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
static VOID STDCALL
|
||||
|
@ -44,8 +34,6 @@ ThreadStartup (LPTHREAD_START_ROUTINE lpStartAddress,
|
|||
{
|
||||
UINT uExitCode;
|
||||
|
||||
ThreadAttachDlls ();
|
||||
|
||||
/* FIXME: notify csrss of thread creation ?? */
|
||||
|
||||
uExitCode = (lpStartAddress)(lpParameter);
|
||||
|
@ -53,42 +41,6 @@ ThreadStartup (LPTHREAD_START_ROUTINE lpStartAddress,
|
|||
ExitThread(uExitCode);
|
||||
}
|
||||
|
||||
static VOID
|
||||
ThreadAttachDlls (VOID)
|
||||
{
|
||||
PLIST_ENTRY ModuleListHead;
|
||||
PLIST_ENTRY Entry;
|
||||
PLDR_MODULE Module;
|
||||
|
||||
DPRINT("ThreadAttachDlls() called\n");
|
||||
|
||||
RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock);
|
||||
|
||||
ModuleListHead = &NtCurrentPeb()->Ldr->InInitializationOrderModuleList;
|
||||
Entry = ModuleListHead->Blink;
|
||||
|
||||
while (Entry != ModuleListHead)
|
||||
{
|
||||
Module = CONTAINING_RECORD(Entry, LDR_MODULE, InInitializationOrderModuleList);
|
||||
|
||||
if (Module->EntryPoint != 0)
|
||||
{
|
||||
PDLLMAIN_FUNC Entrypoint = (PDLLMAIN_FUNC)Module->EntryPoint;
|
||||
|
||||
DPRINT("Calling entry point at 0x%08x\n", Entrypoint);
|
||||
Entrypoint (Module->BaseAddress,
|
||||
DLL_THREAD_ATTACH,
|
||||
NULL);
|
||||
}
|
||||
|
||||
Entry = Entry->Blink;
|
||||
}
|
||||
|
||||
RtlLeaveCriticalSection (NtCurrentPeb()->LoaderLock);
|
||||
|
||||
DPRINT("ThreadAttachDlls() done\n");
|
||||
}
|
||||
|
||||
HANDLE STDCALL CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||||
DWORD dwStackSize,
|
||||
LPTHREAD_START_ROUTINE lpStartAddress,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: startup.c,v 1.39 2002/08/08 17:54:13 dwelch Exp $
|
||||
/* $Id: startup.c,v 1.40 2002/08/09 17:23:56 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -62,11 +62,14 @@ LdrInitializeThunk (ULONG Unknown1,
|
|||
PDLLMAIN_FUNC Entrypoint;
|
||||
PLDR_MODULE current;
|
||||
|
||||
current_entry = NtCurrentPeb()->Ldr->InLoadOrderModuleList.Flink;
|
||||
while (current_entry != &NtCurrentPeb()->Ldr->InLoadOrderModuleList)
|
||||
RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock);
|
||||
current_entry =
|
||||
NtCurrentPeb()->Ldr->InInitializationOrderModuleList.Flink;
|
||||
while (current_entry !=
|
||||
&NtCurrentPeb()->Ldr->InInitializationOrderModuleList)
|
||||
{
|
||||
current = CONTAINING_RECORD(current_entry, LDR_MODULE,
|
||||
InLoadOrderModuleList);
|
||||
InInitializationOrderModuleList);
|
||||
Entrypoint = (PDLLMAIN_FUNC)current->EntryPoint;
|
||||
if (Entrypoint != NULL &&
|
||||
current->BaseAddress != NtCurrentPeb()->ImageBaseAddress)
|
||||
|
@ -75,6 +78,7 @@ LdrInitializeThunk (ULONG Unknown1,
|
|||
}
|
||||
current_entry = current_entry->Flink;
|
||||
}
|
||||
RtlLeaveCriticalSection (NtCurrentPeb()->LoaderLock);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: ps.h,v 1.37 2002/08/08 17:54:14 dwelch Exp $
|
||||
/* $Id: ps.h,v 1.38 2002/08/09 17:23:56 dwelch Exp $
|
||||
*
|
||||
* FILE: ntoskrnl/ke/kthread.c
|
||||
* PURPOSE: Process manager definitions
|
||||
|
@ -580,6 +580,8 @@ PiTimeoutThread(struct _KDPC *dpc,
|
|||
|
||||
VOID STDCALL
|
||||
PsDispatchThread(ULONG NewThreadStatus);
|
||||
VOID
|
||||
PsInitialiseSuspendImplementation(VOID);
|
||||
|
||||
#endif /* ASSEMBLER */
|
||||
|
||||
|
|
|
@ -93,9 +93,13 @@ KiDeliverNormalApc(VOID)
|
|||
{
|
||||
current = Thread->Tcb.ApcState.ApcListHead[0].Blink;
|
||||
Apc = CONTAINING_RECORD(current, KAPC, ApcListEntry);
|
||||
if (Apc->NormalRoutine != NULL)
|
||||
if (Apc->NormalRoutine == NULL)
|
||||
{
|
||||
DbgPrint("Exiting kernel with kernel APCs pending.\n");
|
||||
KeBugCheck(0);
|
||||
}
|
||||
(VOID)RemoveTailList(&Thread->Tcb.ApcState.ApcListHead[0]);
|
||||
Apc->Inserted = FALSE;
|
||||
Thread->Tcb.ApcState.KernelApcInProgress++;
|
||||
Thread->Tcb.ApcState.KernelApcPending--;
|
||||
|
||||
|
@ -115,7 +119,6 @@ KiDeliverNormalApc(VOID)
|
|||
KeAcquireSpinLock(&PiApcLock, &oldlvl);
|
||||
Thread->Tcb.ApcState.KernelApcInProgress--;
|
||||
}
|
||||
}
|
||||
KeReleaseSpinLock(&PiApcLock, oldlvl);
|
||||
}
|
||||
|
||||
|
@ -161,8 +164,9 @@ KiDeliverUserApc(PKTRAP_FRAME TrapFrame)
|
|||
while (!IsListEmpty(&Thread->ApcState.ApcListHead[1]))
|
||||
{
|
||||
current_entry = RemoveHeadList(&Thread->ApcState.ApcListHead[1]);
|
||||
KeReleaseSpinLock(&PiApcLock, oldlvl);
|
||||
Apc = CONTAINING_RECORD(current_entry, KAPC, ApcListEntry);
|
||||
Apc->Inserted = FALSE;
|
||||
KeReleaseSpinLock(&PiApcLock, oldlvl);
|
||||
|
||||
/*
|
||||
* Save the thread's current context (in other words the registers
|
||||
|
@ -259,6 +263,7 @@ KiDeliverApc(ULONG Unknown1,
|
|||
if (Apc->NormalRoutine == NULL)
|
||||
{
|
||||
current_entry = current_entry->Flink;
|
||||
Apc->Inserted = FALSE;
|
||||
RemoveEntryList(&Apc->ApcListEntry);
|
||||
Thread->Tcb.ApcState.KernelApcInProgress++;
|
||||
Thread->Tcb.ApcState.KernelApcPending--;
|
||||
|
|
|
@ -92,7 +92,7 @@ print_user_address(PVOID address)
|
|||
return(TRUE);
|
||||
}
|
||||
|
||||
Status = MmSafeCopyFromUser(&Ldr, Peb->Ldr, sizeof(PPEB_LDR_DATA));
|
||||
Status = MmSafeCopyFromUser(&Ldr, &Peb->Ldr, sizeof(PPEB_LDR_DATA));
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DbgPrint("<%x>", address);
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: kthread.c,v 1.30 2002/08/08 17:54:14 dwelch Exp $
|
||||
/* $Id: kthread.c,v 1.31 2002/08/09 17:23:57 dwelch Exp $
|
||||
*
|
||||
* FILE: ntoskrnl/ke/kthread.c
|
||||
* PURPOSE: Microkernel thread support
|
||||
|
@ -224,7 +224,7 @@ KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First)
|
|||
PiSuspendThreadNormalRoutine,
|
||||
KernelMode,
|
||||
NULL);
|
||||
KeInitializeSemaphore(&Thread->SuspendSemaphore, 0, 255);
|
||||
KeInitializeSemaphore(&Thread->SuspendSemaphore, 0, 128);
|
||||
Thread->ThreadListEntry.Flink = NULL;
|
||||
Thread->ThreadListEntry.Blink = NULL;
|
||||
Thread->FreezeCount = 0;
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: sem.c,v 1.8 2001/03/16 23:04:59 dwelch Exp $
|
||||
/* $Id: sem.c,v 1.9 2002/08/09 17:23:57 dwelch Exp $
|
||||
*
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/ke/sem.c
|
||||
|
@ -81,30 +81,28 @@ KeReleaseSemaphore (PKSEMAPHORE Semaphore,
|
|||
* object is Not-Signaled.
|
||||
*/
|
||||
{
|
||||
ULONG initState = Semaphore->Header.SignalState;
|
||||
ULONG InitialState;
|
||||
|
||||
DPRINT("KeReleaseSemaphore(Semaphore %x, Increment %d, Adjustment %d, "
|
||||
"Wait %d)\n", Semaphore, Increment, Adjustment, Wait);
|
||||
|
||||
KeAcquireDispatcherDatabaseLock(Wait);
|
||||
|
||||
if (Semaphore->Limit < initState+Adjustment
|
||||
|| initState > initState+Adjustment)
|
||||
InitialState = Semaphore->Header.SignalState;
|
||||
if (Semaphore->Limit < InitialState + Adjustment ||
|
||||
InitialState > InitialState + Adjustment)
|
||||
{
|
||||
ExRaiseStatus(STATUS_SEMAPHORE_LIMIT_EXCEEDED);
|
||||
}
|
||||
|
||||
Semaphore->Header.SignalState += Adjustment;
|
||||
DPRINT("initState %d\n", initState);
|
||||
if(initState == 0)
|
||||
if (InitialState == 0)
|
||||
{
|
||||
// wake up SignalState waiters
|
||||
DPRINT("Waking waiters\n");
|
||||
KeDispatcherObjectWake(&Semaphore->Header);
|
||||
}
|
||||
|
||||
KeReleaseDispatcherDatabaseLock(Wait);
|
||||
return initState;
|
||||
return(InitialState);
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: create.c,v 1.48 2002/08/08 17:54:16 dwelch Exp $
|
||||
/* $Id: create.c,v 1.49 2002/08/09 17:23:57 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -590,8 +590,6 @@ NtCreateThread(PHANDLE ThreadHandle,
|
|||
{
|
||||
return(Status);
|
||||
}
|
||||
|
||||
/* Attention: TebBase is in user memory space */
|
||||
Thread->Tcb.Teb = TebBase;
|
||||
|
||||
Thread->StartAddress = NULL;
|
||||
|
@ -615,6 +613,10 @@ NtCreateThread(PHANDLE ThreadHandle,
|
|||
* If the thread is to be created suspended then queue an APC to
|
||||
* do the suspend before we run any userspace code.
|
||||
*/
|
||||
if (CreateSuspended)
|
||||
{
|
||||
PsSuspendThread(Thread, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Queue an APC to the thread that will execute the ntdll startup
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: psmgr.c,v 1.11 2001/07/12 17:21:06 ekohl Exp $
|
||||
/* $Id: psmgr.c,v 1.12 2002/08/09 17:23:57 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -32,6 +32,7 @@ VOID PiInitProcessManager(VOID)
|
|||
PsInitThreadManagment();
|
||||
PsInitIdleThread();
|
||||
PiInitApcManagement();
|
||||
PsInitialiseSuspendImplementation();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: suspend.c,v 1.7 2002/07/10 15:17:35 ekohl Exp $
|
||||
/* $Id: suspend.c,v 1.8 2002/08/09 17:23:57 dwelch Exp $
|
||||
*
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/ps/suspend.c
|
||||
|
@ -39,6 +39,10 @@
|
|||
*
|
||||
*/
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
static FAST_MUTEX SuspendMutex;
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
VOID STDCALL
|
||||
|
@ -62,20 +66,36 @@ PiSuspendThreadNormalRoutine(PVOID NormalContext,
|
|||
PVOID SystemArgument1,
|
||||
PVOID SystemArgument2)
|
||||
{
|
||||
KeWaitForSingleObject(&PsGetCurrentThread()->Tcb.SuspendSemaphore,
|
||||
PETHREAD CurrentThread = PsGetCurrentThread();
|
||||
while (CurrentThread->Tcb.SuspendCount > 0)
|
||||
{
|
||||
KeWaitForSingleObject(&CurrentThread->Tcb.SuspendSemaphore,
|
||||
0,
|
||||
UserMode,
|
||||
TRUE,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
PsResumeThread(PETHREAD Thread, PULONG SuspendCount)
|
||||
{
|
||||
*SuspendCount = InterlockedDecrement((PULONG)&Thread->Tcb.SuspendCount);
|
||||
KeReleaseSemaphore(&Thread->Tcb.SuspendSemaphore, IO_NO_INCREMENT, 1, FALSE);
|
||||
|
||||
ExAcquireFastMutex(&SuspendMutex);
|
||||
if (SuspendCount != NULL)
|
||||
{
|
||||
*SuspendCount = Thread->Tcb.SuspendCount;
|
||||
}
|
||||
if (Thread->Tcb.SuspendCount > 0)
|
||||
{
|
||||
Thread->Tcb.SuspendCount--;
|
||||
if (Thread->Tcb.SuspendCount == 0)
|
||||
{
|
||||
KeReleaseSemaphore(&Thread->Tcb.SuspendSemaphore, IO_NO_INCREMENT,
|
||||
1, FALSE);
|
||||
}
|
||||
}
|
||||
ExReleaseFastMutex(&SuspendMutex);
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
@ -85,19 +105,21 @@ PsSuspendThread(PETHREAD Thread, PULONG PreviousSuspendCount)
|
|||
{
|
||||
ULONG OldValue;
|
||||
|
||||
OldValue = InterlockedIncrement((PULONG)&Thread->Tcb.SuspendCount);
|
||||
if (OldValue == 0)
|
||||
ExAcquireFastMutex(&SuspendMutex);
|
||||
OldValue = Thread->Tcb.SuspendCount;
|
||||
Thread->Tcb.SuspendCount++;
|
||||
if (!Thread->Tcb.SuspendApc.Inserted)
|
||||
{
|
||||
KeInsertQueueApc(&Thread->Tcb.SuspendApc,
|
||||
NULL,
|
||||
NULL,
|
||||
0);
|
||||
}
|
||||
else
|
||||
ExReleaseFastMutex(&SuspendMutex);
|
||||
if (PreviousSuspendCount != NULL)
|
||||
{
|
||||
InterlockedDecrement(&Thread->Tcb.SuspendSemaphore.Header.SignalState);
|
||||
*PreviousSuspendCount = OldValue;
|
||||
}
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
@ -186,4 +208,10 @@ NtSuspendThread(IN HANDLE ThreadHandle,
|
|||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
VOID
|
||||
PsInitialiseSuspendImplementation(VOID)
|
||||
{
|
||||
ExInitializeFastMutex(&SuspendMutex);
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
Loading…
Reference in a new issue