summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--README.pretty-printers7
-rw-r--r--nptl/nptl-printers.py33
-rw-r--r--nptl/test-mutex-printers.py17
4 files changed, 43 insertions, 21 deletions
diff --git a/ChangeLog b/ChangeLog
index 47fccc7642..9573c5c4b2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2017-01-14  Martin Galvan  <martingalvan@sourceware.org>
+
+	* README.pretty-printers (Known issues): Warn about printers not
+	always covering everything.
+	* nptl/nptl-printers.py (MutexPrinter): Change output.
+	* nptl/test-mutex-printers.py: Fix test and adapt to changed output.
+
 2017-01-20  Stefan Liebler  <stli@linux.vnet.ibm.com>
 
 	* sysdeps/unix/sysv/linux/s390/htm.h: Adjust comments.
diff --git a/README.pretty-printers b/README.pretty-printers
index a2536cad80..2522cb858d 100644
--- a/README.pretty-printers
+++ b/README.pretty-printers
@@ -29,7 +29,7 @@ However, with a pretty printer gdb will output something like this:
 (gdb) print mutex
 $1 = pthread_mutex_t = {
   Type = Normal,
-  Status = Unlocked,
+  Status = Not acquired,
   Robust = No,
   Shared = No,
   Protocol = Priority protect,
@@ -145,6 +145,11 @@ any changes to the target code must also update the corresponding printers.
 On the plus side, the printer code itself may serve as a kind of documentation
 for the target code.
 
+* There's no guarantee that the information the pretty printers provide is
+complete, i.e. some details might be left off.  For example, the pthread_mutex_t
+printers won't report whether a thread is spin-waiting in an attempt to acquire
+the mutex.
+
 * Older versions of the gdb Python API have a bug where
 gdb.RegexpCollectionPrettyPrinter would not be able to get a value's real type
 if it was typedef'd.  This would cause gdb to ignore the pretty printers for
diff --git a/nptl/nptl-printers.py b/nptl/nptl-printers.py
index 9d67865577..572a25c32e 100644
--- a/nptl/nptl-printers.py
+++ b/nptl/nptl-printers.py
@@ -101,9 +101,9 @@ class MutexPrinter(object):
     def read_status(self):
         """Read the mutex's status.
 
-        For architectures which support lock elision, this method reads
-        whether the mutex appears as locked in memory (i.e. it may show it as
-        unlocked even after calling pthread_mutex_lock).
+        Architectures that support lock elision might not record the mutex owner
+        ID in the __owner field.  In that case, the owner will be reported as
+        "Unknown".
         """
 
         if self.kind == PTHREAD_MUTEX_DESTROYED:
@@ -124,13 +124,14 @@ class MutexPrinter(object):
         """
 
         if self.lock == PTHREAD_MUTEX_UNLOCKED:
-            self.values.append(('Status', 'Unlocked'))
+            self.values.append(('Status', 'Not acquired'))
         else:
             if self.lock & FUTEX_WAITERS:
-                self.values.append(('Status', 'Locked, possibly with waiters'))
+                self.values.append(('Status',
+                                    'Acquired, possibly with waiters'))
             else:
                 self.values.append(('Status',
-                                    'Locked, possibly with no waiters'))
+                                    'Acquired, possibly with no waiters'))
 
             if self.lock & FUTEX_OWNER_DIED:
                 self.values.append(('Owner ID', '%d (dead)' % self.owner))
@@ -147,7 +148,7 @@ class MutexPrinter(object):
     def read_status_no_robust(self):
         """Read the status of a non-robust mutex.
 
-        Read info on whether the mutex is locked, if it may have waiters
+        Read info on whether the mutex is acquired, if it may have waiters
         and its owner (if any).
         """
 
@@ -157,7 +158,7 @@ class MutexPrinter(object):
             lock_value &= ~(PTHREAD_MUTEX_PRIO_CEILING_MASK)
 
         if lock_value == PTHREAD_MUTEX_UNLOCKED:
-            self.values.append(('Status', 'Unlocked'))
+            self.values.append(('Status', 'Not acquired'))
         else:
             if self.kind & PTHREAD_MUTEX_PRIO_INHERIT_NP:
                 waiters = self.lock & FUTEX_WAITERS
@@ -168,12 +169,18 @@ class MutexPrinter(object):
                 owner = self.owner
 
             if waiters:
-                self.values.append(('Status', 'Locked, possibly with waiters'))
+                self.values.append(('Status',
+                                    'Acquired, possibly with waiters'))
             else:
                 self.values.append(('Status',
-                                    'Locked, possibly with no waiters'))
+                                    'Acquired, possibly with no waiters'))
 
-            self.values.append(('Owner ID', owner))
+            if self.owner != 0:
+                self.values.append(('Owner ID', owner))
+            else:
+                # Owner isn't recorded, probably because lock elision
+                # is enabled.
+                self.values.append(('Owner ID', 'Unknown'))
 
     def read_attributes(self):
         """Read the mutex's attributes."""
@@ -208,14 +215,14 @@ class MutexPrinter(object):
     def read_misc_info(self):
         """Read miscellaneous info on the mutex.
 
-        For now this reads the number of times a recursive mutex was locked
+        For now this reads the number of times a recursive mutex was acquired
         by the same thread.
         """
 
         mutex_type = self.kind & PTHREAD_MUTEX_KIND_MASK
 
         if mutex_type == PTHREAD_MUTEX_RECURSIVE and self.count > 1:
-            self.values.append(('Times locked recursively', self.count))
+            self.values.append(('Times acquired by the owner', self.count))
 
 class MutexAttributesPrinter(object):
     """Pretty printer for pthread_mutexattr_t.
diff --git a/nptl/test-mutex-printers.py b/nptl/test-mutex-printers.py
index 23f16b0b71..687a32c4f7 100644
--- a/nptl/test-mutex-printers.py
+++ b/nptl/test-mutex-printers.py
@@ -39,15 +39,18 @@ try:
 
     break_at(test_source, 'Test status (non-robust)')
     continue_cmd() # Go to test_status_no_robust
-    test_printer(var, to_string, {'Status': 'Unlocked'})
+    test_printer(var, to_string, {'Status': 'Not acquired'})
     next_cmd()
     thread_id = get_current_thread_lwpid()
-    test_printer(var, to_string, {'Status': 'Locked, possibly with no waiters',
-                                  'Owner ID': thread_id})
+    # Owner ID might be reported either as the thread ID or as "Unknown"
+    # (if e.g. lock elision is enabled).
+    test_printer(var, to_string,
+                 {'Status': 'Acquired, possibly with no waiters',
+                  'Owner ID': r'({0}|Unknown)'.format(thread_id)})
 
     break_at(test_source, 'Test status (robust)')
     continue_cmd() # Go to test_status_robust
-    test_printer(var, to_string, {'Status': 'Unlocked'})
+    test_printer(var, to_string, {'Status': 'Not acquired'})
 
     # We'll now test the robust mutex locking states.  We'll create a new
     # thread that will lock a robust mutex and exit without unlocking it.
@@ -75,15 +78,15 @@ try:
     test_printer(var, to_string, {'Owner ID': thread_id,
                            'State protected by this mutex': 'Inconsistent'})
     next_cmd()
-    test_printer(var, to_string, {'Status': 'Unlocked',
+    test_printer(var, to_string, {'Status': 'Not acquired',
                         'State protected by this mutex': 'Not recoverable'})
     set_scheduler_locking(False)
 
     break_at(test_source, 'Test recursive locks')
     continue_cmd() # Go to test_recursive_locks
-    test_printer(var, to_string, {'Times locked recursively': '2'})
+    test_printer(var, to_string, {'Times acquired by the owner': '2'})
     next_cmd()
-    test_printer(var, to_string, {'Times locked recursively': '3'})
+    test_printer(var, to_string, {'Times acquired by the owner': '3'})
     continue_cmd() # Exit
 
 except (NoLineError, pexpect.TIMEOUT) as exception: