Adapt bt stuff to Eina Debug signal infras
authorDaniel Zaoui <daniel.zaoui@yahoo.com>
Wed, 10 May 2017 08:57:07 +0000 (11:57 +0300)
committerDaniel Zaoui <daniel.zaoui@yahoo.com>
Mon, 5 Jun 2017 05:55:36 +0000 (08:55 +0300)
src/lib/eina/eina_debug_bt.c

index 68083e2..61a550b 100644 (file)
 
 static Eina_Semaphore _wait_for_bts_sem;
 
-// _bt_buf[0] is always for mainloop, 1 + is for extra threads
 static void             ***_bt_buf;
 static int                *_bt_buf_len;
 static struct timespec    *_bt_ts;
 static int                *_bt_cpu;
+static int                 _bt_threads_nb;
 
 /* Used by trace timer */
 static double _trace_t0 = 0.0;
+static Eina_Debug_Timer *_timer = NULL;
 
 static int _prof_get_op = EINA_DEBUG_OPCODE_INVALID;
 
@@ -53,7 +54,7 @@ _eina_debug_dump_fhandle_bt(FILE *f, void **bt, int btlen)
      {
         file = NULL;
         offset = base = 0;
-        // we have little choice but to hgope/assume dladdr() doesn't alloc
+        // we have little choice but to hope/assume dladdr() doesn't alloc
         // anything here
         if ((dladdr(bt[i], &info)) && (info.dli_fname[0]))
           {
@@ -91,52 +92,6 @@ _eina_debug_unwind_bt(void **bt, int max)
    return total;
 }
 
-// this signal handler is called inside each and every thread when the
-// thread gets a signal via pthread_kill(). this causes the thread to
-// stop here inside this handler and "do something" then when this returns
-// resume whatever it was doing like any signal handler
-static void
-_eina_debug_signal(int sig EINA_UNUSED,
-                   siginfo_t *si EINA_UNUSED,
-                   void *foo EINA_UNUSED)
-{
-   int i, slot = 0;
-   pthread_t self = pthread_self();
-   clockid_t cid;
-
-   // find which slot in the array of threads we have so we store info
-   // in the correct slot for us
-   if (self != _eina_debug_thread_mainloop)
-     {
-        for (i = 0; i < _eina_debug_thread_active_num; i++)
-          {
-             if (self == _eina_debug_thread_active[i].thread)
-               {
-                  slot = i + 1;
-                  goto found;
-               }
-          }
-        // we couldn't find out thread reference! help!
-        e_debug("EINA DEBUG ERROR: can't find thread slot!");
-        eina_semaphore_release(&_wait_for_bts_sem, 1);
-        return;
-     }
-found:
-   // store thread info like what cpu core we are on now (not reliable
-   // but hey - better than nothing), the amount of cpu time total
-   // we have consumed (it's cumulative so subtracing deltas can give
-   // you an average amount of cpu time consumed between now and the
-   // previous time we looked) and also a full backtrace
-   _bt_cpu[slot] = sched_getcpu();
-   pthread_getcpuclockid(self, &cid);
-   clock_gettime(cid, &(_bt_ts[slot]));
-   _bt_buf_len[slot] = _eina_debug_unwind_bt(_bt_buf[slot], EINA_MAX_BT);
-   // now wake up the monitor to let them know we are done collecting our
-   // backtrace info
-   eina_semaphore_release(&_wait_for_bts_sem, 1);
-}
-
-
 // a quick and dirty local time point getter func - not portable
 static inline double
 get_time(void)
@@ -152,18 +107,25 @@ get_time(void)
 #endif
 }
 
-static void
-_eina_debug_collect_bt(pthread_t pth EINA_UNUSED)
+static Eina_Debug_Error
+_prof_get_cb(Eina_Debug_Session *session EINA_UNUSED, int srcid EINA_UNUSED, void *buffer EINA_UNUSED, int size EINA_UNUSED)
 {
-   // this async signals the thread to switch to the deebug signal handler
-   // and collect a backtrace and other info from inside the thread
-   //pthread_kill(pth, SIG);
+   clockid_t cid;
+   int slot = eina_debug_thread_id_get();
+   if (slot >= _bt_threads_nb) return EINA_DEBUG_OK;
+   _bt_cpu[slot] = sched_getcpu();
+   pthread_getcpuclockid(pthread_self(), &cid);
+   clock_gettime(cid, &(_bt_ts[slot]));
+   _bt_buf_len[slot] = _eina_debug_unwind_bt(_bt_buf[slot], EINA_MAX_BT);
+   return EINA_DEBUG_OK;
 }
 
 static Eina_Bool
 _trace_cb(void *data)
 {
    static Eina_Debug_Packet_Header *hdr = NULL;
+   static int bts = 0;
+   int i;
 
    if (!hdr)
      {
@@ -173,62 +135,39 @@ _trace_cb(void *data)
         hdr->opcode = _prof_get_op;
      }
 
-   eina_debug_dispatch(data, (void *)hdr);
-   return EINA_TRUE;
-}
-
-static Eina_Debug_Error
-_prof_get_cb(Eina_Debug_Session *session EINA_UNUSED, int cid EINA_UNUSED, void *buffer EINA_UNUSED, int size EINA_UNUSED)
-{
-   static int bts = 0;
-   int i;
    if (!_trace_t0) _trace_t0 = get_time();
-   // take a lock on grabbing thread debug info like backtraces
-   eina_spinlock_take(&_eina_debug_thread_lock);
+
+   _bt_threads_nb = _eina_debug_thread_active_num;
    // reset our "stack" of memory se use to dump thread info into
    _eina_debug_chunk_tmp_reset();
    // get an array of pointers for the backtrace array for main + th
-   _bt_buf = _eina_debug_chunk_tmp_push
-      ((1 + _eina_debug_thread_active_num) * sizeof(void *));
+   _bt_buf = _eina_debug_chunk_tmp_push(_bt_threads_nb * sizeof(void *));
    if (!_bt_buf) goto err;
    // get an array of pointers for the timespec array for mainloop + th
-   _bt_ts = _eina_debug_chunk_tmp_push
-      ((1 + _eina_debug_thread_active_num) * sizeof(struct timespec));
+   _bt_ts = _eina_debug_chunk_tmp_push(_bt_threads_nb * sizeof(struct timespec));
    if (!_bt_ts) goto err;
    // get an array of pointers for the cpuid array for mainloop + th
-   _bt_cpu = _eina_debug_chunk_tmp_push
-      ((1 + _eina_debug_thread_active_num) * sizeof(int));
+   _bt_cpu = _eina_debug_chunk_tmp_push(_bt_threads_nb * sizeof(int));
    if (!_bt_cpu) goto err;
-   // now get an array of void pts for mainloop bt
-   _bt_buf[0] = _eina_debug_chunk_tmp_push(EINA_MAX_BT * sizeof(void *));
-   if (!_bt_buf[0]) goto err;
    // get an array of void ptrs for each thread we know about for bt
-   for (i = 0; i < _eina_debug_thread_active_num; i++)
+   for (i = 0; i < _bt_threads_nb; i++)
      {
-        _bt_buf[i + 1] = _eina_debug_chunk_tmp_push(EINA_MAX_BT * sizeof(void *));
-        if (!_bt_buf[i + 1]) goto err;
+        _bt_buf[i] = _eina_debug_chunk_tmp_push(EINA_MAX_BT * sizeof(void *));
+        if (!_bt_buf[i]) goto err;
      }
    // get an array of ints to stor the bt len for mainloop + threads
-   _bt_buf_len = _eina_debug_chunk_tmp_push
-      ((1 + _eina_debug_thread_active_num) * sizeof(int));
-   // collect bt from the mainloop - always there
-   _eina_debug_collect_bt(_eina_debug_thread_mainloop);
+   _bt_buf_len = _eina_debug_chunk_tmp_push(_bt_threads_nb * sizeof(int));
+
    // now collect per thread
-   for (i = 0; i < _eina_debug_thread_active_num; i++)
-      _eina_debug_collect_bt(_eina_debug_thread_active[i].thread);
-   // we're done probing. now collec all the "i'm done" msgs on the
-   // semaphore for every thread + mainloop
-   for (i = 0; i < (_eina_debug_thread_active_num + 1); i++)
-      eina_semaphore_lock(&_wait_for_bts_sem);
-   // we now have gotten all the data from all threadd + mainloop.
+   eina_debug_dispatch(data, (void *)hdr);
+
+   // we now have gotten all the data from all threads
    // we can process it now as we see fit, so release thread lock
-   //// XXX: some debug so we can see the bt's we collect - will go
-   //                  for (i = 0; i < (_eina_debug_thread_active_num + 1); i++)
-   //                    {
-   //                       _eina_debug_dump_fhandle_bt(stderr, _bt_buf[i], _bt_buf_len[i]);
-   //                    }
+   for (i = 0; i < _eina_debug_thread_active_num; i++)
+     {
+        _eina_debug_dump_fhandle_bt(stderr, _bt_buf[i], _bt_buf_len[i]);
+     }
 err:
-   eina_spinlock_release(&_eina_debug_thread_lock);
    //// XXX: some debug just to see how well we perform - will go
    bts++;
    if (bts >= 10000)
@@ -239,7 +178,7 @@ err:
         _trace_t0 = t;
         bts = 0;
      }
-   return EINA_DEBUG_OK;
+   return EINA_TRUE;
 }
 
 // profiling on with poll time gap as uint payload
@@ -251,7 +190,7 @@ _prof_on_cb(Eina_Debug_Session *session, int cid EINA_UNUSED, void *buffer, int
      {
         memcpy(&time, buffer, 4);
         _trace_t0 = 0.0;
-        eina_debug_timer_add(time, _trace_cb, session);
+        _timer = eina_debug_timer_add(time, _trace_cb, session);
      }
    return EINA_DEBUG_OK;
 }
@@ -259,7 +198,8 @@ _prof_on_cb(Eina_Debug_Session *session, int cid EINA_UNUSED, void *buffer, int
 static Eina_Debug_Error
 _prof_off_cb(Eina_Debug_Session *session EINA_UNUSED, int cid EINA_UNUSED, void *buffer EINA_UNUSED, int size EINA_UNUSED)
 {
-   eina_debug_timer_add(0, NULL, NULL);
+   eina_debug_timer_del(_timer);
+   _timer = NULL;
    return EINA_DEBUG_OK;
 }