[ros-diffs] [ion] 20426: Move some profile stuff to NDK and fix some bugs in the executive implementation, as well as support segmented profile objects

ion at svn.reactos.org ion at svn.reactos.org
Thu Dec 29 18:55:51 CET 2005


Move some profile stuff to NDK and fix some bugs in the executive
implementation, as well as support segmented profile objects
Modified: trunk/reactos/include/ndk/extypes.h
Modified: trunk/reactos/ntoskrnl/ex/profile.c
Modified: trunk/reactos/ntoskrnl/include/internal/ke.h
  _____  

Modified: trunk/reactos/include/ndk/extypes.h
--- trunk/reactos/include/ndk/extypes.h	2005-12-29 15:14:50 UTC (rev
20425)
+++ trunk/reactos/include/ndk/extypes.h	2005-12-29 17:55:31 UTC (rev
20426)
@@ -55,46 +55,58 @@

 //
 // Invalid Handle Value Constant
 //
-#define INVALID_HANDLE_VALUE            (HANDLE)-1
+#define INVALID_HANDLE_VALUE                (HANDLE)-1
 
 #endif
 
 //
 // Increments
 //
-#define MUTANT_INCREMENT                1
+#define MUTANT_INCREMENT                    1
 
 //
 // Callback Object Access Mask
 //
-#define CALLBACK_ALL_ACCESS
(STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x0001)
-#define CALLBACK_EXECUTE
(STANDARD_RIGHTS_EXECUTE|SYNCHRONIZE|0x0001)
-#define CALLBACK_WRITE
(STANDARD_RIGHTS_WRITE|SYNCHRONIZE|0x0001)
-#define CALLBACK_READ
(STANDARD_RIGHTS_READ|SYNCHRONIZE|0x0001)
+#define CALLBACK_ALL_ACCESS
(STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x0001)
+#define CALLBACK_EXECUTE
(STANDARD_RIGHTS_EXECUTE|SYNCHRONIZE|0x0001)
+#define CALLBACK_WRITE
(STANDARD_RIGHTS_WRITE|SYNCHRONIZE|0x0001)
+#define CALLBACK_READ
(STANDARD_RIGHTS_READ|SYNCHRONIZE|0x0001)
 
 //
 // Event Object Access Masks
 //
 #ifdef NTOS_MODE_USER
-#define EVENT_QUERY_STATE               0x0001
+#define EVENT_QUERY_STATE                   0x0001
 
 //
 // Semaphore Object Acess Masks
 //
-#define SEMAPHORE_QUERY_STATE           0x0001
+#define SEMAPHORE_QUERY_STATE               0x0001
 #endif
 
 //
 // Event Pair Access Masks
 //
-#define EVENT_PAIR_ALL_ACCESS           0x1F0000L
+#define EVENT_PAIR_ALL_ACCESS               0x1F0000L
 
 //
+// Profile Object Access Masks
+//
+#define PROFILE_CONTROL                     0x0001
+#define PROFILE_ALL_ACCESS                  (STANDARD_RIGHTS_REQUIRED |
PROFILE_CONTROL)
+
+//
 // Maximum Parameters for NtRaiseHardError
 //
-#define MAXIMUM_HARDERROR_PARAMETERS    4
+#define MAXIMUM_HARDERROR_PARAMETERS        4
 
 //
+// Pushlock Wait Block Flags
+//
+#define EX_PUSH_LOCK_FLAGS_EXCLUSIVE        1
+#define EX_PUSH_LOCK_FLAGS_WAIT             2
+
+//
 // Shutdown types for NtShutdownSystem
 //
 typedef enum _SHUTDOWN_ACTION
@@ -271,8 +283,21 @@
 } EX_FAST_REF, *PEX_FAST_REF;
 
 //
-// Executive Fast Reference Wait Block
+// Executive Cache-Aware Rundown Reference Descriptor
 //
+typedef struct _EX_RUNDOWN_REF_CACHE_AWARE
+{
+    union
+    {
+        ULONG_PTR Count;
+        PVOID Ptr;
+    };
+    PVOID PoolToFree;
+} EX_RUNDOWN_REF_CACHE_AWARE, *PEX_RUNDOWN_REF_CACHE_AWARE;
+
+//
+// Executive Rundown Wait Block
+//
 typedef struct _EX_RUNDOWN_WAIT_BLOCK
 {
     ULONG_PTR Count;
@@ -280,6 +305,32 @@
 } EX_RUNDOWN_WAIT_BLOCK, *PEX_RUNDOWN_WAIT_BLOCK;
 
 //
+// Executive Pushlock Wait Block
+//
+#ifndef __GNUC__ // WARNING! PUSHLOCKS WILL NOT WORK IN GCC FOR NOW!!!
+__declspec(align(16))
+#endif
+typedef struct _EX_PUSH_LOCK_WAIT_BLOCK
+{
+    union
+    {
+        KGATE WakeGate;
+        KEVENT WakeEvent;
+    };
+    struct _EX_PUSH_LOCK_WAIT_BLOCK *Next;
+    struct _EX_PUSH_LOCK_WAIT_BLOCK *Last;
+    struct _EX_PUSH_LOCK_WAIT_BLOCK *Previous;
+    LONG ShareCount;
+    LONG Flags;
+#if DBG
+    BOOL Signaled;
+    EX_PUSH_LOCK NewValue;
+    EX_PUSH_LOCK OldValue;
+    PEX_PUSH_LOCK PushLock;
+#endif
+} EX_PUSH_LOCK_WAIT_BLOCK, *PEX_PUSH_LOCK_WAIT_BLOCK;
+
+//
 // Callback Object
 //
 typedef struct _CALLBACK_OBJECT
@@ -291,6 +342,25 @@
 } CALLBACK_OBJECT , *PCALLBACK_OBJECT;
 
 //
+// Profile OBject
+//
+typedef struct _EPROFILE
+{
+    PEPROCESS Process;
+    PVOID ImageBase;
+    SIZE_T ImageSize;
+    PVOID Buffer;
+    ULONG BufferSize;
+    ULONG BucketSize;
+    PKPROFILE KeProfile;
+    PVOID LockedBuffer;
+    PMDL Mdl;
+    ULONG Segment;
+    KPROFILE_SOURCE ProfileSource;
+    KAFFINITY Affinity;
+} EPROFILE, *PEPROFILE;
+
+//
 // Handle Table Structures
 //
 typedef struct _HANDLE_TABLE_ENTRY_INFO
  _____  

Modified: trunk/reactos/ntoskrnl/ex/profile.c
--- trunk/reactos/ntoskrnl/ex/profile.c	2005-12-29 15:14:50 UTC (rev
20425)
+++ trunk/reactos/ntoskrnl/ex/profile.c	2005-12-29 17:55:31 UTC (rev
20426)
@@ -1,65 +1,55 @@

 /*
  * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS kernel
+ * PROJECT:         ReactOS Kernel
  * FILE:            ntoskrnl/ex/profile.c
  * PURPOSE:         Support for Executive Profile Objects
- *
- * PROGRAMMERS:     Alex Ionescu
+ * PROGRAMMERS:     Alex Ionescu (alex at relsoft.net)
+ *                  Thomas Weidenmueller
  */
 
 /* INCLUDES
*****************************************************************/
 
+#include <ntoskrnl.h>
 #define NDEBUG
-#include <ntoskrnl.h>
 #include <internal/debug.h>
 
 #if defined (ALLOC_PRAGMA)
 #pragma alloc_text(INIT, ExpInitializeProfileImplementation)
 #endif
 
-/* FIXME: NDK This structure is a *GUESS* -- Alex */
-typedef struct _EPROFILE {
-    PEPROCESS Process;
-    PVOID ImageBase;
-    ULONG ImageSize;
-    ULONG BucketSize;
-    PVOID Buffer;
-    ULONG BufferSize;
-    PKPROFILE KeProfile;
-    KPROFILE_SOURCE ProfileSource;
-    KAFFINITY Affinity;
-    PMDL Mdl;
-    PVOID LockedBuffer;
-} EPROFILE, *PEPROFILE;
+#define TAG_PROFILE TAG('P', 'r', 'o', 'f')
 
 /* GLOBALS
*******************************************************************/
 
 POBJECT_TYPE ExProfileObjectType = NULL;
+KMUTEX ExpProfileMutex;
 
-static KMUTEX ExpProfileMutex;
-
-#define PROFILE_CONTROL 1
-
-static GENERIC_MAPPING ExpProfileMapping = {
+GENERIC_MAPPING ExpProfileMapping =
+{
     STANDARD_RIGHTS_READ    | PROFILE_CONTROL,
     STANDARD_RIGHTS_WRITE   | PROFILE_CONTROL,
     STANDARD_RIGHTS_EXECUTE | PROFILE_CONTROL,
-    STANDARD_RIGHTS_ALL};
+    PROFILE_ALL_ACCESS
+};
 
+/* FUNCTIONS
*****************************************************************/
+
 VOID
-STDCALL
+NTAPI
 ExpDeleteProfile(PVOID ObjectBody)
 {
     PEPROFILE Profile;
+    ULONG State;
 
     /* Typecast the Object */
     Profile = (PEPROFILE)ObjectBody;
 
     /* Check if there if the Profile was started */
-    if (Profile->LockedBuffer) {
-
+    if (Profile->LockedBuffer)
+    {
         /* Stop the Profile */
-        KeStopProfile(Profile->KeProfile);
+        State = KeStopProfile(Profile->KeProfile);
+        ASSERT(State != FALSE);
 
         /* Unmap the Locked Buffer */
         MmUnmapLockedPages(Profile->LockedBuffer, Profile->Mdl);
@@ -67,28 +57,22 @@
         ExFreePool(Profile->Mdl);
     }
 
-    /* Check if a Process is associated */
-    if (Profile->Process != NULL) {
-
-        /* Dereference it */
-        ObDereferenceObject(Profile->Process);
-        Profile->Process = NULL;
-    }
+    /* Check if a Process is associated and reference it */
+    if (Profile->Process) ObDereferenceObject(Profile->Process);
 }
 
 VOID
 INIT_FUNCTION
-STDCALL
+NTAPI
 ExpInitializeProfileImplementation(VOID)
 {
     OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
     UNICODE_STRING Name;
-  
+    DPRINT("Creating Profile Object Type\n");
+
     /* Initialize the Mutex to lock the States */
-    KeInitializeMutex(&ExpProfileMutex, 0x40);
+    KeInitializeMutex(&ExpProfileMutex, 64);
 
-    DPRINT("Creating Profile Object Type\n");
-  
     /* Create the Event Pair Object Type */
     RtlZeroMemory(&ObjectTypeInitializer,
sizeof(ObjectTypeInitializer));
     RtlInitUnicodeString(&Name, L"Profile");
@@ -97,12 +81,12 @@
     ObjectTypeInitializer.GenericMapping = ExpProfileMapping;
     ObjectTypeInitializer.PoolType = NonPagedPool;
     ObjectTypeInitializer.DeleteProcedure = ExpDeleteProfile;
-    ObjectTypeInitializer.ValidAccessMask = STANDARD_RIGHTS_ALL;
+    ObjectTypeInitializer.ValidAccessMask = PROFILE_ALL_ACCESS;
     ObpCreateTypeObject(&ObjectTypeInitializer, &Name,
&ExProfileObjectType);
 }
 
 NTSTATUS
-STDCALL
+NTAPI
 NtCreateProfile(OUT PHANDLE ProfileHandle,
                 IN HANDLE Process OPTIONAL,
                 IN PVOID ImageBase,
@@ -119,33 +103,79 @@
     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
     OBJECT_ATTRIBUTES ObjectAttributes;
     NTSTATUS Status = STATUS_SUCCESS;
-
+    ULONG Segment = 0, Log2 = 0;
     PAGED_CODE();
 
     /* Easy way out */
-    if(BufferSize == 0) return STATUS_INVALID_PARAMETER_7;
+    if(!BufferSize) return STATUS_INVALID_PARAMETER_7;
 
-    /* Check the Parameters for validity */
-    if(PreviousMode != KernelMode) {
+    /* Check if this is a low-memory profile */
+    if ((!BucketSize) && (ImageBase < (PVOID)(0x10000)))
+    {
+        /* Validate size */
+        if (BufferSize < sizeof(ULONG)) return
STATUS_INVALID_PARAMETER_7;
 
-        _SEH_TRY {
+        /* This will become a segmented profile object */
+        Segment = (ULONG)ImageBase;
+        ImageBase = 0;
 
+        /* Recalculate the bucket size */
+        BucketSize = ImageSize / (BufferSize / sizeof(ULONG));
+
+        /* Convert it to log2 */
+        BucketSize--;
+        while (BucketSize >>= 1) Log2++;
+        BucketSize += Log2 + 1;
+    }
+
+    /* Validate bucket size */
+    if ((BucketSize > 31) || (BucketSize < 2))
+    {
+        DPRINT1("Bucket size invalid\n");
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    /* Make sure that the buckets can map the range */
+    if ((ImageSize >> (BucketSize - 2)) > BufferSize)
+    {
+        DPRINT1("Bucket size too small\n");
+        return STATUS_BUFFER_TOO_SMALL;
+    }
+
+    /* Make sure that the range isn't too gigantic */
+    if (((ULONG_PTR)ImageBase + ImageSize) < ImageSize)
+    {
+        DPRINT1("Range too big\n");
+        return STATUS_BUFFER_OVERFLOW;
+    }
+
+    /* Check if we were called from user-mode */
+    if(PreviousMode != KernelMode)
+    {
+        /* Entry SEH */
+        _SEH_TRY
+        {
+            /* Make sure that the handle pointer is valid */
             ProbeForWriteHandle(ProfileHandle);
 
+            /* Check if the buffer is valid */
             ProbeForWrite(Buffer,
                           BufferSize,
                           sizeof(ULONG));
-        } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+        }
+        _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
+        {
             Status = _SEH_GetExceptionCode();
-        } _SEH_END;
+        }
+        _SEH_END;
 
+        /* Bail out if we failed */
         if(!NT_SUCCESS(Status)) return Status;
     }
 
     /* Check if a process was specified */
-    if (Process) {
-
+    if (Process)
+    {
         /* Reference it */
         Status = ObReferenceObjectByHandle(Process,
                                            PROCESS_QUERY_INFORMATION,
@@ -154,15 +184,18 @@
                                            (PVOID*)&pProcess,
                                            NULL);
         if (!NT_SUCCESS(Status)) return(Status);
+    }
+    else
+    {
+        /* Segmented profile objects cannot be used system-wide */
+        if (Segment) return STATUS_INVALID_PARAMETER;
 
-    } else {
-
         /* No process was specified, which means a System-Wide Profile
*/
         pProcess = NULL;
 
         /* For this, we need to check the Privilege */
-        if(!SeSinglePrivilegeCheck(SeSystemProfilePrivilege,
PreviousMode)) {
-
+        if(!SeSinglePrivilegeCheck(SeSystemProfilePrivilege,
PreviousMode))
+        {
             DPRINT1("NtCreateProfile: Caller requires the
SeSystemProfilePrivilege privilege!\n");
             return STATUS_PRIVILEGE_NOT_HELD;
         }
@@ -181,7 +214,7 @@
                             NULL,
                             sizeof(EPROFILE),
                             0,
-                            0,
+                            sizeof(EPROFILE) + sizeof(KPROFILE),
                             (PVOID*)&Profile);
     if (!NT_SUCCESS(Status)) return(Status);
 
@@ -192,6 +225,8 @@
     Profile->BufferSize = BufferSize;
     Profile->BucketSize = BucketSize;
     Profile->LockedBuffer = NULL;
+    Profile->Segment = Segment;
+    Profile->ProfileSource = ProfileSource;
     Profile->Affinity = Affinity;
     Profile->Process = pProcess;
 
@@ -205,29 +240,31 @@
     ObDereferenceObject(Profile);
 
     /* Check for Success */
-    if (!NT_SUCCESS(Status)) {
-
+    if (!NT_SUCCESS(Status))
+    {
         /* Dereference Process on failure */
         if (pProcess) ObDereferenceObject(pProcess);
         return Status;
     }
 
-    /* Copy the created handle back to the caller*/
-    _SEH_TRY {
-
+    /* Enter SEH */
+    _SEH_TRY
+    {
+        /* Copy the created handle back to the caller*/
         *ProfileHandle = hProfile;
-
-    } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+    }
+    _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
+    {
         Status = _SEH_GetExceptionCode();
-    } _SEH_END;
+    }
+    _SEH_END;
 
     /* Return Status */
     return Status;
 }
 
 NTSTATUS
-STDCALL
+NTAPI
 NtQueryPerformanceCounter(OUT PLARGE_INTEGER PerformanceCounter,
                           OUT PLARGE_INTEGER PerformanceFrequency
OPTIONAL)
 {
@@ -235,43 +272,50 @@
     LARGE_INTEGER PerfFrequency;
     NTSTATUS Status = STATUS_SUCCESS;
 
-    /* Check the Parameters for validity */
-    if(PreviousMode != KernelMode) {
-
-        _SEH_TRY {
-
+    /* Check if we were called from user-mode */
+    if(PreviousMode != KernelMode)
+    {
+        /* Entry SEH Block */
+        _SEH_TRY
+        {
+            /* Make sure the counter and frequency are valid */
             ProbeForWriteLargeInteger(PerformanceCounter);
-
-            ProbeForWriteLargeInteger(PerformanceFrequency);
-        } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+            if (PerformanceFrequency)
+            {
+                ProbeForWriteLargeInteger(PerformanceFrequency);
+            }
+        }
+        _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
+        {
             Status = _SEH_GetExceptionCode();
-        } _SEH_END;
+        }
+        _SEH_END;
 
+        /* If the pointers are invalid, bail out */
         if(!NT_SUCCESS(Status)) return Status;
     }
 
-    _SEH_TRY {
-
+    /* Enter a new SEH Block */
+    _SEH_TRY
+    {
         /* Query the Kernel */
         *PerformanceCounter =
KeQueryPerformanceCounter(&PerfFrequency);
 
         /* Return Frequency if requested */
-        if(PerformanceFrequency) {
-
-            *PerformanceFrequency = PerfFrequency;
-        }
-    } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+        if(PerformanceFrequency) *PerformanceFrequency = PerfFrequency;
+    }
+    _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
+    {
         Status = _SEH_GetExceptionCode();
+    }
+    _SEH_END;
 
-    } _SEH_END;
-
+    /* Return status to caller */
     return Status;
 }
 
 NTSTATUS
-STDCALL
+NTAPI
 NtStartProfile(IN HANDLE ProfileHandle)
 {
     PEPROFILE Profile;
@@ -279,7 +323,6 @@
     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
     PVOID TempLockedBuffer;
     NTSTATUS Status;
-
     PAGED_CODE();
 
     /* Get the Object */
@@ -299,8 +342,8 @@
                           NULL);
 
     /* The Profile can still be enabled though, so handle that */
-    if (Profile->LockedBuffer) {
-
+    if (Profile->LockedBuffer)
+    {
         /* Release our lock, dereference and return */
         KeReleaseMutex(&ExpProfileMutex, FALSE);
         ObDereferenceObject(Profile);
@@ -310,7 +353,7 @@
     /* Allocate a Kernel Profile Object. */
     KeProfile = ExAllocatePoolWithTag(NonPagedPool,
                                       sizeof(EPROFILE),
-                                      TAG('P', 'r', 'o', 'f'));
+                                      TAG_PROFILE);
 
     /* Allocate the Mdl Structure */
     Profile->Mdl = MmCreateMdl(NULL, Profile->Buffer,
Profile->BufferSize);
@@ -344,13 +387,12 @@
 }
 
 NTSTATUS
-STDCALL
+NTAPI
 NtStopProfile(IN HANDLE ProfileHandle)
 {
     PEPROFILE Profile;
     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
     NTSTATUS Status;
-
     PAGED_CODE();
 
     /* Get the Object */
@@ -370,8 +412,8 @@
                           NULL);
 
     /* Make sure the Profile Object is really Started */
-    if (!Profile->LockedBuffer) {
-
+    if (!Profile->LockedBuffer)
+    {
         Status = STATUS_PROFILING_NOT_STARTED;
         goto Exit;
     }
@@ -395,51 +437,55 @@
 }
 
 NTSTATUS
-STDCALL
-NtQueryIntervalProfile(IN  KPROFILE_SOURCE ProfileSource,
+NTAPI
+NtQueryIntervalProfile(IN KPROFILE_SOURCE ProfileSource,
                        OUT PULONG Interval)
 {
     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
     ULONG ReturnInterval;
     NTSTATUS Status = STATUS_SUCCESS;
-
     PAGED_CODE();
 
-    /* Check the Parameters for validity */
-    if(PreviousMode != KernelMode) {
-
-        _SEH_TRY {
-
+    /* Check if we were called from user-mode */
+    if(PreviousMode != KernelMode)
+    {
+        /* Enter SEH Block */
+        _SEH_TRY
+        {
+            /* Validate interval */
             ProbeForWriteUlong(Interval);
-
-        } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+        }
+        _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
+        {
             Status = _SEH_GetExceptionCode();
-        } _SEH_END;
+        }
+        _SEH_END;
 
+        /* If pointer was invalid, bail out */
         if(!NT_SUCCESS(Status)) return Status;
     }
 
     /* Query the Interval */
     ReturnInterval = KeQueryIntervalProfile(ProfileSource);
 
-    /* Return the data */
-    _SEH_TRY  {
-
+    /* Enter SEH block for return */
+    _SEH_TRY
+    {
+        /* Return the data */
         *Interval = ReturnInterval;
-
-    } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+    }
+    _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
+    {
         Status = _SEH_GetExceptionCode();
+    }
+    _SEH_END;
 
-    } _SEH_END;
-
     /* Return Success */
     return STATUS_SUCCESS;
 }
 
 NTSTATUS
-STDCALL
+NTAPI
 NtSetIntervalProfile(IN ULONG Interval,
                      IN KPROFILE_SOURCE Source)
 {
  _____  

Modified: trunk/reactos/ntoskrnl/include/internal/ke.h
--- trunk/reactos/ntoskrnl/include/internal/ke.h	2005-12-29
15:14:50 UTC (rev 20425)
+++ trunk/reactos/ntoskrnl/include/internal/ke.h	2005-12-29
17:55:31 UTC (rev 20426)
@@ -188,7 +188,7 @@

     PVOID Buffer
 );
 
-VOID
+BOOLEAN
 STDCALL
 KeStopProfile(struct _KPROFILE* Profile);
 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.reactos.org/pipermail/ros-diffs/attachments/20051229/b2a209f9/attachment.html


More information about the Ros-diffs mailing list