⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mpheap.c

📁 <Win2k系统编程>源码.次数为国人自编,内容丰富,还是不错的.
💻 C
📖 第 1 页 / 共 2 页
字号:
    )
{
    PMP_HEAP MpHeap;
    DWORD i;
    BOOL Success;
    PMP_HEADER Header;
    PMP_HEAP_ENTRY Entry;

    MpHeap = (PMP_HEAP)hMpHeap;

    if (lpMem == NULL) {

        //
        // Lock and validate each heap in turn.
        //
        for (i=0; i < MpHeap->HeapCount; i++) {
            Entry = &MpHeap->Entry[i];
            try {
                EnterCriticalSection(&Entry->Lock);
                Success = HeapValidate(Entry->Heap, 0, NULL);
                LeaveCriticalSection(&Entry->Lock);
            } except (EXCEPTION_EXECUTE_HANDLER) {
                return(FALSE);
            }

            if (!Success) {
                return(FALSE);
            }
        }
        return(TRUE);
    } else {

        //
        // Lock and validate the given heap entry
        //
        Header = ((PMP_HEADER)lpMem) - 1;
        try {
            EnterCriticalSection(&Header->HeapEntry->Lock);
            Success = HeapValidate(Header->HeapEntry->Heap, 0, Header);
            LeaveCriticalSection(&Header->HeapEntry->Lock);
        } except (EXCEPTION_EXECUTE_HANDLER) {
            return(FALSE);
        }
        return(Success);
    }
}

UINT
WINAPI
MpHeapCompact(
    HANDLE hMpHeap
    )
{
    PMP_HEAP MpHeap;
    DWORD i;
    DWORD LargestFreeSize=0;
    DWORD FreeSize;
    PMP_HEAP_ENTRY Entry;

    MpHeap = (PMP_HEAP)hMpHeap;

    //
    // Lock and compact each heap in turn.
    //
    for (i=0; i < MpHeap->HeapCount; i++) {
        Entry = &MpHeap->Entry[i];
        EnterCriticalSection(&Entry->Lock);
        FreeSize = HeapCompact(Entry->Heap, 0);
        LeaveCriticalSection(&Entry->Lock);

        if (FreeSize > LargestFreeSize) {
            LargestFreeSize = FreeSize;
        }
    }

    return(LargestFreeSize);

}


LPVOID
WINAPI
MpHeapAlloc(
    HANDLE hMpHeap,
    DWORD flOptions,
    DWORD dwBytes
    )
{
    PMP_HEADER Header;
    PMP_HEAP MpHeap;
    DWORD i;
    PMP_HEAP_ENTRY Entry;
    DWORD Index;
    DWORD Size;

    MpHeap = (PMP_HEAP)hMpHeap;

    flOptions |= MpHeap->Flags;

    Size = ((dwBytes + 7) & (ULONG)~7) + sizeof(MP_HEADER);
    Index=LookasideIndexFromSize(Size);

    //
    // Iterate through the heap locks looking for one
    // that is not owned.
    //
    i=HeapHint;
    if (i>=MpHeap->HeapCount) {
        i=0;
        HeapHint=0;
    }
    Entry = &MpHeap->Entry[i];
    do {
        //
        // Check the lookaside list for a suitable allocation.
        //
        if ((Index != NO_LOOKASIDE) &&
            (Entry->Lookaside[Index].Entry != NULL)) {
            if ((Header = (PMP_HEADER)InterlockedExchange((PLONG)&Entry->Lookaside[Index].Entry,
                                                          (LONG)NULL)) != NULL) {
                //
                // We have a lookaside hit, return it immediately.
                //
                ++Entry->LookasideAllocations;
                if (flOptions & MPHEAP_ZERO_MEMORY) {
                    ZeroMemory(Header + 1, dwBytes);
                }
                HeapHint=i;
                return(Header + 1);
            }
        }

        //
        // Attempt to lock this heap without blocking.
        //
        if (TryEnterCriticalSection(&Entry->Lock)) {
            //
            // success, go allocate immediately
            //
            goto LockAcquired;
        }

        //
        // This heap is owned by another thread, try
        // the next one.
        //
        i++;
        Entry++;
        if (i==MpHeap->HeapCount) {
            i=0;
            Entry=&MpHeap->Entry[0];
        }
    } while ( i != HeapHint );

    //
    // All of the critical sections were owned by someone else,
    // so we have no choice but to wait for a critical section.
    //
    EnterCriticalSection(&Entry->Lock);

LockAcquired:
    ++Entry->Allocations;
    if (Entry->DelayedFreeList != NULL) {
        ProcessDelayedFreeList(Entry);
    }
    Header = HeapAlloc(Entry->Heap, 0, Size);
    LeaveCriticalSection(&Entry->Lock);
    if (Header != NULL) {
        Header->HeapEntry = Entry;
        Header->LookasideIndex = Index;
        if (flOptions & MPHEAP_ZERO_MEMORY) {
            ZeroMemory(Header + 1, dwBytes);
        }
        HeapHint = i;
        return(Header + 1);
    } else {
        return(NULL);
    }
}

LPVOID
WINAPI
MpHeapReAlloc(
    HANDLE hMpHeap,
    LPVOID lpMem,
    DWORD dwBytes
    )
{
    PMP_HEADER Header;
    PCRITICAL_SECTION Lock;

    Header = ((PMP_HEADER)lpMem) - 1;
    Lock = &Header->HeapEntry->Lock;
    dwBytes = ((dwBytes + 7) & (ULONG)~7) + sizeof(MP_HEADER);

    EnterCriticalSection(Lock);
    Header = HeapReAlloc(Header->HeapEntry->Heap, 0, Header, dwBytes);
    LeaveCriticalSection(Lock);

    if (Header != NULL) {
        Header->LookasideIndex = LookasideIndexFromSize(dwBytes);
        return(Header + 1);
    } else {
        return(NULL);
    }
}

BOOL
WINAPI
MpHeapFree(
    HANDLE hMpHeap,
    LPVOID lpMem
    )
{
    PMP_HEADER Header;
    PCRITICAL_SECTION Lock;
    BOOL Success;
    PMP_HEAP_ENTRY HeapEntry;
    PSINGLE_LIST_ENTRY Next;
    PMP_HEAP MpHeap;

    Header = ((PMP_HEADER)lpMem) - 1;
    HeapEntry = Header->HeapEntry;
    MpHeap = (PMP_HEAP)hMpHeap;

    HeapHint = HeapEntry - &MpHeap->Entry[0];

    if (Header->LookasideIndex != NO_LOOKASIDE) {
        //
        // Try and put this back on the lookaside list
        //
        if (InterlockedCompareExchange((PVOID *)&HeapEntry->Lookaside[Header->LookasideIndex],
                                       (PVOID)Header,
                                       NULL) == NULL) {
            //
            // Successfully freed to lookaside list.
            //
            ++HeapEntry->LookasideFrees;
            return(TRUE);
        }
    }
    Lock = &HeapEntry->Lock;

    if (TryEnterCriticalSection(Lock)) {
        ++HeapEntry->Frees;
        Success = HeapFree(HeapEntry->Heap, 0, Header);
        LeaveCriticalSection(Lock);
        return(Success);
    }
    //
    // The necessary heap critical section could not be immediately
    // acquired. Post this free onto the Delayed free list and let
    // whoever has the lock process it.
    //
    do {
        Next = HeapEntry->DelayedFreeList;
        Header->Next = Next;
    } while ( InterlockedCompareExchange(&HeapEntry->DelayedFreeList,
                                         &Header->Next,
                                         Next) != Next);
    return(TRUE);
}

VOID
ProcessDelayedFreeList(
    IN PMP_HEAP_ENTRY HeapEntry
    )
{
    PSINGLE_LIST_ENTRY FreeList;
    PSINGLE_LIST_ENTRY Next;
    PMP_HEADER Header;

    //
    // Capture the entire delayed free list with a single interlocked exchange.
    // Once we have removed the entire list, free each entry in turn.
    //
    FreeList = (PSINGLE_LIST_ENTRY)InterlockedExchange((LPLONG)&HeapEntry->DelayedFreeList, (LONG)NULL);
    while (FreeList != NULL) {
        Next = FreeList->Next;
        Header = CONTAINING_RECORD(FreeList, MP_HEADER, Next);
        ++HeapEntry->DelayedFrees;
        HeapFree(HeapEntry->Heap, 0, Header);
        FreeList = Next;
    }
}

DWORD
MpHeapGetStatistics(
    HANDLE hMpHeap,
    LPDWORD lpdwSize,
    MPHEAP_STATISTICS Stats[]
    )
{
    PMP_HEAP MpHeap;
    PMP_HEAP_ENTRY Entry;
    DWORD i;
    DWORD RequiredSize;

    MpHeap = (PMP_HEAP)hMpHeap;
    RequiredSize = MpHeap->HeapCount * sizeof(MPHEAP_STATISTICS);
    if (*lpdwSize < RequiredSize) {
        *lpdwSize = RequiredSize;
        return(ERROR_MORE_DATA);
    }
    ZeroMemory(Stats, MpHeap->HeapCount * sizeof(MPHEAP_STATISTICS));
    for (i=0; i < MpHeap->HeapCount; i++) {
        Entry = &MpHeap->Entry[i];

        Stats[i].Contention = Entry->Lock.DebugInfo->ContentionCount;
        Stats[i].TotalAllocates = (Entry->Allocations + Entry->LookasideAllocations);
        Stats[i].TotalFrees = (Entry->Frees + Entry->LookasideFrees + Entry->DelayedFrees);
        Stats[i].LookasideAllocates = Entry->LookasideAllocations;
        Stats[i].LookasideFrees = Entry->LookasideFrees;
        Stats[i].DelayedFrees = Entry->DelayedFrees;
    }
    *lpdwSize = RequiredSize;
    return(ERROR_SUCCESS);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -