A little bit more of the threads implementation.

The most important change here is understanding that Thread's id_ field
was unrelated to java.lang.Thread's id field.

Change-Id: I832b92145332e1ded63a7824033dae684eeacf28
diff --git a/src/utils.cc b/src/utils.cc
index 90dd842..d890d29 100644
--- a/src/utils.cc
+++ b/src/utils.cc
@@ -12,6 +12,10 @@
 #include "object.h"
 #include "os.h"
 
+#if defined(HAVE_PRCTL)
+#include <sys/prctl.h>
+#endif
+
 namespace art {
 
 bool ReadFileToString(const std::string& file_name, std::string* result) {
@@ -213,6 +217,40 @@
   }
 }
 
+void SetThreadName(const char *threadName) {
+  int hasAt = 0;
+  int hasDot = 0;
+  const char *s = threadName;
+  while (*s) {
+    if (*s == '.') {
+      hasDot = 1;
+    } else if (*s == '@') {
+      hasAt = 1;
+    }
+    s++;
+  }
+  int len = s - threadName;
+  if (len < 15 || hasAt || !hasDot) {
+    s = threadName;
+  } else {
+    s = threadName + len - 15;
+  }
+#if defined(HAVE_ANDROID_PTHREAD_SETNAME_NP)
+  /* pthread_setname_np fails rather than truncating long strings */
+  char buf[16];       // MAX_TASK_COMM_LEN=16 is hard-coded into bionic
+  strncpy(buf, s, sizeof(buf)-1);
+  buf[sizeof(buf)-1] = '\0';
+  errno = pthread_setname_np(pthread_self(), buf);
+  if (errno != 0) {
+    PLOG(WARNING) << "Unable to set the name of current thread to '" << buf << "'";
+  }
+#elif defined(HAVE_PRCTL)
+  prctl(PR_SET_NAME, (unsigned long) s, 0, 0, 0);
+#else
+#error no implementation for SetThreadName
+#endif
+}
+
 }  // namespace art
 
 // Neither bionic nor glibc exposes gettid(2).