You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by id...@apache.org on 2015/05/29 23:34:23 UTC
[2/2] mesos git commit: Support manipulating scheduler policy on
Linux.
Support manipulating scheduler policy on Linux.
Review: https://reviews.apache.org/r/34309
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/6de149e4
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/6de149e4
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/6de149e4
Branch: refs/heads/master
Commit: 6de149e4715743345add600ade967a79351555f9
Parents: d7c0873
Author: Ian Downes <id...@twitter.com>
Authored: Fri May 15 17:58:28 2015 -0700
Committer: Ian Downes <id...@twitter.com>
Committed: Fri May 29 14:33:21 2015 -0700
----------------------------------------------------------------------
src/Makefile.am | 2 +
src/linux/sched.hpp | 93 ++++++++++++++++++++++++++++++++++++++++
src/tests/sched_tests.cpp | 96 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 191 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/6de149e4/src/Makefile.am
----------------------------------------------------------------------
diff --git a/src/Makefile.am b/src/Makefile.am
index e7281ac..9d1f0d5 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -550,6 +550,7 @@ libmesos_no_3rdparty_la_SOURCES += \
linux/fs.hpp \
linux/ns.hpp \
linux/perf.hpp \
+ linux/sched.hpp \
local/flags.hpp \
local/local.hpp \
logging/flags.hpp \
@@ -1480,6 +1481,7 @@ if OS_LINUX
mesos_tests_SOURCES += tests/memory_pressure_tests.cpp
mesos_tests_SOURCES += tests/ns_tests.cpp
mesos_tests_SOURCES += tests/perf_tests.cpp
+ mesos_tests_SOURCES += tests/sched_tests.cpp
mesos_tests_SOURCES += tests/setns_test_helper.cpp
endif
http://git-wip-us.apache.org/repos/asf/mesos/blob/6de149e4/src/linux/sched.hpp
----------------------------------------------------------------------
diff --git a/src/linux/sched.hpp b/src/linux/sched.hpp
new file mode 100644
index 0000000..2ae80be
--- /dev/null
+++ b/src/linux/sched.hpp
@@ -0,0 +1,93 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __LINUX_SCHED_HPP__
+#define __LINUX_SCHED_HPP__
+
+// This file contains Linux-only OS utilities.
+#ifndef __linux__
+#error "linux/sched.hpp is only available on Linux systems."
+#endif
+
+#include <sched.h>
+
+#include <sys/types.h>
+
+#include <stout/error.hpp>
+#include <stout/none.hpp>
+#include <stout/nothing.hpp>
+#include <stout/option.hpp>
+#include <stout/try.hpp>
+
+namespace sched {
+
+enum Policy
+{
+ OTHER = SCHED_OTHER, // Default policy.
+ BATCH = SCHED_BATCH, // Non-interactive, CPU intensive.
+ IDLE = SCHED_IDLE, // Very low priority.
+ FIFO = SCHED_FIFO, // Realtime.
+ RR = SCHED_RR // Realtime, round-robin.
+};
+
+
+namespace policy {
+
+// Return the current scheduling policy for the specified pid, or for
+// the caller if pid is None() or zero.
+inline Try<Policy> get(const Option<pid_t>& pid = None())
+{
+ int status = sched_getscheduler(pid.isSome() ? pid.get() : 0);
+
+ if (status == -1) {
+ return ErrnoError("Failed to get scheduler policy");
+ }
+
+ return static_cast<Policy>(status);
+}
+
+
+// Set the scheduling policy for the specified pid, or for the caller
+// if pid is None() or zero. Only realtime scheduling policies (FIFO
+// and RR) accept a priority (within a range, see
+// sched_setscheduler(2)).
+// TODO(idownes): Add wrappers around sched_get_priority_{min,max}.
+inline Try<Nothing> set(
+ Policy policy,
+ const Option<pid_t>& pid = None(),
+ int priority = 0)
+{
+ if ((policy == OTHER || policy == BATCH || policy == IDLE) &&
+ priority != 0) {
+ return Error("Non-real-time scheduling policies only support priority = 0");
+ }
+
+ sched_param param;
+ param.sched_priority = priority;
+
+ if (sched_setscheduler(pid.isSome() ? pid.get() : 0, policy, ¶m) == -1) {
+ return ErrnoError("Failed to set scheduler policy");
+ }
+
+ return Nothing();
+}
+
+} // namespace policy {
+} // namespace sched {
+
+#endif // __LINUX_SCHED_HPP__
http://git-wip-us.apache.org/repos/asf/mesos/blob/6de149e4/src/tests/sched_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/sched_tests.cpp b/src/tests/sched_tests.cpp
new file mode 100644
index 0000000..00723d0
--- /dev/null
+++ b/src/tests/sched_tests.cpp
@@ -0,0 +1,96 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "linux/sched.hpp"
+
+#include <process/gtest.hpp>
+#include <process/reap.hpp>
+
+#include <gtest/gtest.h>
+
+#include <stout/gtest.hpp>
+
+using sched::Policy;
+
+namespace mesos {
+namespace internal {
+namespace tests {
+
+// TODO(idownes): Test the priority and preemption behavior for
+// running competing SCHED_OTHER and SCHED_IDLE tasks.
+
+TEST(SchedTest, ROOT_PolicySelf)
+{
+ Try<Policy> original = sched::policy::get();
+ ASSERT_SOME(original);
+
+ Policy different = (original.get() == Policy::OTHER ? Policy::IDLE
+ : Policy::OTHER);
+
+ // Change our own scheduling policy.
+ EXPECT_SOME(sched::policy::set(different));
+ EXPECT_SOME_EQ(different, sched::policy::get());
+
+ // Change it back.
+ EXPECT_SOME(sched::policy::set(original.get()));
+ EXPECT_SOME_EQ(original.get(), sched::policy::get());
+}
+
+
+// Change the scheduling policy of a different process (our child).
+TEST(SchedTest, ROOT_PolicyChild)
+{
+ Try<Policy> original = sched::policy::get();
+ ASSERT_SOME(original);
+
+ Policy different = (original.get() == Policy::OTHER ? Policy::IDLE
+ : Policy::OTHER);
+
+ pid_t pid = ::fork();
+ ASSERT_NE(-1, pid);
+
+ if (pid == 0) {
+ // Child.
+ sleep(10);
+
+ ABORT("Child process should not reach here");
+ }
+
+ // Continue in parent.
+ // Check the child has inherited our policy.
+ EXPECT_SOME_EQ(original.get(), sched::policy::get(pid));
+
+ // Check we can change the child's policy.
+ EXPECT_SOME(sched::policy::set(different, pid));
+ EXPECT_SOME_EQ(different, sched::policy::get(pid));
+
+ process::Future<Option<int>> status = process::reap(pid);
+
+ // Kill the child process.
+ ASSERT_NE(-1, ::kill(pid, SIGKILL));
+
+ // Wait for the child process.
+ AWAIT_READY(status);
+ ASSERT_SOME(status.get());
+ EXPECT_TRUE(WIFSIGNALED(status.get().get()));
+ EXPECT_EQ(SIGKILL, WTERMSIG(status.get().get()));
+}
+
+} // namespace tests {
+} // namespace internal {
+} // namespace mesos {