You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by be...@apache.org on 2012/11/26 22:16:55 UTC
svn commit: r1413850 - in /incubator/mesos/trunk: src/linux/proc.cpp
src/linux/proc.hpp src/tests/proc_tests.cpp
third_party/libprocess/include/stout/stringify.hpp
third_party/libprocess/include/stout/strings.hpp
Author: benh
Date: Mon Nov 26 21:16:53 2012
New Revision: 1413850
URL: http://svn.apache.org/viewvc?rev=1413850&view=rev
Log:
Added a proc::cpus function for getting back information about the
CPUs on a machine.
Review: https://reviews.apache.org/r/8059
Modified:
incubator/mesos/trunk/src/linux/proc.cpp
incubator/mesos/trunk/src/linux/proc.hpp
incubator/mesos/trunk/src/tests/proc_tests.cpp
incubator/mesos/trunk/third_party/libprocess/include/stout/stringify.hpp
incubator/mesos/trunk/third_party/libprocess/include/stout/strings.hpp
Modified: incubator/mesos/trunk/src/linux/proc.cpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/linux/proc.cpp?rev=1413850&r1=1413849&r2=1413850&view=diff
==============================================================================
--- incubator/mesos/trunk/src/linux/proc.cpp (original)
+++ incubator/mesos/trunk/src/linux/proc.cpp Mon Nov 26 21:16:53 2012
@@ -1,18 +1,25 @@
#include <sys/types.h> // For pid_t.
#include <fstream>
+#include <list>
#include <set>
#include <string>
+#include <vector>
+#include <stout/foreach.hpp>
#include <stout/numify.hpp>
+#include <stout/option.hpp>
#include <stout/os.hpp>
+#include <stout/strings.hpp>
#include <stout/try.hpp>
#include "linux/proc.hpp"
using std::ifstream;
+using std::list;
using std::set;
using std::string;
+using std::vector;
namespace mesos {
namespace internal {
@@ -39,6 +46,73 @@ Try<set<pid_t> > pids()
}
+Try<list<CPU> > cpus()
+{
+ list<CPU> results;
+
+ ifstream file("/proc/cpuinfo");
+
+ if (!file.is_open()) {
+ return Try<list<CPU> >::error("Failed to open /proc/cpuinfo");
+ }
+
+ // Placeholders as we parse the file.
+ Option<unsigned int> id;
+ Option<unsigned int> core;
+ Option<unsigned int> socket;
+
+ string line;
+ while (getline(file, line)) {
+ if (line.find("processor") == 0 ||
+ line.find("physical id") == 0 ||
+ line.find("core id") == 0) {
+ // Get out and parse the value.
+ vector<string> tokens = strings::tokenize(line, ": ");
+ CHECK(tokens.size() >= 2) << stringify(tokens);
+ Try<unsigned int> value = numify<unsigned int>(tokens.back());
+ if (value.isError()) {
+ return Try<list<CPU> >::error(value.error());
+ }
+
+ // Now save the value.
+ if (line.find("processor") == 0) {
+ if (id.isSome()) {
+ return Try<list<CPU> >::error("Unexpected format of /proc/cpuinfo");
+ }
+ id = value.get();
+ } else if (line.find("physical id") == 0) {
+ if (socket.isSome()) {
+ return Try<list<CPU> >::error("Unexpected format of /proc/cpuinfo");
+ }
+ socket = value.get();
+ } else if (line.find("core id") == 0) {
+ if (core.isSome()) {
+ return Try<list<CPU> >::error("Unexpected format of /proc/cpuinfo");
+ }
+ core = value.get();
+ }
+
+ // And finally create a CPU if we have enough information.
+ if (id.isSome() && core.isSome() && socket.isSome()) {
+ results.push_back(CPU(id.get(), core.get(), socket.get()));
+ id = Option<unsigned int>::none();
+ core = Option<unsigned int>::none();
+ socket = Option<unsigned int>::none();
+ }
+ }
+ }
+
+ if (file.fail() && !file.eof()) {
+ file.close();
+ return Try<list<CPU> >::error("Failed to read /proc/cpuinfo");
+ }
+
+ file.close();
+
+ return results;
+}
+
+
Try<SystemStatistics> stat()
{
unsigned long long btime = 0;
@@ -49,23 +123,26 @@ Try<SystemStatistics> stat()
return Try<SystemStatistics>::error("Failed to open /proc/stat");
}
- while (!file.eof()) {
- string line;
- getline(file, line);
- if (file.fail() && !file.eof()) {
- file.close();
- return Try<SystemStatistics>::error("Failed to read /proc/stat");
- } else if (line.find("btime ") == 0) {
+ string line;
+ while (getline(file, line)) {
+ if (line.find("btime ") == 0) {
Try<unsigned long long> number =
numify<unsigned long long>(line.substr(6));
if (number.isSome()) {
btime = number.get();
} else {
- return Try<SystemStatistics>::error(number.error());
+ return Try<SystemStatistics>::error(
+ "Failed to parse /proc/stat: " + number.error());
}
+ break;
}
}
+ if (file.fail() && !file.eof()) {
+ file.close();
+ return Try<SystemStatistics>::error("Failed to read /proc/stat");
+ }
+
file.close();
return SystemStatistics(btime);
Modified: incubator/mesos/trunk/src/linux/proc.hpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/linux/proc.hpp?rev=1413850&r1=1413849&r2=1413850&view=diff
==============================================================================
--- incubator/mesos/trunk/src/linux/proc.hpp (original)
+++ incubator/mesos/trunk/src/linux/proc.hpp Mon Nov 26 21:16:53 2012
@@ -21,6 +21,7 @@
#include <sys/types.h> // For pid_t.
+#include <list>
#include <set>
#include <string>
@@ -31,6 +32,7 @@ namespace internal {
namespace proc {
// Forward declarations.
+struct CPU;
struct SystemStatistics;
struct ProcessStatistics;
@@ -38,6 +40,9 @@ struct ProcessStatistics;
// Reads from /proc and returns a list of all running processes.
Try<std::set<pid_t> > pids();
+// Reads from /proc/cpuinfo and returns a list of CPUs.
+Try<std::list<CPU> > cpus();
+
// Returns the system statistics from /proc/stat.
Try<SystemStatistics> stat();
@@ -45,6 +50,19 @@ Try<SystemStatistics> stat();
Try<ProcessStatistics> stat(pid_t pid);
+// Representation of a processor (really an execution unit since this
+// captures "hardware threads" as well) modeled after /proc/cpuinfo.
+struct CPU
+{
+ CPU(unsigned int _id, unsigned int _core, unsigned int _socket)
+ : id(_id), core(_core), socket(_socket) {}
+
+ const unsigned int id; // "processor"
+ const unsigned int core; // "core id"
+ const unsigned int socket; // "physical id"
+};
+
+
// Snapshot of a system (modeled after /proc/stat).
struct SystemStatistics
{
Modified: incubator/mesos/trunk/src/tests/proc_tests.cpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/tests/proc_tests.cpp?rev=1413850&r1=1413849&r2=1413850&view=diff
==============================================================================
--- incubator/mesos/trunk/src/tests/proc_tests.cpp (original)
+++ incubator/mesos/trunk/src/tests/proc_tests.cpp Mon Nov 26 21:16:53 2012
@@ -31,6 +31,7 @@
using namespace mesos;
using namespace mesos::internal;
+using proc::CPU;
using proc::SystemStatistics;
using proc::ProcessStatistics;
@@ -48,6 +49,15 @@ TEST(ProcTest, Pids)
}
+TEST(ProcTest, Cpus)
+{
+ Try<std::list<CPU> > cpus = proc::cpus();
+
+ ASSERT_SOME(cpus);
+ EXPECT_LE(1u, cpus.get().size());
+}
+
+
TEST(ProcTest, SystemStatistics)
{
Try<SystemStatistics> statistics = proc::stat();
Modified: incubator/mesos/trunk/third_party/libprocess/include/stout/stringify.hpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/libprocess/include/stout/stringify.hpp?rev=1413850&r1=1413849&r2=1413850&view=diff
==============================================================================
--- incubator/mesos/trunk/third_party/libprocess/include/stout/stringify.hpp (original)
+++ incubator/mesos/trunk/third_party/libprocess/include/stout/stringify.hpp Mon Nov 26 21:16:53 2012
@@ -9,6 +9,7 @@
#include <set>
#include <sstream> // For 'std::ostringstream'.
#include <string>
+#include <vector>
template <typename T>
@@ -65,6 +66,23 @@ std::string stringify(const std::list<T>
}
+template <typename T>
+std::string stringify(const std::vector<T>& vector)
+{
+ std::ostringstream out;
+ out << "[ ";
+ typename std::vector<T>::const_iterator iterator = vector.begin();
+ while (iterator != vector.end()) {
+ out << stringify(*iterator);
+ if (++iterator != vector.end()) {
+ out << ", ";
+ }
+ }
+ out << " ]";
+ return out.str();
+}
+
+
template <typename K, typename V>
std::string stringify(const std::map<K, V>& map)
{
Modified: incubator/mesos/trunk/third_party/libprocess/include/stout/strings.hpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/libprocess/include/stout/strings.hpp?rev=1413850&r1=1413849&r2=1413850&view=diff
==============================================================================
--- incubator/mesos/trunk/third_party/libprocess/include/stout/strings.hpp (original)
+++ incubator/mesos/trunk/third_party/libprocess/include/stout/strings.hpp Mon Nov 26 21:16:53 2012
@@ -8,6 +8,7 @@
#include "foreach.hpp"
#include "format.hpp"
+#include "stringify.hpp"
namespace strings {
@@ -172,9 +173,12 @@ template <typename Iterable>
inline std::string join(const std::string& separator, const Iterable& i)
{
std::string result;
- typename Iterable::const_iterator iterator;
- for (iterator = i.begin(); iterator != i.end(); ++iterator) {
- result += separator + *iterator;
+ typename Iterable::const_iterator iterator = i.begin();
+ while (iterator != i.end()) {
+ result += stringify(*iterator);
+ if (++iterator != i.end()) {
+ result += separator;
+ }
}
return result;
}