2015-05-13 23:41:11 -07:00
|
|
|
/* EINA - EFL data type library
|
|
|
|
* Copyright (C) 2015 Carsten Haitzler
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library;
|
|
|
|
* if not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2015-05-04 19:35:16 -07:00
|
|
|
#include "eina_debug.h"
|
2016-11-26 21:48:10 -08:00
|
|
|
#include "eina_debug_private.h"
|
2015-05-04 19:35:16 -07:00
|
|
|
|
|
|
|
// a really simple store of currently known active threads. the mainloop is
|
|
|
|
// special and inittied at debug init time - assuming eina inits in the
|
|
|
|
// mainloop thread (whihc is expected). also a growable array of thread
|
|
|
|
// id's for other threads is held here so we can loop over them and do things
|
|
|
|
// like get them to stop and dump a backtrace for us
|
2016-11-09 03:57:07 -08:00
|
|
|
Eina_Spinlock _eina_debug_thread_lock;
|
2015-05-04 19:35:16 -07:00
|
|
|
|
2016-11-09 03:57:07 -08:00
|
|
|
pthread_t _eina_debug_thread_mainloop = 0;
|
|
|
|
Eina_Debug_Thread *_eina_debug_thread_active = NULL;
|
|
|
|
int _eina_debug_thread_active_num = 0;
|
2015-05-04 19:35:16 -07:00
|
|
|
|
2016-11-09 03:57:07 -08:00
|
|
|
static int _thread_active_size = 0;
|
2016-11-26 21:48:10 -08:00
|
|
|
static int _thread_id_counter = 1;
|
2015-05-04 19:35:16 -07:00
|
|
|
|
|
|
|
// add a thread id to our tracking array - very simple. add to end, and
|
|
|
|
// if array to small, reallocate it to be bigger by 16 slots AND double that
|
|
|
|
// size (so grows should slow down FAST). we will never shrink this array
|
|
|
|
void
|
|
|
|
_eina_debug_thread_add(void *th)
|
|
|
|
{
|
|
|
|
pthread_t *pth = th;
|
|
|
|
// take thread tracking lock
|
|
|
|
eina_spinlock_take(&_eina_debug_thread_lock);
|
|
|
|
// if we don't have enough space to store thread id's - make some more
|
|
|
|
if (_thread_active_size < (_eina_debug_thread_active_num + 1))
|
|
|
|
{
|
2016-11-09 03:57:07 -08:00
|
|
|
Eina_Debug_Thread *threads = realloc
|
2015-05-04 19:35:16 -07:00
|
|
|
(_eina_debug_thread_active,
|
2016-11-09 03:57:07 -08:00
|
|
|
((_eina_debug_thread_active_num + 16) * 2) *
|
|
|
|
sizeof(Eina_Debug_Thread));
|
2015-05-04 19:35:16 -07:00
|
|
|
if (threads)
|
|
|
|
{
|
|
|
|
_eina_debug_thread_active = threads;
|
|
|
|
_thread_active_size = (_eina_debug_thread_active_num + 16) * 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// add new thread id to the end
|
2016-11-09 03:57:07 -08:00
|
|
|
_eina_debug_thread_active[_eina_debug_thread_active_num].thread = *pth;
|
|
|
|
#if defined(__clockid_t_defined)
|
|
|
|
_eina_debug_thread_active[_eina_debug_thread_active_num].clok.tv_sec = 0;
|
|
|
|
_eina_debug_thread_active[_eina_debug_thread_active_num].clok.tv_nsec = 0;
|
|
|
|
_eina_debug_thread_active[_eina_debug_thread_active_num].val = -1;
|
|
|
|
#endif
|
2016-11-26 21:48:10 -08:00
|
|
|
_eina_debug_thread_active[_eina_debug_thread_active_num].thread_id = _thread_id_counter++;
|
2015-05-04 19:35:16 -07:00
|
|
|
_eina_debug_thread_active_num++;
|
|
|
|
// release our lock cleanly
|
|
|
|
eina_spinlock_release(&_eina_debug_thread_lock);
|
|
|
|
}
|
|
|
|
|
|
|
|
// remove a thread id from our tracking array - simply find and shuffle all
|
|
|
|
// later elements down. this array should be small almsot all the time and
|
|
|
|
// shouldn't bew changing THAT often for this to matter
|
|
|
|
void
|
|
|
|
_eina_debug_thread_del(void *th)
|
|
|
|
{
|
|
|
|
pthread_t *pth = th;
|
|
|
|
int i;
|
|
|
|
// take a thread tracking lock
|
|
|
|
eina_spinlock_take(&_eina_debug_thread_lock);
|
|
|
|
// find the thread id to remove
|
|
|
|
for (i = 0; i < _eina_debug_thread_active_num; i++)
|
|
|
|
{
|
2016-11-09 03:57:07 -08:00
|
|
|
if (_eina_debug_thread_active[i].thread == *pth)
|
2015-05-04 19:35:16 -07:00
|
|
|
{
|
|
|
|
// found it - now shuffle down all further thread id's in array
|
|
|
|
for (; i < (_eina_debug_thread_active_num - 1); i++)
|
|
|
|
_eina_debug_thread_active[i] = _eina_debug_thread_active[i + 1];
|
|
|
|
// reduce our counter and get out of loop
|
|
|
|
_eina_debug_thread_active_num--;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// release lock cleanly
|
|
|
|
eina_spinlock_release(&_eina_debug_thread_lock);
|
|
|
|
}
|
|
|
|
|
|
|
|
// register the thread that is the mainloop - always there
|
|
|
|
void
|
|
|
|
_eina_debug_thread_mainloop_set(void *th)
|
|
|
|
{
|
|
|
|
pthread_t *pth = th;
|
|
|
|
_eina_debug_thread_mainloop = *pth;
|
|
|
|
}
|
2016-11-26 21:48:10 -08:00
|
|
|
|