|
@@ -1582,6 +1582,10 @@ IFileIO *_createIFileIO(const void *buffer, unsigned sz, bool readOnly)
|
|
|
}
|
|
|
virtual void flush() {}
|
|
|
virtual void close() {}
|
|
|
+ virtual unsigned __int64 getStatistic(StatisticKind kind)
|
|
|
+ {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
virtual void setSize(offset_t size)
|
|
|
{
|
|
|
if (size > mb.length())
|
|
@@ -1761,11 +1765,36 @@ offset_t CFileIO::appendFile(IFile *file,offset_t pos,offset_t len)
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+unsigned __int64 CFileIO::getStatistic(StatisticKind kind)
|
|
|
+{
|
|
|
+ switch (kind)
|
|
|
+ {
|
|
|
+ case StCycleDiskReadIOCycles:
|
|
|
+ return ioReadCycles.load(std::memory_order_relaxed);
|
|
|
+ case StCycleDiskWriteIOCycles:
|
|
|
+ return ioWriteCycles.load(std::memory_order_relaxed);
|
|
|
+ case StTimeDiskReadIO:
|
|
|
+ return cycle_to_nanosec(ioReadCycles.load(std::memory_order_relaxed));
|
|
|
+ case StTimeDiskWriteIO:
|
|
|
+ return cycle_to_nanosec(ioWriteCycles.load(std::memory_order_relaxed));
|
|
|
+ case StSizeDiskRead:
|
|
|
+ return ioReadBytes.load(std::memory_order_relaxed);
|
|
|
+ case StSizeDiskWrite:
|
|
|
+ return ioWriteBytes.load(std::memory_order_relaxed);
|
|
|
+ case StNumDiskReads:
|
|
|
+ return ioReads.load(std::memory_order_relaxed);
|
|
|
+ case StNumDiskWrites:
|
|
|
+ return ioWrites.load(std::memory_order_relaxed);
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
#ifdef _WIN32
|
|
|
|
|
|
//-- Windows implementation -------------------------------------------------
|
|
|
|
|
|
CFileIO::CFileIO(HANDLE handle, IFOmode _openmode, IFSHmode _sharemode, IFEflags _extraFlags)
|
|
|
+ : ioReadCycles(0), ioWriteCycles(0), ioReadBytes(0), ioWriteBytes(0), ioReads(0), ioWrites(0)
|
|
|
{
|
|
|
assertex(handle != NULLFILE);
|
|
|
throwOnError = false;
|
|
@@ -1828,10 +1857,14 @@ size32_t CFileIO::read(offset_t pos, size32_t len, void * data)
|
|
|
{
|
|
|
CriticalBlock procedure(cs);
|
|
|
|
|
|
+ CCycleTimer timer;
|
|
|
DWORD numRead;
|
|
|
setPos(pos);
|
|
|
if (ReadFile(file,data,len,&numRead,NULL) == 0)
|
|
|
throw makeOsException(GetLastError(),"CFileIO::read");
|
|
|
+ ioReadCycles.fetch_add(timer.elapsedCycles());
|
|
|
+ ioReadBytes.fetch_add(numRead);
|
|
|
+ ++ioReads;
|
|
|
return (size32_t)numRead;
|
|
|
}
|
|
|
|
|
@@ -1846,12 +1879,16 @@ size32_t CFileIO::write(offset_t pos, size32_t len, const void * data)
|
|
|
{
|
|
|
CriticalBlock procedure(cs);
|
|
|
|
|
|
+ CCycleTimer timer;
|
|
|
DWORD numWritten;
|
|
|
setPos(pos);
|
|
|
if (!WriteFile(file,data,len,&numWritten,NULL))
|
|
|
throw makeOsException(GetLastError(),"CFileIO::write");
|
|
|
if (numWritten != len)
|
|
|
throw makeOsException(DISK_FULL_EXCEPTION_CODE,"CFileIO::write");
|
|
|
+ ioWriteCycles.fetch_add(timer.elapsedCycles());
|
|
|
+ ioWriteBytes.fetch_add(numWritten);
|
|
|
+ ++ioWrites;
|
|
|
return (size32_t)numWritten;
|
|
|
}
|
|
|
|
|
@@ -1870,6 +1907,8 @@ void CFileIO::setSize(offset_t pos)
|
|
|
|
|
|
// More errorno checking TBD
|
|
|
CFileIO::CFileIO(HANDLE handle, IFOmode _openmode, IFSHmode _sharemode, IFEflags _extraFlags)
|
|
|
+ : ioReadCycles(0), ioWriteCycles(0), ioReadBytes(0), ioWriteBytes(0), ioReads(0), ioWrites(0)
|
|
|
+
|
|
|
{
|
|
|
assertex(handle != NULLFILE);
|
|
|
throwOnError = false;
|
|
@@ -1882,7 +1921,6 @@ CFileIO::CFileIO(HANDLE handle, IFOmode _openmode, IFSHmode _sharemode, IFEflags
|
|
|
extraFlags = static_cast<IFEflags>(extraFlags & ~IFEnocache);
|
|
|
atomic_set(&bytesRead, 0);
|
|
|
atomic_set(&bytesWritten, 0);
|
|
|
-
|
|
|
#ifdef CFILEIOTRACE
|
|
|
DBGLOG("CFileIO::CfileIO(%d,%d,%d,%d)", handle, _openmode, _sharemode, _extraFlags);
|
|
|
#endif
|
|
@@ -1956,7 +1994,13 @@ offset_t CFileIO::size()
|
|
|
size32_t CFileIO::read(offset_t pos, size32_t len, void * data)
|
|
|
{
|
|
|
if (0==len) return 0;
|
|
|
+
|
|
|
+ CCycleTimer timer;
|
|
|
size32_t ret = checked_pread(file, data, len, pos);
|
|
|
+ ioReadCycles.fetch_add(timer.elapsedCycles());
|
|
|
+ ioReadBytes.fetch_add(ret);
|
|
|
+ ++ioReads;
|
|
|
+
|
|
|
if ( (extraFlags & IFEnocache) && (ret > 0) )
|
|
|
{
|
|
|
if (atomic_add_and_read(&bytesRead, ret) >= PGCFLUSH_BLKSIZE)
|
|
@@ -1990,7 +2034,12 @@ static void sync_file_region(int fd, offset_t offset, offset_t nbytes)
|
|
|
|
|
|
size32_t CFileIO::write(offset_t pos, size32_t len, const void * data)
|
|
|
{
|
|
|
+ CCycleTimer timer;
|
|
|
size32_t ret = pwrite(file,data,len,pos);
|
|
|
+ ioWriteCycles.fetch_add(timer.elapsedCycles());
|
|
|
+ ioWriteBytes.fetch_add(ret);
|
|
|
+ ++ioWrites;
|
|
|
+
|
|
|
if (ret==(size32_t)-1)
|
|
|
throw makeErrnoException(errno, "CFileIO::write");
|
|
|
if (ret<len)
|
|
@@ -2343,6 +2392,12 @@ offset_t CFileAsyncIO::size()
|
|
|
return length;
|
|
|
}
|
|
|
|
|
|
+unsigned __int64 CFileAsyncIO::getStatistic(StatisticKind kind)
|
|
|
+{
|
|
|
+ //MORE: Could implement - but I don't think this class is currently used
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
size32_t CFileAsyncIO::read(offset_t pos, size32_t len, void * data)
|
|
|
{
|
|
|
CriticalBlock procedure(cs);
|
|
@@ -2410,7 +2465,6 @@ IFileAsyncResult *CFileAsyncIO::writeAsync(offset_t pos, size32_t len, const voi
|
|
|
|
|
|
#endif
|
|
|
|
|
|
-
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
|
CFileIOStream::CFileIOStream(IFileIO * _io)
|
|
@@ -6397,6 +6451,7 @@ class CCachedFileIO: public CInterface, implements IFileIO
|
|
|
CLazyFileIOCache &owner;
|
|
|
RemoteFilename filename;
|
|
|
CriticalSection §
|
|
|
+ CRuntimeStatisticCollection fileStats;
|
|
|
IFOmode mode;
|
|
|
|
|
|
void writeNotSupported(const char *s)
|
|
@@ -6411,16 +6466,31 @@ public:
|
|
|
|
|
|
|
|
|
CCachedFileIO(CLazyFileIOCache &_owner, CriticalSection &_sect, RemoteFilename &_filename, IFOmode _mode)
|
|
|
- : owner(_owner), sect(_sect)
|
|
|
+ : owner(_owner), sect(_sect), fileStats(diskLocalStatistics)
|
|
|
{
|
|
|
filename.set(_filename);
|
|
|
mode = _mode;
|
|
|
+ accesst = 0;
|
|
|
}
|
|
|
|
|
|
virtual void Link(void) const { CInterface::Link(); } \
|
|
|
|
|
|
virtual bool Release(void) const;
|
|
|
|
|
|
+ unsigned __int64 getStatistic(StatisticKind kind)
|
|
|
+ {
|
|
|
+ switch (kind)
|
|
|
+ {
|
|
|
+ case StTimeDiskReadIO:
|
|
|
+ return cycle_to_nanosec(getStatistic(StCycleDiskReadIOCycles));
|
|
|
+ case StTimeDiskWriteIO:
|
|
|
+ return cycle_to_nanosec(getStatistic(StCycleDiskWriteIOCycles));
|
|
|
+ }
|
|
|
+
|
|
|
+ CriticalBlock block(sect);
|
|
|
+ unsigned __int64 openValue = cachedio ? cachedio->getStatistic(kind) : 0;
|
|
|
+ return openValue + fileStats.getStatisticValue(kind);
|
|
|
+ }
|
|
|
|
|
|
IFileIO *open();
|
|
|
|
|
@@ -6452,10 +6522,7 @@ public:
|
|
|
{
|
|
|
CriticalBlock block(sect);
|
|
|
if (cachedio)
|
|
|
- {
|
|
|
- cachedio->close();
|
|
|
- cachedio.clear();
|
|
|
- }
|
|
|
+ forceClose();
|
|
|
}
|
|
|
offset_t appendFile(IFile *file,offset_t pos,offset_t len)
|
|
|
{
|
|
@@ -6470,6 +6537,12 @@ public:
|
|
|
io->setSize(size);
|
|
|
}
|
|
|
|
|
|
+ void forceClose()
|
|
|
+ {
|
|
|
+ cachedio->close();
|
|
|
+ mergeStats(fileStats, cachedio);
|
|
|
+ cachedio.clear();
|
|
|
+ }
|
|
|
};
|
|
|
|
|
|
class CLazyFileIOCache: public CInterface, implements IFileIOCache
|
|
@@ -6524,7 +6597,7 @@ public:
|
|
|
break;
|
|
|
if (!oldest)
|
|
|
break;
|
|
|
- oldest->cachedio.clear();
|
|
|
+ oldest->forceClose();
|
|
|
//If previously had max ios then we now have space.
|
|
|
if (n == max)
|
|
|
break;
|