Skip to content
This repository was archived by the owner on Jul 9, 2025. It is now read-only.

Commit e64355e

Browse files
committed
Bug 1550108 - Prefetch StartupCache off main thread r=froydnj
Does what it says on the tin. Once we have a central scheduling system this should likely just consume that. Differential Revision: https://phabricator.services.mozilla.com/D35454 --HG-- extra : moz-landing-system : lando
1 parent 87f736b commit e64355e

2 files changed

Lines changed: 37 additions & 4 deletions

File tree

startupcache/StartupCache.cpp

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,8 @@ StartupCache::StartupCache()
149149
mCurTableReferenced(false),
150150
mRequestedCount(0),
151151
mCacheEntriesBaseOffset(0),
152-
mWriteThread(nullptr) {}
152+
mWriteThread(nullptr),
153+
mPrefetchThread(nullptr) {}
153154

154155
StartupCache::~StartupCache() {
155156
if (mTimer) {
@@ -160,6 +161,7 @@ StartupCache::~StartupCache() {
160161
// but an early shutdown means either mTimer didn't run
161162
// or the write thread is still running.
162163
WaitOnWriteThread();
164+
WaitOnPrefetchThread();
163165

164166
// If we shutdown quickly timer wont have fired. Instead of writing
165167
// it on the main thread and block the shutdown we simply wont update
@@ -243,6 +245,15 @@ nsresult StartupCache::Init() {
243245
return NS_OK;
244246
}
245247

248+
void StartupCache::StartPrefetchMemoryThread() {
249+
// XXX: It would be great for this to not create its own thread, unfortunately
250+
// there doesn't seem to be an existing thread that makes sense for this, so
251+
// barring a coordinated global scheduling system this is the best we get.
252+
mPrefetchThread = PR_CreateThread(
253+
PR_USER_THREAD, StartupCache::ThreadedPrefetch, this, PR_PRIORITY_NORMAL,
254+
PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
255+
}
256+
246257
/**
247258
* LoadArchive can be called from the main thread or while reloading cache on
248259
* write thread.
@@ -252,6 +263,9 @@ Result<Ok, nsresult> StartupCache::LoadArchive() {
252263

253264
MOZ_TRY(mCacheData.init(mFile));
254265
auto size = mCacheData.size();
266+
if (CanPrefetchMemory()) {
267+
StartPrefetchMemoryThread();
268+
}
255269

256270
uint32_t headerSize;
257271
if (size < sizeof(MAGIC) + sizeof(headerSize)) {
@@ -365,9 +379,6 @@ nsresult StartupCache::GetBuffer(const char* id, const char** outbuf,
365379
Span<const char> compressed = MakeSpan(
366380
mCacheData.get<char>().get() + mCacheEntriesBaseOffset + value.mOffset,
367381
value.mCompressedSize);
368-
if (CanPrefetchMemory()) {
369-
PrefetchMemory((uint8_t*)compressed.Elements(), compressed.Length());
370-
}
371382
value.mData = MakeUnique<char[]>(value.mUncompressedSize);
372383
Span<char> uncompressed =
373384
MakeSpan(value.mData.get(), value.mUncompressedSize);
@@ -611,6 +622,23 @@ void StartupCache::WaitOnWriteThread() {
611622
mWriteThread = nullptr;
612623
}
613624

625+
void StartupCache::WaitOnPrefetchThread() {
626+
if (!mPrefetchThread || mPrefetchThread == PR_GetCurrentThread()) return;
627+
628+
PR_JoinThread(mPrefetchThread);
629+
mPrefetchThread = nullptr;
630+
}
631+
632+
void StartupCache::ThreadedPrefetch(void* aClosure) {
633+
AUTO_PROFILER_REGISTER_THREAD("StartupCache");
634+
NS_SetCurrentThreadName("StartupCache");
635+
mozilla::IOInterposer::RegisterCurrentThread();
636+
StartupCache* startupCacheObj = static_cast<StartupCache*>(aClosure);
637+
PrefetchMemory(startupCacheObj->mCacheData.get<uint8_t>().get(),
638+
startupCacheObj->mCacheData.size());
639+
mozilla::IOInterposer::UnregisterCurrentThread();
640+
}
641+
614642
void StartupCache::ThreadedWrite(void* aClosure) {
615643
AUTO_PROFILER_REGISTER_THREAD("StartupCache");
616644
NS_SetCurrentThreadName("StartupCache");
@@ -660,6 +688,7 @@ void StartupCache::WriteTimeout(nsITimer* aTimer, void* aClosure) {
660688
return;
661689
}
662690

691+
startupCacheObj->WaitOnPrefetchThread();
663692
startupCacheObj->mStartupWriteInitiated = false;
664693
startupCacheObj->mDirty = true;
665694
startupCacheObj->mCacheData.reset();

startupcache/StartupCache.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,10 +202,13 @@ class StartupCache : public nsIMemoryReporter {
202202
Result<Ok, nsresult> WriteToDisk();
203203

204204
void WaitOnWriteThread();
205+
void WaitOnPrefetchThread();
206+
void StartPrefetchMemoryThread();
205207

206208
static nsresult InitSingleton();
207209
static void WriteTimeout(nsITimer* aTimer, void* aClosure);
208210
static void ThreadedWrite(void* aClosure);
211+
static void ThreadedPrefetch(void* aClosure);
209212

210213
HashMap<nsCString, StartupCacheEntry, nsCStringHasher> mTable;
211214
// owns references to the contents of tables which have been invalidated.
@@ -230,6 +233,7 @@ class StartupCache : public nsIMemoryReporter {
230233
static bool gShutdownInitiated;
231234
static bool gIgnoreDiskCache;
232235
PRThread* mWriteThread;
236+
PRThread* mPrefetchThread;
233237
UniquePtr<Compression::LZ4FrameDecompressionContext> mDecompressionContext;
234238
#ifdef DEBUG
235239
nsTHashtable<nsISupportsHashKey> mWriteObjectMap;

0 commit comments

Comments
 (0)