forked from enlightenment/efl
Adapt bt stuff to Eina Debug signal infras
This commit is contained in:
parent
9fadbc00ad
commit
87e68e3ed0
|
@ -30,14 +30,15 @@
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue