diff --git a/libguile/debug.c b/libguile/debug.c index 107b5d4..6f47354 100644 --- a/libguile/debug.c +++ b/libguile/debug.c @@ -263,3 +263,4 @@ scm_init_debug () c-file-style: "gnu" End: */ +int dpe = 0; diff --git a/libguile/debugx.h b/libguile/debugx.h new file mode 100644 index 0000000..b39a7bb --- /dev/null +++ b/libguile/debugx.h @@ -0,0 +1,35 @@ +/* +vim: set ts=8 sts=2 sw=2 noexpandtab filetype=c: +*/ +#include +#include +#include +#include +#include + +extern int dpe; + +#define DEBUG_PRINTF( cond, format, args... ) \ + if ( cond )\ + { \ + struct timespec l_timespec; \ + struct tm l_tm; \ + char date_time_buf[32];\ + char __db_buffer[8*1024]; \ + int written = -1; \ + clock_gettime( CLOCK_REALTIME, &l_timespec ); \ + \ + localtime_r(&(l_timespec.tv_sec), &l_tm); \ + \ + strftime( date_time_buf, 32, "%Y-%m-%dT%H:%M:%S", &l_tm );\ + \ + \ + written = snprintf( __db_buffer, 8*1024, "%s.%09li [%08u:%08u:%010u] DEBUG_VAR [%s:%i:%s] "format"\n", \ + date_time_buf, l_timespec.tv_nsec, \ + ( unsigned int )( getpid() ), ( unsigned int )( getppid() ), ( unsigned int )( pthread_self() ), \ + __FILE__, __LINE__, __FUNCTION__, \ + ##args ); \ + write( fileno( stderr ), __db_buffer, written ); \ + } \ + + diff --git a/libguile/init.c b/libguile/init.c index b320360..33340ce 100644 --- a/libguile/init.c +++ b/libguile/init.c @@ -17,6 +17,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA */ +/* +vim: set ts=8 sts=2 sw=2 noexpandtab filetype=c: +*/ @@ -304,6 +307,7 @@ static void *invoke_main_func(void *body_data); allocate. So, scm_boot_guile function exits, rather than returning, to discourage people from making that mistake. */ +#include "libguile/debugx.h" void scm_boot_guile (int argc, char ** argv, void (*main_func) (), void *closure) @@ -380,6 +384,7 @@ scm_i_init_guile (void *base) { if (scm_initialized_p) return; + dpe = ( getenv( "DEBUG_PRINTF_ENABLE" ) != NULL ); scm_storage_prehistory (); scm_threads_prehistory (base); /* requires storage_prehistory */ diff --git a/libguile/threads.c b/libguile/threads.c index 15e4919..702ce37 100644 --- a/libguile/threads.c +++ b/libguile/threads.c @@ -17,6 +17,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA */ +/* +vim: set ts=8 sts=2 sw=2 noexpandtab filetype=c: +*/ @@ -64,6 +67,7 @@ #include "libguile/scmsigs.h" #include "libguile/strings.h" #include "libguile/weaks.h" +#include "libguile/debugx.h" #include @@ -458,7 +462,10 @@ block_self (SCM queue, SCM sleep_object, scm_i_pthread_mutex_t *mutex, happened above. */ if (remqueue (queue, q_handle) && err == 0) + { + DEBUG_PRINTF( dpe, "[ waittime = %p, errno = %i, errno_string = %s ]", waittime, err, strerror( err ) ); err = EINTR; + } t->block_asyncs--; scm_i_reset_sleep (t); } @@ -1406,6 +1413,8 @@ fat_mutex_lock (SCM mutex, scm_t_timespec *timeout, SCM owner, int *ret) { if (m->level == 0) { + DEBUG_PRINTF( dpe, "mutex = %lu : m->level = %i : owner = %lu -> %lu", + SCM_UNPACK( mutex ), m->level, SCM_UNPACK( m->owner ), SCM_UNPACK( new_owner ) ); m->owner = new_owner; m->level++; @@ -1432,6 +1441,8 @@ fat_mutex_lock (SCM mutex, scm_t_timespec *timeout, SCM owner, int *ret) } else if (SCM_I_IS_THREAD (m->owner) && scm_c_thread_exited_p (m->owner)) { + DEBUG_PRINTF( dpe, "mutex = %lu : m->level = %i : owner = %lu -> %lu", + SCM_UNPACK( mutex ), m->level, SCM_UNPACK( m->owner ), SCM_UNPACK( new_owner ) ); m->owner = new_owner; err = scm_cons (scm_abandoned_mutex_error_key, scm_from_locale_string ("lock obtained on abandoned " @@ -1589,6 +1600,8 @@ fat_mutex_unlock (SCM mutex, SCM cond, if (!m->unchecked_unlock) { scm_i_pthread_mutex_unlock (&m->lock); + DEBUG_PRINTF( dpe, "mutex = %lu : t->handle = %lu : m->level = %i : owner = %lu -> -1", + SCM_UNPACK( mutex ), SCM_UNPACK( t->handle ), m->level, SCM_UNPACK( owner ) ); scm_misc_error (NULL, "mutex not locked", SCM_EOL); } owner = t->handle; @@ -1596,6 +1609,8 @@ fat_mutex_unlock (SCM mutex, SCM cond, else if (!m->allow_external_unlock) { scm_i_pthread_mutex_unlock (&m->lock); + DEBUG_PRINTF( dpe, "mutex = %lu : t->handle = %lu : m->level = %i : owner = %lu -> -1", + SCM_UNPACK( mutex ), SCM_UNPACK( t->handle ), m->level, SCM_UNPACK( owner ) ); scm_misc_error (NULL, "mutex not locked by current thread", SCM_EOL); } } @@ -1619,6 +1634,8 @@ fat_mutex_unlock (SCM mutex, SCM cond, t->block_asyncs++; err = block_self (c->waiting, cond, &m->lock, waittime); + DEBUG_PRINTF( dpe, "mutex = %lu : t->handle = %lu : m->level = %i : owner = %lu -> %lu [ relock = %i, err = %i, errstr = %s ]", + SCM_UNPACK( mutex ), SCM_UNPACK( t->handle ), m->level, SCM_UNPACK( owner ), SCM_UNPACK( m->owner ), relock, err, strerror( err ) ); scm_i_pthread_mutex_unlock (&m->lock); if (err == 0) @@ -1662,6 +1679,8 @@ fat_mutex_unlock (SCM mutex, SCM cond, /* Change the owner of MUTEX. */ t->mutexes = scm_delq_x (mutex, t->mutexes); m->owner = unblock_from_queue (m->waiting); + DEBUG_PRINTF( dpe, "mutex = %lu : t->handle = %lu : m->level = %i : owner = %lu -> %lu [ relock = %i ]", + SCM_UNPACK( mutex ), SCM_UNPACK( t->handle ), m->level, SCM_UNPACK( owner ), SCM_UNPACK( m->owner ), relock ); } scm_i_pthread_mutex_unlock (&m->lock);