forked from mirrors/gecko-dev
Bug 1828265: Remove StartupCache temporary prefetch thread r=kmag
Differential Revision: https://phabricator.services.mozilla.com/D175551
This commit is contained in:
parent
95f7a79d8e
commit
271058f7fc
2 changed files with 35 additions and 34 deletions
|
|
@ -165,8 +165,7 @@ StartupCache::StartupCache()
|
||||||
mWrittenOnce(false),
|
mWrittenOnce(false),
|
||||||
mCurTableReferenced(false),
|
mCurTableReferenced(false),
|
||||||
mRequestedCount(0),
|
mRequestedCount(0),
|
||||||
mCacheEntriesBaseOffset(0),
|
mCacheEntriesBaseOffset(0) {}
|
||||||
mPrefetchThread(nullptr) {}
|
|
||||||
|
|
||||||
StartupCache::~StartupCache() { UnregisterWeakMemoryReporter(this); }
|
StartupCache::~StartupCache() { UnregisterWeakMemoryReporter(this); }
|
||||||
|
|
||||||
|
|
@ -251,14 +250,13 @@ nsresult StartupCache::Init() {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StartupCache::StartPrefetchMemoryThread() {
|
void StartupCache::StartPrefetchMemory() {
|
||||||
// XXX: It would be great for this to not create its own thread, unfortunately
|
{
|
||||||
// there doesn't seem to be an existing thread that makes sense for this, so
|
MonitorAutoLock lock(mPrefetchComplete);
|
||||||
// barring a coordinated global scheduling system this is the best we get.
|
mPrefetchInProgress = true;
|
||||||
// XXX Switch to NS_DispatchBackgroundTask()
|
}
|
||||||
mPrefetchThread = PR_CreateThread(
|
NS_DispatchBackgroundTask(NewRunnableMethod(
|
||||||
PR_USER_THREAD, StartupCache::ThreadedPrefetch, this, PR_PRIORITY_NORMAL,
|
"StartupCache::ThreadedPrefetch", this, &StartupCache::ThreadedPrefetch));
|
||||||
PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 256 * 1024);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -273,7 +271,7 @@ Result<Ok, nsresult> StartupCache::LoadArchive() {
|
||||||
MOZ_TRY(mCacheData.init(mFile));
|
MOZ_TRY(mCacheData.init(mFile));
|
||||||
auto size = mCacheData.size();
|
auto size = mCacheData.size();
|
||||||
if (CanPrefetchMemory()) {
|
if (CanPrefetchMemory()) {
|
||||||
StartPrefetchMemoryThread();
|
StartPrefetchMemory();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t headerSize;
|
uint32_t headerSize;
|
||||||
|
|
@ -309,7 +307,7 @@ Result<Ok, nsresult> StartupCache::LoadArchive() {
|
||||||
}
|
}
|
||||||
auto cleanup = MakeScopeExit([&]() {
|
auto cleanup = MakeScopeExit([&]() {
|
||||||
mTableLock.AssertCurrentThreadOwns();
|
mTableLock.AssertCurrentThreadOwns();
|
||||||
WaitOnPrefetchThread();
|
WaitOnPrefetch();
|
||||||
mTable.clear();
|
mTable.clear();
|
||||||
mCacheData.reset();
|
mCacheData.reset();
|
||||||
});
|
});
|
||||||
|
|
@ -610,7 +608,7 @@ Result<Ok, nsresult> StartupCache::WriteToDisk() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void StartupCache::InvalidateCache(bool memoryOnly) {
|
void StartupCache::InvalidateCache(bool memoryOnly) {
|
||||||
WaitOnPrefetchThread();
|
WaitOnPrefetch();
|
||||||
// Ensure we're not writing using mTable...
|
// Ensure we're not writing using mTable...
|
||||||
MutexAutoLock lock(mTableLock);
|
MutexAutoLock lock(mTableLock);
|
||||||
|
|
||||||
|
|
@ -680,7 +678,7 @@ void StartupCache::EnsureShutdownWriteComplete() {
|
||||||
|
|
||||||
// We got the lock. Keep the following in sync with
|
// We got the lock. Keep the following in sync with
|
||||||
// MaybeWriteOffMainThread:
|
// MaybeWriteOffMainThread:
|
||||||
WaitOnPrefetchThread();
|
WaitOnPrefetch();
|
||||||
mDirty = true;
|
mDirty = true;
|
||||||
mCacheData.reset();
|
mCacheData.reset();
|
||||||
// Most of this should be redundant given MaybeWriteOffMainThread should
|
// Most of this should be redundant given MaybeWriteOffMainThread should
|
||||||
|
|
@ -698,31 +696,30 @@ void StartupCache::IgnoreDiskCache() {
|
||||||
if (gStartupCache) gStartupCache->InvalidateCache();
|
if (gStartupCache) gStartupCache->InvalidateCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
void StartupCache::WaitOnPrefetchThread() {
|
void StartupCache::WaitOnPrefetch() {
|
||||||
if (!mPrefetchThread || mPrefetchThread == PR_GetCurrentThread()) return;
|
// This can't be called from within ThreadedPrefetch()
|
||||||
|
MonitorAutoLock lock(mPrefetchComplete);
|
||||||
PR_JoinThread(mPrefetchThread);
|
while (mPrefetchInProgress) {
|
||||||
mPrefetchThread = nullptr;
|
mPrefetchComplete.Wait();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void StartupCache::ThreadedPrefetch(void* aClosure) {
|
void StartupCache::ThreadedPrefetch() {
|
||||||
AUTO_PROFILER_REGISTER_THREAD("StartupCache");
|
|
||||||
NS_SetCurrentThreadName("StartupCache");
|
|
||||||
mozilla::IOInterposer::RegisterCurrentThread();
|
|
||||||
StartupCache* startupCacheObj = static_cast<StartupCache*>(aClosure);
|
|
||||||
uint8_t* buf;
|
uint8_t* buf;
|
||||||
size_t size;
|
size_t size;
|
||||||
{
|
{
|
||||||
MutexAutoLock lock(startupCacheObj->mTableLock);
|
MutexAutoLock lock(mTableLock);
|
||||||
buf = startupCacheObj->mCacheData.get<uint8_t>().get();
|
buf = mCacheData.get<uint8_t>().get();
|
||||||
size = startupCacheObj->mCacheData.size();
|
size = mCacheData.size();
|
||||||
}
|
}
|
||||||
// PrefetchMemory does madvise/equivalent, but doesn't access the memory
|
// PrefetchMemory does madvise/equivalent, but doesn't access the memory
|
||||||
// pointed to by buf
|
// pointed to by buf
|
||||||
MMAP_FAULT_HANDLER_BEGIN_BUFFER(buf, size)
|
MMAP_FAULT_HANDLER_BEGIN_BUFFER(buf, size)
|
||||||
PrefetchMemory(buf, size);
|
PrefetchMemory(buf, size);
|
||||||
MMAP_FAULT_HANDLER_CATCH()
|
MMAP_FAULT_HANDLER_CATCH()
|
||||||
mozilla::IOInterposer::UnregisterCurrentThread();
|
MonitorAutoLock lock(mPrefetchComplete);
|
||||||
|
mPrefetchInProgress = false;
|
||||||
|
mPrefetchComplete.NotifyAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
// mTableLock must be held
|
// mTableLock must be held
|
||||||
|
|
@ -762,7 +759,7 @@ void StartupCache::MaybeWriteOffMainThread() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Keep this code in sync with EnsureShutdownWriteComplete.
|
// Keep this code in sync with EnsureShutdownWriteComplete.
|
||||||
WaitOnPrefetchThread();
|
WaitOnPrefetch();
|
||||||
{
|
{
|
||||||
MutexAutoLock lock(mTableLock);
|
MutexAutoLock lock(mTableLock);
|
||||||
mDirty = true;
|
mDirty = true;
|
||||||
|
|
@ -790,7 +787,7 @@ nsresult StartupCacheListener::Observe(nsISupports* subject, const char* topic,
|
||||||
|
|
||||||
if (strcmp(topic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) {
|
if (strcmp(topic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) {
|
||||||
// Do not leave the thread running past xpcom shutdown
|
// Do not leave the thread running past xpcom shutdown
|
||||||
sc->WaitOnPrefetchThread();
|
sc->WaitOnPrefetch();
|
||||||
StartupCache::gShutdownInitiated = true;
|
StartupCache::gShutdownInitiated = true;
|
||||||
// Note that we don't do anything special for the background write
|
// Note that we don't do anything special for the background write
|
||||||
// task; we expect the threadpool to finish running any tasks already
|
// task; we expect the threadpool to finish running any tasks already
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
#include "mozilla/AutoMemMap.h"
|
#include "mozilla/AutoMemMap.h"
|
||||||
#include "mozilla/Compression.h"
|
#include "mozilla/Compression.h"
|
||||||
#include "mozilla/MemoryReporting.h"
|
#include "mozilla/MemoryReporting.h"
|
||||||
|
#include "mozilla/Monitor.h"
|
||||||
#include "mozilla/Mutex.h"
|
#include "mozilla/Mutex.h"
|
||||||
#include "mozilla/Result.h"
|
#include "mozilla/Result.h"
|
||||||
#include "mozilla/UniquePtr.h"
|
#include "mozilla/UniquePtr.h"
|
||||||
|
|
@ -209,13 +210,16 @@ class StartupCache : public nsIMemoryReporter {
|
||||||
// Writes the cache to disk
|
// Writes the cache to disk
|
||||||
Result<Ok, nsresult> WriteToDisk() MOZ_REQUIRES(mTableLock);
|
Result<Ok, nsresult> WriteToDisk() MOZ_REQUIRES(mTableLock);
|
||||||
|
|
||||||
void WaitOnPrefetchThread();
|
void WaitOnPrefetch();
|
||||||
void StartPrefetchMemoryThread();
|
void StartPrefetchMemory();
|
||||||
|
|
||||||
static nsresult InitSingleton();
|
static nsresult InitSingleton();
|
||||||
static void WriteTimeout(nsITimer* aTimer, void* aClosure);
|
static void WriteTimeout(nsITimer* aTimer, void* aClosure);
|
||||||
void MaybeWriteOffMainThread();
|
void MaybeWriteOffMainThread();
|
||||||
static void ThreadedPrefetch(void* aClosure);
|
void ThreadedPrefetch();
|
||||||
|
|
||||||
|
Monitor mPrefetchComplete{"StartupCachePrefetch"};
|
||||||
|
bool mPrefetchInProgress MOZ_GUARDED_BY(mPrefetchComplete){false};
|
||||||
|
|
||||||
// This is normally accessed on MainThread, but WriteToDisk() can
|
// This is normally accessed on MainThread, but WriteToDisk() can
|
||||||
// access it on other threads
|
// access it on other threads
|
||||||
|
|
@ -246,7 +250,7 @@ class StartupCache : public nsIMemoryReporter {
|
||||||
static bool gShutdownInitiated;
|
static bool gShutdownInitiated;
|
||||||
static bool gIgnoreDiskCache;
|
static bool gIgnoreDiskCache;
|
||||||
static bool gFoundDiskCacheOnInit;
|
static bool gFoundDiskCacheOnInit;
|
||||||
PRThread* mPrefetchThread;
|
|
||||||
UniquePtr<Compression::LZ4FrameDecompressionContext> mDecompressionContext;
|
UniquePtr<Compression::LZ4FrameDecompressionContext> mDecompressionContext;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
nsTHashSet<nsCOMPtr<nsISupports>> mWriteObjectMap;
|
nsTHashSet<nsCOMPtr<nsISupports>> mWriteObjectMap;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue