]> xenbits.xensource.com Git - pvdrivers/win/xenbus.git/commitdiff
Rename Pool* to Cache*
authorPaul Durrant <paul.durrant@citrix.com>
Thu, 29 May 2014 09:50:58 +0000 (10:50 +0100)
committerPaul Durrant <paul.durrant@citrix.com>
Thu, 29 May 2014 09:50:58 +0000 (10:50 +0100)
No functional change. Just largely mechanical textual substitution.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
proj/xenbus/xenbus.vcxproj
src/xenbus/cache.c [new file with mode: 0644]
src/xenbus/cache.h [new file with mode: 0644]
src/xenbus/gnttab.c
src/xenbus/pool.c [deleted file]
src/xenbus/pool.h [deleted file]

index f4085be769727a62d94f38a0bb3129bb18a1cf38..20844c52822ff0d119b6790a6518038391b7e630 100644 (file)
@@ -90,7 +90,7 @@
                <ClCompile Include="..\..\src\xenbus\thread.c" />
                <ClCompile Include="..\..\src\xenbus\range_set.c" />
                <ClCompile Include="..\..\src\xenbus\balloon.c" />
-               <ClCompile Include="..\..\src\xenbus\pool.c" />
+               <ClCompile Include="..\..\src\xenbus\cache.c" />
        </ItemGroup>
        <ItemGroup>
                <ResourceCompile Include="..\..\src\xenbus\xenbus.rc" />
diff --git a/src/xenbus/cache.c b/src/xenbus/cache.c
new file mode 100644 (file)
index 0000000..9272771
--- /dev/null
@@ -0,0 +1,744 @@
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, 
+ * with or without modification, are permitted provided 
+ * that the following conditions are met:
+ * 
+ * *   Redistributions of source code must retain the above 
+ *     copyright notice, this list of conditions and the 
+ *     following disclaimer.
+ * *   Redistributions in binary form must reproduce the above 
+ *     copyright notice, this list of conditions and the 
+ *     following disclaimer in the documentation and/or other 
+ *     materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE.
+ */
+
+#include <ntddk.h>
+#include <ntstrsafe.h>
+#include <stdlib.h>
+#include <util.h>
+
+#include "cache.h"
+#include "dbg_print.h"
+#include "assert.h"
+
+extern ULONG
+NTAPI
+RtlRandomEx (
+    __inout PULONG Seed
+    );
+
+#define CACHE_TAG   'HCAC'
+
+typedef struct _OBJECT_HEADER {
+    ULONG       Magic;
+
+#define OBJECT_HEADER_MAGIC 0x02121996
+
+    LIST_ENTRY  ListEntry;
+} OBJECT_HEADER, *POBJECT_HEADER;
+
+#define MAXIMUM_SLOTS   6
+
+typedef struct _CACHE_MAGAZINE {
+    PVOID   Slot[MAXIMUM_SLOTS];
+} CACHE_MAGAZINE, *PCACHE_MAGAZINE;
+
+typedef struct _CACHE_FIST {
+    LONG    Defer;
+    ULONG   Probability;
+    ULONG   Seed;
+} CACHE_FIST, *PCACHE_FIST;
+
+#define MAXNAMELEN  128
+
+struct _XENBUS_CACHE {
+    CHAR            Name[MAXNAMELEN];
+    ULONG           Size;
+    ULONG           Reservation;
+    NTSTATUS        (*Ctor)(PVOID, PVOID);
+    VOID            (*Dtor)(PVOID, PVOID);
+    VOID            (*AcquireLock)(PVOID);
+    VOID            (*ReleaseLock)(PVOID);
+    PVOID           Argument;
+    KTIMER          Timer;
+    KDPC            Dpc;
+    LIST_ENTRY      GetList;
+    PLIST_ENTRY     PutList;
+    CACHE_MAGAZINE  Magazine[MAXIMUM_PROCESSORS];
+    LONG            Allocated;
+    LONG            MaximumAllocated;
+    LONG            Population;
+    LONG            MinimumPopulation;
+    CACHE_FIST      FIST;
+};
+
+static FORCEINLINE PVOID
+__CacheAllocate(
+    IN  ULONG   Length
+    )
+{
+    return __AllocateNonPagedPoolWithTag(Length, CACHE_TAG);
+}
+
+static FORCEINLINE VOID
+__CacheFree(
+    IN  PVOID   Buffer
+    )
+{
+    __FreePoolWithTag(Buffer, CACHE_TAG);
+}
+
+static FORCEINLINE VOID
+__CacheFill(
+    IN  PXENBUS_CACHE   Cache,
+    IN  PLIST_ENTRY     List
+    )
+{
+    // Not really a doubly-linked list; it's actually a singly-linked
+    // list via the Flink field.
+    while (List != NULL) {
+        PLIST_ENTRY     Next;
+        POBJECT_HEADER  Header;
+
+        Next = List->Flink;
+        List->Flink = NULL;
+        ASSERT3P(List->Blink, ==, NULL);
+
+        Header = CONTAINING_RECORD(List, OBJECT_HEADER, ListEntry);
+        ASSERT3U(Header->Magic, ==, OBJECT_HEADER_MAGIC);
+
+        InsertTailList(&Cache->GetList, &Header->ListEntry);
+
+        List = Next;
+    }
+}
+
+static FORCEINLINE VOID
+__CacheSwizzle(
+    IN  PXENBUS_CACHE   Cache
+    )
+{
+    PLIST_ENTRY         List;
+
+    List = InterlockedExchangePointer(&Cache->PutList, NULL);
+
+    __CacheFill(Cache, List);
+}
+
+static FORCEINLINE NTSTATUS
+__CacheCreateObject(
+    IN  PXENBUS_CACHE   Cache,
+    OUT POBJECT_HEADER  *Header
+    )
+{
+    PVOID               Object;
+    NTSTATUS            status;
+
+    (*Header) = __CacheAllocate(sizeof (OBJECT_HEADER) + Cache->Size);
+
+    status = STATUS_NO_MEMORY;
+    if (*Header == NULL)
+        goto fail1;
+
+    (*Header)->Magic = OBJECT_HEADER_MAGIC;
+
+    Object = (*Header) + 1;
+
+    status = Cache->Ctor(Cache->Argument, Object);
+    if (!NT_SUCCESS(status))
+        goto fail2;
+
+    return STATUS_SUCCESS;
+
+fail2:
+    Error("fail2\n");
+
+    (*Header)->Magic = 0;
+
+    ASSERT(IsZeroMemory(*Header, sizeof (OBJECT_HEADER)));
+    __CacheFree(*Header);
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    return status;    
+}
+
+static FORCEINLINE PVOID
+__CacheGetShared(
+    IN  PXENBUS_CACHE   Cache,
+    IN  BOOLEAN         Locked
+    )
+{
+    LONG                Population;
+    POBJECT_HEADER      Header;
+    PVOID               Object;
+    LONG                Allocated;
+    NTSTATUS            status;
+
+    Population = InterlockedDecrement(&Cache->Population);
+
+    if (Population >= 0) {
+        PLIST_ENTRY     ListEntry;
+
+        if (!Locked)
+            Cache->AcquireLock(Cache->Argument);
+
+        if (Population < Cache->MinimumPopulation)
+            Cache->MinimumPopulation = Population;
+
+        if (IsListEmpty(&Cache->GetList))
+            __CacheSwizzle(Cache);
+
+        ListEntry = RemoveHeadList(&Cache->GetList);
+        ASSERT(ListEntry != &Cache->GetList);
+
+        if (!Locked)
+            Cache->ReleaseLock(Cache->Argument);
+
+        RtlZeroMemory(ListEntry, sizeof (LIST_ENTRY));
+
+        Header = CONTAINING_RECORD(ListEntry, OBJECT_HEADER, ListEntry);
+        ASSERT3U(Header->Magic, ==, OBJECT_HEADER_MAGIC);
+
+        goto done;
+    }
+
+    (VOID) InterlockedIncrement(&Cache->Population);
+
+    status = __CacheCreateObject(Cache, &Header);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    Allocated = InterlockedIncrement(&Cache->Allocated);
+
+    if (Allocated > Cache->MaximumAllocated) {
+        if (!Locked)
+            Cache->AcquireLock(Cache->Argument);
+
+        if (Allocated > Cache->MaximumAllocated)
+            Cache->MaximumAllocated = Allocated;
+
+        if (!Locked)
+            Cache->ReleaseLock(Cache->Argument);
+    }
+
+done:
+    Object = Header + 1;
+
+    return Object;
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    return NULL;    
+}
+
+static FORCEINLINE VOID
+__CachePutShared(
+    IN  PXENBUS_CACHE   Cache,
+    IN  PVOID           Object,
+    IN  BOOLEAN         Locked
+    )
+{
+    POBJECT_HEADER      Header;
+    PLIST_ENTRY         Old;
+    PLIST_ENTRY         New;
+
+    ASSERT(Object != NULL);
+
+    Header = Object;
+    --Header;
+    ASSERT3U(Header->Magic, ==, OBJECT_HEADER_MAGIC);
+
+    ASSERT(IsZeroMemory(&Header->ListEntry, sizeof (LIST_ENTRY)));
+
+    if (!Locked) {
+        New = &Header->ListEntry;
+
+        do {
+            Old = Cache->PutList;
+            New->Flink = Old;
+        } while (InterlockedCompareExchangePointer(&Cache->PutList, New, Old) != Old);
+    } else {
+        InsertTailList(&Cache->GetList, &Header->ListEntry);
+    }
+
+    KeMemoryBarrier();
+
+    (VOID) InterlockedIncrement(&Cache->Population);
+}
+
+static FORCEINLINE PVOID
+__CacheGetMagazine(
+    IN  PXENBUS_CACHE   Cache,
+    IN  ULONG           Cpu
+    )
+{
+    PCACHE_MAGAZINE     Magazine;
+    ULONG               Index;
+
+    Magazine = &Cache->Magazine[Cpu];
+
+    for (Index = 0; Index < MAXIMUM_SLOTS; Index++) {
+        PVOID   Object;
+
+        if (Magazine->Slot[Index] != NULL) {
+            Object = Magazine->Slot[Index];
+            Magazine->Slot[Index] = NULL;
+
+            return Object;
+        }
+    }
+
+    return NULL;
+}
+
+static FORCEINLINE BOOLEAN
+__CachePutMagazine(
+    IN  PXENBUS_CACHE   Cache,
+    IN  ULONG           Cpu,
+    IN  PVOID           Object
+    )
+{
+    PCACHE_MAGAZINE      Magazine;
+    ULONG               Index;
+
+    Magazine = &Cache->Magazine[Cpu];
+
+    for (Index = 0; Index < MAXIMUM_SLOTS; Index++) {
+        if (Magazine->Slot[Index] == NULL) {
+            Magazine->Slot[Index] = Object;
+            return TRUE;
+        }
+    }
+
+    return FALSE;
+}
+
+PVOID
+CacheGet(
+    IN  PXENBUS_CACHE   Cache,
+    IN  BOOLEAN         Locked
+    )
+{
+    KIRQL               Irql;
+    ULONG               Cpu;
+    PVOID               Object;
+
+    if (Cache->FIST.Probability != 0) {
+        LONG    Defer;
+
+        Defer = InterlockedDecrement(&Cache->FIST.Defer);
+
+        if (Defer <= 0) {
+            ULONG   Random = RtlRandomEx(&Cache->FIST.Seed);
+            ULONG   Threshold = (MAXLONG / 100) * Cache->FIST.Probability;
+
+            if (Random < Threshold)
+                return NULL;
+        }
+    }
+
+    KeRaiseIrql(DISPATCH_LEVEL, &Irql);
+    Cpu = KeGetCurrentProcessorNumber();
+
+    Object = __CacheGetMagazine(Cache, Cpu);
+    if (Object == NULL)
+        Object = __CacheGetShared(Cache, Locked);
+
+    KeLowerIrql(Irql);
+
+    return Object;
+}
+
+VOID
+CachePut(
+    IN  PXENBUS_CACHE   Cache,
+    IN  PVOID           Object,
+    IN  BOOLEAN         Locked
+    )
+{
+    KIRQL               Irql;
+    ULONG               Cpu;
+
+    KeRaiseIrql(DISPATCH_LEVEL, &Irql);
+    Cpu = KeGetCurrentProcessorNumber();
+
+    if (!__CachePutMagazine(Cache, Cpu, Object))
+        __CachePutShared(Cache, Object, Locked);
+
+    KeLowerIrql(Irql);
+}
+
+VOID
+CacheGetStatistics(
+    IN  PXENBUS_CACHE            Cache,
+    OUT PXENBUS_CACHE_STATISTICS Statistics
+    )
+{
+    Statistics->Allocated = Cache->Allocated;
+    Statistics->MaximumAllocated = Cache->MaximumAllocated;
+    Statistics->Population = Cache->Population;
+    Statistics->MinimumPopulation = Cache->MinimumPopulation;
+}
+
+static FORCEINLINE
+__CacheFlushMagazines(
+    IN  PXENBUS_CACHE   Cache
+    )
+{
+    ULONG               Cpu;
+
+    for (Cpu = 0; Cpu < MAXIMUM_PROCESSORS; Cpu++) {
+        PVOID   Object;
+
+        while ((Object = __CacheGetMagazine(Cache, Cpu)) != NULL)
+            __CachePutShared(Cache, Object, TRUE);
+    }
+}
+
+static FORCEINLINE VOID
+__CacheTrimShared(
+    IN      PXENBUS_CACHE   Cache,
+    IN OUT  PLIST_ENTRY     List
+    )
+{
+    LONG                    Population;
+    LONG                    Excess;
+
+    Population = Cache->Population;
+
+    KeMemoryBarrier();
+
+    Excess = __max((LONG)Cache->MinimumPopulation - (LONG)Cache->Reservation, 0);
+    
+    while (Excess != 0) {
+        PLIST_ENTRY     ListEntry;
+
+        Population = InterlockedDecrement(&Cache->Population);
+        if (Population < 0) {
+            Population = InterlockedIncrement(&Cache->Population);
+            break;
+        }
+
+        if (IsListEmpty(&Cache->GetList))
+            __CacheSwizzle(Cache);
+
+        ListEntry = RemoveHeadList(&Cache->GetList);
+        ASSERT(ListEntry != &Cache->GetList);
+
+        InsertTailList(List, ListEntry);
+
+        InterlockedDecrement(&Cache->Allocated);
+        --Excess;
+    }
+
+    Cache->MinimumPopulation = Population;
+}
+
+static FORCEINLINE VOID
+__CacheDestroyObject(
+    IN  PXENBUS_CACHE   Cache,
+    IN  POBJECT_HEADER  Header
+    )
+{
+    PVOID               Object;
+
+    Object = Header + 1;
+
+    Cache->Dtor(Cache->Argument, Object);
+
+    Header->Magic = 0;
+
+    ASSERT(IsZeroMemory(Header, sizeof (OBJECT_HEADER)));
+    __CacheFree(Header);
+}
+
+static FORCEINLINE VOID
+__CacheEmpty(
+    IN      PXENBUS_CACHE   Cache,
+    IN OUT  PLIST_ENTRY     List
+    )
+{
+    while (!IsListEmpty(List)) {
+        PLIST_ENTRY     ListEntry;
+        POBJECT_HEADER  Header;
+
+        ListEntry = RemoveHeadList(List);
+        RtlZeroMemory(ListEntry, sizeof (LIST_ENTRY));
+
+        Header = CONTAINING_RECORD(ListEntry, OBJECT_HEADER, ListEntry);
+        ASSERT3U(Header->Magic, ==, OBJECT_HEADER_MAGIC);
+
+        __CacheDestroyObject(Cache, Header);
+    }
+}
+
+#define TIME_US(_us)        ((_us) * 10)
+#define TIME_MS(_ms)        (TIME_US((_ms) * 1000))
+#define TIME_RELATIVE(_t)   (-(_t))
+
+#define CACHE_PERIOD  1000
+
+KDEFERRED_ROUTINE   CacheDpc;
+
+VOID
+CacheDpc(
+    IN  PKDPC       Dpc,
+    IN  PVOID       Context,
+    IN  PVOID       Argument1,
+    IN  PVOID       Argument2
+    )
+{
+    PXENBUS_CACHE   Cache = Context;
+    LIST_ENTRY      List;
+
+    UNREFERENCED_PARAMETER(Dpc);
+    UNREFERENCED_PARAMETER(Argument1);
+    UNREFERENCED_PARAMETER(Argument2);
+
+    ASSERT(Cache != NULL);
+
+    InitializeListHead(&List);
+
+    Cache->AcquireLock(Cache->Argument);
+    __CacheTrimShared(Cache, &List);
+    Cache->ReleaseLock(Cache->Argument);
+
+    __CacheEmpty(Cache, &List);
+    ASSERT(IsListEmpty(&List));
+}
+
+static FORCEINLINE VOID
+__CacheSetupFIST(
+    IN  PXENBUS_CACHE           Cache,
+    IN  PXENBUS_STORE_INTERFACE StoreInterface
+    )
+{
+    CHAR                        Node[sizeof ("fist/cache/") + MAXNAMELEN];
+    PCHAR                       Buffer;
+    LARGE_INTEGER               Now;
+    NTSTATUS                    status;
+
+    status = RtlStringCbPrintfA(Node,
+                                sizeof (Node),
+                                "fist/cache/%s",
+                                Cache->Name);
+    ASSERT(NT_SUCCESS(status));
+
+    status = STORE(Read,
+                   StoreInterface,
+                   NULL,
+                   Node,
+                   "defer",
+                   &Buffer);
+    if (!NT_SUCCESS(status)) {
+        Cache->FIST.Defer = 0;
+    } else {
+        Cache->FIST.Defer = (ULONG)strtol(Buffer, NULL, 0);
+
+        STORE(Free,
+              StoreInterface,
+              Buffer);
+    }
+
+    status = STORE(Read,
+                   StoreInterface,
+                   NULL,
+                   Node,
+                   "probability",
+                   &Buffer);
+    if (!NT_SUCCESS(status)) {
+        Cache->FIST.Probability = 0;
+    } else {
+        Cache->FIST.Probability = (ULONG)strtol(Buffer, NULL, 0);
+
+        STORE(Free,
+              StoreInterface,
+              Buffer);
+    }
+
+    if (Cache->FIST.Probability > 100)
+        Cache->FIST.Probability = 100;
+
+    if (Cache->FIST.Probability != 0)
+        Info("%s: Defer = %d Probability = %d\n",
+             Cache->Name,
+             Cache->FIST.Defer,
+             Cache->FIST.Probability);
+
+    KeQuerySystemTime(&Now);
+    Cache->FIST.Seed = Now.LowPart;
+}
+
+NTSTATUS
+CacheInitialize(
+    IN  PXENBUS_STORE_INTERFACE StoreInterface,
+    IN  const CHAR              *Name,
+    IN  ULONG                   Size,
+    IN  ULONG                   Reservation,
+    IN  NTSTATUS                (*Ctor)(PVOID, PVOID),
+    IN  VOID                    (*Dtor)(PVOID, PVOID),
+    IN  VOID                    (*AcquireLock)(PVOID),
+    IN  VOID                    (*ReleaseLock)(PVOID),
+    IN  PVOID                   Argument,
+    OUT PXENBUS_CACHE           *Cache
+    )
+{
+    LARGE_INTEGER               Timeout;
+    LIST_ENTRY                  List;
+    NTSTATUS                    status;
+
+    *Cache = __CacheAllocate(sizeof (XENBUS_CACHE));
+
+    status = STATUS_NO_MEMORY;
+    if (*Cache == NULL)
+        goto fail1;
+
+    status = RtlStringCbPrintfA((*Cache)->Name,
+                                sizeof ((*Cache)->Name),
+                                "%s",
+                                Name);
+    if (!NT_SUCCESS(status))
+        goto fail2;
+
+    (*Cache)->Size = Size;
+    (*Cache)->Ctor = Ctor;
+    (*Cache)->Dtor = Dtor;
+    (*Cache)->AcquireLock = AcquireLock;
+    (*Cache)->ReleaseLock = ReleaseLock;
+    (*Cache)->Argument = Argument;
+
+    __CacheSetupFIST(*Cache, StoreInterface);
+
+    InitializeListHead(&(*Cache)->GetList);
+
+    while (Reservation != 0) {
+        POBJECT_HEADER  Header;
+
+        status = __CacheCreateObject(*Cache, &Header);
+        if (!NT_SUCCESS(status))
+            goto fail3;
+
+        (VOID) InterlockedIncrement(&(*Cache)->Allocated);
+
+        InsertTailList(&(*Cache)->GetList, &Header->ListEntry);
+        (VOID) InterlockedIncrement(&(*Cache)->Population);
+
+        --Reservation;
+    }
+    (*Cache)->MaximumAllocated = (*Cache)->Allocated;
+    (*Cache)->Reservation = (*Cache)->Population;
+
+    KeInitializeDpc(&(*Cache)->Dpc,
+                    CacheDpc,
+                    (*Cache));
+
+    Timeout.QuadPart = TIME_RELATIVE(TIME_MS(CACHE_PERIOD));
+
+    KeInitializeTimer(&(*Cache)->Timer);
+    KeSetTimerEx(&(*Cache)->Timer,
+                 Timeout,
+                 CACHE_PERIOD,
+                 &(*Cache)->Dpc);
+
+    return STATUS_SUCCESS;
+
+fail3:
+    Error("fail3\n");
+
+    InitializeListHead(&List);
+
+    (*Cache)->MinimumPopulation = (*Cache)->Population;
+    __CacheTrimShared(*Cache, &List);
+    __CacheEmpty(*Cache, &List);
+
+    ASSERT3U((*Cache)->Population, ==, 0);
+    ASSERT3U((*Cache)->Allocated, ==, 0);
+
+    RtlZeroMemory(&(*Cache)->GetList, sizeof (LIST_ENTRY));
+
+    RtlZeroMemory(&(*Cache)->FIST, sizeof (CACHE_FIST));
+
+    (*Cache)->Argument = NULL;
+    (*Cache)->ReleaseLock = NULL;
+    (*Cache)->AcquireLock = NULL;
+    (*Cache)->Dtor = NULL;
+    (*Cache)->Ctor = NULL;
+    (*Cache)->Size = 0;
+
+fail2:
+    Error("fail2\n");
+
+    RtlZeroMemory((*Cache)->Name, sizeof ((*Cache)->Name));
+    
+    ASSERT(IsZeroMemory(*Cache, sizeof (XENBUS_CACHE)));
+    __CacheFree(*Cache);
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    return status;    
+}
+
+VOID
+CacheTeardown(
+    IN  PXENBUS_CACHE   Cache
+    )
+{
+    LIST_ENTRY          List;
+
+    KeCancelTimer(&Cache->Timer);
+    KeFlushQueuedDpcs();
+
+    RtlZeroMemory(&Cache->Timer, sizeof (KTIMER));
+    RtlZeroMemory(&Cache->Dpc, sizeof (KDPC));
+
+    Cache->Reservation = 0;
+    Cache->MaximumAllocated = 0;
+
+    InitializeListHead(&List);
+
+    __CacheFlushMagazines(Cache);
+
+    Cache->MinimumPopulation = Cache->Population;
+    __CacheTrimShared(Cache, &List);
+    __CacheEmpty(Cache, &List);
+
+    ASSERT3U(Cache->Population, ==, 0);
+    ASSERT3U(Cache->Allocated, ==, 0);
+
+    RtlZeroMemory(&Cache->GetList, sizeof (LIST_ENTRY));
+
+    RtlZeroMemory(&Cache->FIST, sizeof (CACHE_FIST));
+
+    Cache->Argument = NULL;
+    Cache->ReleaseLock = NULL;
+    Cache->AcquireLock = NULL;
+    Cache->Dtor = NULL;
+    Cache->Ctor = NULL;
+    Cache->Size = 0;
+
+    RtlZeroMemory(Cache->Name, sizeof (Cache->Name));
+
+    ASSERT(IsZeroMemory(Cache, sizeof (XENBUS_CACHE)));
+    __CacheFree(Cache);
+}
diff --git a/src/xenbus/cache.h b/src/xenbus/cache.h
new file mode 100644 (file)
index 0000000..7714748
--- /dev/null
@@ -0,0 +1,85 @@
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, 
+ * with or without modification, are permitted provided 
+ * that the following conditions are met:
+ * 
+ * *   Redistributions of source code must retain the above 
+ *     copyright notice, this list of conditions and the 
+ *     following disclaimer.
+ * *   Redistributions in binary form must reproduce the above 
+ *     copyright notice, this list of conditions and the 
+ *     following disclaimer in the documentation and/or other 
+ *     materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE.
+ */
+
+#ifndef _XENBUS_CACHE_H
+#define _XENBUS_CACHE_H
+
+#include <ntddk.h>
+#include <store_interface.h>
+
+typedef struct _XENBUS_CACHE XENBUS_CACHE, *PXENBUS_CACHE;
+
+extern NTSTATUS
+CacheInitialize(
+    IN  PXENBUS_STORE_INTERFACE StoreInterface,
+    IN  const CHAR              *Name,
+    IN  ULONG                   Size,
+    IN  ULONG                   Reservation,
+    IN  NTSTATUS                (*Ctor)(PVOID, PVOID),
+    IN  VOID                    (*Dtor)(PVOID, PVOID),
+    IN  VOID                    (*AcquireLock)(PVOID),
+    IN  VOID                    (*ReleaseLock)(PVOID),
+    IN  PVOID                   Argument,
+    OUT PXENBUS_CACHE           *Cache
+    );
+
+extern VOID
+CacheTeardown(
+    IN  PXENBUS_CACHE   Cache
+    );
+
+extern PVOID
+CacheGet(
+    IN  PXENBUS_CACHE   Cache,
+    IN  BOOLEAN         Locked
+    );
+
+extern VOID
+CachePut(
+    IN  PXENBUS_CACHE   Cache,
+    IN  PVOID           Object,
+    IN  BOOLEAN         Locked
+    );
+
+typedef struct _XENBUS_CACHE_STATISTICS {
+    ULONG   Allocated;
+    ULONG   MaximumAllocated;
+    ULONG   Population;
+    ULONG   MinimumPopulation;
+} XENBUS_CACHE_STATISTICS, *PXENBUS_CACHE_STATISTICS;
+
+extern VOID
+CacheGetStatistics(
+    IN  PXENBUS_CACHE            Cache,
+    OUT PXENBUS_CACHE_STATISTICS Statistics
+    );
+
+#endif  // _XENBUS_CACHE_H
index 42573cd1dc0a820a5de2e4991148a46df2976e21..3c4a66f9598797e073b369c16bfb2d8ab676941f 100644 (file)
@@ -38,7 +38,7 @@
 #include "gnttab.h"
 #include "fdo.h"
 #include "range_set.h"
-#include "pool.h"
+#include "cache.h"
 #include "dbg_print.h"
 #include "assert.h"
 
@@ -66,7 +66,7 @@ struct _XENBUS_GNTTAB_CONTEXT {
     PXENBUS_RANGE_SET           RangeSet;
     ULONG                       Seed;
     LONG                        GetFailed;
-    PXENBUS_POOL                DescriptorPool;
+    PXENBUS_CACHE               DescriptorCache;
     PXENBUS_STORE_INTERFACE     StoreInterface;
     PXENBUS_SUSPEND_INTERFACE   SuspendInterface;
     PXENBUS_SUSPEND_CALLBACK    SuspendCallbackEarly;
@@ -244,7 +244,7 @@ __GnttabFill(
     if (!NT_SUCCESS(status))
         goto fail1;
 
-    status = PoolInitialize(Context->StoreInterface,
+    status = CacheInitialize(Context->StoreInterface,
                             "gnttab",
                             sizeof (XENBUS_GNTTAB_DESCRIPTOR),
                             GNTTAB_RESERVATION,
@@ -253,7 +253,7 @@ __GnttabFill(
                             GnttabAcquireLock,
                             GnttabReleaseLock,
                             Context,
-                            &Context->DescriptorPool);
+                            &Context->DescriptorCache);
     if (!NT_SUCCESS(status))
         goto fail2;
 
@@ -278,8 +278,8 @@ __GnttabEmpty(
 {
     LONGLONG                    Entry;
 
-    PoolTeardown(Context->DescriptorPool);
-    Context->DescriptorPool = NULL;
+    CacheTeardown(Context->DescriptorCache);
+    Context->DescriptorCache = NULL;
 
     for (Entry = GNTTAB_RESERVED_ENTRY_COUNT;
          Entry < (LONGLONG)(Context->FrameCount * GNTTAB_ENTRY_PER_FRAME);
@@ -301,7 +301,7 @@ GnttabGet(
 {
     PXENBUS_GNTTAB_DESCRIPTOR   Descriptor;
 
-    Descriptor = PoolGet(Context->DescriptorPool, FALSE);
+    Descriptor = CacheGet(Context->DescriptorCache, FALSE);
 
     if (Descriptor == NULL)
         (VOID) InterlockedIncrement(&Context->GetFailed);
@@ -319,7 +319,7 @@ GnttabPut(
 {
     ASSERT3U(Descriptor->Magic, ==, GNTTAB_DESCRIPTOR_MAGIC);
 
-    PoolPut(Context->DescriptorPool, Descriptor, FALSE);
+    CachePut(Context->DescriptorCache, Descriptor, FALSE);
 }
 
 static FORCEINLINE NTSTATUS
@@ -525,7 +525,7 @@ GnttabDebugCallback(
     )
 {
     PXENBUS_GNTTAB_CONTEXT  Context = Argument;
-    XENBUS_POOL_STATISTICS  Statistics;
+    XENBUS_CACHE_STATISTICS  Statistics;
 
     UNREFERENCED_PARAMETER(Crashing);
 
@@ -541,20 +541,20 @@ GnttabDebugCallback(
           "FrameCount = %u\n",
           Context->FrameCount);
 
-    PoolGetStatistics(Context->DescriptorPool,
-                      &Statistics);
+    CacheGetStatistics(Context->DescriptorCache,
+                       &Statistics);
 
     DEBUG(Printf,
           Context->DebugInterface,
           Context->DebugCallback,
-          "DESCRIPTOR POOL: Allocated = %u (Maximum = %u)\n",
+          "DESCRIPTOR CACHE: Allocated = %u (Maximum = %u)\n",
           Statistics.Allocated,
           Statistics.MaximumAllocated);
 
     DEBUG(Printf,
           Context->DebugInterface,
           Context->DebugCallback,
-          "DESCRIPTOR POOL: Population = %u (Minimum = %u)\n",
+          "DESCRIPTOR CACHE: Population = %u (Minimum = %u)\n",
           Statistics.Population,
           Statistics.MinimumPopulation);
 
diff --git a/src/xenbus/pool.c b/src/xenbus/pool.c
deleted file mode 100644 (file)
index 67c8d58..0000000
+++ /dev/null
@@ -1,744 +0,0 @@
-/* Copyright (c) Citrix Systems Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, 
- * with or without modification, are permitted provided 
- * that the following conditions are met:
- * 
- * *   Redistributions of source code must retain the above 
- *     copyright notice, this list of conditions and the 
- *     following disclaimer.
- * *   Redistributions in binary form must reproduce the above 
- *     copyright notice, this list of conditions and the 
- *     following disclaimer in the documentation and/or other 
- *     materials provided with the distribution.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
- * SUCH DAMAGE.
- */
-
-#include <ntddk.h>
-#include <ntstrsafe.h>
-#include <stdlib.h>
-#include <util.h>
-
-#include "pool.h"
-#include "dbg_print.h"
-#include "assert.h"
-
-extern ULONG
-NTAPI
-RtlRandomEx (
-    __inout PULONG Seed
-    );
-
-#define POOL_POOL   'OBJE'
-
-typedef struct _OBJECT_HEADER {
-    ULONG       Magic;
-
-#define OBJECT_HEADER_MAGIC 0x02121996
-
-    LIST_ENTRY  ListEntry;
-} OBJECT_HEADER, *POBJECT_HEADER;
-
-#define MAXIMUM_SLOTS   6
-
-typedef struct _POOL_MAGAZINE {
-    PVOID   Slot[MAXIMUM_SLOTS];
-} POOL_MAGAZINE, *PPOOL_MAGAZINE;
-
-typedef struct _POOL_FIST {
-    LONG    Defer;
-    ULONG   Probability;
-    ULONG   Seed;
-} POOL_FIST, *PPOOL_FIST;
-
-#define MAXNAMELEN  128
-
-struct _XENBUS_POOL {
-    CHAR            Name[MAXNAMELEN];
-    ULONG           Size;
-    ULONG           Reservation;
-    NTSTATUS        (*Ctor)(PVOID, PVOID);
-    VOID            (*Dtor)(PVOID, PVOID);
-    VOID            (*AcquireLock)(PVOID);
-    VOID            (*ReleaseLock)(PVOID);
-    PVOID           Argument;
-    KTIMER          Timer;
-    KDPC            Dpc;
-    LIST_ENTRY      GetList;
-    PLIST_ENTRY     PutList;
-    POOL_MAGAZINE   Magazine[MAXIMUM_PROCESSORS];
-    LONG            Allocated;
-    LONG            MaximumAllocated;
-    LONG            Population;
-    LONG            MinimumPopulation;
-    POOL_FIST       FIST;
-};
-
-static FORCEINLINE PVOID
-__PoolAllocate(
-    IN  ULONG   Length
-    )
-{
-    return __AllocateNonPagedPoolWithTag(Length, POOL_POOL);
-}
-
-static FORCEINLINE VOID
-__PoolFree(
-    IN  PVOID   Buffer
-    )
-{
-    __FreePoolWithTag(Buffer, POOL_POOL);
-}
-
-static FORCEINLINE VOID
-__PoolFill(
-    IN  PXENBUS_POOL    Pool,
-    IN  PLIST_ENTRY     List
-    )
-{
-    // Not really a doubly-linked list; it's actually a singly-linked
-    // list via the Flink field.
-    while (List != NULL) {
-        PLIST_ENTRY     Next;
-        POBJECT_HEADER  Header;
-
-        Next = List->Flink;
-        List->Flink = NULL;
-        ASSERT3P(List->Blink, ==, NULL);
-
-        Header = CONTAINING_RECORD(List, OBJECT_HEADER, ListEntry);
-        ASSERT3U(Header->Magic, ==, OBJECT_HEADER_MAGIC);
-
-        InsertTailList(&Pool->GetList, &Header->ListEntry);
-
-        List = Next;
-    }
-}
-
-static FORCEINLINE VOID
-__PoolSwizzle(
-    IN  PXENBUS_POOL    Pool
-    )
-{
-    PLIST_ENTRY         List;
-
-    List = InterlockedExchangePointer(&Pool->PutList, NULL);
-
-    __PoolFill(Pool, List);
-}
-
-static FORCEINLINE NTSTATUS
-__PoolCreateObject(
-    IN  PXENBUS_POOL    Pool,
-    OUT POBJECT_HEADER  *Header
-    )
-{
-    PVOID               Object;
-    NTSTATUS            status;
-
-    (*Header) = __PoolAllocate(sizeof (OBJECT_HEADER) + Pool->Size);
-
-    status = STATUS_NO_MEMORY;
-    if (*Header == NULL)
-        goto fail1;
-
-    (*Header)->Magic = OBJECT_HEADER_MAGIC;
-
-    Object = (*Header) + 1;
-
-    status = Pool->Ctor(Pool->Argument, Object);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    return STATUS_SUCCESS;
-
-fail2:
-    Error("fail2\n");
-
-    (*Header)->Magic = 0;
-
-    ASSERT(IsZeroMemory(*Header, sizeof (OBJECT_HEADER)));
-    __PoolFree(*Header);
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    return status;    
-}
-
-static FORCEINLINE PVOID
-__PoolGetShared(
-    IN  PXENBUS_POOL    Pool,
-    IN  BOOLEAN         Locked
-    )
-{
-    LONG                Population;
-    POBJECT_HEADER      Header;
-    PVOID               Object;
-    LONG                Allocated;
-    NTSTATUS            status;
-
-    Population = InterlockedDecrement(&Pool->Population);
-
-    if (Population >= 0) {
-        PLIST_ENTRY     ListEntry;
-
-        if (!Locked)
-            Pool->AcquireLock(Pool->Argument);
-
-        if (Population < Pool->MinimumPopulation)
-            Pool->MinimumPopulation = Population;
-
-        if (IsListEmpty(&Pool->GetList))
-            __PoolSwizzle(Pool);
-
-        ListEntry = RemoveHeadList(&Pool->GetList);
-        ASSERT(ListEntry != &Pool->GetList);
-
-        if (!Locked)
-            Pool->ReleaseLock(Pool->Argument);
-
-        RtlZeroMemory(ListEntry, sizeof (LIST_ENTRY));
-
-        Header = CONTAINING_RECORD(ListEntry, OBJECT_HEADER, ListEntry);
-        ASSERT3U(Header->Magic, ==, OBJECT_HEADER_MAGIC);
-
-        goto done;
-    }
-
-    (VOID) InterlockedIncrement(&Pool->Population);
-
-    status = __PoolCreateObject(Pool, &Header);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    Allocated = InterlockedIncrement(&Pool->Allocated);
-
-    if (Allocated > Pool->MaximumAllocated) {
-        if (!Locked)
-            Pool->AcquireLock(Pool->Argument);
-
-        if (Allocated > Pool->MaximumAllocated)
-            Pool->MaximumAllocated = Allocated;
-
-        if (!Locked)
-            Pool->ReleaseLock(Pool->Argument);
-    }
-
-done:
-    Object = Header + 1;
-
-    return Object;
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    return NULL;    
-}
-
-static FORCEINLINE VOID
-__PoolPutShared(
-    IN  PXENBUS_POOL    Pool,
-    IN  PVOID           Object,
-    IN  BOOLEAN         Locked
-    )
-{
-    POBJECT_HEADER      Header;
-    PLIST_ENTRY         Old;
-    PLIST_ENTRY         New;
-
-    ASSERT(Object != NULL);
-
-    Header = Object;
-    --Header;
-    ASSERT3U(Header->Magic, ==, OBJECT_HEADER_MAGIC);
-
-    ASSERT(IsZeroMemory(&Header->ListEntry, sizeof (LIST_ENTRY)));
-
-    if (!Locked) {
-        New = &Header->ListEntry;
-
-        do {
-            Old = Pool->PutList;
-            New->Flink = Old;
-        } while (InterlockedCompareExchangePointer(&Pool->PutList, New, Old) != Old);
-    } else {
-        InsertTailList(&Pool->GetList, &Header->ListEntry);
-    }
-
-    KeMemoryBarrier();
-
-    (VOID) InterlockedIncrement(&Pool->Population);
-}
-
-static FORCEINLINE PVOID
-__PoolGetMagazine(
-    IN  PXENBUS_POOL    Pool,
-    IN  ULONG           Cpu
-    )
-{
-    PPOOL_MAGAZINE      Magazine;
-    ULONG               Index;
-
-    Magazine = &Pool->Magazine[Cpu];
-
-    for (Index = 0; Index < MAXIMUM_SLOTS; Index++) {
-        PVOID   Object;
-
-        if (Magazine->Slot[Index] != NULL) {
-            Object = Magazine->Slot[Index];
-            Magazine->Slot[Index] = NULL;
-
-            return Object;
-        }
-    }
-
-    return NULL;
-}
-
-static FORCEINLINE BOOLEAN
-__PoolPutMagazine(
-    IN  PXENBUS_POOL    Pool,
-    IN  ULONG           Cpu,
-    IN  PVOID           Object
-    )
-{
-    PPOOL_MAGAZINE      Magazine;
-    ULONG               Index;
-
-    Magazine = &Pool->Magazine[Cpu];
-
-    for (Index = 0; Index < MAXIMUM_SLOTS; Index++) {
-        if (Magazine->Slot[Index] == NULL) {
-            Magazine->Slot[Index] = Object;
-            return TRUE;
-        }
-    }
-
-    return FALSE;
-}
-
-PVOID
-PoolGet(
-    IN  PXENBUS_POOL    Pool,
-    IN  BOOLEAN         Locked
-    )
-{
-    KIRQL               Irql;
-    ULONG               Cpu;
-    PVOID               Object;
-
-    if (Pool->FIST.Probability != 0) {
-        LONG    Defer;
-
-        Defer = InterlockedDecrement(&Pool->FIST.Defer);
-
-        if (Defer <= 0) {
-            ULONG   Random = RtlRandomEx(&Pool->FIST.Seed);
-            ULONG   Threshold = (MAXLONG / 100) * Pool->FIST.Probability;
-
-            if (Random < Threshold)
-                return NULL;
-        }
-    }
-
-    KeRaiseIrql(DISPATCH_LEVEL, &Irql);
-    Cpu = KeGetCurrentProcessorNumber();
-
-    Object = __PoolGetMagazine(Pool, Cpu);
-    if (Object == NULL)
-        Object = __PoolGetShared(Pool, Locked);
-
-    KeLowerIrql(Irql);
-
-    return Object;
-}
-
-VOID
-PoolPut(
-    IN  PXENBUS_POOL    Pool,
-    IN  PVOID           Object,
-    IN  BOOLEAN         Locked
-    )
-{
-    KIRQL               Irql;
-    ULONG               Cpu;
-
-    KeRaiseIrql(DISPATCH_LEVEL, &Irql);
-    Cpu = KeGetCurrentProcessorNumber();
-
-    if (!__PoolPutMagazine(Pool, Cpu, Object))
-        __PoolPutShared(Pool, Object, Locked);
-
-    KeLowerIrql(Irql);
-}
-
-VOID
-PoolGetStatistics(
-    IN  PXENBUS_POOL            Pool,
-    OUT PXENBUS_POOL_STATISTICS Statistics
-    )
-{
-    Statistics->Allocated = Pool->Allocated;
-    Statistics->MaximumAllocated = Pool->MaximumAllocated;
-    Statistics->Population = Pool->Population;
-    Statistics->MinimumPopulation = Pool->MinimumPopulation;
-}
-
-static FORCEINLINE
-__PoolFlushMagazines(
-    IN  PXENBUS_POOL    Pool
-    )
-{
-    ULONG               Cpu;
-
-    for (Cpu = 0; Cpu < MAXIMUM_PROCESSORS; Cpu++) {
-        PVOID   Object;
-
-        while ((Object = __PoolGetMagazine(Pool, Cpu)) != NULL)
-            __PoolPutShared(Pool, Object, TRUE);
-    }
-}
-
-static FORCEINLINE VOID
-__PoolTrimShared(
-    IN      PXENBUS_POOL    Pool,
-    IN OUT  PLIST_ENTRY     List
-    )
-{
-    LONG                    Population;
-    LONG                    Excess;
-
-    Population = Pool->Population;
-
-    KeMemoryBarrier();
-
-    Excess = __max((LONG)Pool->MinimumPopulation - (LONG)Pool->Reservation, 0);
-    
-    while (Excess != 0) {
-        PLIST_ENTRY     ListEntry;
-
-        Population = InterlockedDecrement(&Pool->Population);
-        if (Population < 0) {
-            Population = InterlockedIncrement(&Pool->Population);
-            break;
-        }
-
-        if (IsListEmpty(&Pool->GetList))
-            __PoolSwizzle(Pool);
-
-        ListEntry = RemoveHeadList(&Pool->GetList);
-        ASSERT(ListEntry != &Pool->GetList);
-
-        InsertTailList(List, ListEntry);
-
-        InterlockedDecrement(&Pool->Allocated);
-        --Excess;
-    }
-
-    Pool->MinimumPopulation = Population;
-}
-
-static FORCEINLINE VOID
-__PoolDestroyObject(
-    IN  PXENBUS_POOL    Pool,
-    IN  POBJECT_HEADER  Header
-    )
-{
-    PVOID               Object;
-
-    Object = Header + 1;
-
-    Pool->Dtor(Pool->Argument, Object);
-
-    Header->Magic = 0;
-
-    ASSERT(IsZeroMemory(Header, sizeof (OBJECT_HEADER)));
-    __PoolFree(Header);
-}
-
-static FORCEINLINE VOID
-__PoolEmpty(
-    IN      PXENBUS_POOL    Pool,
-    IN OUT  PLIST_ENTRY     List
-    )
-{
-    while (!IsListEmpty(List)) {
-        PLIST_ENTRY     ListEntry;
-        POBJECT_HEADER  Header;
-
-        ListEntry = RemoveHeadList(List);
-        RtlZeroMemory(ListEntry, sizeof (LIST_ENTRY));
-
-        Header = CONTAINING_RECORD(ListEntry, OBJECT_HEADER, ListEntry);
-        ASSERT3U(Header->Magic, ==, OBJECT_HEADER_MAGIC);
-
-        __PoolDestroyObject(Pool, Header);
-    }
-}
-
-#define TIME_US(_us)        ((_us) * 10)
-#define TIME_MS(_ms)        (TIME_US((_ms) * 1000))
-#define TIME_RELATIVE(_t)   (-(_t))
-
-#define POOL_PERIOD  1000
-
-KDEFERRED_ROUTINE   PoolDpc;
-
-VOID
-PoolDpc(
-    IN  PKDPC       Dpc,
-    IN  PVOID       Context,
-    IN  PVOID       Argument1,
-    IN  PVOID       Argument2
-    )
-{
-    PXENBUS_POOL    Pool = Context;
-    LIST_ENTRY      List;
-
-    UNREFERENCED_PARAMETER(Dpc);
-    UNREFERENCED_PARAMETER(Argument1);
-    UNREFERENCED_PARAMETER(Argument2);
-
-    ASSERT(Pool != NULL);
-
-    InitializeListHead(&List);
-
-    Pool->AcquireLock(Pool->Argument);
-    __PoolTrimShared(Pool, &List);
-    Pool->ReleaseLock(Pool->Argument);
-
-    __PoolEmpty(Pool, &List);
-    ASSERT(IsListEmpty(&List));
-}
-
-static FORCEINLINE VOID
-__PoolSetupFIST(
-    IN  PXENBUS_POOL            Pool,
-    IN  PXENBUS_STORE_INTERFACE StoreInterface
-    )
-{
-    CHAR                        Node[sizeof ("fist/pool/") + MAXNAMELEN];
-    PCHAR                       Buffer;
-    LARGE_INTEGER               Now;
-    NTSTATUS                    status;
-
-    status = RtlStringCbPrintfA(Node,
-                                sizeof (Node),
-                                "fist/pool/%s",
-                                Pool->Name);
-    ASSERT(NT_SUCCESS(status));
-
-    status = STORE(Read,
-                   StoreInterface,
-                   NULL,
-                   Node,
-                   "defer",
-                   &Buffer);
-    if (!NT_SUCCESS(status)) {
-        Pool->FIST.Defer = 0;
-    } else {
-        Pool->FIST.Defer = (ULONG)strtol(Buffer, NULL, 0);
-
-        STORE(Free,
-              StoreInterface,
-              Buffer);
-    }
-
-    status = STORE(Read,
-                   StoreInterface,
-                   NULL,
-                   Node,
-                   "probability",
-                   &Buffer);
-    if (!NT_SUCCESS(status)) {
-        Pool->FIST.Probability = 0;
-    } else {
-        Pool->FIST.Probability = (ULONG)strtol(Buffer, NULL, 0);
-
-        STORE(Free,
-              StoreInterface,
-              Buffer);
-    }
-
-    if (Pool->FIST.Probability > 100)
-        Pool->FIST.Probability = 100;
-
-    if (Pool->FIST.Probability != 0)
-        Info("%s: Defer = %d Probability = %d\n",
-             Pool->Name,
-             Pool->FIST.Defer,
-             Pool->FIST.Probability);
-
-    KeQuerySystemTime(&Now);
-    Pool->FIST.Seed = Now.LowPart;
-}
-
-NTSTATUS
-PoolInitialize(
-    IN  PXENBUS_STORE_INTERFACE StoreInterface,
-    IN  const CHAR              *Name,
-    IN  ULONG                   Size,
-    IN  ULONG                   Reservation,
-    IN  NTSTATUS                (*Ctor)(PVOID, PVOID),
-    IN  VOID                    (*Dtor)(PVOID, PVOID),
-    IN  VOID                    (*AcquireLock)(PVOID),
-    IN  VOID                    (*ReleaseLock)(PVOID),
-    IN  PVOID                   Argument,
-    OUT PXENBUS_POOL            *Pool
-    )
-{
-    LARGE_INTEGER               Timeout;
-    LIST_ENTRY                  List;
-    NTSTATUS                    status;
-
-    *Pool = __PoolAllocate(sizeof (XENBUS_POOL));
-
-    status = STATUS_NO_MEMORY;
-    if (*Pool == NULL)
-        goto fail1;
-
-    status = RtlStringCbPrintfA((*Pool)->Name,
-                                sizeof ((*Pool)->Name),
-                                "%s",
-                                Name);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    (*Pool)->Size = Size;
-    (*Pool)->Ctor = Ctor;
-    (*Pool)->Dtor = Dtor;
-    (*Pool)->AcquireLock = AcquireLock;
-    (*Pool)->ReleaseLock = ReleaseLock;
-    (*Pool)->Argument = Argument;
-
-    __PoolSetupFIST(*Pool, StoreInterface);
-
-    InitializeListHead(&(*Pool)->GetList);
-
-    while (Reservation != 0) {
-        POBJECT_HEADER  Header;
-
-        status = __PoolCreateObject(*Pool, &Header);
-        if (!NT_SUCCESS(status))
-            goto fail3;
-
-        (VOID) InterlockedIncrement(&(*Pool)->Allocated);
-
-        InsertTailList(&(*Pool)->GetList, &Header->ListEntry);
-        (VOID) InterlockedIncrement(&(*Pool)->Population);
-
-        --Reservation;
-    }
-    (*Pool)->MaximumAllocated = (*Pool)->Allocated;
-    (*Pool)->Reservation = (*Pool)->Population;
-
-    KeInitializeDpc(&(*Pool)->Dpc,
-                    PoolDpc,
-                    (*Pool));
-
-    Timeout.QuadPart = TIME_RELATIVE(TIME_MS(POOL_PERIOD));
-
-    KeInitializeTimer(&(*Pool)->Timer);
-    KeSetTimerEx(&(*Pool)->Timer,
-                 Timeout,
-                 POOL_PERIOD,
-                 &(*Pool)->Dpc);
-
-    return STATUS_SUCCESS;
-
-fail3:
-    Error("fail3\n");
-
-    InitializeListHead(&List);
-
-    (*Pool)->MinimumPopulation = (*Pool)->Population;
-    __PoolTrimShared(*Pool, &List);
-    __PoolEmpty(*Pool, &List);
-
-    ASSERT3U((*Pool)->Population, ==, 0);
-    ASSERT3U((*Pool)->Allocated, ==, 0);
-
-    RtlZeroMemory(&(*Pool)->GetList, sizeof (LIST_ENTRY));
-
-    RtlZeroMemory(&(*Pool)->FIST, sizeof (POOL_FIST));
-
-    (*Pool)->Argument = NULL;
-    (*Pool)->ReleaseLock = NULL;
-    (*Pool)->AcquireLock = NULL;
-    (*Pool)->Dtor = NULL;
-    (*Pool)->Ctor = NULL;
-    (*Pool)->Size = 0;
-
-fail2:
-    Error("fail2\n");
-
-    RtlZeroMemory((*Pool)->Name, sizeof ((*Pool)->Name));
-    
-    ASSERT(IsZeroMemory(*Pool, sizeof (XENBUS_POOL)));
-    __PoolFree(*Pool);
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    return status;    
-}
-
-VOID
-PoolTeardown(
-    IN  PXENBUS_POOL    Pool
-    )
-{
-    LIST_ENTRY          List;
-
-    KeCancelTimer(&Pool->Timer);
-    KeFlushQueuedDpcs();
-
-    RtlZeroMemory(&Pool->Timer, sizeof (KTIMER));
-    RtlZeroMemory(&Pool->Dpc, sizeof (KDPC));
-
-    Pool->Reservation = 0;
-    Pool->MaximumAllocated = 0;
-
-    InitializeListHead(&List);
-
-    __PoolFlushMagazines(Pool);
-
-    Pool->MinimumPopulation = Pool->Population;
-    __PoolTrimShared(Pool, &List);
-    __PoolEmpty(Pool, &List);
-
-    ASSERT3U(Pool->Population, ==, 0);
-    ASSERT3U(Pool->Allocated, ==, 0);
-
-    RtlZeroMemory(&Pool->GetList, sizeof (LIST_ENTRY));
-
-    RtlZeroMemory(&Pool->FIST, sizeof (POOL_FIST));
-
-    Pool->Argument = NULL;
-    Pool->ReleaseLock = NULL;
-    Pool->AcquireLock = NULL;
-    Pool->Dtor = NULL;
-    Pool->Ctor = NULL;
-    Pool->Size = 0;
-
-    RtlZeroMemory(Pool->Name, sizeof (Pool->Name));
-
-    ASSERT(IsZeroMemory(Pool, sizeof (XENBUS_POOL)));
-    __PoolFree(Pool);
-}
diff --git a/src/xenbus/pool.h b/src/xenbus/pool.h
deleted file mode 100644 (file)
index aa88390..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/* Copyright (c) Citrix Systems Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, 
- * with or without modification, are permitted provided 
- * that the following conditions are met:
- * 
- * *   Redistributions of source code must retain the above 
- *     copyright notice, this list of conditions and the 
- *     following disclaimer.
- * *   Redistributions in binary form must reproduce the above 
- *     copyright notice, this list of conditions and the 
- *     following disclaimer in the documentation and/or other 
- *     materials provided with the distribution.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
- * SUCH DAMAGE.
- */
-
-#ifndef _XENBUS_POOL_H
-#define _XENBUS_POOL_H
-
-#include <ntddk.h>
-#include <store_interface.h>
-
-typedef struct _XENBUS_POOL XENBUS_POOL, *PXENBUS_POOL;
-
-extern NTSTATUS
-PoolInitialize(
-    IN  PXENBUS_STORE_INTERFACE StoreInterface,
-    IN  const CHAR              *Name,
-    IN  ULONG                   Size,
-    IN  ULONG                   Reservation,
-    IN  NTSTATUS                (*Ctor)(PVOID, PVOID),
-    IN  VOID                    (*Dtor)(PVOID, PVOID),
-    IN  VOID                    (*AcquireLock)(PVOID),
-    IN  VOID                    (*ReleaseLock)(PVOID),
-    IN  PVOID                   Argument,
-    OUT PXENBUS_POOL            *Pool
-    );
-
-extern VOID
-PoolTeardown(
-    IN  PXENBUS_POOL    Pool
-    );
-
-extern PVOID
-PoolGet(
-    IN  PXENBUS_POOL    Pool,
-    IN  BOOLEAN         Locked
-    );
-
-extern VOID
-PoolPut(
-    IN  PXENBUS_POOL    Pool,
-    IN  PVOID           Object,
-    IN  BOOLEAN         Locked
-    );
-
-typedef struct _XENBUS_POOL_STATISTICS {
-    ULONG   Allocated;
-    ULONG   MaximumAllocated;
-    ULONG   Population;
-    ULONG   MinimumPopulation;
-} XENBUS_POOL_STATISTICS, *PXENBUS_POOL_STATISTICS;
-
-extern VOID
-PoolGetStatistics(
-    IN  PXENBUS_POOL            Pool,
-    OUT PXENBUS_POOL_STATISTICS Statistics
-    );
-
-#endif  // _XENBUS_POOL_H