am 23433b93: Add Sony-Ericsson to adb.

Merge commit '23433b93d1acb01650c9480d9bb5d5d869ba4f79' into eclair

* commit '23433b93d1acb01650c9480d9bb5d5d869ba4f79':
  Add Sony-Ericsson to adb.
diff --git a/include/cutils/sched_policy.h b/include/cutils/sched_policy.h
index efa7cbc..eaf3993 100644
--- a/include/cutils/sched_policy.h
+++ b/include/cutils/sched_policy.h
@@ -27,6 +27,7 @@
 } SchedPolicy;
 
 extern int set_sched_policy(int tid, SchedPolicy policy);
+extern int get_sched_policy(int tid, SchedPolicy *policy);
 
 #ifdef __cplusplus
 }
diff --git a/libcutils/atomic-android-arm.S b/libcutils/atomic-android-arm.S
index f4299fd..7befd78 100644
--- a/libcutils/atomic-android-arm.S
+++ b/libcutils/atomic-android-arm.S
@@ -66,6 +66,8 @@
  */
  
 android_atomic_inc:
+    .fnstart
+    .save {r4, lr}
     stmdb   sp!, {r4, lr}
     mov     r2, r0
 1: @ android_atomic_inc
@@ -85,6 +87,7 @@
     sub     r0, r1, #1
     ldmia   sp!, {r4, lr}
     bx      lr
+    .fnend
   
 /*
  * ----------------------------------------------------------------------------
@@ -94,6 +97,8 @@
  */
  
 android_atomic_dec:
+    .fnstart
+    .save {r4, lr}
     stmdb   sp!, {r4, lr}
     mov     r2, r0
 1: @ android_atomic_dec
@@ -113,6 +118,7 @@
     add     r0, r1, #1
     ldmia   sp!, {r4, lr}
     bx      lr
+    .fnend
     
 /*
  * ----------------------------------------------------------------------------
@@ -122,6 +128,8 @@
  */
 
 android_atomic_add:
+    .fnstart
+    .save {r4, lr}
     stmdb   sp!, {r4, lr}
     mov     r2, r1
     mov     r4, r0
@@ -142,6 +150,7 @@
     sub     r0, r1, r4
     ldmia   sp!, {r4, lr}
     bx      lr
+    .fnend
     
     
 /*
@@ -152,6 +161,8 @@
  */
 
 android_atomic_and:
+    .fnstart
+    .save {r4, r5, lr}
     stmdb   sp!, {r4, r5, lr}   
     mov     r2, r1              /* r2 = address */
     mov     r4, r0              /* r4 = the value */
@@ -174,6 +185,7 @@
     mov     r0, r5
     ldmia   sp!, {r4, r5, lr}
     bx      lr
+    .fnend
     
 /*
  * ----------------------------------------------------------------------------
@@ -183,6 +195,8 @@
  */
 
 android_atomic_or:
+    .fnstart
+    .save {r4, r5, lr}
     stmdb   sp!, {r4, r5, lr}   
     mov     r2, r1              /* r2 = address */
     mov     r4, r0              /* r4 = the value */
@@ -205,6 +219,7 @@
     mov     r0, r5
     ldmia   sp!, {r4, r5, lr}
     bx      lr
+    .fnend
 
 /*
  * ----------------------------------------------------------------------------
@@ -228,6 +243,8 @@
  */
 
 android_atomic_cmpxchg:
+    .fnstart
+    .save {r4, lr}
     stmdb   sp!, {r4, lr}
     mov     r4, r0          /* r4 = save oldvalue */
 1: @ android_atomic_cmpxchg
@@ -249,6 +266,7 @@
 2: @ android_atomic_cmpxchg
     ldmia   sp!, {r4, lr}
     bx      lr
+    .fnend
 
 /*
  * ----------------------------------------------------------------------------
diff --git a/libcutils/sched_policy.c b/libcutils/sched_policy.c
index 7553090..64d9bb7 100644
--- a/libcutils/sched_policy.c
+++ b/libcutils/sched_policy.c
@@ -23,6 +23,9 @@
 #include <errno.h>
 #include <fcntl.h>
 
+#define LOG_TAG "SchedPolicy"
+#include "cutils/log.h"
+
 #ifdef HAVE_SCHED_H
 
 #include <sched.h>
@@ -37,6 +40,10 @@
   #define SCHED_BATCH 3
 #endif
 
+#define POLICY_DEBUG 0
+
+static int __sys_supports_schedgroups = -1;
+
 static int add_tid_to_cgroup(int tid, const char *grp_name)
 {
     int fd;
@@ -45,8 +52,10 @@
 
     sprintf(path, "/dev/cpuctl/%s/tasks", grp_name);
 
-    if ((fd = open(path, O_WRONLY)) < 0)
+    if ((fd = open(path, O_WRONLY)) < 0) {
+        LOGE("add_tid_to_cgroup failed to open '%s' (%s)\n", path, strerror(errno));
         return -1;
+    }
 
     sprintf(text, "%d", tid);
     if (write(fd, text, strlen(text)) < 0) {
@@ -58,10 +67,8 @@
     return 0;
 }
 
-int set_sched_policy(int tid, SchedPolicy policy)
+static inline void initialize()
 {
-    static int __sys_supports_schedgroups = -1;
-
     if (__sys_supports_schedgroups < 0) {
         if (!access("/dev/cpuctl/tasks", F_OK)) {
             __sys_supports_schedgroups = 1;
@@ -69,9 +76,126 @@
             __sys_supports_schedgroups = 0;
         }
     }
+}
+
+/*
+ * Try to get the scheduler group.
+ *
+ * The data from /proc/<pid>/cgroup looks like:
+ *  2:cpu:/bg_non_interactive
+ *
+ * We return the part after the "/", which will be an empty string for
+ * the default cgroup.  If the string is longer than "bufLen", the string
+ * will be truncated.
+ */
+static int getSchedulerGroup(int tid, char* buf, size_t bufLen)
+{
+#ifdef HAVE_ANDROID_OS
+    char pathBuf[32];
+    char readBuf[256];
+    ssize_t count;
+    int fd;
+
+    snprintf(pathBuf, sizeof(pathBuf), "/proc/%d/cgroup", tid);
+    if ((fd = open(pathBuf, O_RDONLY)) < 0) {
+        return -1;
+    }
+
+    count = read(fd, readBuf, sizeof(readBuf));
+    if (count <= 0) {
+        close(fd);
+        errno = ENODATA;
+        return -1;
+    }
+    close(fd);
+
+    readBuf[--count] = '\0';    /* remove the '\n', now count==strlen */
+
+    char* cp = strchr(readBuf, '/');
+    if (cp == NULL) {
+        readBuf[sizeof(readBuf)-1] = '\0';
+        errno = ENODATA;
+        return -1;
+    }
+
+    memcpy(buf, cp+1, count);   /* count-1 for cp+1, count+1 for NUL */
+    return 0;
+#else
+    errno = ENOSYS;
+    return -1;
+#endif
+}
+
+int get_sched_policy(int tid, SchedPolicy *policy)
+{
+    initialize();
 
     if (__sys_supports_schedgroups) {
-        const char *grp = NULL;
+        char grpBuf[32];
+        if (getSchedulerGroup(tid, grpBuf, sizeof(grpBuf)) < 0)
+            return -1;
+        if (grpBuf[0] == '\0') {
+            *policy = SP_FOREGROUND;
+        } else if (!strcmp(grpBuf, "bg_non_interactive")) {
+            *policy = SP_BACKGROUND;
+        } else {
+            errno = ERANGE;
+            return -1;
+        }
+    } else {
+        int rc = sched_getscheduler(tid);
+        if (rc < 0)
+            return -1;
+        else if (rc == SCHED_NORMAL)
+            *policy = SP_FOREGROUND;
+        else if (rc == SCHED_BATCH)
+            *policy = SP_BACKGROUND;
+        else {
+            errno = ERANGE;
+            return -1;
+        }
+    }
+    return 0;
+}
+
+int set_sched_policy(int tid, SchedPolicy policy)
+{
+    initialize();
+
+#if POLICY_DEBUG
+    char statfile[64];
+    char statline[1024];
+    char thread_name[255];
+    int fd;
+
+    sprintf(statfile, "/proc/%d/stat", tid);
+    memset(thread_name, 0, sizeof(thread_name));
+
+    fd = open(statfile, O_RDONLY);
+    if (fd >= 0) {
+        int rc = read(fd, statline, 1023);
+        close(fd);
+        statline[rc] = 0;
+        char *p = statline;
+        char *q;
+
+        for (p = statline; *p != '('; p++);
+        p++;
+        for (q = p; *q != ')'; q++);
+
+        strncpy(thread_name, p, (q-p));
+    }
+    if (policy == SP_BACKGROUND) {
+        LOGD("vvv tid %d (%s)", tid, thread_name);
+    } else if (policy == SP_FOREGROUND) {
+        LOGD("^^^ tid %d (%s)", tid, thread_name);
+    } else {
+        LOGD("??? tid %d (%s)", tid, thread_name);
+    }
+#endif
+
+    if (__sys_supports_schedgroups) {
+        const char *grp = "";
 
         if (policy == SP_BACKGROUND) {
             grp = "bg_non_interactive";
diff --git a/toolbox/ps.c b/toolbox/ps.c
index 3b86fa2..bc50cfa 100644
--- a/toolbox/ps.c
+++ b/toolbox/ps.c
@@ -11,6 +11,8 @@
 
 #include <pwd.h>
 
+#include <cutils/sched_policy.h>
+
 
 static char *nexttoksep(char **strp, char *sep)
 {
@@ -24,6 +26,7 @@
 
 #define SHOW_PRIO 1
 #define SHOW_TIME 2
+#define SHOW_POLICY 4
 
 static int display_flags = 0;
 
@@ -138,12 +141,26 @@
     }
     
     if(!namefilter || !strncmp(name, namefilter, strlen(namefilter))) {
-        printf("%-8s %-5d %-5d %-5d %-5d", user, pid, ppid, vss / 1024, rss * 4);
+        printf("%-9s %-5d %-5d %-6d %-5d", user, pid, ppid, vss / 1024, rss * 4);
         if(display_flags&SHOW_PRIO)
             printf(" %-5d %-5d %-5d %-5d", prio, nice, rtprio, sched);
+        if (display_flags & SHOW_POLICY) {
+            SchedPolicy p;
+            if (get_sched_policy(pid, &p) < 0)
+                printf(" un ");
+            else {
+                if (p == SP_BACKGROUND)
+                    printf(" bg ");
+                else if (p == SP_FOREGROUND)
+                    printf(" fg ");
+                else
+                    printf(" er ");
+            }
+        }
         printf(" %08x %08x %s %s", wchan, eip, state, cmdline[0] ? cmdline : name);
         if(display_flags&SHOW_TIME)
             printf(" (u:%d, s:%d)", utime, stime);
+
         printf("\n");
     }
     return 0;
@@ -186,6 +203,8 @@
             threads = 1;
         } else if(!strcmp(argv[1],"-x")) {
             display_flags |= SHOW_TIME;
+        } else if(!strcmp(argv[1],"-P")) {
+            display_flags |= SHOW_POLICY;
         } else if(!strcmp(argv[1],"-p")) {
             display_flags |= SHOW_PRIO;
         }  else if(isdigit(argv[1][0])){
@@ -197,8 +216,9 @@
         argv++;
     }
 
-    printf("USER     PID   PPID  VSIZE RSS   %sWCHAN    PC         NAME\n", 
-           (display_flags&SHOW_PRIO)?"PRIO  NICE  RTPRI SCHED ":"");
+    printf("USER     PID   PPID  VSIZE  RSS   %s %s WCHAN    PC         NAME\n", 
+           (display_flags&SHOW_PRIO)?"PRIO  NICE  RTPRI SCHED ":"",
+           (display_flags&SHOW_POLICY)?"PCY " : "");
     while((de = readdir(d)) != 0){
         if(isdigit(de->d_name[0])){
             int pid = atoi(de->d_name);
diff --git a/toolbox/top.c b/toolbox/top.c
index dcc0843..daade6d 100644
--- a/toolbox/top.c
+++ b/toolbox/top.c
@@ -39,6 +39,8 @@
 #include <sys/types.h>
 #include <unistd.h>
 
+#include <cutils/sched_policy.h>
+
 struct cpu_info {
     long unsigned utime, ntime, stime, itime;
     long unsigned iowtime, irqtime, sirqtime;
@@ -64,6 +66,7 @@
     long vss;
     long rss;
     int num_threads;
+    char policy[32];
 };
 
 struct proc_list {
@@ -88,6 +91,7 @@
 static void free_proc(struct proc_info *proc);
 static void read_procs(void);
 static int read_stat(char *filename, struct proc_info *proc);
+static void read_policy(int pid, struct proc_info *proc);
 static void add_proc(int proc_num, struct proc_info *proc);
 static int read_cmdline(char *filename, struct proc_info *proc);
 static int read_status(char *filename, struct proc_info *proc);
@@ -260,6 +264,8 @@
             sprintf(filename, "/proc/%d/status", pid);
             read_status(filename, proc);
 
+            read_policy(pid, proc);
+
             proc->num_threads = 0;
         } else {
             sprintf(filename, "/proc/%d/cmdline", pid);
@@ -289,6 +295,8 @@
                 sprintf(filename, "/proc/%d/task/%d/stat", pid, tid);
                 read_stat(filename, proc);
 
+                read_policy(tid, proc);
+
                 strcpy(proc->name, cur_proc.name);
                 proc->uid = cur_proc.uid;
                 proc->gid = cur_proc.gid;
@@ -368,6 +376,20 @@
     return 0;
 }
 
+static void read_policy(int pid, struct proc_info *proc) {
+    SchedPolicy p;
+    if (get_sched_policy(pid, &p) < 0)
+        strcpy(proc->policy, "unk");
+    else {
+        if (p == SP_BACKGROUND)
+            strcpy(proc->policy, "bg");
+        else if (p == SP_FOREGROUND)
+            strcpy(proc->policy, "fg");
+        else
+            strcpy(proc->policy, "er");
+    }
+}
+
 static int read_status(char *filename, struct proc_info *proc) {
     FILE *file;
     char line[MAX_LINE];
@@ -432,9 +454,9 @@
             total_delta_time);
     printf("\n");
     if (!threads) 
-        printf("%5s %4s %1s %5s %7s %7s %-8s %s\n", "PID", "CPU%", "S", "#THR", "VSS", "RSS", "UID", "Name");
+        printf("%5s %4s %1s %5s %7s %7s %3s %-8s %s\n", "PID", "CPU%", "S", "#THR", "VSS", "RSS", "PCY", "UID", "Name");
     else
-        printf("%5s %5s %4s %1s %7s %7s %-8s %-15s %s\n", "PID", "TID", "CPU%", "S", "VSS", "RSS", "UID", "Thread", "Proc");
+        printf("%5s %5s %4s %1s %7s %7s %3s %-8s %-15s %s\n", "PID", "TID", "CPU%", "S", "VSS", "RSS", "PCY", "UID", "Thread", "Proc");
 
     for (i = 0; i < num_new_procs; i++) {
         proc = new_procs[i];
@@ -456,11 +478,11 @@
             group_str = group_buf;
         }
         if (!threads) 
-            printf("%5d %3ld%% %c %5d %6ldK %6ldK %-8.8s %s\n", proc->pid, proc->delta_time * 100 / total_delta_time, proc->state, proc->num_threads,
-                proc->vss / 1024, proc->rss * getpagesize() / 1024, user_str, proc->name[0] != 0 ? proc->name : proc->tname);
+            printf("%5d %3ld%% %c %5d %6ldK %6ldK %3s %-8.8s %s\n", proc->pid, proc->delta_time * 100 / total_delta_time, proc->state, proc->num_threads,
+                proc->vss / 1024, proc->rss * getpagesize() / 1024, proc->policy, user_str, proc->name[0] != 0 ? proc->name : proc->tname);
         else
-            printf("%5d %5d %3ld%% %c %6ldK %6ldK %-8.8s %-15s %s\n", proc->pid, proc->tid, proc->delta_time * 100 / total_delta_time, proc->state,
-                proc->vss / 1024, proc->rss * getpagesize() / 1024, user_str, proc->tname, proc->name);
+            printf("%5d %5d %3ld%% %c %6ldK %6ldK %3s %-8.8s %-15s %s\n", proc->pid, proc->tid, proc->delta_time * 100 / total_delta_time, proc->state,
+                proc->vss / 1024, proc->rss * getpagesize() / 1024, proc->policy, user_str, proc->tname, proc->name);
     }
 }