Skip to content

Commit

Permalink
Bug 867762: NSPR and SQLite Main Thread I/O Interposing. r=BenWa
Browse files Browse the repository at this point in the history
UltraBlame original commit: 1a0ff6b97e035ddc3be189a8db8a0a75493177c1
  • Loading branch information
marco-c committed Sep 29, 2019
1 parent 242798e commit f7df283
Show file tree
Hide file tree
Showing 12 changed files with 806 additions and 6 deletions.
26 changes: 20 additions & 6 deletions storage/src/TelemetryVFS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "mozilla/Util.h"
#include "mozilla/dom/quota/QuotaManager.h"
#include "mozilla/dom/quota/QuotaObject.h"
#include "mozilla/SQLiteInterposer.h"



Expand Down Expand Up @@ -67,21 +68,34 @@ class IOThreadAutoTimer {



IOThreadAutoTimer(Telemetry::ID id)





IOThreadAutoTimer(Telemetry::ID id,
SQLiteInterposer::EventHandlerFn evtFn = nullptr)
: start(TimeStamp::Now()),
id(id)
id(id),
evtFn(evtFn)
{
}

~IOThreadAutoTimer() {
TimeStamp end(TimeStamp::Now());
uint32_t mainThread = NS_IsMainThread() ? 1 : 0;
Telemetry::AccumulateTimeDelta(static_cast<Telemetry::ID>(id + mainThread),
start);
start, end);
if (evtFn && mainThread) {
double duration = (end - start).ToMilliseconds();
evtFn(duration);
}
}

private:
const TimeStamp start;
const Telemetry::ID id;
SQLiteInterposer::EventHandlerFn evtFn;
};

struct telemetry_file {
Expand Down Expand Up @@ -122,7 +136,7 @@ int
xRead(sqlite3_file *pFile, void *zBuf, int iAmt, sqlite_int64 iOfst)
{
telemetry_file *p = (telemetry_file *)pFile;
IOThreadAutoTimer ioTimer(p->histograms->readMS);
IOThreadAutoTimer ioTimer(p->histograms->readMS, &SQLiteInterposer::OnRead);
int rc;
rc = p->pReal->pMethods->xRead(p->pReal, zBuf, iAmt, iOfst);

Expand All @@ -141,7 +155,7 @@ xWrite(sqlite3_file *pFile, const void *zBuf, int iAmt, sqlite_int64 iOfst)
if (p->quotaObject && !p->quotaObject->MaybeAllocateMoreSpace(iOfst, iAmt)) {
return SQLITE_FULL;
}
IOThreadAutoTimer ioTimer(p->histograms->writeMS);
IOThreadAutoTimer ioTimer(p->histograms->writeMS, &SQLiteInterposer::OnWrite);
int rc;
rc = p->pReal->pMethods->xWrite(p->pReal, zBuf, iAmt, iOfst);
Telemetry::Accumulate(p->histograms->writeB, rc == SQLITE_OK ? iAmt : 0);
Expand Down Expand Up @@ -172,7 +186,7 @@ int
xSync(sqlite3_file *pFile, int flags)
{
telemetry_file *p = (telemetry_file *)pFile;
IOThreadAutoTimer ioTimer(p->histograms->syncMS);
IOThreadAutoTimer ioTimer(p->histograms->syncMS, &SQLiteInterposer::OnFSync);
return p->pReal->pMethods->xSync(p->pReal, flags);
}

Expand Down
154 changes: 154 additions & 0 deletions tools/profiler/IOInterposer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@




#include "IOInterposer.h"
#include "NSPRInterposer.h"
#include "SQLiteInterposer.h"

using namespace mozilla;

static StaticAutoPtr<IOInterposer> sSingleton;

IOInterposer*
IOInterposer::GetInstance()
{
if (!sSingleton) {



sSingleton = new IOInterposer();
sSingleton->Init();
}

return sSingleton.get();
}

void
IOInterposer::ClearInstance()
{



sSingleton = nullptr;
}

IOInterposer::IOInterposer()
:mMutex("IOInterposer::mMutex")
{



}

IOInterposer::~IOInterposer()
{



Enable(false);
NSPRInterposer::ClearInstance();
SQLiteInterposer::ClearInstance();
}

bool
IOInterposer::Init()
{



mozilla::MutexAutoLock lock(mMutex);
IOInterposerModule* nsprModule = NSPRInterposer::GetInstance(this,
IOInterposeObserver::OpAll);
if (!nsprModule) {
return false;
}

IOInterposerModule* sqlModule = SQLiteInterposer::GetInstance(this,
IOInterposeObserver::OpAll);
if (!sqlModule) {
return false;
}

mModules.AppendElement(nsprModule);
mModules.AppendElement(sqlModule);
return true;
}

void
IOInterposer::Enable(bool aEnable)
{
mozilla::MutexAutoLock lock(mMutex);
for (PRUint32 i = 0; i < mModules.Length(); ++i ) {
mModules[i]->Enable(aEnable);
}
}

void
IOInterposer::Register(IOInterposeObserver::Operation aOp,
IOInterposeObserver* aObserver)
{



if (aOp & IOInterposeObserver::OpRead) {
mReadObservers.AppendElement(aObserver);
}
if (aOp & IOInterposeObserver::OpWrite) {
mWriteObservers.AppendElement(aObserver);
}
if (aOp & IOInterposeObserver::OpFSync) {
mFSyncObservers.AppendElement(aObserver);
}
}

void
IOInterposer::Deregister(IOInterposeObserver::Operation aOp,
IOInterposeObserver* aObserver)
{



if (aOp & IOInterposeObserver::OpRead) {
mReadObservers.RemoveElement(aObserver);
}
if (aOp & IOInterposeObserver::OpWrite) {
mWriteObservers.RemoveElement(aObserver);
}
if (aOp & IOInterposeObserver::OpFSync) {
mFSyncObservers.RemoveElement(aObserver);
}
}

void
IOInterposer::Observe(IOInterposeObserver::Operation aOp, double& aDuration,
const char* aModuleInfo)
{
MOZ_ASSERT(NS_IsMainThread());
switch (aOp) {
case IOInterposeObserver::OpRead:
{
for (PRUint32 i = 0; i < mReadObservers.Length(); ++i) {
mReadObservers[i]->Observe(aOp, aDuration, aModuleInfo);
}
}
break;
case IOInterposeObserver::OpWrite:
{
for (PRUint32 i = 0; i < mWriteObservers.Length(); ++i) {
mWriteObservers[i]->Observe(aOp, aDuration, aModuleInfo);
}
}
break;
case IOInterposeObserver::OpFSync:
{
for (PRUint32 i = 0; i < mFSyncObservers.Length(); ++i) {
mFSyncObservers[i]->Observe(aOp, aDuration, aModuleInfo);
}
}
break;
default:
break;
}
}

106 changes: 106 additions & 0 deletions tools/profiler/IOInterposer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@




#ifndef IOINTERPOSER_H_
#define IOINTERPOSER_H_

#include "mozilla/Attributes.h"
#include "mozilla/Mutex.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/XPCOM.h"

namespace mozilla {






class IOInterposeObserver
{
public:
enum Operation
{
OpNone = 0,
OpRead = (1 << 0),
OpWrite = (1 << 1),
OpFSync = (1 << 2),
OpWriteFSync = (OpWrite | OpFSync),
OpAll = (OpRead | OpWrite | OpFSync)
};
virtual void Observe(Operation aOp, double& aDuration,
const char* aModuleInfo) = 0;
};





class IOInterposerModule
{
public:
virtual ~IOInterposerModule() {}
virtual void Enable(bool aEnable) = 0;

protected:
IOInterposerModule() {}

private:
IOInterposerModule(const IOInterposerModule&);
IOInterposerModule& operator=(const IOInterposerModule&);
};







class IOInterposer MOZ_FINAL : public IOInterposeObserver
{
public:
~IOInterposer();






void Enable(bool aEnable);

void Register(IOInterposeObserver::Operation aOp,
IOInterposeObserver* aObserver);
void Deregister(IOInterposeObserver::Operation aOp,
IOInterposeObserver* aObserver);
void Observe(IOInterposeObserver::Operation aOp, double& aDuration,
const char* aModuleInfo);

static IOInterposer* GetInstance();






static void ClearInstance();

private:
IOInterposer();
bool Init();
IOInterposer(const IOInterposer&);
IOInterposer& operator=(const IOInterposer&);



mozilla::Mutex mMutex;
nsTArray<IOInterposerModule*> mModules;
nsTArray<IOInterposeObserver*> mReadObservers;
nsTArray<IOInterposeObserver*> mWriteObservers;
nsTArray<IOInterposeObserver*> mFSyncObservers;
};

}

#endif

Loading

0 comments on commit f7df283

Please sign in to comment.