name our threads for ease of debugging

Change-Id: If35518ed5f33aa38cc054d075cbe2850960ea3f5
diff --git a/aos/linux_code/init.cc b/aos/linux_code/init.cc
index a4e72db..4f153e9 100644
--- a/aos/linux_code/init.cc
+++ b/aos/linux_code/init.cc
@@ -10,13 +10,21 @@
 #include <unistd.h>
 #include <stdlib.h>
 #include <stdint.h>
+#include <sys/prctl.h>
 
 #include "aos/common/die.h"
 #include "aos/linux_code/logging/linux_logging.h"
 #include "aos/linux_code/ipc_lib/shared_mem.h"
 
 namespace aos {
+namespace logging {
+namespace internal {
 
+// Implemented in aos/linux_code/logging/linux_interface.cc.
+void ReloadThreadName();
+
+}  // namespace internal
+}  // namespace logging
 namespace {
 
 void SetSoftRLimit(int resource, rlim64_t soft, bool set_for_root) {
@@ -117,4 +125,13 @@
   }
 }
 
+void SetCurrentThreadName(const ::std::string &name) {
+  if (name.size() > 16) {
+    LOG(FATAL, "thread name '%s' too long\n", name.c_str());
+  }
+  LOG(INFO, "this thread is changing to '%s'\n", name.c_str());
+  PCHECK(prctl(PR_SET_NAME, name.c_str()));
+  logging::internal::ReloadThreadName();
+}
+
 }  // namespace aos
diff --git a/aos/linux_code/init.h b/aos/linux_code/init.h
index ab1aab5..2e57166 100644
--- a/aos/linux_code/init.h
+++ b/aos/linux_code/init.h
@@ -1,6 +1,8 @@
 #ifndef AOS_LINUX_CODE_INIT_H_
 #define AOS_LINUX_CODE_INIT_H_
 
+#include <string>
+
 namespace aos {
 
 // In order to use shared memory, one of the Init* functions must be called in
@@ -28,6 +30,11 @@
 // Sets the current thread's realtime priority.
 void SetCurrentThreadRealtimePriority(int priority);
 
+// Sets the name of the current thread.
+// This will displayed by `top -H`, dump_rtprio, and show up in logs.
+// name can have a maximum of 16 characters.
+void SetCurrentThreadName(const ::std::string &name);
+
 }  // namespace aos
 
 #endif  // AOS_LINUX_CODE_INIT_H_
diff --git a/aos/linux_code/logging/linux_interface.cc b/aos/linux_code/logging/linux_interface.cc
index 0040e94..4e8317b 100644
--- a/aos/linux_code/logging/linux_interface.cc
+++ b/aos/linux_code/logging/linux_interface.cc
@@ -11,7 +11,8 @@
 namespace internal {
 namespace {
 
-// TODO(brians): Differentiate between threads in the same process.
+// TODO(brians): Differentiate between threads with the same name in the same
+// process.
 
 ::std::string GetMyName() {
   // The maximum number of characters that can make up a thread name.
@@ -50,6 +51,17 @@
 
 }  // namespace
 
+// Used in aos/linux_code/init.cc when a thread's name is changed.
+void ReloadThreadName() {
+  if (my_context.created()) {
+    my_context->name = GetMyName();
+    if (my_context->name.size() + 1 > sizeof(LogMessage::name)) {
+      Die("logging: process/thread name '%s' is too long\n",
+          my_context->name.c_str());
+    }
+  }
+}
+
 Context *Context::Get() {
   if (__builtin_expect(delete_current_context, false)) {
     my_context.Clear();
@@ -58,10 +70,7 @@
   if (__builtin_expect(!my_context.created(), false)) {
     my_context.Create();
     my_context->name = GetMyName();
-    if (my_context->name.size() + 1 > sizeof(LogMessage::name)) {
-      Die("logging: process/thread name '%s' is too long\n",
-          my_context->name.c_str());
-    }
+    ReloadThreadName();
     my_context->source = getpid();
   }
   return my_context.get();