diff options
Diffstat (limited to 'src/vm/cachelinealloc.cpp')
-rw-r--r-- | src/vm/cachelinealloc.cpp | 295 |
1 files changed, 295 insertions, 0 deletions
diff --git a/src/vm/cachelinealloc.cpp b/src/vm/cachelinealloc.cpp new file mode 100644 index 0000000000..a797b1427e --- /dev/null +++ b/src/vm/cachelinealloc.cpp @@ -0,0 +1,295 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +//--------------------------------------------------------------------------- +// CCacheLineAllocator +// + +// +// This file dImplements the CCacheLineAllocator class. +// +// @comm +// +// Notes: +// The CacheLineAllocator maintains a pool of free CacheLines +// +// The CacheLine Allocator provides static member functions +// GetCacheLine and FreeCacheLine, +//--------------------------------------------------------------------------- + + + +#include "common.h" +#include <stddef.h> +#include "cachelinealloc.h" + +#include "threads.h" +#include "excep.h" + +/////////////////////////////////////////////////////// +// CCacheLineAllocator::CCacheLineAllocator() +// +////////////////////////////////////////////////////// + +CCacheLineAllocator::CCacheLineAllocator() +{ + CONTRACTL + { + NOTHROW; + GC_NOTRIGGER; + MODE_ANY; + } + CONTRACTL_END; + + m_freeList32.Init(); + m_freeList64.Init(); + m_registryList.Init(); +} + +/////////////////////////////////////////////////////// +// void CCacheLineAllocator::~CCacheLineAllocator() +// +////////////////////////////////////////////////////// + +CCacheLineAllocator::~CCacheLineAllocator() +{ + CONTRACTL + { + NOTHROW; + GC_NOTRIGGER; + MODE_ANY; + } + CONTRACTL_END; + + LPCacheLine tempPtr = NULL; + while((tempPtr = m_registryList.RemoveHead()) != NULL) + { + for (int i =0; i < CacheLine::numEntries; i++) + { + if(tempPtr->m_pAddr[i] != NULL) + { + if (!g_fProcessDetach) + VFree(tempPtr->m_pAddr[i]); + } + } + delete tempPtr; + } +} + + + +/////////////////////////////////////////////////////// +// static void *CCacheLineAllocator::VAlloc(ULONG cbSize) +// +////////////////////////////////////////////////////// + + +void *CCacheLineAllocator::VAlloc(ULONG cbSize) +{ + CONTRACT(void*) + { + NOTHROW; + GC_NOTRIGGER; + MODE_ANY; + INJECT_FAULT(CONTRACT_RETURN NULL); + POSTCONDITION(CheckPointer(RETVAL, NULL_OK)); + } + CONTRACT_END; + + // helper to call virtual free to release memory + + int i =0; + void* pv = ClrVirtualAlloc (NULL, cbSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); + if (pv != NULL) + { + LPCacheLine tempPtr = m_registryList.GetHead(); + if (tempPtr == NULL) + { + goto LNew; + } + + for (i =0; i < CacheLine::numEntries; i++) + { + if(tempPtr->m_pAddr[i] == NULL) + { + tempPtr->m_pAddr[i] = pv; + RETURN pv; + } + } + +LNew: + // initialize the bucket before returning + tempPtr = new (nothrow) CacheLine(); + if (tempPtr != NULL) + { + tempPtr->Init64(); + tempPtr->m_pAddr[0] = pv; + m_registryList.InsertHead(tempPtr); + } + else + { + // couldn't find space to register this page + ClrVirtualFree(pv, 0, MEM_RELEASE); + RETURN NULL; + } + } + RETURN pv; +} + +/////////////////////////////////////////////////////// +// void CCacheLineAllocator::VFree(void* pv) +// +////////////////////////////////////////////////////// + + +void CCacheLineAllocator::VFree(void* pv) +{ + BOOL bRes = FALSE; + + CONTRACT_VOID + { + NOTHROW; + GC_NOTRIGGER; + MODE_ANY; + PRECONDITION(CheckPointer(pv)); + POSTCONDITION(bRes); + } + CONTRACT_END; + + // helper to call virtual free to release memory + + bRes = ClrVirtualFree (pv, 0, MEM_RELEASE); + + RETURN_VOID; +} + +/////////////////////////////////////////////////////// +// void *CCacheLineAllocator::GetCacheLine() +// +////////////////////////////////////////////////////// + +//WARNING: must have a lock when calling this function +void *CCacheLineAllocator::GetCacheLine64() +{ + CONTRACT(void*) + { + NOTHROW; + GC_NOTRIGGER; + MODE_ANY; + INJECT_FAULT(CONTRACT_RETURN NULL); + POSTCONDITION(CheckPointer(RETVAL, NULL_OK)); + } + CONTRACT_END; + + LPCacheLine tempPtr = m_freeList64.RemoveHead(); + if (tempPtr != NULL) + { + // initialize the bucket before returning + tempPtr->Init64(); + RETURN tempPtr; + } + +#define AllocSize 4096*16 + + ////////////////////////////////' + /// Virtual Allocation for some more cache lines + + BYTE* ptr = (BYTE*)VAlloc(AllocSize); + + if(!ptr) + RETURN NULL; + + + tempPtr = (LPCacheLine)ptr; + // Link all the buckets + tempPtr = tempPtr+1; + LPCacheLine maxPtr = (LPCacheLine)(ptr + AllocSize); + + while(tempPtr < maxPtr) + { + m_freeList64.InsertHead(tempPtr); + tempPtr++; + } + + // return the first block + tempPtr = (LPCacheLine)ptr; + tempPtr->Init64(); + RETURN tempPtr; +} + + +/////////////////////////////////////////////////////// +// void *CCacheLineAllocator::GetCacheLine32() +// +////////////////////////////////////////////////////// + +//WARNING: must have a lock when calling this function +void *CCacheLineAllocator::GetCacheLine32() +{ + CONTRACT(void*) + { + NOTHROW; + GC_NOTRIGGER; + MODE_ANY; + INJECT_FAULT(CONTRACT_RETURN NULL); + POSTCONDITION(CheckPointer(RETVAL, NULL_OK)); + } + CONTRACT_END; + + LPCacheLine tempPtr = m_freeList32.RemoveHead(); + if (tempPtr != NULL) + { + // initialize the bucket before returning + tempPtr->Init32(); + RETURN tempPtr; + } + tempPtr = (LPCacheLine)GetCacheLine64(); + if (tempPtr != NULL) + { + m_freeList32.InsertHead(tempPtr); + tempPtr = (LPCacheLine)((BYTE *)tempPtr+32); + } + RETURN tempPtr; +} +/////////////////////////////////////////////////////// +// void CCacheLineAllocator::FreeCacheLine64(void * tempPtr) +// +////////////////////////////////////////////////////// +//WARNING: must have a lock when calling this function +void CCacheLineAllocator::FreeCacheLine64(void * tempPtr) +{ + CONTRACTL + { + NOTHROW; + GC_NOTRIGGER; + MODE_ANY; + + PRECONDITION(CheckPointer(tempPtr)); + } + CONTRACTL_END; + + LPCacheLine pCLine = (LPCacheLine )tempPtr; + m_freeList64.InsertHead(pCLine); +} + + +/////////////////////////////////////////////////////// +// void CCacheLineAllocator::FreeCacheLine32(void * tempPtr) +// +////////////////////////////////////////////////////// +//WARNING: must have a lock when calling this function +void CCacheLineAllocator::FreeCacheLine32(void * tempPtr) +{ + CONTRACTL + { + NOTHROW; + GC_NOTRIGGER; + MODE_ANY; + + PRECONDITION(CheckPointer(tempPtr)); + } + CONTRACTL_END; + + LPCacheLine pCLine = (LPCacheLine )tempPtr; + m_freeList32.InsertHead(pCLine); +} |