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/portcls/irpstream.c?rev=40823&r1=40822&r2=40823&view=diff
==============================================================================
--- 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/portcls/pin_wavepci.c?rev=40823&r1=40822&r2=40823&view=diff
==============================================================================
--- 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);
    }