OSDN Git Service

vm: Add support for using scheduler policies instead of cgroups
authorSan Mehat <san@google.com>
Wed, 9 Sep 2009 03:29:15 +0000 (20:29 -0700)
committerSan Mehat <san@google.com>
Thu, 10 Sep 2009 14:19:06 +0000 (07:19 -0700)
Signed-off-by: San Mehat <san@google.com>
vm/Globals.h
vm/Init.c
vm/Thread.c
vm/Thread.h
vm/alloc/Heap.c

index e1a91de..9b12d84 100644 (file)
@@ -633,6 +633,8 @@ struct DvmGlobals {
      */
     pid_t systemServerPid;
 
+    int kernelGroupScheduling;
+
 //#define COUNT_PRECISE_METHODS
 #ifdef COUNT_PRECISE_METHODS
     PointerSet* preciseMethods;
index 45c66e1..c46de25 100644 (file)
--- a/vm/Init.c
+++ b/vm/Init.c
@@ -1117,6 +1117,14 @@ int dvmStartup(int argc, const char* const argv[], bool ignoreUnrecognized,
     }
 #endif
 
+    /* Configure group scheduling capabilities */
+    if (!access("/dev/cpuctl/tasks", F_OK)) {
+        LOGV("Using kernel group scheduling");
+        gDvm.kernelGroupScheduling = 1;
+    } else {
+        LOGV("Using kernel scheduler policies");
+    }
+
     /* configure signal handling */
     if (!gDvm.reduceSignals)
         blockSignals();
index 4cce9f8..8f3650f 100644 (file)
@@ -3067,7 +3067,7 @@ static const int kNiceValues[10] = {
  *
  * Returns 0 on success.
  */
-int dvmChangeThreadSchedulerGroup(const char *cgroup)
+static int dvmChangeThreadSchedulerGroup(const char *cgroup)
 {
 #ifdef HAVE_ANDROID_OS
     int fd;
@@ -3103,6 +3103,29 @@ int dvmChangeThreadSchedulerGroup(const char *cgroup)
 }
 
 /*
+ * Change the scheduling policy of the current thread
+ */
+void dvmChangeThreadSchedulerPolicy(SchedPolicy policy)
+{
+    if (gDvm.kernelGroupScheduling) {
+        const char *grp = NULL;
+
+        if (policy == SCHED_BACKGROUND) {
+            grp = "bg_non_interactive";
+        }
+
+        dvmChangeThreadSchedulerGroup(grp);
+    } else {
+        struct sched_param param;
+
+        param.sched_priority = 0;
+        sched_setscheduler(getpid(),
+                           (policy == SCHED_BACKGROUND) ? 5 : 0,
+                            &param);
+    }
+}
+
+/*
  * Change the priority of a system thread to match that of the Thread object.
  *
  * We map a priority value from 1-10 to Linux "nice" values, where lower
@@ -3120,9 +3143,9 @@ void dvmChangeThreadPriority(Thread* thread, int newPriority)
     newNice = kNiceValues[newPriority-1];
 
     if (newNice >= ANDROID_PRIORITY_BACKGROUND) {
-        dvmChangeThreadSchedulerGroup("bg_non_interactive");
+        dvmChangeThreadSchedulerPolicy(SCHED_BACKGROUND);
     } else if (getpriority(PRIO_PROCESS, pid) >= ANDROID_PRIORITY_BACKGROUND) {
-        dvmChangeThreadSchedulerGroup(NULL);
+        dvmChangeThreadSchedulerPolicy(SCHED_FOREGROUND);
     }
 
     if (setpriority(PRIO_PROCESS, pid, newNice) != 0) {
index 3baf9aa..0859513 100644 (file)
@@ -416,10 +416,17 @@ bool dvmIsOnThreadList(const Thread* thread);
 INLINE JNIEnv* dvmGetThreadJNIEnv(Thread* self) { return self->jniEnv; }
 INLINE void dvmSetThreadJNIEnv(Thread* self, JNIEnv* env) { self->jniEnv = env;}
 
+typedef enum SchedPolicy {
+    SCHED_BACKGROUND = 0,
+    SCHED_FOREGROUND = 1,
+} SchedPolicy;
+
 /*
- * Change the scheduler group of the current process
+ * Change the scheduling policy of the current process.
+ * This is mapped onto whatever underlying scheme the kernel
+ * supports (cgroups/scheduler policies/wombats/etc)
  */
-int dvmChangeThreadSchedulerGroup(const char *group);
+void dvmChangeThreadSchedulerPolicy(SchedPolicy policy);
 
 /*
  * Update the priority value of the underlying pthread.
index c548190..cdb94c7 100644 (file)
@@ -783,7 +783,7 @@ void dvmCollectGarbageInternal(bool collectSoftReferences)
          */
 
         if (priorityResult >= ANDROID_PRIORITY_BACKGROUND) {
-            dvmChangeThreadSchedulerGroup(NULL);
+            dvmChangeThreadSchedulerPolicy(SCHED_FOREGROUND);
         }
 
         if (setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_NORMAL) != 0) {
@@ -1036,7 +1036,7 @@ void dvmCollectGarbageInternal(bool collectSoftReferences)
         }
 
         if (oldThreadPriority >= ANDROID_PRIORITY_BACKGROUND) {
-            dvmChangeThreadSchedulerGroup("bg_non_interactive");
+            dvmChangeThreadSchedulerPolicy(SCHED_BACKGROUND);
         }
     }
     gcElapsedTime = (dvmGetRelativeTimeUsec() - gcHeap->gcStartTime) / 1000;