- Add Pushlock support for GCC (Thanks Thomas!)
authorAlex Ionescu <aionescu@gmail.com>
Thu, 20 Jul 2006 17:44:30 +0000 (17:44 +0000)
committerAlex Ionescu <aionescu@gmail.com>
Thu, 20 Jul 2006 17:44:30 +0000 (17:44 +0000)
- Remove a bunch of deprecated crap from ps.h
- Get rid of PsLockProcess, PsUnlockProcess. Use the process pushlock instead.
- When assigning the job, only acquiring rundown protection is enough.
- Use interlocked intrinsics for setting the ExceptionPort instead of locking the entire process object.
- Disable locking in ProcessSessionInformation for NtSetInformationProcess. The whole API seems wrong anyway, on my XP machine calling it does not change the session or change any token data. To verify later...

svn path=/trunk/; revision=23197

reactos/include/ndk/extypes.h
reactos/ntoskrnl/include/internal/ex.h
reactos/ntoskrnl/include/internal/ps.h
reactos/ntoskrnl/ps/job.c
reactos/ntoskrnl/ps/kill.c
reactos/ntoskrnl/ps/process.c
reactos/ntoskrnl/ps/psmgr.c
reactos/ntoskrnl/ps/query.c

index 20603aa..8656815 100644 (file)
@@ -32,6 +32,17 @@ Author:
 #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
 //
@@ -411,9 +422,7 @@ typedef struct _EX_PUSH_LOCK
 //
 // 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
index 056543a..213c31f 100644 (file)
@@ -466,6 +466,7 @@ ExAcquirePushLockExclusive(PEX_PUSH_LOCK PushLock)
     if (InterlockedBitTestAndSet((PLONG)PushLock, EX_PUSH_LOCK_LOCK_V))
     {
         /* Someone changed it, use the slow path */
+        DbgPrint("%s - Contention!\n", __FUNCTION__);
         ExfAcquirePushLockExclusive(PushLock);
     }
 
@@ -500,9 +501,10 @@ ExAcquirePushLockShared(PEX_PUSH_LOCK 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);
     }
 
@@ -575,6 +577,7 @@ ExReleasePushLockShared(PEX_PUSH_LOCK PushLock)
         OldValue.Ptr)
     {
         /* There are still other people waiting on it */
+        DbgPrint("%s - Contention!\n", __FUNCTION__);
         ExfReleasePushLockShared(PushLock);
     }
 }
@@ -621,6 +624,7 @@ ExReleasePushLockExclusive(PEX_PUSH_LOCK PushLock)
     if ((OldValue.Waiting) && !(OldValue.Waking))
     {
         /* Wake it up */
+        DbgPrint("%s - Contention!\n", __FUNCTION__);
         ExfTryToWakePushLock(PushLock);
     }
 }
@@ -672,6 +676,7 @@ ExReleasePushLock(PEX_PUSH_LOCK PushLock)
          OldValue.Ptr))
     {
         /* We have waiters, use the long path */
+        DbgPrint("%s - Contention!\n", __FUNCTION__);
         ExfReleasePushLock(PushLock);
     }
 }
index 3cf057a..5f0b2d6 100644 (file)
@@ -19,10 +19,6 @@ struct _EJOB;
 #define PSP_MAX_LOAD_IMAGE_NOTIFY               8
 #define PSP_MAX_CREATE_PROCESS_NOTIFY           8
 
-VOID
-NTAPI
-PiInitProcessManager(VOID);
-
 VOID
 NTAPI
 PspShutdownProcessManager(VOID);
@@ -32,86 +28,17 @@ NTAPI
 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
@@ -129,27 +56,6 @@ PsOpenTokenOfProcess(
     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(
@@ -198,10 +104,6 @@ PsInitializeIdleOrFirstThread(
     BOOLEAN First
 );
 
-VOID
-STDCALL
-PiDeleteProcess(PVOID ObjectBody);
-
 VOID
 STDCALL
 PspReapRoutine(PVOID Context);
@@ -218,68 +120,14 @@ PspTerminateThreadByPointer(
     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,
@@ -293,23 +141,6 @@ VOID
 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
@@ -341,17 +172,6 @@ NTSTATUS
 STDCALL
 PspGetSystemDllEntryPoints(VOID);
 
-NTSTATUS 
-NTAPI
-PsLockProcess(
-    PEPROCESS Process,
-    BOOLEAN Timeout
-);
-
-VOID
-NTAPI
-PsUnlockProcess(PEPROCESS Process);
-
 VOID
 NTAPI
 PspRemoveProcessFromJob(
@@ -391,7 +211,7 @@ extern PEPROCESS PsInitialSystemProcess;
 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
index fe53a04..f4112b5 100644 (file)
@@ -169,7 +169,7 @@ NtAssignProcessToJobObject (
                 /* 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)
@@ -185,7 +185,7 @@ NtAssignProcessToJobObject (
                         /* process is already assigned to a job or session id differs! */
                         Status = STATUS_ACCESS_DENIED;
                     }
-                    PsUnlockProcess(Process);
+                    ExReleaseRundownProtection(&Process->RundownProtect);
 
                     if(NT_SUCCESS(Status))
                     {
index e9559c2..5c5fe93 100644 (file)
@@ -296,13 +296,15 @@ PspDeleteThread(IN PVOID ObjectBody)
     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 */
@@ -385,10 +387,11 @@ PspExitThread(IN NTSTATUS ExitStatus)
     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))
@@ -425,7 +428,8 @@ PspExitThread(IN NTSTATUS ExitStatus)
     }
 
     /* 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))
index 96d905c..f201c93 100644 (file)
@@ -25,87 +25,7 @@ ULONG PsMinimumWorkingSet, PsMaximumWorkingSet;
 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 *********************************************************/
 
@@ -135,7 +55,8 @@ PsGetNextProcessThread(IN PEPROCESS Process,
     PAGED_CODE();
 
     /* Lock the process */
-    PsLockProcess(Process, FALSE);
+    KeEnterCriticalRegion();
+    ExAcquirePushLockShared(&Process->ProcessLock);
 
     /* Check if we're already starting somewhere */
     if (Thread)
@@ -162,7 +83,8 @@ PsGetNextProcessThread(IN PEPROCESS Process,
     }
 
     /* Unlock the process */
-    PsUnlockProcess(Process);
+    ExReleasePushLockShared(&Process->ProcessLock);
+    KeLeaveCriticalRegion();
 
     /* Check if we had a starting thread, and dereference it */
     if (Thread) ObDereferenceObject(Thread);
@@ -422,14 +344,6 @@ PspCreateProcess(OUT PHANDLE ProcessHandle,
     /* 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;
 
index c265516..d95f057 100644 (file)
@@ -138,7 +138,7 @@ PsInitProcessManagment(VOID)
    OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
 
    ShortPsLockDelay.QuadPart = -100LL;
-   PsLockTimeout.QuadPart = -10000000LL; /* one second */
+
    /*
     * Register the process object type
     */
index 0cb1fca..aab9bf4 100644 (file)
@@ -551,30 +551,14 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
                                                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;
 
@@ -644,7 +628,7 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
             }
 
             /* 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 */
@@ -677,7 +661,7 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
             }
 
             /* Unlock the process */
-            PsUnlockProcess(Process);
+            //PsUnlockProcess(Process);
             break;
 
         /* Priority class: HACK! */