blob: d039c700ba1abb84e2cac4bc80d662c7218dbdb7 [file] [log] [blame]
Brian Silvermanb0893882014-02-10 14:48:30 -08001#include "aos/linux_code/logging/linux_logging.h"
2
3#include <sys/prctl.h>
4
5#include "aos/linux_code/thread_local.h"
6#include "aos/common/die.h"
7
8namespace aos {
9namespace logging {
10namespace internal {
11namespace {
12
13::std::string GetMyName() {
14 // The maximum number of characters that can make up a thread name.
15 // The docs are unclear if it can be 16 characters with no '\0', so we'll be
16 // safe by adding our own where necessary.
17 static const size_t kThreadNameLength = 16;
18
19 ::std::string process_name(program_invocation_short_name);
20
21 char thread_name_array[kThreadNameLength + 1];
22 if (prctl(PR_GET_NAME, thread_name_array) != 0) {
23 Die("prctl(PR_GET_NAME, %p) failed with %d: %s\n",
24 thread_name_array, errno, strerror(errno));
25 }
26 thread_name_array[sizeof(thread_name_array) - 1] = '\0';
27 ::std::string thread_name(thread_name_array);
28
29 // If the first bunch of characters are the same.
30 // We cut off comparing at the shorter of the 2 strings because one or the
31 // other often ends up cut off.
32 if (strncmp(thread_name.c_str(), process_name.c_str(),
33 ::std::min(thread_name.length(), process_name.length())) == 0) {
34 // This thread doesn't have an actual name.
35 return process_name;
36 }
37
38 return process_name + '.' + thread_name;
39}
40
41AOS_THREAD_LOCAL Context *my_context(NULL);
42
43} // namespace
44
45Context *Context::Get() {
46 if (my_context == NULL) {
47 my_context = new Context();
48 my_context->name = GetMyName();
49 if (my_context->name.size() + 1 > sizeof(LogMessage::name)) {
50 Die("logging: process/thread name '%s' is too long\n",
51 my_context->name.c_str());
52 }
53 my_context->source = getpid();
54 }
55 return my_context;
56}
57
58void Context::Delete() {
59 delete my_context;
60 my_context = NULL;
61}
62
63} // namespace internal
64} // namespace logging
65} // namespace aos