Merge branch 'vv/merge-squash-with-explicit-commit'
[gitweb.git] / trace2 / tr2_tls.c
index 8e65b0361dbedb7360d3d0f30229875faf5088d4..067c23755fb557895bf8cd12d497130dd55041fe 100644 (file)
 #define TR2_REGION_NESTING_INITIAL_SIZE (100)
 
 static struct tr2tls_thread_ctx *tr2tls_thread_main;
-static uint64_t tr2tls_us_start_main;
+static uint64_t tr2tls_us_start_process;
 
 static pthread_mutex_t tr2tls_mutex;
 static pthread_key_t tr2tls_key;
 
 static int tr2_next_thread_id; /* modify under lock */
 
-struct tr2tls_thread_ctx *tr2tls_create_self(const char *thread_name)
+void tr2tls_start_process_clock(void)
+{
+       if (tr2tls_us_start_process)
+               return;
+
+       /*
+        * Keep the absolute start time of the process (i.e. the main
+        * process) in a fixed variable since other threads need to
+        * access it.  This allows them to do that without a lock on
+        * main thread's array data (because of reallocs).
+        */
+       tr2tls_us_start_process = getnanotime() / 1000;
+}
+
+struct tr2tls_thread_ctx *tr2tls_create_self(const char *thread_name,
+                                            uint64_t us_thread_start)
 {
-       uint64_t us_now = getnanotime() / 1000;
        struct tr2tls_thread_ctx *ctx = xcalloc(1, sizeof(*ctx));
 
        /*
@@ -29,7 +43,7 @@ struct tr2tls_thread_ctx *tr2tls_create_self(const char *thread_name)
         */
        ctx->alloc = TR2_REGION_NESTING_INITIAL_SIZE;
        ctx->array_us_start = (uint64_t *)xcalloc(ctx->alloc, sizeof(uint64_t));
-       ctx->array_us_start[ctx->nr_open_regions++] = us_now;
+       ctx->array_us_start[ctx->nr_open_regions++] = us_thread_start;
 
        ctx->thread_id = tr2tls_locked_increment(&tr2_next_thread_id);
 
@@ -47,7 +61,12 @@ struct tr2tls_thread_ctx *tr2tls_create_self(const char *thread_name)
 
 struct tr2tls_thread_ctx *tr2tls_get_self(void)
 {
-       struct tr2tls_thread_ctx *ctx = pthread_getspecific(tr2tls_key);
+       struct tr2tls_thread_ctx *ctx;
+
+       if (!HAVE_THREADS)
+               return tr2tls_thread_main;
+
+       ctx = pthread_getspecific(tr2tls_key);
 
        /*
         * If the thread-proc did not call trace2_thread_start(), we won't
@@ -55,16 +74,17 @@ struct tr2tls_thread_ctx *tr2tls_get_self(void)
         * here and silently continue.
         */
        if (!ctx)
-               ctx = tr2tls_create_self("unknown");
+               ctx = tr2tls_create_self("unknown", getnanotime() / 1000);
 
        return ctx;
 }
 
 int tr2tls_is_main_thread(void)
 {
-       struct tr2tls_thread_ctx *ctx = pthread_getspecific(tr2tls_key);
+       if (!HAVE_THREADS)
+               return 1;
 
-       return ctx == tr2tls_thread_main;
+       return pthread_getspecific(tr2tls_key) == tr2tls_thread_main;
 }
 
 void tr2tls_unset_self(void)
@@ -124,22 +144,18 @@ uint64_t tr2tls_absolute_elapsed(uint64_t us)
        if (!tr2tls_thread_main)
                return 0;
 
-       return us - tr2tls_us_start_main;
+       return us - tr2tls_us_start_process;
 }
 
 void tr2tls_init(void)
 {
+       tr2tls_start_process_clock();
+
        pthread_key_create(&tr2tls_key, NULL);
        init_recursive_mutex(&tr2tls_mutex);
 
-       tr2tls_thread_main = tr2tls_create_self("main");
-       /*
-        * Keep a copy of the absolute start time of the main thread
-        * in a fixed variable since other threads need to access it.
-        * This also eliminates the need to lock accesses to the main
-        * thread's array (because of reallocs).
-        */
-       tr2tls_us_start_main = tr2tls_thread_main->array_us_start[0];
+       tr2tls_thread_main =
+               tr2tls_create_self("main", tr2tls_us_start_process);
 }
 
 void tr2tls_release(void)