blob: dff48e1e9a7d7d3849624ecdb4f74212b13840e1 [file] [log] [blame]
Austin Schuh044e18b2015-10-21 20:17:09 -07001#include "aos/common/logging/context.h"
Brian Silvermanb0893882014-02-10 14:48:30 -08002
Austin Schuh044e18b2015-10-21 20:17:09 -07003#include <string>
4#include <string.h>
Brian Silvermanb0893882014-02-10 14:48:30 -08005#include <sys/prctl.h>
Austin Schuh044e18b2015-10-21 20:17:09 -07006#include <sys/types.h>
7#include <unistd.h>
Brian Silvermanb0893882014-02-10 14:48:30 -08008
Brian Silverman17311c92014-09-06 00:48:59 -04009#include "aos/linux_code/complex_thread_local.h"
Brian Silvermanb0893882014-02-10 14:48:30 -080010#include "aos/common/die.h"
11
12namespace aos {
13namespace logging {
14namespace internal {
15namespace {
16
Brian Silverman2fe007c2014-12-28 12:20:01 -080017// TODO(brians): Differentiate between threads with the same name in the same
18// process.
Brian Silverman8bd31532014-09-05 11:40:55 -040019
Brian Silvermanb0893882014-02-10 14:48:30 -080020::std::string GetMyName() {
21 // The maximum number of characters that can make up a thread name.
22 // The docs are unclear if it can be 16 characters with no '\0', so we'll be
23 // safe by adding our own where necessary.
24 static const size_t kThreadNameLength = 16;
25
26 ::std::string process_name(program_invocation_short_name);
27
28 char thread_name_array[kThreadNameLength + 1];
29 if (prctl(PR_GET_NAME, thread_name_array) != 0) {
Brian Silverman01be0002014-05-10 15:44:38 -070030 PDie("prctl(PR_GET_NAME, %p) failed", thread_name_array);
Brian Silvermanb0893882014-02-10 14:48:30 -080031 }
32 thread_name_array[sizeof(thread_name_array) - 1] = '\0';
33 ::std::string thread_name(thread_name_array);
34
35 // If the first bunch of characters are the same.
36 // We cut off comparing at the shorter of the 2 strings because one or the
37 // other often ends up cut off.
38 if (strncmp(thread_name.c_str(), process_name.c_str(),
39 ::std::min(thread_name.length(), process_name.length())) == 0) {
40 // This thread doesn't have an actual name.
41 return process_name;
42 }
43
44 return process_name + '.' + thread_name;
45}
46
Brian Silverman17311c92014-09-06 00:48:59 -040047::aos::ComplexThreadLocal<Context> my_context;
Brian Silverman43d57d12014-05-20 14:04:07 -070048
Brian Silverman17311c92014-09-06 00:48:59 -040049// True if we're going to delete the current Context object ASAP. The
Brian Silverman43d57d12014-05-20 14:04:07 -070050// reason for doing this instead of just deleting them is that tsan (at least)
51// doesn't like it when pthread_atfork handlers do complicated stuff and it's
52// not a great idea anyways.
Brian Silverman8f373b12015-04-03 15:36:52 -040053thread_local bool delete_current_context(false);
Brian Silvermanb0893882014-02-10 14:48:30 -080054
55} // namespace
56
Brian Silverman2fe007c2014-12-28 12:20:01 -080057// Used in aos/linux_code/init.cc when a thread's name is changed.
58void ReloadThreadName() {
59 if (my_context.created()) {
Austin Schuhaebbc342015-01-25 02:25:13 -080060 ::std::string my_name = GetMyName();
61 if (my_name.size() + 1 > sizeof(Context::name)) {
Brian Silverman2fe007c2014-12-28 12:20:01 -080062 Die("logging: process/thread name '%s' is too long\n",
Austin Schuhaebbc342015-01-25 02:25:13 -080063 my_name.c_str());
Brian Silverman2fe007c2014-12-28 12:20:01 -080064 }
Austin Schuhaebbc342015-01-25 02:25:13 -080065 strcpy(my_context->name, my_name.c_str());
66 my_context->name_size = my_name.size();
Brian Silverman2fe007c2014-12-28 12:20:01 -080067 }
68}
69
Brian Silvermanb0893882014-02-10 14:48:30 -080070Context *Context::Get() {
Brian Silverman17311c92014-09-06 00:48:59 -040071 if (__builtin_expect(delete_current_context, false)) {
72 my_context.Clear();
73 delete_current_context = false;
74 }
75 if (__builtin_expect(!my_context.created(), false)) {
76 my_context.Create();
Brian Silverman2fe007c2014-12-28 12:20:01 -080077 ReloadThreadName();
Brian Silvermanb0893882014-02-10 14:48:30 -080078 my_context->source = getpid();
79 }
Brian Silverman17311c92014-09-06 00:48:59 -040080 return my_context.get();
Brian Silvermanb0893882014-02-10 14:48:30 -080081}
82
83void Context::Delete() {
Brian Silverman17311c92014-09-06 00:48:59 -040084 delete_current_context = true;
Brian Silvermanb0893882014-02-10 14:48:30 -080085}
86
87} // namespace internal
88} // namespace logging
89} // namespace aos