Fix bug with registry loading on bootcd (Thanks Steven). Properly implement Profile Objects with Ex/Ke architecture (structures are a guess, and code is based on dwelch and some simple testing/common sense, but not ready for primetime (NT doesnt even use theirs). Optimize Device Queues a bit and use the inserted field properly. Modified: branches/alex_devel_branch/reactos/include/ntos/zwtypes.h Modified: branches/alex_devel_branch/reactos/ntoskrnl/cm/registry.c Modified: branches/alex_devel_branch/reactos/ntoskrnl/ex/profile.c Modified: branches/alex_devel_branch/reactos/ntoskrnl/include/internal/ke.h Modified: branches/alex_devel_branch/reactos/ntoskrnl/ke/kqueue.c Modified: branches/alex_devel_branch/reactos/ntoskrnl/ke/profile.c Modified: branches/alex_devel_branch/reactos/ntoskrnl/ke/timer.c _____
Modified: branches/alex_devel_branch/reactos/include/ntos/zwtypes.h --- branches/alex_devel_branch/reactos/include/ntos/zwtypes.h 2005-03-03 02:46:43 UTC (rev 13804) +++ branches/alex_devel_branch/reactos/include/ntos/zwtypes.h 2005-03-03 03:57:59 UTC (rev 13805) @@ -58,6 +58,7 @@
ProfileTime } KPROFILE_SOURCE;
+ // file disposition values
#define FILE_SUPERSEDE 0x0000 _____
Modified: branches/alex_devel_branch/reactos/ntoskrnl/cm/registry.c --- branches/alex_devel_branch/reactos/ntoskrnl/cm/registry.c 2005-03-03 02:46:43 UTC (rev 13804) +++ branches/alex_devel_branch/reactos/ntoskrnl/cm/registry.c 2005-03-03 03:57:59 UTC (rev 13805) @@ -248,10 +248,12 @@
{ PCHAR BaseAddress;
- /* Load Registry Hives */ - BaseAddress = (PCHAR)CachedModules[SystemRegistry]->ModStart; - CmImportSystemHive(BaseAddress, - CachedModules[SystemRegistry]->ModEnd - (ULONG_PTR)BaseAddress); + /* Load Registry Hives. This one can be missing. */ + if (CachedModules[SystemRegistry]) { + BaseAddress = (PCHAR)CachedModules[SystemRegistry]->ModStart; + CmImportSystemHive(BaseAddress, + CachedModules[SystemRegistry]->ModEnd - (ULONG_PTR)BaseAddress); + }
BaseAddress = (PCHAR)CachedModules[HardwareRegistry]->ModStart; CmImportHardwareHive(BaseAddress, _____
Modified: branches/alex_devel_branch/reactos/ntoskrnl/ex/profile.c --- branches/alex_devel_branch/reactos/ntoskrnl/ex/profile.c 2005-03-03 02:46:43 UTC (rev 13804) +++ branches/alex_devel_branch/reactos/ntoskrnl/ex/profile.c 2005-03-03 03:57:59 UTC (rev 13805) @@ -1,11 +1,10 @@
-/* $Id:$ - * +/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel - * FILE: ntoskrnl/nt/profile.c - * PURPOSE: Support for profiling + * FILE: ntoskrnl/ex/profile.c + * PURPOSE: Support for Executive Profile Objects * - * PROGRAMMERS: No programmer listed. + * PROGRAMMERS: Alex Ionescu */
/* INCLUDES *****************************************************************/ @@ -13,369 +12,448 @@ #include <ntoskrnl.h> #include <internal/debug.h>
-/* TYPES ********************************************************************/ +/* 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;
/* GLOBALS *******************************************************************/
POBJECT_TYPE EXPORTED ExProfileObjectType = NULL;
-static GENERIC_MAPPING ExpProfileMapping = { - STANDARD_RIGHTS_READ, - STANDARD_RIGHTS_WRITE, - STANDARD_RIGHTS_EXECUTE, - STANDARD_RIGHTS_ALL}; +static KMUTEX ExpProfileMutex;
-/* - * Size of the profile hash table. - */ -#define PROFILE_HASH_TABLE_SIZE (32) +#define PROFILE_CONTROL 1
-/* - * Table of lists of per-process profiling data structures hashed by PID. - */ -LIST_ENTRY ProcessProfileListHashTable[PROFILE_HASH_TABLE_SIZE]; +static GENERIC_MAPPING ExpProfileMapping = { + STANDARD_RIGHTS_READ | PROFILE_CONTROL, + STANDARD_RIGHTS_WRITE | PROFILE_CONTROL, + STANDARD_RIGHTS_EXECUTE | PROFILE_CONTROL, + STANDARD_RIGHTS_ALL};
-/* - * Head of the list of profile data structures for the kernel. - */ -LIST_ENTRY SystemProfileList; - -/* - * Lock that protects the profiling data structures. - */ -KSPIN_LOCK ProfileListLock; - -/* - * Timer interrupts happen before we have initialized the profiling - * data structures so just ignore them before that. - */ -BOOLEAN ProfileInitDone = FALSE; - -VOID INIT_FUNCTION -ExpInitializeProfileImplementation(VOID) +VOID +STDCALL +ExpDeleteProfile(PVOID ObjectBody) { - ULONG i; + PEPROFILE Profile;
- InitializeListHead(&SystemProfileList); + /* Typecast the Object */ + Profile = (PEPROFILE)ObjectBody; + + /* Check if there if the Profile was started */ + if (Profile->LockedBuffer) { + + /* Stop the Profile */ + KeStopProfile(Profile->KeProfile); + + /* Unmap the Locked Buffer */ + MmUnmapLockedPages(Profile->LockedBuffer, Profile->Mdl); + MmUnlockPages(Profile->Mdl); + ExFreePool(Profile->Mdl); + }
- for (i = 0; i < PROFILE_HASH_TABLE_SIZE; i++) - { - InitializeListHead(&ProcessProfileListHashTable[i]); + /* Check if a Process is associated */ + if (Profile->Process != NULL) { + + /* Dereference it */ + ObDereferenceObject(Profile->Process); + Profile->Process = NULL; } +}
- KeInitializeSpinLock(&ProfileListLock); - ProfileInitDone = TRUE; - - ExProfileObjectType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE)); - - RtlpCreateUnicodeString(&ExProfileObjectType->TypeName, L"Profile", NonPagedPool); - - ExProfileObjectType->Tag = TAG('P', 'R', 'O', 'F'); - ExProfileObjectType->PeakObjects = 0; - ExProfileObjectType->PeakHandles = 0; - ExProfileObjectType->TotalObjects = 0; - ExProfileObjectType->TotalHandles = 0; - ExProfileObjectType->PagedPoolCharge = 0; - ExProfileObjectType->NonpagedPoolCharge = sizeof(KPROFILE); - ExProfileObjectType->Mapping = &ExpProfileMapping; - ExProfileObjectType->Dump = NULL; - ExProfileObjectType->Open = NULL; - ExProfileObjectType->Close = NULL; - ExProfileObjectType->Delete = KiDeleteProfile; - ExProfileObjectType->Parse = NULL; - ExProfileObjectType->Security = NULL; - ExProfileObjectType->QueryName = NULL; - ExProfileObjectType->OkayToClose = NULL; - ExProfileObjectType->Create = NULL; - - ObpCreateTypeObject(ExProfileObjectType); +VOID +INIT_FUNCTION +ExpInitializeProfileImplementation(VOID) +{ + /* Initialize the Mutex to lock the States */ + KeInitializeMutex(&ExpProfileMutex, 0x40); + + /* Create the Object Type */ + ExProfileObjectType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE)); + RtlpCreateUnicodeString(&ExProfileObjectType->TypeName, L"Profile", NonPagedPool); + ExProfileObjectType->Tag = TAG('P', 'R', 'O', 'F'); + ExProfileObjectType->PeakObjects = 0; + ExProfileObjectType->PeakHandles = 0; + ExProfileObjectType->TotalObjects = 0; + ExProfileObjectType->TotalHandles = 0; + ExProfileObjectType->PagedPoolCharge = 0; + ExProfileObjectType->NonpagedPoolCharge = sizeof(EPROFILE); + ExProfileObjectType->Mapping = &ExpProfileMapping; + ExProfileObjectType->Dump = NULL; + ExProfileObjectType->Open = NULL; + ExProfileObjectType->Close = NULL; + ExProfileObjectType->Delete = ExpDeleteProfile; + ExProfileObjectType->Parse = NULL; + ExProfileObjectType->Security = NULL; + ExProfileObjectType->QueryName = NULL; + ExProfileObjectType->OkayToClose = NULL; + ExProfileObjectType->Create = NULL; + ObpCreateTypeObject(ExProfileObjectType); }
-NTSTATUS STDCALL +NTSTATUS +STDCALL NtCreateProfile(OUT PHANDLE ProfileHandle, - IN HANDLE Process OPTIONAL, - IN PVOID ImageBase, - IN ULONG ImageSize, - IN ULONG BucketSize, - IN PVOID Buffer, - IN ULONG BufferSize, - IN KPROFILE_SOURCE ProfileSource, - IN KAFFINITY Affinity) + IN HANDLE Process OPTIONAL, + IN PVOID ImageBase, + IN ULONG ImageSize, + IN ULONG BucketSize, + IN PVOID Buffer, + IN ULONG BufferSize, + IN KPROFILE_SOURCE ProfileSource, + IN KAFFINITY Affinity) { - HANDLE hProfile; - PKPROFILE Profile; - PEPROCESS pProcess; - KPROCESSOR_MODE PreviousMode; - OBJECT_ATTRIBUTES ObjectAttributes; - NTSTATUS Status = STATUS_SUCCESS; + HANDLE hProfile; + PEPROFILE Profile; + PEPROCESS pProcess; + KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); + OBJECT_ATTRIBUTES ObjectAttributes; + NTSTATUS Status = STATUS_SUCCESS;
- PAGED_CODE(); + PAGED_CODE();
- PreviousMode = ExGetPreviousMode(); - - if(BufferSize == 0) - { - return STATUS_INVALID_PARAMETER_7; - } - - if(PreviousMode != KernelMode) - { - _SEH_TRY - { - ProbeForWrite(ProfileHandle, - sizeof(HANDLE), - sizeof(ULONG)); - ProbeForWrite(Buffer, - BufferSize, - sizeof(ULONG)); - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; + /* Easy way out */ + if(BufferSize == 0) return STATUS_INVALID_PARAMETER_7; + + /* Check the Parameters for validity */ + if(PreviousMode != KernelMode) { + + _SEH_TRY { + + ProbeForWrite(ProfileHandle, + sizeof(HANDLE), + sizeof(ULONG)); + + ProbeForWrite(Buffer, + BufferSize, + sizeof(ULONG)); + } _SEH_HANDLE { + + Status = _SEH_GetExceptionCode(); + } _SEH_END;
- if(!NT_SUCCESS(Status)) - { - return Status; + if(!NT_SUCCESS(Status)) return Status; } - }
- /* - * Reference the associated process - */ - if (Process != NULL) - { - Status = ObReferenceObjectByHandle(Process, - PROCESS_QUERY_INFORMATION, - PsProcessType, - PreviousMode, - (PVOID*)&pProcess, - NULL); - if (!NT_SUCCESS(Status)) - { - return(Status); - } + /* Check if a process was specified */ + if (Process) { + + /* Reference it */ + Status = ObReferenceObjectByHandle(Process, + PROCESS_QUERY_INFORMATION, + PsProcessType, + PreviousMode, + (PVOID*)&pProcess, + NULL); + if (!NT_SUCCESS(Status)) return(Status); + + } 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)) { + + DPRINT1("NtCreateProfile: Caller requires the SeSystemProfilePrivilege privilege!\n"); + return STATUS_PRIVILEGE_NOT_HELD; + } } - else - { - pProcess = NULL; - if(!SeSinglePrivilegeCheck(SeSystemProfilePrivilege, - PreviousMode)) - { - DPRINT1("NtCreateProfile: Caller requires the SeSystemProfilePrivilege privilege!\n"); - return STATUS_PRIVILEGE_NOT_HELD; - } - }
- /* - * Check the parameters - */ - if ((pProcess == NULL && ImageBase < (PVOID)KERNEL_BASE) || - (pProcess != NULL && ImageBase >= (PVOID)KERNEL_BASE)) - { - return(STATUS_INVALID_PARAMETER_3); - } - if (((ImageSize >> BucketSize) * 4) >= BufferSize) - { - return(STATUS_BUFFER_TOO_SMALL); - } - if (ProfileSource != ProfileTime) - { - return(STATUS_INVALID_PARAMETER_9); - } - if (Affinity != 0) - { - return(STATUS_INVALID_PARAMETER_10); - } + /* Create the object */ + InitializeObjectAttributes(&ObjectAttributes, + NULL, + 0, + NULL, + NULL); + Status = ObCreateObject(KernelMode, + ExProfileObjectType, + &ObjectAttributes, + PreviousMode, + NULL, + sizeof(EPROFILE), + 0, + 0, + (PVOID*)&Profile); + if (!NT_SUCCESS(Status)) return(Status);
- /* - * Create the object - */ - InitializeObjectAttributes(&ObjectAttributes, + /* Initialize it */ + Profile->ImageBase = ImageBase; + Profile->ImageSize = ImageSize; + Profile->Buffer = Buffer; + Profile->BufferSize = BufferSize; + Profile->BucketSize = BucketSize; + Profile->LockedBuffer = NULL; + Profile->Affinity = Affinity; + Profile->Process = pProcess; + + /* Insert into the Object Tree */ + Status = ObInsertObject ((PVOID)Profile, NULL, + PROFILE_CONTROL, 0, NULL, - NULL); - - Status = ObCreateObject(KernelMode, - ExProfileObjectType, - &ObjectAttributes, - PreviousMode, - NULL, - sizeof(KPROFILE), - 0, - 0, - (PVOID*)&Profile); - if (!NT_SUCCESS(Status)) - { - return(Status); - } - - /* - * Initialize it - */ - Profile->Base = ImageBase; - Profile->Size = ImageSize; - Profile->BucketShift = BucketSize; - Profile->BufferMdl = MmCreateMdl(NULL, Buffer, BufferSize); - if(Profile->BufferMdl == NULL) { - DPRINT("MmCreateMdl: Out of memory!"); - ObDereferenceObject (Profile); - return(STATUS_NO_MEMORY); - } - MmProbeAndLockPages(Profile->BufferMdl, UserMode, IoWriteAccess); - Profile->Buffer = MmGetSystemAddressForMdl(Profile->BufferMdl); - Profile->BufferSize = BufferSize; - Profile->ProcessorMask = Affinity; - Profile->Started = FALSE; - Profile->Process = pProcess; - - /* - * Insert the profile into the profile list data structures - */ - KiInsertProfile(Profile); - - Status = ObInsertObject ((PVOID)Profile, - NULL, - STANDARD_RIGHTS_ALL, - 0, - NULL, - &hProfile); - if (!NT_SUCCESS(Status)) - { - ObDereferenceObject (Profile); - return Status; + &hProfile); + ObDereferenceObject(Profile); + + /* Check for Success */ + if (!NT_SUCCESS(Status)) { + + /* Dereference Process on failure */ + if (pProcess) ObDereferenceObject(pProcess); + return Status; } + + /* Copy the created handle back to the caller*/ + _SEH_TRY { + + *ProfileHandle = hProfile; + + } _SEH_HANDLE { + + Status = _SEH_GetExceptionCode(); + } _SEH_END;
- /* - * Copy the created handle back to the caller - */ - _SEH_TRY - { - *ProfileHandle = hProfile; - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - - ObDereferenceObject(Profile); - - return Status; + /* Return Status */ + return Status; }
-NTSTATUS STDCALL -NtQueryIntervalProfile(IN KPROFILE_SOURCE ProfileSource, - OUT PULONG Interval) +NTSTATUS +STDCALL +NtQueryPerformanceCounter(OUT PLARGE_INTEGER PerformanceCounter, + OUT PLARGE_INTEGER PerformanceFrequency OPTIONAL) { - KPROCESSOR_MODE PreviousMode; - NTSTATUS Status = STATUS_SUCCESS; + KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); + NTSTATUS Status = STATUS_SUCCESS; + LARGE_INTEGER PerfFrequency;
- PAGED_CODE(); - - PreviousMode = ExGetPreviousMode(); - - if(PreviousMode != KernelMode) - { - _SEH_TRY - { - ProbeForWrite(Interval, - sizeof(ULONG), - sizeof(ULONG)); - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; + /* Check the Parameters for validity */ + if(PreviousMode != KernelMode) { + + _SEH_TRY { + + ProbeForWrite(PerformanceCounter, + sizeof(LARGE_INTEGER), + sizeof(ULONG)); + + ProbeForWrite(PerformanceFrequency, + sizeof(LARGE_INTEGER), + sizeof(ULONG)); + } _SEH_HANDLE { + + Status = _SEH_GetExceptionCode(); + } _SEH_END;
- if(!NT_SUCCESS(Status)) - { - return Status; + if(!NT_SUCCESS(Status)) return Status; } - }
- if (ProfileSource == ProfileTime) - { - ULONG ReturnInterval; - - /* FIXME: What units does this use, for now nanoseconds */ - ReturnInterval = 100; - - _SEH_TRY - { - *Interval = ReturnInterval; - } - _SEH_HANDLE - { + _SEH_TRY { + + /* Query the Kernel */ + *PerformanceCounter = KeQueryPerformanceCounter(&PerfFrequency); + + /* Return Frequency if requested */ + if(PerformanceFrequency) { + + *PerformanceFrequency = PerfFrequency; + } + } _SEH_HANDLE { + Status = _SEH_GetExceptionCode(); - } - _SEH_END; - - return Status; - } - return STATUS_INVALID_PARAMETER_2; -} + + } _SEH_END;
-NTSTATUS STDCALL -NtSetIntervalProfile(IN ULONG Interval, - IN KPROFILE_SOURCE Source) -{ - return(STATUS_NOT_IMPLEMENTED); + return Status; }
-NTSTATUS STDCALL +NTSTATUS +STDCALL NtStartProfile(IN HANDLE ProfileHandle) { - PKPROFILE Profile; - KPROCESSOR_MODE PreviousMode; - NTSTATUS Status; + PEPROFILE Profile; + PKPROFILE KeProfile; + KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); + PVOID TempLockedBuffer; + NTSTATUS Status;
- PAGED_CODE(); + PAGED_CODE();
- PreviousMode = ExGetPreviousMode(); - - Status = ObReferenceObjectByHandle(ProfileHandle, - STANDARD_RIGHTS_ALL, - ExProfileObjectType, - PreviousMode, - (PVOID*)&Profile, - NULL); - if (!NT_SUCCESS(Status)) - { - return(Status); + /* Get the Object */ + Status = ObReferenceObjectByHandle(ProfileHandle, + PROFILE_CONTROL, + ExProfileObjectType, + PreviousMode, + (PVOID*)&Profile, + NULL); + if (!NT_SUCCESS(Status)) return(Status); + + /* To avoid a Race, wait on the Mutex */ + KeWaitForSingleObject(&ExpProfileMutex, + Executive, + KernelMode, + FALSE, + NULL); + + /* The Profile can still be enabled though, so handle that */ + if (Profile->LockedBuffer) { + + /* Release our lock, dereference and return */ + KeReleaseMutex(&ExpProfileMutex, FALSE); + ObDereferenceObject(Profile); + return STATUS_PROFILING_NOT_STOPPED; } - Profile->Started = TRUE; - ObDereferenceObject(Profile); - return(STATUS_SUCCESS); + + /* Allocate a Kernel Profile Object. */ + KeProfile = ExAllocatePoolWithTag(NonPagedPool, + sizeof(EPROFILE), + TAG('P', 'r', 'o', 'f')); + + /* Allocate the Mdl Structure */ + Profile->Mdl = MmCreateMdl(NULL, Profile->Buffer, Profile->BufferSize); + + /* Probe and Lock for Write Access */ + MmProbeAndLockPages(Profile->Mdl, PreviousMode, IoWriteAccess); + + /* Map the pages */ + TempLockedBuffer = MmMapLockedPages(Profile->Mdl, KernelMode); + + /* Initialize the Kernel Profile Object */ + Profile->KeProfile = KeProfile; + KeInitializeProfile(KeProfile, + (PKPROCESS)Profile->Process, + Profile->ImageBase, + Profile->ImageSize, + Profile->BucketSize, + Profile->ProfileSource, + Profile->Affinity); + + /* Start the Profiling */ + KeStartProfile(KeProfile, TempLockedBuffer); + + /* Now it's safe to save this */ + Profile->LockedBuffer = TempLockedBuffer; + + /* Release mutex, dereference and return */ + KeReleaseMutex(&ExpProfileMutex, FALSE); + ObDereferenceObject(Profile); + return STATUS_SUCCESS; }
-NTSTATUS STDCALL +NTSTATUS +STDCALL NtStopProfile(IN HANDLE ProfileHandle) { - PKPROFILE Profile; - KPROCESSOR_MODE PreviousMode; - NTSTATUS Status; + PEPROFILE Profile; + KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); + NTSTATUS Status;
- PAGED_CODE(); - - PreviousMode = ExGetPreviousMode(); + PAGED_CODE();
- Status = ObReferenceObjectByHandle(ProfileHandle, - STANDARD_RIGHTS_ALL, - ExProfileObjectType, - PreviousMode, - (PVOID*)&Profile, - NULL); - if (!NT_SUCCESS(Status)) - { - return(Status); + /* Get the Object */ + Status = ObReferenceObjectByHandle(ProfileHandle, + PROFILE_CONTROL, + ExProfileObjectType, + PreviousMode, + (PVOID*)&Profile, + NULL); + if (!NT_SUCCESS(Status)) return(Status); + + /* Get the Mutex */ + KeWaitForSingleObject(&ExpProfileMutex, + Executive, + KernelMode, + FALSE, + NULL); + + /* Make sure the Profile Object is really Started */ + if (!Profile->LockedBuffer) { + + Status = STATUS_PROFILING_NOT_STARTED; + goto Exit; } - Profile->Started = FALSE; - ObDereferenceObject(Profile); - return(STATUS_SUCCESS); + + /* Stop the Profile */ + KeStopProfile(Profile->KeProfile); + + /* Unlock the Buffer */ + MmUnmapLockedPages(Profile->LockedBuffer, Profile->Mdl); + MmUnlockPages(Profile->Mdl); + ExFreePool(Profile->KeProfile); + + /* Clear the Locked Buffer pointer, meaning the Object is Stopped */ + Profile->LockedBuffer = NULL; + +Exit: + /* Release Mutex, Dereference and Return */ + KeReleaseMutex(&ExpProfileMutex, FALSE); + ObDereferenceObject(Profile); + return Status; }
+NTSTATUS +STDCALL +NtQueryIntervalProfile(IN KPROFILE_SOURCE ProfileSource, + OUT PULONG Interval) +{ + KPROCESSOR_MODE PreviousMode= ExGetPreviousMode(); + NTSTATUS Status = STATUS_SUCCESS; + ULONG ReturnInterval; + + PAGED_CODE(); + + /* Check the Parameters for validity */ + if(PreviousMode != KernelMode) { + + _SEH_TRY { + + ProbeForWrite(Interval, + sizeof(ULONG), + sizeof(ULONG)); + + } _SEH_HANDLE { + + Status = _SEH_GetExceptionCode(); + } _SEH_END; + + if(!NT_SUCCESS(Status)) return Status; + } + + /* Query the Interval */ + ReturnInterval = KeQueryIntervalProfile(ProfileSource);
+ /* Return the data */ + _SEH_TRY { + + *Interval = ReturnInterval; + + } _SEH_HANDLE { + + Status = _SEH_GetExceptionCode(); + + } _SEH_END; + + /* Return Success */ + return STATUS_SUCCESS; +} + +NTSTATUS +STDCALL +NtSetIntervalProfile(IN ULONG Interval, + IN KPROFILE_SOURCE Source) +{ + /* Let the Kernel do the job */ + KeSetIntervalProfile(Interval, Source); + + /* Nothing can go wrong */ + return STATUS_SUCCESS; +} _____
Modified: branches/alex_devel_branch/reactos/ntoskrnl/include/internal/ke.h --- branches/alex_devel_branch/reactos/ntoskrnl/include/internal/ke.h 2005-03-03 02:46:43 UTC (rev 13804) +++ branches/alex_devel_branch/reactos/ntoskrnl/include/internal/ke.h 2005-03-03 03:57:59 UTC (rev 13805) @@ -64,56 +64,26 @@
/* next file ***************************************************************/
-typedef struct _KPROCESS_PROFILE -/* - * List of the profile data structures associated with a process. - */ -{ - LIST_ENTRY ProfileListHead; - LIST_ENTRY ListEntry; - HANDLE Pid; -} KPROCESS_PROFILE, *PKPROCESS_PROFILE; +typedef struct _KPROFILE_SOURCE_OBJECT { + KPROFILE_SOURCE Source; + LIST_ENTRY ListEntry; +} KPROFILE_SOURCE_OBJECT, *PKPROFILE_SOURCE_OBJECT;
-typedef struct _KPROFILE /* * Describes a contiguous region of process memory that is being profiled. */ -{ - CSHORT Type; - CSHORT Name; - - /* Entry in the list of profile data structures for this process. */ - LIST_ENTRY ListEntry; - - /* Base of the region being profiled. */ - PVOID Base; - - /* Size of the region being profiled. */ - ULONG Size; - - /* Shift of offsets from the region to buckets in the profiling buffer. */ - ULONG BucketShift; - - /* MDL which described the buffer that receives profiling data. */ - struct _MDL *BufferMdl; - - /* System alias for the profiling buffer. */ - PULONG Buffer; - - /* Size of the buffer for profiling data. */ - ULONG BufferSize; - - /* - * Mask of processors for which profiling data should be collected. - * Currently unused. - */ - ULONG ProcessorMask; - - /* TRUE if profiling has been started for this region. */ - BOOLEAN Started; - - /* Pointer (and reference) to the process which is being profiled. */ - struct _EPROCESS *Process; +typedef struct _KPROFILE { + CSHORT Type; + CSHORT Size; + LIST_ENTRY ListEntry; + PVOID RegionStart; + ULONG RegionEnd; + ULONG BucketShift; + PVOID Buffer; + CSHORT Source; + ULONG Affinity; + BOOLEAN Active; + struct _KPROCESS *Process; } KPROFILE, *PKPROFILE;
/* Cached modules from the loader block */ @@ -130,8 +100,36 @@ VOID STDCALL DbgBreakPointNoBugCheck(VOID);
+STDCALL VOID +KeInitializeProfile(struct _KPROFILE* Profile, + struct _KPROCESS* Process, + PVOID ImageBase, + ULONG ImageSize, + ULONG BucketSize, + KPROFILE_SOURCE ProfileSource, + KAFFINITY Affinity); + STDCALL +VOID +KeStartProfile(struct _KPROFILE* Profile, + PVOID Buffer); + +STDCALL +VOID +KeStopProfile(struct _KPROFILE* Profile); + +STDCALL +ULONG +KeQueryIntervalProfile(KPROFILE_SOURCE ProfileSource); + +STDCALL +VOID +KeSetIntervalProfile(KPROFILE_SOURCE ProfileSource, + ULONG Interval); + +VOID +STDCALL KeProfileInterrupt( PKTRAP_FRAME TrapFrame ); @@ -143,14 +141,6 @@ IN KPROFILE_SOURCE Source );
-VOID KiAddProfileEventToProcess(PLIST_ENTRY ListHead, PVOID Eip); -VOID KiAddProfileEvent(KPROFILE_SOURCE Source, ULONG Eip); -VOID KiInsertProfileIntoProcess(PLIST_ENTRY ListHead, PKPROFILE Profile); -VOID KiInsertProfile(PKPROFILE Profile); -VOID KiRemoveProfile(PKPROFILE Profile); -VOID STDCALL KiDeleteProfile(PVOID ObjectBody); - - VOID STDCALL KeUpdateSystemTime(PKTRAP_FRAME TrapFrame, KIRQL Irql); VOID STDCALL KeUpdateRunTime(PKTRAP_FRAME TrapFrame, KIRQL Irql);
_____
Modified: branches/alex_devel_branch/reactos/ntoskrnl/ke/kqueue.c --- branches/alex_devel_branch/reactos/ntoskrnl/ke/kqueue.c 2005-03-03 02:46:43 UTC (rev 13804) +++ branches/alex_devel_branch/reactos/ntoskrnl/ke/kqueue.c 2005-03-03 03:57:59 UTC (rev 13805) @@ -1,11 +1,13 @@
-/* $Id$ - * +/* * COPYRIGHT: See COPYING in the top level directory * PURPOSE: ReactOS kernel * FILE: ntoskrnl/ke/kqueue.c * PURPOSE: Implement device queues * - * PROGRAMMERS: David Welch (welch@mcmail.com) + * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) - Several optimizations and implement + * usage of Inserted flag + reformat and + * add debug output. + * David Welch (welch@mcmail.com) */
/* INCLUDES ****************************************************************/ @@ -16,216 +18,255 @@
/* FUNCTIONS *****************************************************************/
+/* + * @implemented + * + * FUNCTION: Intializes a device queue + * ARGUMENTS: + * DeviceQueue = Device queue to initialize + */ +VOID +STDCALL +KeInitializeDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue) +{
+ /* Initialize the Header */ + DeviceQueue->Type = DeviceQueueObject; + DeviceQueue->Size = sizeof(KDEVICE_QUEUE); + + /* Initialize the Listhead and Spinlock */ + InitializeListHead(&DeviceQueue->DeviceListHead); + KeInitializeSpinLock(&DeviceQueue->Lock); + + /* Set it as busy */ + DeviceQueue->Busy=FALSE; +} + /* * @implemented + * + * FUNCTION: Inserts an entry in a device queue + * ARGUMENTS: + * DeviceQueue = Queue to insert the entry in + * DeviceQueueEntry = Entry to insert + * RETURNS: False is the device queue wasn't busy + * True otherwise */ [truncated at 1000 lines; 947 more skipped]