#include <potypes.h>
#include <lpctypes.h>
+//
+// GCC compatibility
+//
+#if defined(__GNUC__)
+#define __ALIGNED(n) __attribute__((aligned (n)))
+#elif defined(_MSC_VER)
+#define __ALIGNED(n) __declspec(align(n))
+#else
+#error __ALIGNED not defined for your compiler!
+#endif
+
//
// Atom and Language IDs
//
//
// Executive Pushlock Wait Block
//
-#ifndef __GNUC__ // WARNING! PUSHLOCKS WILL NOT WORK IN GCC FOR NOW!!!
-__declspec(align(16))
-#endif
+__ALIGNED(16)
typedef struct _EX_PUSH_LOCK_WAIT_BLOCK
{
union
if (InterlockedBitTestAndSet((PLONG)PushLock, EX_PUSH_LOCK_LOCK_V))
{
/* Someone changed it, use the slow path */
+ DbgPrint("%s - Contention!\n", __FUNCTION__);
ExfAcquirePushLockExclusive(PushLock);
}
/* Try acquiring the lock */
NewValue.Value = EX_PUSH_LOCK_LOCK | EX_PUSH_LOCK_SHARE_INC;
- if (!InterlockedCompareExchangePointer(PushLock, NewValue.Ptr, 0))
+ if (InterlockedCompareExchangePointer(PushLock, NewValue.Ptr, 0))
{
/* Someone changed it, use the slow path */
+ DbgPrint("%s - Contention!\n", __FUNCTION__);
ExfAcquirePushLockShared(PushLock);
}
OldValue.Ptr)
{
/* There are still other people waiting on it */
+ DbgPrint("%s - Contention!\n", __FUNCTION__);
ExfReleasePushLockShared(PushLock);
}
}
if ((OldValue.Waiting) && !(OldValue.Waking))
{
/* Wake it up */
+ DbgPrint("%s - Contention!\n", __FUNCTION__);
ExfTryToWakePushLock(PushLock);
}
}
OldValue.Ptr))
{
/* We have waiters, use the long path */
+ DbgPrint("%s - Contention!\n", __FUNCTION__);
ExfReleasePushLock(PushLock);
}
}
#define PSP_MAX_LOAD_IMAGE_NOTIFY 8
#define PSP_MAX_CREATE_PROCESS_NOTIFY 8
-VOID
-NTAPI
-PiInitProcessManager(VOID);
-
VOID
NTAPI
PspShutdownProcessManager(VOID);
PsInitThreadManagment(VOID);
VOID
+INIT_FUNCTION
NTAPI
-PsInitProcessManagment(VOID);
-
-VOID
-NTAPI
-PsInitIdleThread(VOID);
-
-VOID
-NTAPI
-PiTerminateProcessThreads(
- PEPROCESS Process,
- NTSTATUS ExitStatus
-);
-
-VOID
-NTAPI
-PsTerminateCurrentThread(NTSTATUS ExitStatus);
-
-VOID
-NTAPI
-PsTerminateOtherThread(
- PETHREAD Thread,
- NTSTATUS ExitStatus
-);
-
-VOID
-NTAPI
-PsReleaseThread(PETHREAD Thread);
-
-VOID
-NTAPI
-PsBeginThread(
- PKSTART_ROUTINE StartRoutine,
- PVOID StartContext
-);
-
-VOID
-NTAPI
-PsBeginThreadWithContextInternal(VOID);
-
-VOID
-NTAPI
-PiKillMostProcesses(VOID);
-
-NTSTATUS
-STDCALL
-PiTerminateProcess(
- PEPROCESS Process,
- NTSTATUS ExitStatus
-);
-
-VOID
-NTAPI
-PiInitApcManagement(VOID);
-
-VOID
-STDCALL
-PiDeleteThread(PVOID ObjectBody);
-
-VOID
-NTAPI
-PsReapThreads(VOID);
+PiInitProcessManager(VOID);
VOID
NTAPI
-PsInitializeThreadReaper(VOID);
+PsInitProcessManagment(VOID);
VOID
NTAPI
-PsQueueThreadReap(PETHREAD Thread);
-
-NTSTATUS
-NTAPI
-PsInitializeThread(
- PEPROCESS Process,
- PETHREAD* ThreadPtr,
- POBJECT_ATTRIBUTES ObjectAttributes,
- KPROCESSOR_MODE AccessMode,
- BOOLEAN First
-);
+PsInitIdleThread(VOID);
PACCESS_TOKEN
STDCALL
PACCESS_TOKEN* Token
);
-VOID
-STDCALL
-PspTerminateProcessThreads(
- PEPROCESS Process,
- NTSTATUS ExitStatus
-);
-
-NTSTATUS
-NTAPI
-PsSuspendThread(
- PETHREAD Thread,
- PULONG PreviousCount
-);
-
-NTSTATUS
-NTAPI
-PsResumeThread(
- PETHREAD Thread,
- PULONG PreviousCount
-);
-
NTSTATUS
STDCALL
PspAssignPrimaryToken(
BOOLEAN First
);
-VOID
-STDCALL
-PiDeleteProcess(PVOID ObjectBody);
-
VOID
STDCALL
PspReapRoutine(PVOID Context);
BOOLEAN bSelf
);
-NTSTATUS
-NTAPI
-PsUnfreezeOtherThread(PETHREAD Thread);
-
-VOID
-NTAPI
-PsFreezeOtherThread(PETHREAD Thread);
-
-VOID
-NTAPI
-PsFreezeProcessThreads(PEPROCESS Process);
-
-VOID
-NTAPI
-PsUnfreezeProcessThreads(PEPROCESS Process);
-
-ULONG
-NTAPI
-PsEnumThreadsByProcess(PEPROCESS Process);
-
PEPROCESS
STDCALL
PsGetNextProcess(PEPROCESS OldProcess);
-VOID
-NTAPI
-PsApplicationProcessorInit(VOID);
-
-VOID
-NTAPI
-PsPrepareForApplicationProcessorInit(ULONG Id);
-
VOID
STDCALL
PsIdleThreadMain(PVOID Context);
-VOID
-STDCALL
-PiSuspendThreadRundownRoutine(PKAPC Apc);
-
-VOID
-STDCALL
-PiSuspendThreadKernelRoutine(
- PKAPC Apc,
- PKNORMAL_ROUTINE* NormalRoutine,
- PVOID* NormalContext,
- PVOID* SystemArgument1,
- PVOID* SystemArguemnt2
-);
-
-VOID
-STDCALL
-PiSuspendThreadNormalRoutine(
- PVOID NormalContext,
- PVOID SystemArgument1,
- PVOID SystemArgument2
-);
-
-VOID
-NTAPI
-PsInitialiseSuspendImplementation(VOID);
-
VOID
STDCALL
PspExitProcess(BOOLEAN LastThread,
STDCALL
PspDeleteThread(PVOID ObjectBody);
-
-NTSTATUS
-NTAPI
-PsInitWin32Thread(PETHREAD Thread);
-
-VOID
-NTAPI
-PsTerminateWin32Process(PEPROCESS Process);
-
-VOID
-NTAPI
-PsTerminateWin32Thread(PETHREAD Thread);
-
-VOID
-NTAPI
-PsInitialiseW32Call(VOID);
-
VOID
NTAPI
INIT_FUNCTION
STDCALL
PspGetSystemDllEntryPoints(VOID);
-NTSTATUS
-NTAPI
-PsLockProcess(
- PEPROCESS Process,
- BOOLEAN Timeout
-);
-
-VOID
-NTAPI
-PsUnlockProcess(PEPROCESS Process);
-
VOID
NTAPI
PspRemoveProcessFromJob(
extern PEPROCESS PsIdleProcess;
extern LIST_ENTRY PsActiveProcessHead;
extern KGUARDED_MUTEX PspActiveProcessMutex;
-extern LARGE_INTEGER ShortPsLockDelay, PsLockTimeout;
+extern LARGE_INTEGER ShortPsLockDelay;
extern EPROCESS_QUOTA_BLOCK PspDefaultQuotaBlock;
extern PHANDLE_TABLE PspCidTable;
extern PCREATE_THREAD_NOTIFY_ROUTINE
/* lock the process so we can safely assign the process. Note that in the
meanwhile another thread could have assigned this process to a job! */
- Status = PsLockProcess(Process, FALSE);
+ ExAcquireRundownProtection(&Process->RundownProtect);
if(NT_SUCCESS(Status))
{
if(Process->Job == NULL && Process->Session == Job->SessionId)
/* process is already assigned to a job or session id differs! */
Status = STATUS_ACCESS_DENIED;
}
- PsUnlockProcess(Process);
+ ExReleaseRundownProtection(&Process->RundownProtect);
if(NT_SUCCESS(Status))
{
if (Thread->ThreadListEntry.Flink)
{
/* Lock the thread's process */
- PsLockProcess(Process, FALSE);
+ KeEnterCriticalRegion();
+ ExAcquirePushLockExclusive(&Process->ProcessLock);
/* Remove us from the list */
RemoveEntryList(&Thread->ThreadListEntry);
/* Release the lock */
- PsUnlockProcess(Process);
+ ExReleasePushLockExclusive(&Process->ProcessLock);
+ KeLeaveCriticalRegion();
}
/* Dereference the Process */
PspRunCreateThreadNotifyRoutines(Thread, FALSE);
/* Lock the Process before we modify its thread entries */
- PsLockProcess(CurrentProcess, FALSE);
+ KeEnterCriticalRegion();
+ ExAcquirePushLockExclusive(&CurrentProcess->ProcessLock);
- /* Wake up the thread so we don't deadlock on PsLockProcess */
- KeForceResumeThread(&Thread->Tcb);
+ /* Wake up the thread so we don't deadlock on lock */
+ //KeForceResumeThread(&Thread->Tcb);
/* Decrease the active thread count, and check if it's 0 */
if (!(--CurrentProcess->ActiveThreads))
}
/* Unlock the Process */
- PsUnlockProcess(CurrentProcess);
+ ExReleasePushLockExclusive(&CurrentProcess->ProcessLock);
+ KeLeaveCriticalRegion();
/* Check if the process has a debug port and if this is a user thread */
if ((CurrentProcess->DebugPort) && !(Thread->SystemThread))
LIST_ENTRY PsActiveProcessHead;
KGUARDED_MUTEX PspActiveProcessMutex;
-#if 1
-LARGE_INTEGER ShortPsLockDelay, PsLockTimeout;
-#define LockEvent Spare0[0]
-#define LockCount Spare0[1]
-#define LockOwner Spare0[2]
-NTSTATUS
-NTAPI
-PsLockProcess(PEPROCESS Process, BOOLEAN Timeout)
-{
- ULONG Attempts = 0;
- PKTHREAD PrevLockOwner;
- NTSTATUS Status = STATUS_UNSUCCESSFUL;
- PLARGE_INTEGER Delay = (Timeout ? &PsLockTimeout : NULL);
- PKTHREAD CallingThread = KeGetCurrentThread();
-
- PAGED_CODE();
-
- KeEnterCriticalRegion();
-
- for(;;)
- {
- PrevLockOwner = (PKTHREAD)InterlockedCompareExchangePointer(
- &Process->LockOwner, CallingThread, NULL);
- if(PrevLockOwner == NULL || PrevLockOwner == CallingThread)
- {
- /* we got the lock or already locked it */
- if(InterlockedIncrementUL(&Process->LockCount) == 1)
- {
- KeClearEvent(Process->LockEvent);
- }
-
- return STATUS_SUCCESS;
- }
- else
- {
- if(++Attempts > 2)
- {
- Status = KeWaitForSingleObject(Process->LockEvent,
- Executive,
- KernelMode,
- FALSE,
- Delay);
- if(!NT_SUCCESS(Status) || Status == STATUS_TIMEOUT)
- {
-#ifndef NDEBUG
- if(Status == STATUS_TIMEOUT)
- {
- DPRINT1("PsLockProcess(0x%x) timed out!\n", Process);
- }
-#endif
- KeLeaveCriticalRegion();
- break;
- }
- }
- else
- {
- KeDelayExecutionThread(KernelMode, FALSE, &ShortPsLockDelay);
- }
- }
- }
-
- return Status;
-}
-
-VOID
-NTAPI
-PsUnlockProcess(PEPROCESS Process)
-{
- PAGED_CODE();
-
- ASSERT(Process->LockOwner == KeGetCurrentThread());
-
- if(InterlockedDecrementUL(&Process->LockCount) == 0)
- {
- (void)InterlockedExchangePointer(&Process->LockOwner, NULL);
- KeSetEvent(Process->LockEvent, IO_NO_INCREMENT, FALSE);
- }
-
- KeLeaveCriticalRegion();
-}
-#endif
+LARGE_INTEGER ShortPsLockDelay;
/* PRIVATE FUNCTIONS *********************************************************/
PAGED_CODE();
/* Lock the process */
- PsLockProcess(Process, FALSE);
+ KeEnterCriticalRegion();
+ ExAcquirePushLockShared(&Process->ProcessLock);
/* Check if we're already starting somewhere */
if (Thread)
}
/* Unlock the process */
- PsUnlockProcess(Process);
+ ExReleasePushLockShared(&Process->ProcessLock);
+ KeLeaveCriticalRegion();
/* Check if we had a starting thread, and dereference it */
if (Thread) ObDereferenceObject(Thread);
/* Save the pointer to the section object */
Process->SectionObject = SectionObject;
- /* Setup the Lock Event */
-#if 1
- Process->LockEvent = ExAllocatePoolWithTag(PagedPool,
- sizeof(KEVENT),
- TAG('P', 's', 'L', 'k'));
- KeInitializeEvent(Process->LockEvent, SynchronizationEvent, FALSE);
-#endif
-
/* Set default exit code */
Process->ExitStatus = STATUS_TIMEOUT;
OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
ShortPsLockDelay.QuadPart = -100LL;
- PsLockTimeout.QuadPart = -10000000LL; /* one second */
+
/*
* Register the process object type
*/
NULL);
if (!NT_SUCCESS(Status)) break;
- /* Lock the process to be thread-safe! */
- Status = PsLockProcess(Process, FALSE);
- if(NT_SUCCESS(Status))
+ /* Change the pointer */
+ if (InterlockedCompareExchangePointer(&Process->ExceptionPort,
+ ExceptionPort,
+ NULL))
{
- /* Make sure we don't already have a port */
- if (!Process->ExceptionPort)
- {
- /* Save the exception port */
- Process->ExceptionPort = ExceptionPort;
- }
- else
- {
- /* We already have one, fail */
- ObDereferenceObject(ExceptionPort);
- Status = STATUS_PORT_ALREADY_SET;
- }
-
- /* Unlock the process */
- PsUnlockProcess(Process);
- }
- else
- {
- /* Locking failed, dereference the port */
+ /* We already had one, fail */
ObDereferenceObject(ExceptionPort);
+ Status = STATUS_PORT_ALREADY_SET;
}
break;
}
/* FIXME - update the session id for the process token */
- Status = PsLockProcess(Process, FALSE);
+ //Status = PsLockProcess(Process, FALSE);
if (!NT_SUCCESS(Status)) break;
/* Write the session ID in the EPROCESS */
}
/* Unlock the process */
- PsUnlockProcess(Process);
+ //PsUnlockProcess(Process);
break;
/* Priority class: HACK! */