Hello,

I'm about to drop the following local patch as it didn't help me much
so far to help diagnose an occasional lock that ECL occasionally
experience under high load (where all threads end up parked or
yielding, so possibly some deadlock situation).

I thought I'd post it here in case you think some of these changes
should be in the official tree (basically, it adds logs for mutex lock
operations, extending the functionality that existed for condition
variables, and it's perhaps even too verbose).
-- 
Matt
diff --git a/src/c/threads/mutex.d b/src/c/threads/mutex.d
index cdd91a1..07b4a5d 100755
--- a/src/c/threads/mutex.d
+++ b/src/c/threads/mutex.d
@@ -23,6 +23,21 @@
  * LOCKS or MUTEX
  */
 
+static char *
+lock_name(cl_object lock)
+{
+       char *name = "NIL";
+       cl_object cl_name = lock->lock.name;
+
+       if (cl_name != ECL_NIL) {
+               cl_name = cl_string(cl_name);
+               name = ecl_base_string_pointer_safe(
+                   si_copy_to_simple_base_string(cl_name));
+       }
+
+       return name;
+}
+
 static void
 FEerror_not_a_lock(cl_object lock)
 {
@@ -103,6 +118,8 @@ mp_lock_count(cl_object lock)
 cl_object
 mp_giveup_lock(cl_object lock)
 {
+       print_lock("Unlocking lock %p (%s)\t", lock, lock,
+                  lock_name(lock));
         /* Must be called with interrupts disabled. */
         cl_env_ptr env = ecl_process_env();
        cl_object own_process = env->own_process;
@@ -117,11 +134,17 @@ mp_giveup_lock(cl_object lock)
                if (first == ECL_NIL) {
                        lock->lock.owner = ECL_NIL;
                } else {
+                       print_lock("Transfering lock %p (%s) from %p to %p\t",
+                                  lock, lock, lock_name(lock),
+                                  own_process, first);
                        lock->lock.counter = 1;
                        lock->lock.owner = first;
                        ecl_wakeup_process(first);
                }
-       } 
+       } else if (lock->lock.counter < 0) {
+               print_lock("Warning, lock %p (%s) has negative count!\t",
+                          lock, lock, lock_name(lock));
+       }
         ecl_return1(env, ECL_T);
 }
 
@@ -135,16 +158,19 @@ get_lock_inner(cl_env_ptr env, cl_object lock)
                                     (AO_t)ECL_NIL, (AO_t)own_process)) {
                lock->lock.counter = 1;
                output = ECL_T;
-               print_lock("acquired %p\t", lock, lock);
+               print_lock("Acquired lock %p (%s)\t", lock, lock,
+                          lock_name(lock));
        } else if (lock->lock.owner == own_process) {
                 unlikely_if (!lock->lock.recursive) {
                        FEerror_not_a_recursive_lock(lock);
                }
                 ++lock->lock.counter;
                output = ECL_T;
+               print_lock("Acquired lock %p (%s) recursively\t", lock, lock,
+                          lock_name(lock));
         } else {
-               print_lock("failed acquiring %p for %d\t", lock, lock,
-                          lock->lock.owner);
+               print_lock("Failed acquiring lock %p (%s) for %d\t", lock, lock,
+                          lock_name(lock), lock->lock.owner);
                output = ECL_NIL;
        }
        ecl_enable_interrupts_env(env);
@@ -171,7 +197,8 @@ own_or_get_lock(cl_env_ptr env, cl_object lock)
                                     (AO_t)ECL_NIL, (AO_t)own_process)) {
                lock->lock.counter = 1;
                output = ECL_T;
-               print_lock("acquired %p\t", lock, lock);
+               print_lock("Acquired lock %p (%s)\t", lock, lock,
+                          lock_name(lock));
        } else if (lock->lock.owner == own_process) {
                output = ECL_T;
         } else {
@@ -189,6 +216,8 @@ mp_get_lock_wait(cl_object lock)
                FEerror_not_a_lock(lock);
        }
        if (get_lock_inner(env, lock) == ECL_NIL) {
+               print_lock("Waiting on lock %p (%s)\t", lock, lock,
+                          lock_name(lock));
                ecl_wait_on(env, own_or_get_lock, lock);
        }
        @(return ECL_T)
@@ -196,6 +225,8 @@ mp_get_lock_wait(cl_object lock)
 
 @(defun mp::get-lock (lock &optional (wait ECL_T))
 @
+       print_lock("Attempting to lock %p (%s)\t", lock, lock,
+                  lock_name(lock));
        if (Null(wait))
                return mp_get_lock_nowait(lock);
         else
diff --git a/src/c/threads/queue.d b/src/c/threads/queue.d
index 7aad83b..b4786ff 100755
--- a/src/c/threads/queue.d
+++ b/src/c/threads/queue.d
@@ -364,7 +364,7 @@ ecl_wakeup_waiters(cl_env_ptr the_env, cl_object q, int 
flags)
        ecl_process_yield();
 }
 
-#undef print_lock
+/*#undef print_lock*/
 
 void
 print_lock(char *prefix, cl_object l, ...)
@@ -374,10 +374,11 @@ print_lock(char *prefix, cl_object l, ...)
        va_start(args, l);
        if (l == ECL_NIL
            || type_of(l) == t_condition_variable
+           || type_of(l) == t_lock
            || ECL_FIXNUMP(l->lock.name)) {
                cl_env_ptr env = ecl_process_env();
                ecl_get_spinlock(env, &lock);
-               printf("\n%ld\t", ecl_fixnum(env->own_process->process.name));
+               printf("\n%p\t", env->own_process);
                vprintf(prefix, args);
                if (l != ECL_NIL) {
                        cl_object p = l->lock.queue_list;
diff --git a/src/h/internal.h b/src/h/internal.h
index b6d3b97..a9b260d 100755
--- a/src/h/internal.h
+++ b/src/h/internal.h
@@ -489,7 +489,7 @@ extern cl_fixnum ecl_runtime(void);
 #ifdef ECL_THREADS
 extern void ecl_process_yield(void);
 extern void print_lock(char *s, cl_object lock, ...);
-#define print_lock(a,b,...) ((void)0)
+/*#define print_lock(a,b,...) ((void)0)*/
 extern void ecl_get_spinlock(cl_env_ptr env, cl_object *lock);
 extern void ecl_giveup_spinlock(cl_object *lock);
 extern cl_object ecl_wait_on(cl_env_ptr env, cl_object 
(*condition)(cl_env_ptr, cl_object), cl_object o);
------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_sfd2d_oct
_______________________________________________
Ecls-list mailing list
Ecls-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ecls-list

Reply via email to