ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

pageop.c
Go to the documentation of this file.
00001 /*
00002  * COPYRIGHT:       See COPYING in the top level directory
00003  * PROJECT:         ReactOS kernel
00004  * FILE:            ntoskrnl/mm/pageop.c
00005  * PURPOSE:         No purpose listed.
00006  *
00007  * PROGRAMMERS:     David Welch (welch@cwcom.net)
00008  */
00009 
00010 /* INCLUDES ****************************************************************/
00011 
00012 #include <ntoskrnl.h>
00013 #define NDEBUG
00014 #include <debug.h>
00015 
00016 #if defined (ALLOC_PRAGMA)
00017 #pragma alloc_text(INIT, MmInitializePageOp)
00018 #endif
00019 
00020 
00021 /* GLOBALS *******************************************************************/
00022 
00023 #define PAGEOP_HASH_TABLE_SIZE       (32)
00024 
00025 static KSPIN_LOCK MmPageOpHashTableLock;
00026 static PMM_PAGEOP MmPageOpHashTable[PAGEOP_HASH_TABLE_SIZE];
00027 static NPAGED_LOOKASIDE_LIST MmPageOpLookasideList;
00028 
00029 /* FUNCTIONS *****************************************************************/
00030 
00031 VOID
00032 NTAPI
00033 MmReleasePageOp(PMM_PAGEOP PageOp)
00034 /*
00035  * FUNCTION: Release a reference to a page operation descriptor
00036  */
00037 {
00038    KIRQL oldIrql;
00039    PMM_PAGEOP PrevPageOp;
00040 
00041    KeAcquireSpinLock(&MmPageOpHashTableLock, &oldIrql);
00042    PageOp->ReferenceCount--;
00043    if (PageOp->ReferenceCount > 0)
00044    {
00045       KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
00046       return;
00047    }
00048    (void)InterlockedDecrementUL(&PageOp->MArea->PageOpCount);
00049    PrevPageOp = MmPageOpHashTable[PageOp->Hash];
00050    if (PrevPageOp == PageOp)
00051    {
00052       MmPageOpHashTable[PageOp->Hash] = PageOp->Next;
00053       KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
00054       ExFreeToNPagedLookasideList(&MmPageOpLookasideList, PageOp);
00055       return;
00056    }
00057    while (PrevPageOp->Next != NULL)
00058    {
00059       if (PrevPageOp->Next == PageOp)
00060       {
00061          PrevPageOp->Next = PageOp->Next;
00062          KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
00063          ExFreeToNPagedLookasideList(&MmPageOpLookasideList, PageOp);
00064          return;
00065       }
00066       PrevPageOp = PrevPageOp->Next;
00067    }
00068    KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
00069    KeBugCheck(MEMORY_MANAGEMENT);
00070 }
00071 
00072 PMM_PAGEOP
00073 NTAPI
00074 MmCheckForPageOp(PMEMORY_AREA MArea, HANDLE Pid, PVOID Address,
00075                  PMM_SECTION_SEGMENT Segment, ULONGLONG Offset)
00076 {
00077    ULONG_PTR Hash;
00078    KIRQL oldIrql;
00079    PMM_PAGEOP PageOp;
00080 
00081    /*
00082     * Calcuate the hash value for pageop structure
00083     */
00084    if (MArea->Type == MEMORY_AREA_SECTION_VIEW)
00085    {
00086       Hash = (((ULONG_PTR)Segment) | (((ULONG_PTR)Offset) / PAGE_SIZE));
00087    }
00088    else
00089    {
00090       Hash = (((ULONG_PTR)Pid) | (((ULONG_PTR)Address) / PAGE_SIZE));
00091    }
00092    Hash = Hash % PAGEOP_HASH_TABLE_SIZE;
00093 
00094    KeAcquireSpinLock(&MmPageOpHashTableLock, &oldIrql);
00095 
00096    /*
00097     * Check for an existing pageop structure
00098     */
00099    PageOp = MmPageOpHashTable[Hash];
00100    while (PageOp != NULL)
00101    {
00102       if (MArea->Type == MEMORY_AREA_SECTION_VIEW)
00103       {
00104          if (PageOp->Segment == Segment &&
00105                PageOp->Offset == Offset)
00106          {
00107             break;
00108          }
00109       }
00110       else
00111       {
00112          if (PageOp->Pid == Pid &&
00113                PageOp->Address == Address)
00114          {
00115             break;
00116          }
00117       }
00118       PageOp = PageOp->Next;
00119    }
00120 
00121    /*
00122     * If we found an existing pageop then increment the reference count
00123     * and return it.
00124     */
00125    if (PageOp != NULL)
00126    {
00127       PageOp->ReferenceCount++;
00128       KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
00129       return(PageOp);
00130    }
00131    KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
00132    return(NULL);
00133 }
00134 
00135 PMM_PAGEOP
00136 NTAPI
00137 MmGetPageOp(PMEMORY_AREA MArea, HANDLE Pid, PVOID Address,
00138             PMM_SECTION_SEGMENT Segment, ULONGLONG Offset, ULONG OpType, BOOLEAN First)
00139 /*
00140  * FUNCTION: Get a page operation descriptor corresponding to
00141  * the memory area and either the segment, offset pair or the
00142  * pid, address pair.
00143  */
00144 {
00145    ULONG_PTR Hash;
00146    KIRQL oldIrql;
00147    PMM_PAGEOP PageOp;
00148 
00149    Address = (PVOID)PAGE_ROUND_DOWN(Address);
00150    Offset = PAGE_ROUND_DOWN(Offset);
00151 
00152    /* Making a page op during marea destruction is illegal */
00153    ASSERT(!MArea->DeleteInProgress);
00154 
00155    /*
00156     * Calcuate the hash value for pageop structure
00157     */
00158    if (MArea->Type == MEMORY_AREA_SECTION_VIEW)
00159    {
00160       Hash = (((ULONG_PTR)Segment) | (((ULONG_PTR)Offset) / PAGE_SIZE));
00161    }
00162    else
00163    {
00164       Hash = (((ULONG_PTR)Pid) | (((ULONG_PTR)Address) / PAGE_SIZE));
00165    }
00166    Hash = Hash % PAGEOP_HASH_TABLE_SIZE;
00167 
00168    KeAcquireSpinLock(&MmPageOpHashTableLock, &oldIrql);
00169 
00170    /*
00171     * Check for an existing pageop structure
00172     */
00173    PageOp = MmPageOpHashTable[Hash];
00174    while (PageOp != NULL)
00175    {
00176       if (MArea->Type == MEMORY_AREA_SECTION_VIEW)
00177       {
00178          if (PageOp->Segment == Segment &&
00179                PageOp->Offset == Offset)
00180          {
00181             break;
00182          }
00183       }
00184       else
00185       {
00186          if (PageOp->Pid == Pid &&
00187                PageOp->Address == Address)
00188          {
00189             break;
00190          }
00191       }
00192       PageOp = PageOp->Next;
00193    }
00194 
00195    /*
00196     * If we found an existing pageop then increment the reference count
00197     * and return it.
00198     */
00199    if (PageOp != NULL)
00200    {
00201       if (First)
00202       {
00203          PageOp = NULL;
00204       }
00205       else
00206       {
00207          PageOp->ReferenceCount++;
00208       }
00209       KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
00210       return(PageOp);
00211    }
00212 
00213    /*
00214     * Otherwise add a new pageop.
00215     */
00216    PageOp = ExAllocateFromNPagedLookasideList(&MmPageOpLookasideList);
00217    if (PageOp == NULL)
00218    {
00219       KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
00220       KeBugCheck(MEMORY_MANAGEMENT);
00221       return(NULL);
00222    }
00223 
00224    if (MArea->Type != MEMORY_AREA_SECTION_VIEW)
00225    {
00226       PageOp->Pid = Pid;
00227       PageOp->Address = Address;
00228    }
00229    else
00230    {
00231       PageOp->Segment = Segment;
00232       PageOp->Offset = Offset;
00233    }
00234    PageOp->ReferenceCount = 1;
00235    PageOp->Next = MmPageOpHashTable[Hash];
00236    PageOp->Hash = (ULONG)Hash;
00237    PageOp->Thread = PsGetCurrentThread();
00238    PageOp->Abandoned = FALSE;
00239    PageOp->Status = STATUS_PENDING;
00240    PageOp->OpType = OpType;
00241    PageOp->MArea = MArea;
00242    KeInitializeEvent(&PageOp->CompletionEvent, SynchronizationEvent, FALSE);
00243    MmPageOpHashTable[Hash] = PageOp;
00244    (void)InterlockedIncrementUL(&MArea->PageOpCount);
00245 
00246    KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
00247    return(PageOp);
00248 }
00249 
00250 VOID
00251 INIT_FUNCTION
00252 NTAPI
00253 MmInitializePageOp(VOID)
00254 {
00255    memset(MmPageOpHashTable, 0, sizeof(MmPageOpHashTable));
00256    KeInitializeSpinLock(&MmPageOpHashTableLock);
00257 
00258    ExInitializeNPagedLookasideList (&MmPageOpLookasideList,
00259                                     NULL,
00260                                     NULL,
00261                                     0,
00262                                     sizeof(MM_PAGEOP),
00263                                     TAG_MM_PAGEOP,
00264                                     50);
00265 }
00266 
00267 
00268 
00269 
00270 
00271 
00272 
00273 
00274 

Generated on Sat May 26 2012 04:36:30 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.