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:
David Welch 2002-08-09 17:23:57 +00:00
parent 5a801d58c3
commit 95fbecfd46
12 changed files with 165 additions and 126 deletions

View file

@ -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

View file

@ -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;
}

View file

@ -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,

View file

@ -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;
}

View file

@ -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 */

View file

@ -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--;

View file

@ -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);

View file

@ -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;

View file

@ -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 */

View file

@ -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

View file

@ -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();
}

View file

@ -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 */