From ed3df3667f1dbe3bf5a4bf85e22a8310d1ae066b Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Fri, 30 Jun 2006 16:56:18 +0000 Subject: [PATCH] - Refactor Io*Event APIs to call an internal worker function instead of duplicating the same code twice. - Optimize Io*Work APIs and initialize the event on allocation, not on queue!! svn path=/trunk/; revision=22719 --- reactos/ntoskrnl/include/internal/io.h | 11 ++ reactos/ntoskrnl/io/event.c | 144 +++++++++++-------------- reactos/ntoskrnl/io/iowork.c | 113 ++++++++++--------- 3 files changed, 129 insertions(+), 139 deletions(-) diff --git a/reactos/ntoskrnl/include/internal/io.h b/reactos/ntoskrnl/include/internal/io.h index a438a4a66c7..0e51017a4d7 100644 --- a/reactos/ntoskrnl/include/internal/io.h +++ b/reactos/ntoskrnl/include/internal/io.h @@ -197,6 +197,17 @@ typedef struct _IO_COMPLETION_PACKET IO_STATUS_BLOCK IoStatus; } IO_COMPLETION_PACKET, *PIO_COMPLETION_PACKET; +// +// I/O Wrapper around the Executive Work Item +// +typedef struct _IO_WORKITEM +{ + WORK_QUEUE_ITEM Item; + PDEVICE_OBJECT DeviceObject; + PIO_WORKITEM_ROUTINE WorkerRoutine; + PVOID Context; +} IO_WORKITEM, *PIO_WORKITEM; + // // Dummy File Object used inside the Open Packet so that OB knows how to // deal with the Object Pointer even though it's not a real file. diff --git a/reactos/ntoskrnl/io/event.c b/reactos/ntoskrnl/io/event.c index 8d02bb824ab..e3fb3411db0 100644 --- a/reactos/ntoskrnl/io/event.c +++ b/reactos/ntoskrnl/io/event.c @@ -1,11 +1,10 @@ -/* $Id$ - * - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory * FILE: ntoskrnl/io/event.c - * PURPOSE: Implements named events - * - * PROGRAMMERS: David Welch (welch@mcmail.com) + * PURPOSE: I/O Wrappers for the Executive Event Functions + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) + * Eric Kohl */ /* INCLUDES *****************************************************************/ @@ -13,92 +12,73 @@ #include #include -/* FUNCTIONS *****************************************************************/ +/* PRIVATE FUNCTIONS *********************************************************/ + +PKEVENT +NTAPI +IopCreateEvent(IN PUNICODE_STRING EventName, + IN PHANDLE EventHandle, + IN EVENT_TYPE Type) +{ + OBJECT_ATTRIBUTES ObjectAttributes; + PKEVENT Event; + HANDLE Handle; + NTSTATUS Status; + PAGED_CODE(); + + /* Initialize the object attributes */ + InitializeObjectAttributes(&ObjectAttributes, + EventName, + OBJ_OPENIF, + NULL, + NULL); + + /* Create the event */ + Status = ZwCreateEvent(&Handle, + EVENT_ALL_ACCESS, + &ObjectAttributes, + Type, + TRUE); + if (!NT_SUCCESS(Status)) return NULL; + + /* Get a handle to it */ + ObReferenceObjectByHandle(Handle, + 0, + ExEventObjectType, + KernelMode, + (PVOID*)&Event, + NULL); + + /* Dereference the extra count, and return the handle */ + ObDereferenceObject(Event); + *EventHandle = Handle; + return Event; +} + +/* PUBLIC FUNCTIONS **********************************************************/ /* * @implemented */ -PKEVENT STDCALL -IoCreateNotificationEvent(PUNICODE_STRING EventName, - PHANDLE EventHandle) +PKEVENT +NTAPI +IoCreateNotificationEvent(IN PUNICODE_STRING EventName, + IN PHANDLE EventHandle) { - OBJECT_ATTRIBUTES ObjectAttributes; - PKEVENT Event; - HANDLE Handle; - NTSTATUS Status; - - InitializeObjectAttributes(&ObjectAttributes, - EventName, - OBJ_OPENIF, - NULL, - NULL); - - Status = ZwCreateEvent(&Handle, - EVENT_ALL_ACCESS, - &ObjectAttributes, - NotificationEvent, - TRUE); - if (!NT_SUCCESS(Status)) - { - return NULL; - } - - ObReferenceObjectByHandle(Handle, - 0, - ExEventObjectType, - KernelMode, - (PVOID*)&Event, - NULL); - ObDereferenceObject(Event); - - *EventHandle = Handle; - - return Event; + /* Call the internal API */ + return IopCreateEvent(EventName, EventHandle, NotificationEvent); } /* * @implemented */ -PKEVENT STDCALL -IoCreateSynchronizationEvent(PUNICODE_STRING EventName, - PHANDLE EventHandle) +PKEVENT +NTAPI +IoCreateSynchronizationEvent(IN PUNICODE_STRING EventName, + IN PHANDLE EventHandle) { - OBJECT_ATTRIBUTES ObjectAttributes; - KPROCESSOR_MODE PreviousMode; - PKEVENT Event; - HANDLE Handle; - NTSTATUS Status; - - PreviousMode = ExGetPreviousMode(); - - InitializeObjectAttributes(&ObjectAttributes, - EventName, - OBJ_OPENIF, - NULL, - NULL); - - Status = ZwCreateEvent(&Handle, - EVENT_ALL_ACCESS, - &ObjectAttributes, - SynchronizationEvent, - TRUE); - - if (!NT_SUCCESS(Status)) - { - return NULL; - } - - ObReferenceObjectByHandle(Handle, - 0, - ExEventObjectType, - KernelMode, - (PVOID*)&Event, - NULL); - ObDereferenceObject(Event); - - *EventHandle = Handle; - - return Event; + /* Call the internal API */ + return IopCreateEvent(EventName, EventHandle, SynchronizationEvent); } /* EOF */ diff --git a/reactos/ntoskrnl/io/iowork.c b/reactos/ntoskrnl/io/iowork.c index 838d2a90b27..c3db3adaff5 100644 --- a/reactos/ntoskrnl/io/iowork.c +++ b/reactos/ntoskrnl/io/iowork.c @@ -1,11 +1,9 @@ -/* $Id$ - * - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory * FILE: ntoskrnl/io/iowork.c - * PURPOSE: Manage IO system work queues - * - * PROGRAMMERS: David Welch (welch@mcmail.com) + * PURPOSE: I/O Wrappers for the Executive Work Item Functions + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) * Robert Dickenson (odin@pnc.com.au) */ @@ -15,80 +13,81 @@ #define NDEBUG #include -/* TYPES ********************************************************************/ +/* PRIVATE FUNCTIONS *********************************************************/ -typedef struct _IO_WORKITEM +VOID +NTAPI +IopWorkItemCallback(IN PVOID Parameter) { - WORK_QUEUE_ITEM Item; - PDEVICE_OBJECT DeviceObject; - PIO_WORKITEM_ROUTINE WorkerRoutine; - PVOID Context; -} IO_WORKITEM; + PIO_WORKITEM IoWorkItem = (PIO_WORKITEM)Parameter; + PDEVICE_OBJECT DeviceObject = IoWorkItem->DeviceObject; + PAGED_CODE(); -/* FUNCTIONS ****************************************************************/ + /* Call the work routine */ + IoWorkItem->WorkerRoutine(DeviceObject, IoWorkItem->Context); -VOID STATIC STDCALL -IoWorkItemCallback(PVOID Parameter) -{ - PIO_WORKITEM IoWorkItem = (PIO_WORKITEM)Parameter; - PDEVICE_OBJECT DeviceObject = IoWorkItem->DeviceObject; - IoWorkItem->WorkerRoutine(IoWorkItem->DeviceObject, IoWorkItem->Context); - ObDereferenceObject(DeviceObject); + /* Dereferenece the device object */ + ObDereferenceObject(DeviceObject); } +/* PUBLIC FUNCTIONS **********************************************************/ + /* * @implemented */ -VOID STDCALL +VOID +NTAPI IoQueueWorkItem(IN PIO_WORKITEM IoWorkItem, - IN PIO_WORKITEM_ROUTINE WorkerRoutine, - IN WORK_QUEUE_TYPE QueueType, - IN PVOID Context) -/* - * FUNCTION: Inserts a work item in a queue for one of the system worker - * threads to process - * ARGUMENTS: - * IoWorkItem = Item to insert - * QueueType = Queue to insert it in - */ + IN PIO_WORKITEM_ROUTINE WorkerRoutine, + IN WORK_QUEUE_TYPE QueueType, + IN PVOID Context) { - ExInitializeWorkItem(&IoWorkItem->Item, IoWorkItemCallback, - (PVOID)IoWorkItem); - IoWorkItem->WorkerRoutine = WorkerRoutine; - IoWorkItem->Context = Context; - ObReferenceObjectByPointer(IoWorkItem->DeviceObject, - FILE_ALL_ACCESS, - NULL, - KernelMode); - ExQueueWorkItem(&IoWorkItem->Item, QueueType); + /* Make sure we're called at DISPATCH or lower */ + ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); + + /* Reference the device object */ + ObReferenceObject(IoWorkItem->DeviceObject); + + /* Setup the work item */ + IoWorkItem->WorkerRoutine = WorkerRoutine; + IoWorkItem->Context = Context; + + /* Queue the work item */ + ExQueueWorkItem(&IoWorkItem->Item, QueueType); } /* * @implemented */ -VOID STDCALL -IoFreeWorkItem(PIO_WORKITEM IoWorkItem) +VOID +NTAPI +IoFreeWorkItem(IN PIO_WORKITEM IoWorkItem) { - ExFreePool(IoWorkItem); + /* Free the work item */ + ExFreePool(IoWorkItem); } /* * @implemented */ -PIO_WORKITEM STDCALL -IoAllocateWorkItem(PDEVICE_OBJECT DeviceObject) +PIO_WORKITEM +NTAPI +IoAllocateWorkItem(IN PDEVICE_OBJECT DeviceObject) { - PIO_WORKITEM IoWorkItem = NULL; + PIO_WORKITEM IoWorkItem; - IoWorkItem = - ExAllocatePoolWithTag(NonPagedPool, sizeof(IO_WORKITEM), TAG_IOWI); - if (IoWorkItem == NULL) - { - return(NULL); - } - RtlZeroMemory(IoWorkItem, sizeof(IO_WORKITEM)); - IoWorkItem->DeviceObject = DeviceObject; - return(IoWorkItem); + /* Allocate the work item */ + IoWorkItem = ExAllocatePoolWithTag(NonPagedPool, + sizeof(IO_WORKITEM), + TAG_IOWI); + if (!IoWorkItem) return NULL; + + /* Initialize it */ + IoWorkItem->DeviceObject = DeviceObject; + ExInitializeWorkItem(&IoWorkItem->Item, IopWorkItemCallback, IoWorkItem); + + /* Return it */ + return IoWorkItem; } /* EOF */