#endif
-/******************************************************************************/
-/* DEBUGGING MACROS */
-/******************************************************************************/
-
-/* #define LOCK_VERBOSE */
-
-#if defined(LOCK_VERBOSE)
-#define LOCK_LOG(args) do { printf args; fflush(stdout); } while (0)
+/* debug **********************************************************************/
+
+#if !defined(NDEBUG)
+# define DEBUGLOCKS(format) \
+ do { \
+ if (opt_DebugLocks) { \
+ log_println format; \
+ } \
+ } while (0)
#else
-#define LOCK_LOG(args)
+# define DEBUGLOCKS(format)
#endif
pthread_mutex_init(&(lr->mutex), NULL);
+ DEBUGLOCKS(("[lock_record_new : lr=%p]", (void *) lr));
+
return lr;
}
static void lock_record_free(lock_record_t *lr)
{
+ DEBUGLOCKS(("[lock_record_free : lr=%p]", (void *) lr));
+
/* Destroy the mutex. */
pthread_mutex_destroy(&(lr->mutex));
oldsize = lock_hashtable.size;
newsize = oldsize*2 + 1; /* XXX should use prime numbers */
- LOCK_LOG(("growing lock hashtable to size %d\n", newsize));
+ DEBUGLOCKS(("growing lock hashtable to size %d", newsize));
oldtable = lock_hashtable.ptr;
newtable = MNEW(lock_record_t *, newsize);
GC_REGISTER_FINALIZER(o, lock_record_finalizer, 0, 0, 0);
#endif
- LOCK_LOG(("thread %d allocated for %p new lr %p\n",
- t->index, (void*) o, (void*) lr));
-
/* enter it in the hashtable */
lr->hashlink = lock_hashtable.ptr[slot];
lr->count = (lockword & THIN_LOCK_COUNT_MASK) >> THIN_LOCK_COUNT_SHIFT;
}
- LOCK_LOG(("thread %3d: inflating lock of object %p current lockword %lx, count %d\n",
- t->index, (void*) o, (long)o->monitorPtr, (int)lr->count));
+ DEBUGLOCKS(("[lock_inflate : lr=%p, t=%p, o=%p, o->monitorPtr=%lx, count=%d]",
+ lr, t, o, o->monitorPtr, lr->count));
/* clear flat-lock-contention bit */
LOCK_SET_FLC_BIT(o);
- LOCK_LOG(("thread %d set flc bit on %p lr %p\n",
- t->index, (void*) o, (void*) lr));
+ DEBUGLOCKS(("thread %d set flc bit on %p lr %p",
+ t->index, (void*) o, (void*) lr));
/* try to lock the object */
if (COMPARE_AND_SWAP_SUCCEEDS(&(o->monitorPtr), THIN_UNLOCKED, thinlock)) {
/* we can inflate the lock ourselves */
- LOCK_LOG(("thread %d inflating lock of %p to lr %p\n",
- t->index, (void*) o, (void*) lr));
+ DEBUGLOCKS(("thread %d inflating lock of %p to lr %p",
+ t->index, (void*) o, (void*) lr));
lock_inflate(t, o, lr);
}
else {
- /* wait until another thread sees the flc bit and notifies
- us of unlocking */
-
- LOCK_LOG(("thread %d waiting for notification on %p lr %p\n",
- t->index, (void*) o, (void*) lr));
+ /* Wait until another thread sees the flc bit and notifies
+ us of unlocking. */
(void) lock_record_wait(t, lr, 0, 0);
}
if (LOCK_TEST_FLC_BIT(o)) {
lock_record_t *lr;
- LOCK_LOG(("thread %d saw flc bit on %p %s\n",
- t->index, (void*) o, o->vftbl->class->name->text));
+ DEBUGLOCKS(("thread %d saw flc bit on %p",
+ t->index, (void*) o));
/* there has been a contention on this thin lock */
lr = lock_hashtable_get(o);
- LOCK_LOG(("thread %d for %p got lr %p\n",
- t->index, (void*) o, (void*) lr));
+ DEBUGLOCKS(("thread %d for %p got lr %p",
+ t->index, (void*) o, (void*) lr));
lock_record_enter(t, lr);
s4 lockcount;
bool wasinterrupted;
+ DEBUGLOCKS(("[lock_record_wait : lr=%p, t=%p, millis=%lld, nanos=%d]",
+ lr, thread, millis, nanos));
+
/* { the thread t owns the fat lock record lr on the object o } */
/* register us as waiter for this object */
pthread_mutex_lock(&(waitingthread->waitmutex));
+ DEBUGLOCKS(("[lock_record_notify: lr=%p, t=%p, waitingthread=%p, sleeping=%d, one=%d]",
+ lr, t, waitingthread, waitingthread->sleeping, one));
+
/* Signal the thread if it's sleeping. */
if (waitingthread->sleeping)
/* NOTE: For better readability keep these alpha-sorted. */
int opt_DebugExceptions = 0;
+int opt_DebugLocks = 0;
int opt_DebugPatcher = 0;
int opt_DebugProperties = 0;
int32_t opt_DebugStackFrameInfo = 0;
enum {
OPT_DebugExceptions,
+ OPT_DebugLocks,
OPT_DebugPatcher,
OPT_DebugProperties,
OPT_DebugStackFrameInfo,
option_t options_XX[] = {
{ "DebugExceptions", OPT_DebugExceptions, OPT_TYPE_BOOLEAN, "debug exceptions" },
+ { "DebugLocks", OPT_DebugLocks, OPT_TYPE_BOOLEAN, "print debug information for locks" },
{ "DebugPatcher", OPT_DebugPatcher, OPT_TYPE_BOOLEAN, "debug JIT code patching" },
{ "DebugProperties", OPT_DebugProperties, OPT_TYPE_BOOLEAN, "print debug information for properties" },
{ "DebugStackFrameInfo", OPT_DebugStackFrameInfo, OPT_TYPE_BOOLEAN, "TODO" },
opt_DebugExceptions = enable;
break;
+ case OPT_DebugLocks:
+ opt_DebugLocks = enable;
+ break;
+
case OPT_DebugPatcher:
opt_DebugPatcher = enable;
break;