Add sched_getattr()/sched_setattr().

Still a questionable ABI (because the struct changes size over time without changing its name), but it's in glibc 2.41, so my assumption is that _not_ having it is likely to be more disruptive than the ABI issues going forward. (Hopefully no-one was planning on passing these structs between separately compiled libraries anyway!)

Bug: http://b/183240349
Change-Id: I80c39900b70af7e84913e547f38f656efa3e16ec
diff --git a/tests/sched_test.cpp b/tests/sched_test.cpp
index 448fae9..4009e1d 100644
--- a/tests/sched_test.cpp
+++ b/tests/sched_test.cpp
@@ -165,7 +165,6 @@
   }
 }
 
-
 TEST(sched, cpu_alloc_small) {
   cpu_set_t* set = CPU_ALLOC(17);
   size_t size = CPU_ALLOC_SIZE(17);
@@ -313,7 +312,7 @@
 #pragma clang diagnostic pop
 }
 
-TEST(pthread, sched_getaffinity) {
+TEST(sched, sched_getaffinity) {
   cpu_set_t set;
   CPU_ZERO(&set);
   ASSERT_EQ(0, sched_getaffinity(getpid(), sizeof(set), &set));
@@ -329,7 +328,7 @@
 #pragma clang diagnostic pop
 }
 
-TEST(pthread, sched_setaffinity) {
+TEST(sched, sched_setaffinity) {
   cpu_set_t set;
   CPU_ZERO(&set);
   ASSERT_EQ(0, sched_getaffinity(getpid(), sizeof(set), &set));
@@ -337,3 +336,25 @@
   // but it ought to be safe to ask for the same affinity you already have.
   ASSERT_EQ(0, sched_setaffinity(getpid(), sizeof(set), &set));
 }
+
+TEST(sched, sched_getattr) {
+#if defined(__BIONIC__)
+  struct sched_attr sa;
+  ASSERT_EQ(0, sched_getattr(getpid(), &sa, sizeof(sa), 0));
+#else
+  GTEST_SKIP() << "our glibc is too old";
+#endif
+}
+
+TEST(sched, sched_setattr_failure) {
+#if defined(__BIONIC__)
+  // Trivial test of the errno-preserving/returning behavior.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
+  ASSERT_EQ(-1, sched_setattr(getpid(), nullptr, 0));
+  ASSERT_ERRNO(EINVAL);
+#pragma clang diagnostic pop
+#else
+  GTEST_SKIP() << "our glibc is too old";
+#endif
+}