+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
-/* $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 $
*
*
*
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.
printf("Creating %d threads...\n",NR_THREADS*2);
for (i=0;i<NR_THREADS;i++)
{
- CreateThread(NULL,
- 0,
- thread_main1,
- (LPVOID)i,
- 0,
- &id);
+ ThreadHandle[i] = CreateThread(NULL,
+ 0,
+ thread_main1,
+ (LPVOID)i,
+ 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;
}
-/* $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
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
{
UINT uExitCode;
- ThreadAttachDlls ();
-
/* FIXME: notify csrss of thread creation ?? */
uExitCode = (lpStartAddress)(lpParameter);
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,
-/* $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
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)
}
current_entry = current_entry->Flink;
}
+ RtlLeaveCriticalSection (NtCurrentPeb()->LoaderLock);
return;
}
* 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
VOID STDCALL
PsDispatchThread(ULONG NewThreadStatus);
+VOID
+PsInitialiseSuspendImplementation(VOID);
#endif /* ASSEMBLER */
KeAcquireSpinLock(&PiApcLock, &oldlvl);
while(!IsListEmpty(&(Thread->Tcb.ApcState.ApcListHead[0])))
- {
- current = Thread->Tcb.ApcState.ApcListHead[0].Blink;
- Apc = CONTAINING_RECORD(current, KAPC, ApcListEntry);
- if (Apc->NormalRoutine != NULL)
- {
- (VOID)RemoveTailList(&Thread->Tcb.ApcState.ApcListHead[0]);
- Thread->Tcb.ApcState.KernelApcInProgress++;
- Thread->Tcb.ApcState.KernelApcPending--;
-
- KeReleaseSpinLock(&PiApcLock, oldlvl);
-
- NormalRoutine = Apc->NormalRoutine;
- NormalContext = Apc->NormalContext;
- SystemArgument1 = Apc->SystemArgument1;
- SystemArgument2 = Apc->SystemArgument2;
- Apc->KernelRoutine(Apc,
- &NormalRoutine,
- &NormalContext,
- &SystemArgument1,
- &SystemArgument2);
- NormalRoutine(NormalContext, SystemArgument1, SystemArgument2);
-
- KeAcquireSpinLock(&PiApcLock, &oldlvl);
- Thread->Tcb.ApcState.KernelApcInProgress--;
- }
- }
+ {
+ current = Thread->Tcb.ApcState.ApcListHead[0].Blink;
+ Apc = CONTAINING_RECORD(current, KAPC, ApcListEntry);
+ 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--;
+
+ KeReleaseSpinLock(&PiApcLock, oldlvl);
+
+ NormalRoutine = Apc->NormalRoutine;
+ NormalContext = Apc->NormalContext;
+ SystemArgument1 = Apc->SystemArgument1;
+ SystemArgument2 = Apc->SystemArgument2;
+ Apc->KernelRoutine(Apc,
+ &NormalRoutine,
+ &NormalContext,
+ &SystemArgument1,
+ &SystemArgument2);
+ NormalRoutine(NormalContext, SystemArgument1, SystemArgument2);
+
+ KeAcquireSpinLock(&PiApcLock, &oldlvl);
+ Thread->Tcb.ApcState.KernelApcInProgress--;
+ }
KeReleaseSpinLock(&PiApcLock, oldlvl);
}
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
if (Apc->NormalRoutine == NULL)
{
current_entry = current_entry->Flink;
+ Apc->Inserted = FALSE;
RemoveEntryList(&Apc->ApcListEntry);
Thread->Tcb.ApcState.KernelApcInProgress++;
Thread->Tcb.ApcState.KernelApcPending--;
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);
* 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
PiSuspendThreadNormalRoutine,
KernelMode,
NULL);
- KeInitializeSemaphore(&Thread->SuspendSemaphore, 0, 255);
+ KeInitializeSemaphore(&Thread->SuspendSemaphore, 0, 128);
Thread->ThreadListEntry.Flink = NULL;
Thread->ThreadListEntry.Blink = NULL;
Thread->FreezeCount = 0;
* 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
* 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)
+ Semaphore->Header.SignalState += Adjustment;
+ if (InitialState == 0)
{
- // wake up SignalState waiters
- DPRINT("Waking waiters\n");
- KeDispatcherObjectWake(&Semaphore->Header);
+ KeDispatcherObjectWake(&Semaphore->Header);
}
KeReleaseDispatcherDatabaseLock(Wait);
- return initState;
+ return(InitialState);
}
/* EOF */
-/* $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
{
return(Status);
}
-
- /* Attention: TebBase is in user memory space */
Thread->Tcb.Teb = TebBase;
- Thread->StartAddress=NULL;
+ Thread->StartAddress = NULL;
if (Client != NULL)
{
- *Client=Thread->Cid;
+ *Client = Thread->Cid;
}
/*
* 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
return(Status);
}
- Thread->StartAddress=StartRoutine;
+ Thread->StartAddress = StartRoutine;
Status = Ke386InitThread(&Thread->Tcb,
StartRoutine,
StartContext);
return(Status);
}
- if (ClientId!=NULL)
+ if (ClientId != NULL)
{
*ClientId=Thread->Cid;
}
-/* $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
PsInitThreadManagment();
PsInitIdleThread();
PiInitApcManagement();
+ PsInitialiseSuspendImplementation();
}
* 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
*
*/
+/* GLOBALS *******************************************************************/
+
+static FAST_MUTEX SuspendMutex;
+
/* FUNCTIONS *****************************************************************/
VOID STDCALL
PVOID SystemArgument1,
PVOID SystemArgument2)
{
- KeWaitForSingleObject(&PsGetCurrentThread()->Tcb.SuspendSemaphore,
- 0,
- UserMode,
- TRUE,
- NULL);
+ 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);
}
{
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);
}
return(STATUS_SUCCESS);
}
+VOID
+PsInitialiseSuspendImplementation(VOID)
+{
+ ExInitializeFastMutex(&SuspendMutex);
+}
+
/* EOF */