Author: janderwald
Date: Mon May 11 21:22:27 2009
New Revision: 40886
URL:
http://svn.reactos.org/svn/reactos?rev=40886&view=rev
Log:
- Use ExInterlockedList * functions for speed and stability
- Increment reference count on the correct miniport adapter from IPortDMus
Modified:
trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h
trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.c
trunk/reactos/drivers/wdm/audio/backpln/portcls/port_dmus.c
trunk/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h [iso-8859-1] Mon May 11
21:22:27 2009
@@ -231,6 +231,7 @@
IN PVOID Tag);
STDMETHOD_(BOOL, HasLastMappingFailed)(THIS);
+ STDMETHOD_(VOID, PrintQueueStatus)(THIS);
};
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.c [iso-8859-1] Mon May 11
21:22:27 2009
@@ -11,12 +11,13 @@
typedef struct _IRP_MAPPING_
{
LIST_ENTRY Entry;
- KSSTREAM_HEADER *Header;
+ PVOID Buffer;
+ ULONG BufferSize;
+ ULONG OriginalBufferSize;
+ PVOID OriginalBuffer;
PIRP Irp;
- ULONG References;
- ULONG NumTags;
- PVOID * Tag;
+ PVOID Tag;
}IRP_MAPPING, *PIRP_MAPPING;
typedef struct
@@ -34,6 +35,7 @@
KSPIN_LOCK Lock;
LIST_ENTRY ListHead;
+ LIST_ENTRY FreeHead;
ULONG OutOfMapping;
ULONG MaxFrameSize;
@@ -49,18 +51,15 @@
if (CurMapping->Irp)
{
- CurMapping->Irp->IoStatus.Information =
CurMapping->Header->FrameExtent;
+ CurMapping->Irp->IoStatus.Information = CurMapping->OriginalBufferSize;
CurMapping->Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(CurMapping->Irp, IO_SOUND_INCREMENT);
}
- if (CurMapping->Tag)
- {
- FreeItem(CurMapping->Tag, TAG_PORTCLASS);
- }
-
- ExFreePool(CurMapping->Header->Data);
- ExFreePool(CurMapping->Header);
+ if (CurMapping->OriginalBuffer)
+ {
+ ExFreePool(CurMapping->OriginalBuffer);
+ }
ExFreePool(CurMapping);
}
@@ -128,6 +127,7 @@
This->MaxFrameSize = FrameSize;
InitializeListHead(&This->ListHead);
+ InitializeListHead(&This->FreeHead);
KeInitializeSpinLock(&This->Lock);
return STATUS_SUCCESS;
@@ -141,58 +141,76 @@
IN ULONG BufferSize,
IN PIRP Irp)
{
- PIRP_MAPPING Mapping;
- IIrpQueueImpl * This = (IIrpQueueImpl*)iface;
-
- Mapping = AllocateItem(NonPagedPool, sizeof(IRP_MAPPING), TAG_PORTCLASS);
- if (!Mapping)
- return STATUS_UNSUCCESSFUL;
-
- Mapping->Header = (KSSTREAM_HEADER*)Buffer;
- Mapping->Irp = Irp;
+ PIRP_MAPPING Mapping = NULL;
+ KSSTREAM_HEADER * Header = (KSSTREAM_HEADER*)Buffer;
+ ULONG Index, NumMappings, Offset;
+ IIrpQueueImpl * This = (IIrpQueueImpl*)iface;
+
if (This->MaxFrameSize)
{
- if (This->MaxFrameSize > Mapping->Header->DataUsed)
+ if (This->MaxFrameSize > Header->DataUsed)
{
/* small mapping */
- Mapping->NumTags = 1;
+ NumMappings = 1;
}
else
{
- ULONG Rest = Mapping->Header->DataUsed % This->MaxFrameSize;
-
- Mapping->NumTags = Mapping->Header->DataUsed /
This->MaxFrameSize;
+ ULONG Rest = Header->DataUsed % This->MaxFrameSize;
+
+ NumMappings = Header->DataUsed / This->MaxFrameSize;
if (Rest)
{
- Mapping->NumTags++;
+ NumMappings++;
}
}
}
else
{
/* no framesize restriction */
- Mapping->NumTags = 1;
- }
-
- Mapping->Tag = AllocateItem(NonPagedPool, sizeof(PVOID) * Mapping->NumTags,
TAG_PORTCLASS);
- if (!Mapping->Tag)
- {
- FreeItem(Mapping, TAG_PORTCLASS);
- return STATUS_UNSUCCESSFUL;
- }
- ASSERT(Mapping->NumTags < 32);
- Mapping->References = (1 << Mapping->NumTags) - 1;
-
- This->NumDataAvailable += Mapping->Header->DataUsed;
-
- DPRINT("IIrpQueue_fnAddMapping NumMappings %u SizeOfMapping %lu NumDataAvailable
%lu Mapping %p NumTags %u References %x FrameSize %u\n", This->NumMappings,
Mapping->Header->DataUsed, This->NumDataAvailable, Mapping, Mapping->NumTags,
Mapping->References, This->MaxFrameSize);
-
- KeAcquireSpinLockAtDpcLevel(&This->Lock);
- InsertTailList(&This->ListHead, &Mapping->Entry);
- KeReleaseSpinLockFromDpcLevel(&This->Lock);
-
- (void)InterlockedIncrement((volatile long*)&This->NumMappings);
+ NumMappings = 1;
+ }
+
+ for(Index = 0; Index < NumMappings; Index++)
+ {
+ Mapping = AllocateItem(NonPagedPool, sizeof(IRP_MAPPING), TAG_PORTCLASS);
+ if (!Mapping)
+ {
+ DPRINT("OutOfMemory\n");
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ if (Index)
+ Offset = Index * This->MaxFrameSize;
+ else
+ Offset = 0;
+
+ Mapping->Buffer = (PVOID)UlongToPtr(PtrToUlong(Header->Data) + Offset);
+
+ if (This->MaxFrameSize)
+ Mapping->BufferSize = min(Header->DataUsed - Offset,
This->MaxFrameSize);
+ else
+ Mapping->BufferSize = Header->DataUsed;
+
+ Mapping->OriginalBufferSize = Header->FrameExtent;
+ Mapping->OriginalBuffer = NULL;
+ Mapping->Irp = NULL;
+ Mapping->Tag = NULL;
+
+ This->NumDataAvailable += Mapping->BufferSize;
+
+ if (Index == NumMappings - 1)
+ {
+ /* last mapping should free the irp if provided */
+ Mapping->OriginalBuffer = Header->Data;
+ Mapping->Irp = Irp;
+ }
+
+ ExInterlockedInsertTailList(&This->ListHead, &Mapping->Entry,
&This->Lock);
+ (void)InterlockedIncrement((volatile long*)&This->NumMappings);
+
+ DPRINT("IIrpQueue_fnAddMapping NumMappings %u SizeOfMapping %lu
NumDataAvailable %lu Mapping %p FrameSize %u\n", This->NumMappings,
Mapping->BufferSize, This->NumDataAvailable, Mapping, This->MaxFrameSize);
+ }
if (Irp)
{
@@ -216,23 +234,20 @@
IIrpQueueImpl * This = (IIrpQueueImpl*)iface;
PLIST_ENTRY CurEntry;
- KeAcquireSpinLockAtDpcLevel(&This->Lock);
-
-
- CurEntry = This->ListHead.Flink;
- CurMapping = CONTAINING_RECORD(CurEntry, IRP_MAPPING, Entry);
- if (CurEntry == &This->ListHead)
- {
- KeReleaseSpinLockFromDpcLevel(&This->Lock);
+ CurEntry = ExInterlockedRemoveHeadList(&This->ListHead, &This->Lock);
+ if (!CurEntry)
+ {
+ This->StartStream = FALSE;
This->OutOfMapping = TRUE;
return STATUS_UNSUCCESSFUL;
}
- *Buffer = (PUCHAR)CurMapping->Header->Data + This->CurrentOffset;
- *BufferSize = CurMapping->Header->DataUsed - This->CurrentOffset;
+ CurMapping = CONTAINING_RECORD(CurEntry, IRP_MAPPING, Entry);
+ *Buffer = (PUCHAR)CurMapping->Buffer + This->CurrentOffset;
+ *BufferSize = CurMapping->BufferSize - This->CurrentOffset;
+ ExInterlockedInsertHeadList(&This->ListHead, &CurMapping->Entry,
&This->Lock);
This->OutOfMapping = FALSE;
- KeReleaseSpinLockFromDpcLevel(&This->Lock);
return STATUS_SUCCESS;
}
@@ -248,24 +263,22 @@
PIRP_MAPPING CurMapping;
IIrpQueueImpl * This = (IIrpQueueImpl*)iface;
+ CurEntry = ExInterlockedRemoveHeadList(&This->ListHead, &This->Lock);
+ CurMapping = CONTAINING_RECORD(CurEntry, IRP_MAPPING, Entry);
+
This->CurrentOffset += BytesWritten;
This->NumDataAvailable -= BytesWritten;
- CurEntry = This->ListHead.Flink;
- CurMapping = CONTAINING_RECORD(CurEntry, IRP_MAPPING, Entry);
-
- if (CurMapping->Header->DataUsed <= This->CurrentOffset)
+ if (CurMapping->BufferSize <= This->CurrentOffset)
{
This->CurrentOffset = 0;
-
- KeAcquireSpinLockAtDpcLevel(&This->Lock);
- RemoveHeadList(&This->ListHead);
- KeReleaseSpinLockFromDpcLevel(&This->Lock);
-
InterlockedDecrement(&This->NumMappings);
FreeMappingRoutine(CurMapping);
}
-
+ else
+ {
+ ExInterlockedInsertHeadList(&This->ListHead, &CurMapping->Entry,
&This->Lock);
+ }
}
ULONG
@@ -331,51 +344,6 @@
This->StartStream = FALSE;
}
-
-VOID
-GetMapping(
- IIrpQueueImpl * This,
- IN ULONG Index,
- IN PVOID Tag,
- IN PIRP_MAPPING CurMapping,
- OUT PPHYSICAL_ADDRESS PhysicalAddress,
- OUT PVOID *VirtualAddress,
- OUT PULONG ByteCount,
- OUT PULONG Flags)
-{
- ULONG Offset;
-
- /* calculate the offset */
- if (Index)
- Offset = Index * This->MaxFrameSize;
- else
- Offset = 0;
-
- ASSERT(CurMapping->Header->DataUsed > Offset);
-
- *VirtualAddress = (PUCHAR)CurMapping->Header->Data + Offset;
- *PhysicalAddress = MmGetPhysicalAddress(*VirtualAddress);
- /* FIXME alignment */
- *ByteCount = min(CurMapping->Header->DataUsed - Offset,
This->MaxFrameSize);
-
- /* reset out of mapping indicator */
- This->OutOfMapping = FALSE;
-
- /* decrement available byte counter */
- This->NumDataAvailable -= *ByteCount;
-
- /* store the tag */
- CurMapping->Tag[Index] = Tag;
-
- if (Index + 1 == CurMapping->NumTags)
- {
- /* indicate end of packet */
- *Flags = 1;
- }
-
- DPRINT("IIrpQueue_fnGetMappingWithTag Tag %p Mapping %p Index %u NumTags
%u\n", Tag, CurMapping, Index, CurMapping->NumTags);
-}
-
NTSTATUS
NTAPI
@@ -389,45 +357,47 @@
{
PIRP_MAPPING CurMapping;
PLIST_ENTRY CurEntry;
- ULONG Index;
- ULONG Value;
IIrpQueueImpl * This = (IIrpQueueImpl*)iface;
*Flags = 0;
ASSERT(Tag != NULL);
- KeAcquireSpinLockAtDpcLevel(&This->Lock);
-
- CurEntry = This->ListHead.Flink;
- if (CurEntry == &This->ListHead)
- {
- KeReleaseSpinLockFromDpcLevel(&This->Lock);
+
+ CurEntry = ExInterlockedRemoveHeadList(&This->ListHead, &This->Lock);
+ if (!CurEntry)
+ {
This->OutOfMapping = TRUE;
This->StartStream = FALSE;
return STATUS_UNSUCCESSFUL;
}
- while (CurEntry != &This->ListHead)
- {
- CurMapping = CONTAINING_RECORD(CurEntry, IRP_MAPPING, Entry);
- for(Index = 0; Index < CurMapping->NumTags; Index++)
- {
- Value = CurMapping->References & ( 1 << Index);
- if (CurMapping->Tag[Index] == NULL && Value)
- {
- /* found a free mapping within audio irp */
- GetMapping(This, Index, Tag, CurMapping, PhysicalAddress, VirtualAddress,
ByteCount, Flags);
- KeReleaseSpinLockFromDpcLevel(&This->Lock);
- return STATUS_SUCCESS;
- }
- }
- CurEntry = CurEntry->Flink;
- }
- KeReleaseSpinLockFromDpcLevel(&This->Lock);
- This->OutOfMapping = TRUE;
- This->StartStream = FALSE;
- DPRINT("No Mapping available\n");
- return STATUS_UNSUCCESSFUL;
+ CurMapping = CONTAINING_RECORD(CurEntry, IRP_MAPPING, Entry);
+
+ *PhysicalAddress = MmGetPhysicalAddress(CurMapping->Buffer);
+ *VirtualAddress = CurMapping->Buffer;
+ *ByteCount = CurMapping->BufferSize;
+
+ InterlockedDecrement(&This->NumMappings);
+ This->NumDataAvailable -= CurMapping->BufferSize;
+
+ if (CurMapping->OriginalBuffer)
+ {
+ /* last partial buffer */
+ *Flags = 1;
+
+ /* store tag */
+ CurMapping->Tag = Tag;
+
+ /* insert into list to free later */
+ ExInterlockedInsertTailList(&This->FreeHead, &CurMapping->Entry,
&This->Lock);
+ }
+ else
+ {
+ /* we can free this entry now */
+ FreeItem(CurMapping, TAG_PORTCLASS);
+ }
+ DPRINT("IIrpQueue_fnGetMappingWithTag Tag %p\n", Tag);
+ return STATUS_SUCCESS;
}
NTSTATUS
@@ -438,62 +408,28 @@
{
PIRP_MAPPING CurMapping = NULL;
PLIST_ENTRY CurEntry;
- ULONG Index = 0;
- ULONG Found;
- IIrpQueueImpl * This = (IIrpQueueImpl*)iface;
-
- KeAcquireSpinLockAtDpcLevel(&This->Lock);
-
- CurEntry = This->ListHead.Flink;
- if (CurEntry == &This->ListHead)
- {
- KeReleaseSpinLockFromDpcLevel(&This->Lock);
- return STATUS_UNSUCCESSFUL;
- }
-
- Found = FALSE;
- while (CurEntry != &This->ListHead)
- {
- CurMapping = CONTAINING_RECORD(CurEntry, IRP_MAPPING, Entry);
- for(Index = 0; Index < CurMapping->NumTags; Index++)
- {
- if (CurMapping->Tag[Index] == Tag)
- {
- Found = TRUE;
- CurMapping->Tag[Index] = NULL;
- break;
- }
- }
- if (Found)
- break;
-
- CurEntry = CurEntry->Flink;
- }
-
- if (!Found)
- {
- DPRINT1("Tag %p not found\n", Tag);
- ASSERT(Found);
- }
- DPRINT("References %x\n", CurMapping->References);
- CurMapping->References &= ~(1 << Index);
-
- if (CurMapping->References)
- {
- /* released mapping is not the last mapping of the irp */
- DPRINT1("IIrpQueue_fnReleaseMappingWithTag Tag %p Index %u NumTags %u Refs
%x\n", Tag, Index, CurMapping->NumTags, CurMapping->References);
- KeReleaseSpinLockFromDpcLevel(&This->Lock);
+ IIrpQueueImpl * This = (IIrpQueueImpl*)iface;
+
+ DPRINT("IIrpQueue_fnReleaseMappingWithTag Tag %p\n", Tag);
+
+ CurEntry = ExInterlockedRemoveHeadList(&This->FreeHead, &This->Lock);
+ if (!CurMapping)
+ {
return STATUS_SUCCESS;
}
- RemoveEntryList(&CurMapping->Entry);
+ CurMapping = CONTAINING_RECORD(CurEntry, IRP_MAPPING, Entry);
+ if (CurMapping->Tag != Tag)
+ {
+ /* the released mapping is not the last one */
+ ExInterlockedInsertHeadList(&This->FreeHead, &CurMapping->Entry,
&This->Lock);
+ return STATUS_SUCCESS;
+ }
/* last mapping of the irp, free irp */
- DPRINT("Freeing mapping %p\n", CurMapping);
- InterlockedDecrement(&This->NumMappings);
+ DPRINT("IIrpQueue_fnReleaseMappingWithTag Tag %p Mapping %p FREED\n", Tag,
CurMapping);
+
FreeMappingRoutine(CurMapping);
- KeReleaseSpinLockFromDpcLevel(&This->Lock);
-
return STATUS_SUCCESS;
}
@@ -505,6 +441,32 @@
IIrpQueueImpl * This = (IIrpQueueImpl*)iface;
return This->OutOfMapping;
}
+
+VOID
+NTAPI
+IIrpQueue_fnPrintQueueStatus(
+ IN IIrpQueue *iface)
+{
+ PIRP_MAPPING CurMapping = NULL;
+ PLIST_ENTRY CurEntry;
+
+ IIrpQueueImpl * This = (IIrpQueueImpl*)iface;
+ KeAcquireSpinLockAtDpcLevel(&This->Lock);
+
+ CurEntry = This->ListHead.Flink;
+ DPRINT("IIrpQueue_fnPrintQueueStatus % u ===============\n",
This->NumMappings);
+
+ while (CurEntry != &This->ListHead)
+ {
+ CurMapping = CONTAINING_RECORD(CurEntry, IRP_MAPPING, Entry);
+ DPRINT("Mapping %p Size %u Original %p\n", CurMapping,
CurMapping->BufferSize, CurMapping->OriginalBuffer);
+ CurEntry = CurEntry->Flink;
+ }
+
+ KeReleaseSpinLockFromDpcLevel(&This->Lock);
+ DPRINT("IIrpQueue_fnPrintQueueStatus ===============\n");
+}
+
static IIrpQueueVtbl vt_IIrpQueue =
{
@@ -522,7 +484,8 @@
IIrpQueue_fnUpdateFormat,
IIrpQueue_fnGetMappingWithTag,
IIrpQueue_fnReleaseMappingWithTag,
- IIrpQueue_fnHasLastMappingFailed
+ IIrpQueue_fnHasLastMappingFailed,
+ IIrpQueue_fnPrintQueueStatus
};
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/port_dmus.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/port_dmus.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/port_dmus.c [iso-8859-1] Mon May 11
21:22:27 2009
@@ -207,6 +207,10 @@
Miniport->lpVtbl->Release(Miniport);
return Status;
}
+
+ /* increment reference on miniport adapter */
+ Miniport->lpVtbl->AddRef(Miniport);
+
}
else
{
@@ -226,6 +230,9 @@
MidiMiniport->lpVtbl->Release(MidiMiniport);
return Status;
}
+
+ /* increment reference on miniport adapter */
+ MidiMiniport->lpVtbl->AddRef(MidiMiniport);
}
/* create the subdevice descriptor */
@@ -265,10 +272,6 @@
This->pDeviceObject = DeviceObject;
This->bInitialized = TRUE;
- /* increment reference on miniport adapter */
- Miniport->lpVtbl->AddRef(Miniport);
-
-
/* check if it supports IPinCount interface */
Status = UnknownMiniport->lpVtbl->QueryInterface(UnknownMiniport,
&IID_IPinCount, (PVOID*)&PinCount);
if (NT_SUCCESS(Status))
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c [iso-8859-1]
(original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c [iso-8859-1] Mon May
11 21:22:27 2009
@@ -504,7 +504,6 @@
PIO_STACK_LOCATION IoStack;
ISubdevice * SubDevice;
PPCLASS_DEVICE_EXTENSION DeviceExt;
- SUBDEVICE_ENTRY * Entry;
IIrpTarget *Filter;
PKSOBJECT_CREATE_ITEM CreateItem;
PPIN_WORKER_CONTEXT Context;
@@ -526,13 +525,6 @@
{
DPRINT1("PcCreateItemDispatch SubDevice %p DeviceExt %p\n", SubDevice,
DeviceExt);
return STATUS_UNSUCCESSFUL;
- }
-
- Entry = AllocateItem(NonPagedPool, sizeof(SUBDEVICE_ENTRY), TAG_PORTCLASS);
- if (!Entry)
- {
- DPRINT1("PcCreateItemDispatch no memory\n");
- return STATUS_INSUFFICIENT_RESOURCES;
}
#if KS_IMPLEMENTED