test: hivefree.c File Reference

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# hivefree.c File Reference

`#include "cmp.h"`

Go to the source code of this file.

## Functions

VOID | HvFreeHive (PHHIVE Hive)
VOID | HvFreeHivePartial (PHHIVE Hive, HCELL_INDEX Start, HSTORAGE_TYPE Type)

## Function Documentation

VOID HvFreeHive | ( | PHHIVE | Hive | ) |

Definition at line 34 of file hivefree.c.

References ASSERT, _HHIVE::BaseBlock, Bin, _HMAP_ENTRY::BinAddress, _HMAP_ENTRY::BlockAddress, CML_BIN, CMLOG, CmpFree(), CMS_BIN_MAP, _HHIVE::DirtyAlloc, _HHIVE::DirtyVector, FALSE, _HBASE_BLOCK::FileName, _FREE_HBIN::Flags, _HHIVE::Flat, _HHIVE::Free, FREE_HBIN_DISCARDABLE, HBLOCK_SIZE, HCELL_INDEX, HCELL_TYPE_MASK, Hive, HMAP_BASE, HMAP_DISCARDABLE, HMAP_NEWALLOC, HTABLE_SLOTS, HvpFreeMap(), HvpGetCellMap(), _HBIN::MemAlloc, NULL, _HHIVE::ReadOnly, _FREE_HBIN::Size, Stable, VALIDATE_CELL_MAP, and Volatile.

Referenced by CmpDestroyTemporaryHive(), CmpInitializeHive(), CmpValidateAlternate(), CmReplaceKey(), and CmUnloadKey().

    00039                    :
    00040
    00041     Free all of the pieces of a hive.
    00042
    00043 Arguments:
    00044
    00045     Hive - supplies a pointer to hive control structure for hive to free.
    00046             this structure itself will NOT be freed, but everything it
    00047             points to will.
    00048
    00049 Return Value:
    00050
    00051     NONE.
    00052
    00053 --*/
    00054 {
    00055     PHMAP_DIRECTORY Dir;
    00056     PHMAP_ENTRY     Me;
    00057     HCELL_INDEX     Address;
    00058     ULONG           Type;
    00059     ULONG           Length;
    00060     PHBIN           Bin;
    00061     ULONG           Tables;
    00062     PFREE_HBIN      FreeBin;
    00063
    00064     ASSERT(Hive->Flat == FALSE);
    00065     ASSERT(Hive->ReadOnly == FALSE);
    00066     ASSERT(Stable == 0);
    00067     ASSERT(Volatile == 1);
    00068
    00069     CMLOG(CML_BIN, CMS_BIN_MAP) {
    00070         KdPrint(("HvFreeHive(%ws) :\n", Hive->BaseBlock->FileName));
    00071     }
    00072     //
    00073     // Iterate through both types of storage
    00074     //
    00075     for (Type = 0; Type <= Volatile; Type++) {
    00076
    00077         Address = HCELL_TYPE_MASK * Type;
    00078         Length = Hive->Storage[Type].Length + (HCELL_TYPE_MASK * Type);
    00079
    00080         if (Length > (HCELL_TYPE_MASK * Type)) {
    00081
    00082             //
    00083             // Sweep through bin set
    00084             //
    00085             do {
    00086                 Me = HvpGetCellMap(Hive, Address);
    00087                 VALIDATE_CELL_MAP(__LINE__,Me,Hive,Address);
    00088                 if (Me->BinAddress & HMAP_DISCARDABLE) {
    00089                     //
    00090                     // hbin is either discarded or discardable, check the tombstone
    00091                     //
    00092                     FreeBin = (PFREE_HBIN)Me->BlockAddress;
    00093                     Address += FreeBin->Size;
    00094                     if (FreeBin->Flags & FREE_HBIN_DISCARDABLE) {
    00095                         CmpFree((PHBIN)(Me->BinAddress & HMAP_BASE), FreeBin->Size);
    00096                     }
    00097                     CmpFree(FreeBin, sizeof(FREE_HBIN));
    00098                 } else {
    00099                     Bin = (PHBIN)(Me->BinAddress & HMAP_BASE);
    00100                     Address += Bin->MemAlloc;
    00101 #if DBG
    00102                     //
    00103                     // Make sure that the next bin in the list is
    00104                     // actually the start of an alloc before freeing it
    00105                     //
    00106                     if (Address < Length) {
    00107                         Me = HvpGetCellMap(Hive, Address);
    00108                         VALIDATE_CELL_MAP(__LINE__,Me,Hive,Address);
    00109                         ASSERT(Me->BinAddress & HMAP_NEWALLOC);
    00110                     }
    00111 #endif
    00112
    00113                     CMLOG(CML_BIN, CMS_BIN_MAP) {
    00114                         if( Type == Stable ) {
    00115                             KdPrint(("HvFreeHive: BinAddress = 0x%08lx\t Size = 0x%lx\n", Bin, Bin->MemAlloc));
    00116                         }
    00117                     }
    00118
    00119                     CmpFree(Bin, Bin->MemAlloc);
    00120                 }
    00121
    00122             } while (Address < Length);
    00123
    00124             //
    00125             // Free map table storage
    00126             //
    00127             ASSERT(Hive->Storage[Type].Length != (HCELL_TYPE_MASK * Type));
    00128             Tables = (((Hive->Storage[Type].Length) / HBLOCK_SIZE)-1) / HTABLE_SLOTS;
    00129             Dir = Hive->Storage[Type].Map;
    00130             HvpFreeMap(Hive, Dir, 0, Tables);
    00131
    00132             if (Tables > 0) {
    00133                 CmpFree(Hive->Storage[Type].Map, sizeof(HMAP_DIRECTORY));  // free dir if it exists
    00134             }
    00135         }
    00136         Hive->Storage[Type].Length = 0;
    00137     }
    00138
    00139     CMLOG(CML_BIN, CMS_BIN_MAP) {
    00140         KdPrint(("\n"));
    00141     }
    00142     //
    00143     // Free the base block
    00144     //
    00145     (Hive->Free)(Hive->BaseBlock, sizeof(HBASE_BLOCK));
    00146     Hive->BaseBlock = NULL;
    00147
    00148     //
    00149     // Free the dirty vector
    00150     //
    00151     if (Hive->DirtyVector.Buffer != NULL) {
    00152         CmpFree((PVOID)(Hive->DirtyVector.Buffer), Hive->DirtyAlloc);
    00153     }
    00154
    00155     return;
    00156 }

VOID HvFreeHivePartial | ( | PHHIVE | Hive,
|  | HCELL_INDEX | Start,
|  | HSTORAGE_TYPE | Type
| ) |

Definition at line 160 of file hivefree.c.

References ASSERT, Bin, _HMAP_ENTRY::BinAddress, _HMAP_ENTRY::BlockAddress, CmpFree(), CmpReleaseGlobalQuota(), _HHIVE::DirtyCount, _HHIVE::DirtyVector, FALSE, _FREE_HBIN::Flags, _HHIVE::Flat, FREE_HBIN_DISCARDABLE, HBLOCK_SIZE, HCELL_INDEX, HCELL_TYPE_MASK, Hive, HMAP_BASE, HMAP_DISCARDABLE, HSECTOR_SIZE, HTABLE_SLOTS, HvpFreeMap(), HvpGetCellMap(), _FREE_HBIN::ListEntry, _HBIN::MemAlloc, _HHIVE::ReadOnly, RtlClearBits(), RtlNumberOfSetBits(), _FREE_HBIN::Size, Stable, Start, and VALIDATE_CELL_MAP.

Referenced by HvpTruncateBins(), and HvRefreshHive().

    00167                    :
    00168
    00169     Free the memory and associated maps for the end of a hive
    00170     starting at Start.  The baseblock, hive, etc will not be touched.
    00171
    00172 Arguments:
    00173
    00174     Hive - supplies a pointer to hive control structure for hive to
    00175             partially free.
    00176
    00177     Start - HCELL_INDEX of first bin to free, will free from this
    00178             bin (inclusive) to the end of the hives stable storage.
    00179
    00180     Type - Type of storage (Stable or Volatile) to be freed.
    00181
    00182 Return Value:
    00183
    00184     NONE.
    00185
    00186 --*/
    00187 {
    00188     PHMAP_DIRECTORY Dir;
    00189     PHMAP_ENTRY     Me;
    00190     HCELL_INDEX     Address;
    00191     ULONG           StartTable;
    00192     ULONG           Length;
    00193     PHBIN           Bin;
    00194     ULONG           Tables;
    00195     ULONG           FirstBit;
    00196     ULONG           LastBit;
    00197     PFREE_HBIN      FreeBin;
    00198
    00199     ASSERT(Hive->Flat == FALSE);
    00200     ASSERT(Hive->ReadOnly == FALSE);
    00201
    00202     Address = Start;
    00203     Length = Hive->Storage[Type].Length;
    00204     ASSERT(Address <= Length);
    00205
    00206     if (Address == Length) {
    00207         return;
    00208     }
    00209
    00210     //
    00211     // Sweep through bin set
    00212     //
    00213     do {
    00214         Me = HvpGetCellMap(Hive, Address + (Type*HCELL_TYPE_MASK));
    00215         VALIDATE_CELL_MAP(__LINE__,Me,Hive,Address + (Type*HCELL_TYPE_MASK));
    00216         if (Me->BinAddress & HMAP_DISCARDABLE) {
    00217             FreeBin = (PFREE_HBIN)Me->BlockAddress;
    00218             if (FreeBin->Flags & FREE_HBIN_DISCARDABLE) {
    00219                 CmpFree((PVOID)(Me->BinAddress & HMAP_BASE), FreeBin->Size);
    00220             } else {
    00221                 //
    00222                 // The bin has been freed, but quota is still charged.
    00223                 // Since the file will now shrink, the quota must be
    00224                 // returned here.
    00225                 //
    00226                 CmpReleaseGlobalQuota(FreeBin->Size);
    00227             }
    00228             RemoveEntryList(&FreeBin->ListEntry);
    00229             Address += FreeBin->Size;
    00230             CmpFree(FreeBin, sizeof(FREE_HBIN));
    00231
    00232         } else {
    00233             Bin = (PHBIN)(Me->BinAddress & HMAP_BASE);
    00234
    00235             Address += Bin->MemAlloc;
    00236             CmpFree(Bin, Bin->MemAlloc);
    00237         }
    00238     } while (Address < Length);
    00239
    00240     //
    00241     // Free map table storage
    00242     //
    00243     Tables = (((Hive->Storage[Type].Length) / HBLOCK_SIZE) - 1) / HTABLE_SLOTS;
    00244     Dir = Hive->Storage[Type].Map;
    00245     if (Start > 0) {
    00246         StartTable = ((Start-1) / HBLOCK_SIZE) / HTABLE_SLOTS;
    00247     } else {
    00248         StartTable = (ULONG)-1;
    00249     }
    00250     HvpFreeMap(Hive, Dir, StartTable+1, Tables);
    00251
    00252     Hive->Storage[Type].Length = Start;
    00253
    00254     if (Type==Stable) {
    00255         //
    00256         // Clear dirty vector for data past Hive->Storage[Stable].Length
    00257         //
    00258         FirstBit = Start / HSECTOR_SIZE;
    00259         LastBit = Hive->DirtyVector.SizeOfBitMap;
    00260         ASSERT(Hive->DirtyCount == RtlNumberOfSetBits(&Hive->DirtyVector));
    00261         RtlClearBits(&Hive->DirtyVector, FirstBit, LastBit-FirstBit);
    00262         Hive->DirtyCount = RtlNumberOfSetBits(&Hive->DirtyVector);
    00263     }
    00264
    00265     return;
    00266 }
    }