diff options
author | dotnet-bot <dotnet-bot@microsoft.com> | 2015-01-30 14:14:42 -0800 |
---|---|---|
committer | dotnet-bot <dotnet-bot@microsoft.com> | 2015-01-30 14:14:42 -0800 |
commit | ef1e2ab328087c61a6878c1e84f4fc5d710aebce (patch) | |
tree | dee1bbb89e9d722e16b0d1485e3cdd1b6c8e2cfa /src/vm/syncclean.cpp | |
download | coreclr-ef1e2ab328087c61a6878c1e84f4fc5d710aebce.tar.gz coreclr-ef1e2ab328087c61a6878c1e84f4fc5d710aebce.tar.bz2 coreclr-ef1e2ab328087c61a6878c1e84f4fc5d710aebce.zip |
Initial commit to populate CoreCLR repo
[tfs-changeset: 1407945]
Diffstat (limited to 'src/vm/syncclean.cpp')
-rw-r--r-- | src/vm/syncclean.cpp | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/src/vm/syncclean.cpp b/src/vm/syncclean.cpp new file mode 100644 index 0000000000..0e1e70f54c --- /dev/null +++ b/src/vm/syncclean.cpp @@ -0,0 +1,104 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + + +#include "common.h" + +#include "syncclean.hpp" +#include "virtualcallstub.h" +#include "threadsuspend.h" + +VolatilePtr<Bucket> SyncClean::m_HashMap = NULL; +VolatilePtr<EEHashEntry*> SyncClean::m_EEHashTable; + +void SyncClean::Terminate() +{ + CONTRACTL { + NOTHROW; + GC_NOTRIGGER; + } CONTRACTL_END; + + CleanUp(); +} + +void SyncClean::AddHashMap (Bucket *bucket) +{ + WRAPPER_NO_CONTRACT; + + if (!g_fEEStarted) { + delete [] bucket; + return; + } + + BEGIN_GETTHREAD_ALLOWED + _ASSERTE (GetThread() == NULL || GetThread()->PreemptiveGCDisabled()); + END_GETTHREAD_ALLOWED + + Bucket * pTempBucket = NULL; + do + { + pTempBucket = (Bucket *)m_HashMap; + NextObsolete (bucket) = pTempBucket; + } + while (FastInterlockCompareExchangePointer(m_HashMap.GetPointer(), bucket, pTempBucket) != pTempBucket); +} + +void SyncClean::AddEEHashTable (EEHashEntry** entry) +{ + WRAPPER_NO_CONTRACT; + + if (!g_fEEStarted) { + delete [] (entry-1); + return; + } + + BEGIN_GETTHREAD_ALLOWED + _ASSERTE (GetThread() == NULL || GetThread()->PreemptiveGCDisabled()); + END_GETTHREAD_ALLOWED + + EEHashEntry ** pTempHashEntry = NULL; + do + { + pTempHashEntry = (EEHashEntry**)m_EEHashTable; + entry[-1] = (EEHashEntry *)pTempHashEntry; + } + while (FastInterlockCompareExchangePointer(m_EEHashTable.GetPointer(), entry, pTempHashEntry) != pTempHashEntry); +} + +void SyncClean::CleanUp () +{ + LIMITED_METHOD_CONTRACT; + + // Only GC thread can call this. + _ASSERTE (g_fProcessDetach || + IsGCSpecialThread() || + (GCHeap::IsGCInProgress() && GetThread() == ThreadSuspend::GetSuspensionThread())); + if (m_HashMap) + { + Bucket * pTempBucket = FastInterlockExchangePointer(m_HashMap.GetPointer(), NULL); + + while (pTempBucket) + { + Bucket* pNextBucket = NextObsolete (pTempBucket); + delete [] pTempBucket; + pTempBucket = pNextBucket; + } + } + + if (m_EEHashTable) + { + EEHashEntry ** pTempHashEntry = FastInterlockExchangePointer(m_EEHashTable.GetPointer(), NULL); + + while (pTempHashEntry) { + EEHashEntry **pNextHashEntry = (EEHashEntry **)pTempHashEntry[-1]; + pTempHashEntry --; + delete [] pTempHashEntry; + pTempHashEntry = pNextHashEntry; + } + } + + // Give others we want to reclaim during the GC sync point a chance to do it + VirtualCallStubManager::ReclaimAll(); +} |