summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/CMakeLists.txt1
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/cmGlobalVisualStudio7Generator.cxx18
-rw-r--r--Source/cmLinkedTree.h164
-rw-r--r--Source/cmState.cxx144
-rw-r--r--Source/cmState.h29
-rw-r--r--Source/kwsys/CMakeLists.txt9
-rw-r--r--Source/kwsys/SystemInformation.cxx98
-rw-r--r--Source/kwsys/SystemInformation.hxx.in4
-rw-r--r--Source/kwsys/kwsysPlatformTestsCXX.cxx13
-rw-r--r--Source/kwsys/testSystemInformation.cxx1
11 files changed, 386 insertions, 97 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index b434327..6d012fd 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -281,6 +281,7 @@ set(SRCS
cmInstallTargetGenerator.cxx
cmInstallDirectoryGenerator.h
cmInstallDirectoryGenerator.cxx
+ cmLinkedTree.h
cmListFileCache.cxx
cmListFileCache.h
cmListFileLexer.c
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index a4c877e..c9aec51 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,5 +1,5 @@
# CMake version number components.
set(CMake_VERSION_MAJOR 3)
set(CMake_VERSION_MINOR 3)
-set(CMake_VERSION_PATCH 20150604)
+set(CMake_VERSION_PATCH 20150608)
#set(CMake_VERSION_RC 1)
diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx
index a242046..0ced245 100644
--- a/Source/cmGlobalVisualStudio7Generator.cxx
+++ b/Source/cmGlobalVisualStudio7Generator.cxx
@@ -15,6 +15,7 @@
#include "cmGeneratedFileStream.h"
#include "cmLocalVisualStudio7Generator.h"
#include "cmMakefile.h"
+#include "cmUuid.h"
#include "cmake.h"
#include <cmsys/Encoding.hxx>
@@ -953,14 +954,15 @@ std::string cmGlobalVisualStudio7Generator::GetGUID(std::string const& name)
std::string input = this->CMakeInstance->GetState()->GetBinaryDirectory();
input += "|";
input += name;
- std::string md5 = cmSystemTools::ComputeStringMD5(input);
- assert(md5.length() == 32);
- std::string const& guid =
- (md5.substr( 0,8)+"-"+
- md5.substr( 8,4)+"-"+
- md5.substr(12,4)+"-"+
- md5.substr(16,4)+"-"+
- md5.substr(20,12));
+
+ cmUuid uuidGenerator;
+
+ std::vector<unsigned char> uuidNamespace;
+ uuidGenerator.StringToBinary(
+ "ee30c4be-5192-4fb0-b335-722a2dffe760", uuidNamespace);
+
+ std::string guid = uuidGenerator.FromMd5(uuidNamespace, input);
+
return cmSystemTools::UpperCase(guid);
}
diff --git a/Source/cmLinkedTree.h b/Source/cmLinkedTree.h
new file mode 100644
index 0000000..d2339c4
--- /dev/null
+++ b/Source/cmLinkedTree.h
@@ -0,0 +1,164 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2015 Stephen Kelly <steveire@gmail.com>
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cmLinkedTree_h
+#define cmLinkedTree_h
+
+#include "cmStandardIncludes.h"
+
+#include <assert.h>
+
+/**
+ @brief A adaptor for traversing a tree structure in a vector
+
+ This class is not intended to be wholly generic like a standard library
+ container adaptor. Mostly it exists to facilitate code sharing for the
+ needs of the cmState. For example, the Truncate() method is a specific
+ requirement of the cmState.
+
+ An empty cmLinkedTree provides a Root() method, and an Extend() method,
+ each of which return iterators. A Tree can be built up by extending
+ from the root, and then extending from any other iterator.
+
+ An iterator resulting from this tree construction can be
+ forward-only-iterated toward the root. Extending the tree never
+ invalidates existing iterators.
+ */
+template<typename T>
+class cmLinkedTree
+{
+ typedef typename std::vector<T>::size_type PositionType;
+ typedef T* PointerType;
+ typedef T& ReferenceType;
+public:
+ class iterator : public std::iterator<std::forward_iterator_tag, T>
+ {
+ friend class cmLinkedTree;
+ cmLinkedTree* Tree;
+
+ // The Position is always 'one past the end'.
+ PositionType Position;
+
+ iterator(cmLinkedTree* tree, PositionType pos)
+ : Tree(tree), Position(pos)
+ {
+
+ }
+
+ public:
+ iterator()
+ : Tree(0), Position(0)
+ {
+
+ }
+
+ void operator++()
+ {
+ assert(this->Tree);
+ assert(this->Tree->UpPositions.size() == this->Tree->Data.size());
+ assert(this->Position <= this->Tree->Data.size());
+ assert(this->Position > 0);
+ this->Position = this->Tree->UpPositions[this->Position - 1];
+ }
+
+ PointerType operator->() const
+ {
+ assert(this->Tree);
+ assert(this->Tree->UpPositions.size() == this->Tree->Data.size());
+ assert(this->Position <= this->Tree->Data.size());
+ assert(this->Position > 0);
+ return this->Tree->GetPointer(this->Position - 1);
+ }
+
+ PointerType operator->()
+ {
+ assert(this->Tree);
+ assert(this->Tree->UpPositions.size() == this->Tree->Data.size());
+ assert(this->Position <= this->Tree->Data.size());
+ assert(this->Position > 0);
+ return this->Tree->GetPointer(this->Position - 1);
+ }
+
+ bool operator==(iterator other) const
+ {
+ assert(this->Tree);
+ assert(this->Tree->UpPositions.size() == this->Tree->Data.size());
+ assert(this->Tree == other.Tree);
+ return this->Position == other.Position;
+ }
+
+ bool operator!=(iterator other) const
+ {
+ assert(this->Tree);
+ assert(this->Tree->UpPositions.size() == this->Tree->Data.size());
+ return !(*this == other);
+ }
+
+ bool IsValid() const
+ {
+ if (!this->Tree)
+ {
+ return false;
+ }
+ return this->Position <= this->Tree->Data.size();
+ }
+ };
+
+ iterator Root() const
+ {
+ return iterator(const_cast<cmLinkedTree*>(this), 0);
+ }
+
+ iterator Extend(iterator it)
+ {
+ return Extend_impl(it, T());
+ }
+
+ iterator Extend(iterator it, T t)
+ {
+ return Extend_impl(it, t);
+ }
+
+ iterator Truncate()
+ {
+ assert(this->UpPositions.size() > 0);
+ this->UpPositions.erase(this->UpPositions.begin() + 1,
+ this->UpPositions.end());
+ assert(this->Data.size() > 0);
+ this->Data.erase(this->Data.begin() + 1, this->Data.end());
+ return iterator(this, 1);
+ }
+
+private:
+ T& GetReference(PositionType pos)
+ {
+ return this->Data[pos];
+ }
+
+ T* GetPointer(PositionType pos)
+ {
+ return &this->Data[pos];
+ }
+
+ iterator Extend_impl(iterator it, T t)
+ {
+ assert(this->UpPositions.size() == this->Data.size());
+ assert(it.Position <= this->UpPositions.size());
+ this->UpPositions.push_back(it.Position);
+ this->Data.push_back(t);
+ return iterator(this, this->UpPositions.size());
+ }
+
+ std::vector<T> Data;
+ std::vector<PositionType> UpPositions;
+};
+
+#endif
diff --git a/Source/cmState.cxx b/Source/cmState.cxx
index 3278d56..6ca875d 100644
--- a/Source/cmState.cxx
+++ b/Source/cmState.cxx
@@ -18,6 +18,30 @@
#include <assert.h>
+struct cmState::SnapshotDataType
+{
+ cmState::PositionType DirectoryParent;
+ cmState::SnapshotType SnapshotType;
+ cmLinkedTree<cmState::BuildsystemDirectoryStateType>::iterator
+ BuildSystemDirectory;
+};
+
+struct cmState::BuildsystemDirectoryStateType
+{
+ std::string Location;
+ std::string OutputLocation;
+
+ std::vector<std::string> CurrentSourceDirectoryComponents;
+ std::vector<std::string> CurrentBinaryDirectoryComponents;
+ // The top-most directories for relative path conversion. Both the
+ // source and destination location of a relative path conversion
+ // must be underneath one of these directories (both under source or
+ // both under binary) in order for the relative path to be evaluated
+ // safely by the build tools.
+ std::string RelativePathTopSource;
+ std::string RelativePathTopBinary;
+};
+
cmState::cmState(cmake* cm)
: CMakeInstance(cm),
IsInTryCompile(false),
@@ -200,29 +224,8 @@ void cmState::Reset()
this->GlobalProperties.clear();
this->PropertyDefinitions.clear();
- assert(this->Locations.size() > 0);
- assert(this->OutputLocations.size() > 0);
- assert(this->ParentPositions.size() > 0);
- assert(this->CurrentSourceDirectoryComponents.size() > 0);
- assert(this->CurrentBinaryDirectoryComponents.size() > 0);
- assert(this->RelativePathTopSource.size() > 0);
- assert(this->RelativePathTopBinary.size() > 0);
-
- this->Locations.erase(this->Locations.begin() + 1, this->Locations.end());
- this->OutputLocations.erase(this->OutputLocations.begin() + 1,
- this->OutputLocations.end());
- this->ParentPositions.erase(this->ParentPositions.begin() + 1,
- this->ParentPositions.end());
- this->CurrentSourceDirectoryComponents.erase(
- this->CurrentSourceDirectoryComponents.begin() + 1,
- this->CurrentSourceDirectoryComponents.end());
- this->CurrentBinaryDirectoryComponents.erase(
- this->CurrentBinaryDirectoryComponents.begin() + 1,
- this->CurrentBinaryDirectoryComponents.end());
- this->RelativePathTopSource.erase(this->RelativePathTopSource.begin() + 1,
- this->RelativePathTopSource.end());
- this->RelativePathTopBinary.erase(this->RelativePathTopBinary.begin() + 1,
- this->RelativePathTopBinary.end());
+ this->BuildsystemDirectory.Truncate();
+ this->SnapshotData.Truncate();
this->DefineProperty
("RULE_LAUNCH_COMPILE", cmProperty::DIRECTORY,
@@ -612,7 +615,7 @@ void cmState::Snapshot::ComputeRelativePathTopSource()
result = currentSource;
}
}
- this->State->RelativePathTopSource[this->Position] = result;
+ this->Position->BuildSystemDirectory->RelativePathTopSource = result;
}
void cmState::Snapshot::ComputeRelativePathTopBinary()
@@ -651,24 +654,21 @@ void cmState::Snapshot::ComputeRelativePathTopBinary()
// is a network path.
if(result.size() < 2 || result.substr(0, 2) != "//")
{
- this->State->RelativePathTopBinary[this->Position] = result;
+ this->Position->BuildSystemDirectory->RelativePathTopBinary = result;
}
else
{
- this->State->RelativePathTopBinary[this->Position] = "";
+ this->Position->BuildSystemDirectory->RelativePathTopBinary = "";
}
}
cmState::Snapshot cmState::CreateBaseSnapshot()
{
- PositionType pos = 0;
- this->ParentPositions.push_back(pos);
- this->Locations.resize(1);
- this->OutputLocations.resize(1);
- this->CurrentSourceDirectoryComponents.resize(1);
- this->CurrentBinaryDirectoryComponents.resize(1);
- this->RelativePathTopSource.resize(1);
- this->RelativePathTopBinary.resize(1);
+ PositionType pos = this->SnapshotData.Extend(this->SnapshotData.Root());
+ pos->DirectoryParent = this->SnapshotData.Root();
+ pos->SnapshotType = BuildsystemDirectoryType;
+ pos->BuildSystemDirectory =
+ this->BuildsystemDirectory.Extend(this->BuildsystemDirectory.Root());
return cmState::Snapshot(this, pos);
}
@@ -676,16 +676,12 @@ cmState::Snapshot
cmState::CreateBuildsystemDirectorySnapshot(Snapshot originSnapshot)
{
assert(originSnapshot.IsValid());
- PositionType pos = this->ParentPositions.size();
- this->ParentPositions.push_back(originSnapshot.Position);
- this->Locations.resize(this->Locations.size() + 1);
- this->OutputLocations.resize(this->OutputLocations.size() + 1);
- this->CurrentSourceDirectoryComponents.resize(
- this->CurrentSourceDirectoryComponents.size() + 1);
- this->CurrentBinaryDirectoryComponents.resize(
- this->CurrentBinaryDirectoryComponents.size() + 1);
- this->RelativePathTopSource.resize(this->RelativePathTopSource.size() + 1);
- this->RelativePathTopBinary.resize(this->RelativePathTopBinary.size() + 1);
+ PositionType pos = this->SnapshotData.Extend(originSnapshot.Position);
+ pos->DirectoryParent = originSnapshot.Position;
+ pos->SnapshotType = BuildsystemDirectoryType;
+ pos->BuildSystemDirectory =
+ this->BuildsystemDirectory.Extend(
+ originSnapshot.Position->BuildSystemDirectory);
return cmState::Snapshot(this, pos);
}
@@ -698,92 +694,94 @@ cmState::Snapshot::Snapshot(cmState* state, PositionType position)
const char* cmState::Snapshot::GetCurrentSourceDirectory() const
{
- return this->State->Locations[this->Position].c_str();
+ return this->Position->BuildSystemDirectory->Location.c_str();
}
void cmState::Snapshot::SetCurrentSourceDirectory(std::string const& dir)
{
assert(this->State);
- assert(this->State->Locations.size() > this->Position);
- this->State->Locations[this->Position] = dir;
- cmSystemTools::ConvertToUnixSlashes(
- this->State->Locations[this->Position]);
- this->State->Locations[this->Position] =
- cmSystemTools::CollapseFullPath(this->State->Locations[this->Position]);
+ std::string& loc = this->Position->BuildSystemDirectory->Location;
+ loc = dir;
+ cmSystemTools::ConvertToUnixSlashes(loc);
+ loc = cmSystemTools::CollapseFullPath(loc);
cmSystemTools::SplitPath(
- this->State->Locations[this->Position],
- this->State->CurrentSourceDirectoryComponents[this->Position]);
+ loc,
+ this->Position->BuildSystemDirectory->CurrentSourceDirectoryComponents);
this->ComputeRelativePathTopSource();
}
const char* cmState::Snapshot::GetCurrentBinaryDirectory() const
{
- return this->State->OutputLocations[this->Position].c_str();
+ return this->Position->BuildSystemDirectory->OutputLocation.c_str();
}
void cmState::Snapshot::SetCurrentBinaryDirectory(std::string const& dir)
{
- assert(this->State->OutputLocations.size() > this->Position);
- this->State->OutputLocations[this->Position] = dir;
- cmSystemTools::ConvertToUnixSlashes(
- this->State->OutputLocations[this->Position]);
- this->State->OutputLocations[this->Position] =
- cmSystemTools::CollapseFullPath(
- this->State->OutputLocations[this->Position]);
+ std::string& loc = this->Position->BuildSystemDirectory->OutputLocation;
+ loc = dir;
+ cmSystemTools::ConvertToUnixSlashes(loc);
+ loc = cmSystemTools::CollapseFullPath(loc);
cmSystemTools::SplitPath(
- this->State->OutputLocations[this->Position],
- this->State->CurrentBinaryDirectoryComponents[this->Position]);
+ loc,
+ this->Position->BuildSystemDirectory->CurrentBinaryDirectoryComponents);
this->ComputeRelativePathTopBinary();
}
std::vector<std::string> const&
cmState::Snapshot::GetCurrentSourceDirectoryComponents()
{
- return this->State->CurrentSourceDirectoryComponents[this->Position];
+ return this->Position->BuildSystemDirectory
+ ->CurrentSourceDirectoryComponents;
}
std::vector<std::string> const&
cmState::Snapshot::GetCurrentBinaryDirectoryComponents()
{
- return this->State->CurrentBinaryDirectoryComponents[this->Position];
+ return this->Position->BuildSystemDirectory
+ ->CurrentBinaryDirectoryComponents;
}
const char* cmState::Snapshot::GetRelativePathTopSource() const
{
- return this->State->RelativePathTopSource[this->Position].c_str();
+ return this->Position->BuildSystemDirectory->RelativePathTopSource.c_str();
}
const char* cmState::Snapshot::GetRelativePathTopBinary() const
{
- return this->State->RelativePathTopBinary[this->Position].c_str();
+ return this->Position->BuildSystemDirectory->RelativePathTopBinary.c_str();
}
void cmState::Snapshot::SetRelativePathTopSource(const char* dir)
{
- this->State->RelativePathTopSource[this->Position] = dir;
+ this->Position->BuildSystemDirectory->RelativePathTopSource = dir;
}
void cmState::Snapshot::SetRelativePathTopBinary(const char* dir)
{
- this->State->RelativePathTopBinary[this->Position] = dir;
+ this->Position->BuildSystemDirectory->RelativePathTopBinary = dir;
}
bool cmState::Snapshot::IsValid() const
{
- return this->State ? true : false;
+ return this->State && this->Position.IsValid()
+ ? this->Position != this->State->SnapshotData.Root()
+ : false;
}
cmState::Snapshot cmState::Snapshot::GetBuildsystemDirectoryParent() const
{
Snapshot snapshot;
- if (!this->State || this->Position == 0)
+ if (!this->State || this->Position == this->State->SnapshotData.Root())
{
return snapshot;
}
- PositionType parentPos = this->State->ParentPositions[this->Position];
- snapshot = Snapshot(this->State, parentPos);
+ PositionType parentPos = this->Position->DirectoryParent;
+ if (parentPos != this->State->SnapshotData.Root())
+ {
+ snapshot = Snapshot(this->State, parentPos);
+ }
return snapshot;
}
diff --git a/Source/cmState.h b/Source/cmState.h
index 39c9b76..7a39d01 100644
--- a/Source/cmState.h
+++ b/Source/cmState.h
@@ -15,21 +15,28 @@
#include "cmStandardIncludes.h"
#include "cmPropertyDefinitionMap.h"
#include "cmPropertyMap.h"
+#include "cmLinkedTree.h"
class cmake;
class cmCommand;
class cmState
{
- typedef std::vector<std::string>::size_type PositionType;
+ struct SnapshotDataType;
+ typedef cmLinkedTree<SnapshotDataType>::iterator PositionType;
friend class Snapshot;
public:
cmState(cmake* cm);
~cmState();
+ enum SnapshotType
+ {
+ BuildsystemDirectoryType
+ };
+
class Snapshot {
public:
- Snapshot(cmState* state = 0, PositionType position = 0);
+ Snapshot(cmState* state = 0, PositionType position = PositionType());
const char* GetCurrentSourceDirectory() const;
void SetCurrentSourceDirectory(std::string const& dir);
@@ -160,19 +167,11 @@ private:
std::map<std::string, cmCommand*> Commands;
cmPropertyMap GlobalProperties;
cmake* CMakeInstance;
- std::vector<std::string> Locations;
- std::vector<std::string> OutputLocations;
- std::vector<PositionType> ParentPositions;
-
- std::vector<std::vector<std::string> > CurrentSourceDirectoryComponents;
- std::vector<std::vector<std::string> > CurrentBinaryDirectoryComponents;
- // The top-most directories for relative path conversion. Both the
- // source and destination location of a relative path conversion
- // must be underneath one of these directories (both under source or
- // both under binary) in order for the relative path to be evaluated
- // safely by the build tools.
- std::vector<std::string> RelativePathTopSource;
- std::vector<std::string> RelativePathTopBinary;
+
+ struct BuildsystemDirectoryStateType;
+ cmLinkedTree<BuildsystemDirectoryStateType> BuildsystemDirectory;
+
+ cmLinkedTree<SnapshotDataType> SnapshotData;
std::vector<std::string> SourceDirectoryComponents;
std::vector<std::string> BinaryDirectoryComponents;
diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt
index c88e888..7eb678b 100644
--- a/Source/kwsys/CMakeLists.txt
+++ b/Source/kwsys/CMakeLists.txt
@@ -786,6 +786,15 @@ IF(KWSYS_USE_SystemInformation)
SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS KWSYS_BUILD_SHARED=1)
ENDIF()
+
+ IF(UNIX AND NOT CYGWIN)
+ KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_GETLOADAVG
+ "Checking whether CXX compiler has getloadavg" DIRECT)
+ IF(KWSYS_CXX_HAS_GETLOADAVG)
+ SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+ COMPILE_DEFINITIONS KWSYS_CXX_HAS_GETLOADAVG=1)
+ ENDIF()
+ ENDIF()
ENDIF()
#-----------------------------------------------------------------------------
diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx
index b0434f4..6e81b0b 100644
--- a/Source/kwsys/SystemInformation.cxx
+++ b/Source/kwsys/SystemInformation.cxx
@@ -81,6 +81,11 @@ typedef int siginfo_t;
# include <errno.h> // extern int errno;
#endif
+#if defined (__CYGWIN__) && !defined(_WIN32)
+# include <windows.h>
+# undef _WIN32
+#endif
+
#ifdef __FreeBSD__
# include <sys/sysctl.h>
# include <fenv.h>
@@ -366,6 +371,8 @@ public:
const char *procLimitEnvVarName);
LongLong GetProcMemoryUsed();
+ double GetLoadAverage();
+
// enable/disable stack trace signal handler.
static
void SetStackTraceOnError(int enable);
@@ -820,6 +827,11 @@ SystemInformation::LongLong SystemInformation::GetProcMemoryUsed()
return this->Implementation->GetProcMemoryUsed();
}
+double SystemInformation::GetLoadAverage()
+{
+ return this->Implementation->GetLoadAverage();
+}
+
SystemInformation::LongLong SystemInformation::GetProcessId()
{
return this->Implementation->GetProcessId();
@@ -1490,6 +1502,60 @@ void SymbolProperties::Initialize(void *address)
}
#endif // don't define this class if we're not using it
+// --------------------------------------------------------------------------
+#if defined(_WIN32) || defined(__CYGWIN__)
+# define KWSYS_SYSTEMINFORMATION_USE_GetSystemTimes
+#endif
+#if defined(_MSC_VER) && _MSC_VER < 1310
+# undef KWSYS_SYSTEMINFORMATION_USE_GetSystemTimes
+#endif
+#if defined(KWSYS_SYSTEMINFORMATION_USE_GetSystemTimes)
+double calculateCPULoad(unsigned __int64 idleTicks,
+ unsigned __int64 totalTicks)
+{
+ static double previousLoad = -0.0;
+ static unsigned __int64 previousIdleTicks = 0;
+ static unsigned __int64 previousTotalTicks = 0;
+
+ unsigned __int64 const idleTicksSinceLastTime =
+ idleTicks - previousIdleTicks;
+ unsigned __int64 const totalTicksSinceLastTime =
+ totalTicks - previousTotalTicks;
+
+ double load;
+ if (previousTotalTicks == 0 || totalTicksSinceLastTime == 0)
+ {
+ // No new information. Use previous result.
+ load = previousLoad;
+ }
+ else
+ {
+ // Calculate load since last time.
+ load = 1.0 - double(idleTicksSinceLastTime) / totalTicksSinceLastTime;
+
+ // Smooth if possible.
+ if (previousLoad > 0)
+ {
+ load = 0.25 * load + 0.75 * previousLoad;
+ }
+ }
+
+ previousLoad = load;
+ previousIdleTicks = idleTicks;
+ previousTotalTicks = totalTicks;
+
+ return load;
+}
+
+unsigned __int64 fileTimeToUInt64(FILETIME const& ft)
+{
+ LARGE_INTEGER out;
+ out.HighPart = ft.dwHighDateTime;
+ out.LowPart = ft.dwLowDateTime;
+ return out.QuadPart;
+}
+#endif
+
} // anonymous namespace
@@ -3612,6 +3678,38 @@ SystemInformationImplementation::GetProcMemoryUsed()
#endif
}
+double SystemInformationImplementation::GetLoadAverage()
+{
+#if defined(KWSYS_CXX_HAS_GETLOADAVG)
+ double loadavg[3] = { 0.0, 0.0, 0.0 };
+ if (getloadavg(loadavg, 3) > 0)
+ {
+ return loadavg[0];
+ }
+ return -0.0;
+#elif defined(KWSYS_SYSTEMINFORMATION_USE_GetSystemTimes)
+ // Old windows.h headers do not provide GetSystemTimes.
+ typedef BOOL (WINAPI *GetSystemTimesType)(LPFILETIME, LPFILETIME,
+ LPFILETIME);
+ static GetSystemTimesType pGetSystemTimes =
+ (GetSystemTimesType)GetProcAddress(GetModuleHandleW(L"kernel32"),
+ "GetSystemTimes");
+ FILETIME idleTime, kernelTime, userTime;
+ if (pGetSystemTimes && pGetSystemTimes(&idleTime, &kernelTime, &userTime))
+ {
+ unsigned __int64 const idleTicks =
+ fileTimeToUInt64(idleTime);
+ unsigned __int64 const totalTicks =
+ fileTimeToUInt64(kernelTime) + fileTimeToUInt64(userTime);
+ return calculateCPULoad(idleTicks, totalTicks) * GetNumberOfPhysicalCPU();
+ }
+ return -0.0;
+#else
+ // Not implemented on this platform.
+ return -0.0;
+#endif
+}
+
/**
Get the process id of the running process.
*/
diff --git a/Source/kwsys/SystemInformation.hxx.in b/Source/kwsys/SystemInformation.hxx.in
index a9fd05d..4acdc4f 100644
--- a/Source/kwsys/SystemInformation.hxx.in
+++ b/Source/kwsys/SystemInformation.hxx.in
@@ -130,6 +130,10 @@ public:
// Get system RAM used by this process id in units of KiB.
LongLong GetProcMemoryUsed();
+ // Return the load average of the machine or -0.0 if it cannot
+ // be determined.
+ double GetLoadAverage();
+
// enable/disable stack trace signal handler. In order to
// produce an informative stack trace the application should
// be dynamically linked and compiled with debug symbols.
diff --git a/Source/kwsys/kwsysPlatformTestsCXX.cxx b/Source/kwsys/kwsysPlatformTestsCXX.cxx
index 82620da..1596fe4 100644
--- a/Source/kwsys/kwsysPlatformTestsCXX.cxx
+++ b/Source/kwsys/kwsysPlatformTestsCXX.cxx
@@ -452,6 +452,19 @@ int main()
}
#endif
+#ifdef TEST_KWSYS_CXX_HAS_GETLOADAVG
+// Match feature definitions from SystemInformation.cxx
+#if (defined(__GNUC__) || defined(__PGI)) && !defined(_GNU_SOURCE)
+# define _GNU_SOURCE
+#endif
+#include <stdlib.h>
+int main()
+{
+ double loadavg[3] = { 0.0, 0.0, 0.0 };
+ return getloadavg(loadavg, 3);
+}
+#endif
+
#ifdef TEST_KWSYS_CXX_HAS_RLIMIT64
# if defined(KWSYS_HAS_LFS)
# define _LARGEFILE_SOURCE
diff --git a/Source/kwsys/testSystemInformation.cxx b/Source/kwsys/testSystemInformation.cxx
index 53d51ac..fc8ea55 100644
--- a/Source/kwsys/testSystemInformation.cxx
+++ b/Source/kwsys/testSystemInformation.cxx
@@ -87,6 +87,7 @@ int testSystemInformation(int, char*[])
printMethod3(info, GetProcMemoryAvailable("KWSHL","KWSPL"), "KiB");
printMethod3(info, GetHostMemoryUsed(), "KiB");
printMethod3(info, GetProcMemoryUsed(), "KiB");
+ printMethod(info, GetLoadAverage);
for (long int i = 0; i <= 31; i++)
{