Author: janderwald Date: Thu May 7 02:58:57 2009 New Revision: 40823
URL: http://svn.reactos.org/svn/reactos?rev=40823&view=rev Log: - Use a spinlock with list functions over interlocked list functions - Use a bitmap for storing reference count of the mappings as mapping are complete async and not very likely in determined order
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.c trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavepci.c
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- 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] Thu May 7 02:58:57 2009 @@ -14,6 +14,7 @@ KSSTREAM_HEADER *Header; PIRP Irp;
+ ULONG References; ULONG NumTags; PVOID * Tag; }IRP_MAPPING, *PIRP_MAPPING; @@ -141,6 +142,7 @@ IN PIRP Irp) { PIRP_MAPPING Mapping; + ULONG Index; IIrpQueueImpl * This = (IIrpQueueImpl*)iface;
Mapping = AllocateItem(NonPagedPool, sizeof(IRP_MAPPING), TAG_PORTCLASS); @@ -166,7 +168,6 @@ { Mapping->NumTags++; } - ASSERT(Mapping->NumTags < 32); } } else @@ -181,12 +182,18 @@ FreeItem(Mapping, TAG_PORTCLASS); return STATUS_UNSUCCESSFUL; } + ASSERT(Mapping->NumTags < 32); + for(Index = 0; Index < Mapping->NumTags; Index++); + Mapping->References |= (1 << Index);
This->NumDataAvailable += Mapping->Header->DataUsed;
- DPRINT("IIrpQueue_fnAddMapping NumMappings %u SizeOfMapping %lu NumDataAvailable %lu Mapping %p NumTags %u FrameSize %u\n", This->NumMappings, Mapping->Header->DataUsed, This->NumDataAvailable, Mapping, Mapping->NumTags, This->MaxFrameSize); - - ExInterlockedInsertTailList(&This->ListHead, &Mapping->Entry, &This->Lock); + 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);
if (Irp) @@ -253,7 +260,10 @@ { This->CurrentOffset = 0;
- (void)ExInterlockedRemoveHeadList(&This->ListHead, &This->Lock); + KeAcquireSpinLockAtDpcLevel(&This->Lock); + RemoveHeadList(&This->ListHead); + KeReleaseSpinLockFromDpcLevel(&This->Lock); + InterlockedDecrement(&This->NumMappings); FreeMappingRoutine(CurMapping); } @@ -339,7 +349,7 @@
/* calculate the offset */ if (Index) - Offset = (Index + 1) * This->MaxFrameSize; + Offset = Index * This->MaxFrameSize; else Offset = 0;
@@ -416,6 +426,7 @@ KeReleaseSpinLockFromDpcLevel(&This->Lock); This->OutOfMapping = TRUE; This->StartStream = FALSE; + DPRINT("No Mapping available\n"); return STATUS_UNSUCCESSFUL; }
@@ -425,9 +436,9 @@ IN IIrpQueue *iface, IN PVOID Tag) { - PIRP_MAPPING CurMapping; + PIRP_MAPPING CurMapping = NULL; PLIST_ENTRY CurEntry; - ULONG Index; + ULONG Index = 0; ULONG Found; IIrpQueueImpl * This = (IIrpQueueImpl*)iface;
@@ -440,40 +451,48 @@ return STATUS_UNSUCCESSFUL; }
- CurMapping = CONTAINING_RECORD(CurEntry, IRP_MAPPING, Entry); Found = FALSE; - - for(Index = 0; Index < CurMapping->NumTags; Index++) - { - if (CurMapping->Tag[Index] == Tag) + MapIndex = 0; + while (CurEntry != &This->ListHead) + { + CurMapping = CONTAINING_RECORD(CurEntry, IRP_MAPPING, Entry); + for(Index = 0; Index < CurMapping->NumTags; Index++) { - Found = TRUE; + if (CurMapping->Tag[Index] == Tag) + { + Found = TRUE; + break; + } + } + if (Found) break; - } - } - KeReleaseSpinLockFromDpcLevel(&This->Lock); + + CurEntry = CurEntry->Flink; + }
if (!Found) { - DPRINT("Tag %p not in first mapping %p\n", Tag, CurMapping); - return STATUS_UNSUCCESSFUL; - } - - if (Index != CurMapping->NumTags - 1) + 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\n", Tag, Index, CurMapping->NumTags); + DPRINT1("IIrpQueue_fnReleaseMappingWithTag Tag %p Index %u NumTags %u Refs %x\n", Tag, Index, CurMapping->NumTags, CurMapping->References); + KeReleaseSpinLockFromDpcLevel(&This->Lock); return STATUS_SUCCESS; }
- CurEntry = ExInterlockedRemoveHeadList(&This->ListHead, &This->Lock); - ASSERT(CurEntry); - CurMapping = CONTAINING_RECORD(CurEntry, IRP_MAPPING, Entry); + RemoveEntryList(&CurMapping->Entry);
/* last mapping of the irp, free irp */ DPRINT("Freeing mapping %p\n", CurMapping); InterlockedDecrement(&This->NumMappings); FreeMappingRoutine(CurMapping); + KeReleaseSpinLockFromDpcLevel(&This->Lock);
return STATUS_SUCCESS; }
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavepci.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavepci.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavepci.c [iso-8859-1] Thu May 7 02:58:57 2009 @@ -636,6 +636,7 @@ if (This->IrpQueue->lpVtbl->HasLastMappingFailed(This->IrpQueue)) { /* notify port driver that new mapping is available */ + DPRINT("Notifying of new mapping\n"); This->Stream->lpVtbl->MappingAvailable(This->Stream); }
RtlBitmap? Best regards, Alex Ionescu
On Thu, May 7, 2009 at 12:58 AM, janderwald@svn.reactos.org wrote:
Author: janderwald Date: Thu May 7 02:58:57 2009 New Revision: 40823
URL: http://svn.reactos.org/svn/reactos?rev=40823&view=rev Log:
- Use a spinlock with list functions over interlocked list functions
- Use a bitmap for storing reference count of the mappings as mapping are
complete async and not very likely in determined order
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.c trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavepci.c
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p...
============================================================================== --- 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] Thu May 7 02:58:57 2009 @@ -14,6 +14,7 @@ KSSTREAM_HEADER *Header; PIRP Irp;
- ULONG References; ULONG NumTags; PVOID * Tag;
}IRP_MAPPING, *PIRP_MAPPING; @@ -141,6 +142,7 @@ IN PIRP Irp) { PIRP_MAPPING Mapping;
ULONG Index; IIrpQueueImpl * This = (IIrpQueueImpl*)iface;
Mapping = AllocateItem(NonPagedPool, sizeof(IRP_MAPPING),
TAG_PORTCLASS); @@ -166,7 +168,6 @@ { Mapping->NumTags++; }
} elseASSERT(Mapping->NumTags < 32); }@@ -181,12 +182,18 @@ FreeItem(Mapping, TAG_PORTCLASS); return STATUS_UNSUCCESSFUL; }
ASSERT(Mapping->NumTags < 32);
for(Index = 0; Index < Mapping->NumTags; Index++);
Mapping->References |= (1 << Index);This->NumDataAvailable += Mapping->Header->DataUsed;
- DPRINT("IIrpQueue_fnAddMapping NumMappings %u SizeOfMapping %lu
NumDataAvailable %lu Mapping %p NumTags %u FrameSize %u\n", This->NumMappings, Mapping->Header->DataUsed, This->NumDataAvailable, Mapping, Mapping->NumTags, This->MaxFrameSize);
- ExInterlockedInsertTailList(&This->ListHead, &Mapping->Entry,
&This->Lock);
- 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);
if (Irp)
@@ -253,7 +260,10 @@ { This->CurrentOffset = 0;
(void)ExInterlockedRemoveHeadList(&This->ListHead, &This->Lock);
KeAcquireSpinLockAtDpcLevel(&This->Lock);RemoveHeadList(&This->ListHead);KeReleaseSpinLockFromDpcLevel(&This->Lock); }InterlockedDecrement(&This->NumMappings); FreeMappingRoutine(CurMapping);@@ -339,7 +349,7 @@
/* calculate the offset */ if (Index)
Offset = (Index + 1) * This->MaxFrameSize;
else Offset = 0;Offset = Index * This->MaxFrameSize;@@ -416,6 +426,7 @@ KeReleaseSpinLockFromDpcLevel(&This->Lock); This->OutOfMapping = TRUE; This->StartStream = FALSE;
- DPRINT("No Mapping available\n"); return STATUS_UNSUCCESSFUL;
}
@@ -425,9 +436,9 @@ IN IIrpQueue *iface, IN PVOID Tag) {
- PIRP_MAPPING CurMapping;
- PIRP_MAPPING CurMapping = NULL; PLIST_ENTRY CurEntry;
- ULONG Index;
- ULONG Index = 0; ULONG Found; IIrpQueueImpl * This = (IIrpQueueImpl*)iface;
@@ -440,40 +451,48 @@ return STATUS_UNSUCCESSFUL; }
- CurMapping = CONTAINING_RECORD(CurEntry, IRP_MAPPING, Entry); Found = FALSE;
- for(Index = 0; Index < CurMapping->NumTags; Index++)
- {
if (CurMapping->Tag[Index] == Tag)
- MapIndex = 0;
- while (CurEntry != &This->ListHead)
- {
CurMapping = CONTAINING_RECORD(CurEntry, IRP_MAPPING, Entry);for(Index = 0; Index < CurMapping->NumTags; Index++) {
Found = TRUE;
if (CurMapping->Tag[Index] == Tag){Found = TRUE;break;}}if (Found) break;
}- }
- KeReleaseSpinLockFromDpcLevel(&This->Lock);
CurEntry = CurEntry->Flink;}
if (!Found) {
DPRINT("Tag %p not in first mapping %p\n", Tag, CurMapping);return STATUS_UNSUCCESSFUL;- }
- if (Index != CurMapping->NumTags - 1)
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\n", Tag, Index, CurMapping->NumTags);
DPRINT1("IIrpQueue_fnReleaseMappingWithTag Tag %p Index %u NumTags%u Refs %x\n", Tag, Index, CurMapping->NumTags, CurMapping->References);
}KeReleaseSpinLockFromDpcLevel(&This->Lock); return STATUS_SUCCESS;
- CurEntry = ExInterlockedRemoveHeadList(&This->ListHead, &This->Lock);
- ASSERT(CurEntry);
- CurMapping = CONTAINING_RECORD(CurEntry, IRP_MAPPING, Entry);
RemoveEntryList(&CurMapping->Entry);
/* last mapping of the irp, free irp */ DPRINT("Freeing mapping %p\n", CurMapping); InterlockedDecrement(&This->NumMappings); FreeMappingRoutine(CurMapping);
KeReleaseSpinLockFromDpcLevel(&This->Lock);
return STATUS_SUCCESS;
}
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavepci.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p...
============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavepci.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavepci.c [iso-8859-1] Thu May 7 02:58:57 2009 @@ -636,6 +636,7 @@ if (This->IrpQueue->lpVtbl->HasLastMappingFailed(This->IrpQueue)) { /* notify port driver that new mapping is available */
}DPRINT("Notifying of new mapping\n"); This->Stream->lpVtbl->MappingAvailable(This->Stream);