diff mbox

[RFC] Fixing pthread_* namespace issues for thrd_* symbols

Message ID CAD82F-qqRsNwymfdXOEuHRGedBq1SjtqgjZO5poyDDzExRs0_g@mail.gmail.com
State New
Headers show

Commit Message

Juan Manuel Torres Palma June 18, 2015, 7:56 a.m. UTC
Sorry for late reply.

My solution so far is this one, only for x86, will work on other
architectures as long as this strategy is acceptable. What I have
mainly done is copy pthread_mutex_t and pthread_cond_t renaming them,
so I won't be breaking any ABI and namespaces will be clean. Let me
know if it's acceptable.

Cheers.

--------------------------------------------------------------------------------------------------------------------------------------------

From 73f2aee3c1fc299c73607d23a49d75fefc72ad75 Mon Sep 17 00:00:00 2001
From: Juan Manuel Torres Palma <jmtorrespalma@gmail.com>
Date: Thu, 18 Jun 2015 09:48:19 +0200
Subject: [PATCH] New threads.h types

---
 nptl/Makefile                   |   3 +-
 sysdeps/x86/bits/threadstypes.h | 116 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 118 insertions(+), 1 deletion(-)
 create mode 100644 sysdeps/x86/bits/threadstypes.h

Comments

Joseph Myers June 18, 2015, 2:12 p.m. UTC | #1
On Thu, 18 Jun 2015, Juan Manuel Torres Palma wrote:

> Sorry for late reply.
> 
> My solution so far is this one, only for x86, will work on other
> architectures as long as this strategy is acceptable. What I have
> mainly done is copy pthread_mutex_t and pthread_cond_t renaming them,
> so I won't be breaking any ABI and namespaces will be clean. Let me
> know if it's acceptable.

Contents shouldn't be duplicated, but you could e.g. have a shared header 
that defines macros such as __PTHREAD_COND_T_CONTENT, so cnd_t would be

typedef union
{
  __PTHREAD_COND_T_CONTENT
} cnd_t;

and pthread_cond_t similarly.
Torvald Riegel June 18, 2015, 4:20 p.m. UTC | #2
On Thu, 2015-06-18 at 14:12 +0000, Joseph Myers wrote:
> On Thu, 18 Jun 2015, Juan Manuel Torres Palma wrote:
> 
> > Sorry for late reply.
> > 
> > My solution so far is this one, only for x86, will work on other
> > architectures as long as this strategy is acceptable. What I have
> > mainly done is copy pthread_mutex_t and pthread_cond_t renaming them,
> > so I won't be breaking any ABI and namespaces will be clean. Let me
> > know if it's acceptable.
> 
> Contents shouldn't be duplicated, but you could e.g. have a shared header 
> that defines macros such as __PTHREAD_COND_T_CONTENT, so cnd_t would be
> 
> typedef union
> {
>   __PTHREAD_COND_T_CONTENT
> } cnd_t;
> 
> and pthread_cond_t similarly.
> 

I'm still not convinced that we should just create thrd_* data
structures that are the same size as pthread_*, especially for mutex.
I'm aware we have discussed this before, and using the same size might
be considered a safe bet -- however, we certainly don't need a robust
mutex list pointer for C11, nor do we know that a larger pthread_* type
would be sufficiently large for whatever we might want to do in the
future with the thrd_* types.

Also, just copying the algorithms isn't ideal in every case.  For
example, C11 mutex has different semantics than various POSIX mutex
types, which affects lock elision:
https://sourceware.org/glibc/wiki/LockElisionGuide
Also, we don't need to distinguish between mtx_plain and mtx_timed, nor
between recursive and non-recursive, I believe.

condvar semantics are the same IIRC.  We could make the cnd_t struct
smaller than current pthread_cond_t, but that is probably not as
relevant for performance as in the case of mutex, which could be
embedded with the data they are supposed to protect.
Rich Felker June 18, 2015, 5:53 p.m. UTC | #3
On Thu, Jun 18, 2015 at 06:20:48PM +0200, Torvald Riegel wrote:
> On Thu, 2015-06-18 at 14:12 +0000, Joseph Myers wrote:
> > On Thu, 18 Jun 2015, Juan Manuel Torres Palma wrote:
> > 
> > > Sorry for late reply.
> > > 
> > > My solution so far is this one, only for x86, will work on other
> > > architectures as long as this strategy is acceptable. What I have
> > > mainly done is copy pthread_mutex_t and pthread_cond_t renaming them,
> > > so I won't be breaking any ABI and namespaces will be clean. Let me
> > > know if it's acceptable.
> > 
> > Contents shouldn't be duplicated, but you could e.g. have a shared header 
> > that defines macros such as __PTHREAD_COND_T_CONTENT, so cnd_t would be
> > 
> > typedef union
> > {
> >   __PTHREAD_COND_T_CONTENT
> > } cnd_t;
> > 
> > and pthread_cond_t similarly.
> > 
> 
> I'm still not convinced that we should just create thrd_* data
> structures that are the same size as pthread_*, especially for mutex.
> I'm aware we have discussed this before, and using the same size might
> be considered a safe bet -- however, we certainly don't need a robust
> mutex list pointer for C11, nor do we know that a larger pthread_* type
> would be sufficiently large for whatever we might want to do in the
> future with the thrd_* types.

Actually you _do_ need robust list pointers if the committee decides
that the behavior is well-defined when a thread exits with a recursive
mutex held. The only way to implement this efficiently is to have a
linked list of all mutexes the thread holds so that they can be
changed to a permanently-locked state immune to tid reuse. I think the
possibility of needing to make this change, even if you think it would
be an unwanted change now, is a _major_ argument for keeping the
same-sized structures.

Rich
Torvald Riegel June 18, 2015, 7:37 p.m. UTC | #4
On Thu, 2015-06-18 at 13:53 -0400, Rich Felker wrote:
> On Thu, Jun 18, 2015 at 06:20:48PM +0200, Torvald Riegel wrote:
> > On Thu, 2015-06-18 at 14:12 +0000, Joseph Myers wrote:
> > > On Thu, 18 Jun 2015, Juan Manuel Torres Palma wrote:
> > > 
> > > > Sorry for late reply.
> > > > 
> > > > My solution so far is this one, only for x86, will work on other
> > > > architectures as long as this strategy is acceptable. What I have
> > > > mainly done is copy pthread_mutex_t and pthread_cond_t renaming them,
> > > > so I won't be breaking any ABI and namespaces will be clean. Let me
> > > > know if it's acceptable.
> > > 
> > > Contents shouldn't be duplicated, but you could e.g. have a shared header 
> > > that defines macros such as __PTHREAD_COND_T_CONTENT, so cnd_t would be
> > > 
> > > typedef union
> > > {
> > >   __PTHREAD_COND_T_CONTENT
> > > } cnd_t;
> > > 
> > > and pthread_cond_t similarly.
> > > 
> > 
> > I'm still not convinced that we should just create thrd_* data
> > structures that are the same size as pthread_*, especially for mutex.
> > I'm aware we have discussed this before, and using the same size might
> > be considered a safe bet -- however, we certainly don't need a robust
> > mutex list pointer for C11, nor do we know that a larger pthread_* type
> > would be sufficiently large for whatever we might want to do in the
> > future with the thrd_* types.
> 
> Actually you _do_ need robust list pointers if the committee decides
> that the behavior is well-defined when a thread exits with a recursive
> mutex held. The only way to implement this efficiently is to have a
> linked list of all mutexes the thread holds so that they can be
> changed to a permanently-locked state immune to tid reuse. I think the
> possibility of needing to make this change, even if you think it would
> be an unwanted change now, is a _major_ argument for keeping the
> same-sized structures.

But that's just accidental.  There may be other potential changes to the
standard that we're not aware of right now, so we don't really know
whether the same size would be sufficient, less would be sufficient, or
we'd actually need a bigger structure.

Maybe we should let the committee clarify that before giving ABI
stability guarantees for mtx_t.
Rich Felker June 18, 2015, 8 p.m. UTC | #5
On Thu, Jun 18, 2015 at 09:37:05PM +0200, Torvald Riegel wrote:
> On Thu, 2015-06-18 at 13:53 -0400, Rich Felker wrote:
> > On Thu, Jun 18, 2015 at 06:20:48PM +0200, Torvald Riegel wrote:
> > > On Thu, 2015-06-18 at 14:12 +0000, Joseph Myers wrote:
> > > > On Thu, 18 Jun 2015, Juan Manuel Torres Palma wrote:
> > > > 
> > > > > Sorry for late reply.
> > > > > 
> > > > > My solution so far is this one, only for x86, will work on other
> > > > > architectures as long as this strategy is acceptable. What I have
> > > > > mainly done is copy pthread_mutex_t and pthread_cond_t renaming them,
> > > > > so I won't be breaking any ABI and namespaces will be clean. Let me
> > > > > know if it's acceptable.
> > > > 
> > > > Contents shouldn't be duplicated, but you could e.g. have a shared header 
> > > > that defines macros such as __PTHREAD_COND_T_CONTENT, so cnd_t would be
> > > > 
> > > > typedef union
> > > > {
> > > >   __PTHREAD_COND_T_CONTENT
> > > > } cnd_t;
> > > > 
> > > > and pthread_cond_t similarly.
> > > > 
> > > 
> > > I'm still not convinced that we should just create thrd_* data
> > > structures that are the same size as pthread_*, especially for mutex.
> > > I'm aware we have discussed this before, and using the same size might
> > > be considered a safe bet -- however, we certainly don't need a robust
> > > mutex list pointer for C11, nor do we know that a larger pthread_* type
> > > would be sufficiently large for whatever we might want to do in the
> > > future with the thrd_* types.
> > 
> > Actually you _do_ need robust list pointers if the committee decides
> > that the behavior is well-defined when a thread exits with a recursive
> > mutex held. The only way to implement this efficiently is to have a
> > linked list of all mutexes the thread holds so that they can be
> > changed to a permanently-locked state immune to tid reuse. I think the
> > possibility of needing to make this change, even if you think it would
> > be an unwanted change now, is a _major_ argument for keeping the
> > same-sized structures.
> 
> But that's just accidental.  There may be other potential changes to the

That's your view; I'm not clear what the committee's will be. But as
is, requiring the tracking would not be a change to the standard; it
would be sticking with the requirements of the standard-as-written
rather than considering those requirements a defect (which they may
be, as you think they are) and changing the text so that they're no
longer required.

> standard that we're not aware of right now, so we don't really know
> whether the same size would be sufficient, less would be sufficient, or
> we'd actually need a bigger structure.
> 
> Maybe we should let the committee clarify that before giving ABI
> stability guarantees for mtx_t.

I would just go with the already-discussed type sizes rather than
leaving C11 threads support pending indefinitely waiting for the
committee's response, but I agree it would be good to go ahead and try
to push the issue forward as a request for interpretation. Any such
request should cite the Austin Group issue (which was ruled the other
direction) so it's clear that you're asking for a license for C11
recursive-mutex semantics to be more relaxed/lest-costly to implement
versus POSIX ones.

Rich
diff mbox

Patch

diff --git a/nptl/Makefile b/nptl/Makefile
index 530d14b..1527134 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -22,7 +22,8 @@  subdir := nptl

 include ../Makeconfig

-headers := pthread.h semaphore.h bits/semaphore.h
+headers := pthread.h semaphore.h bits/semaphore.h \
+   bits/threadstypes.h

 extra-libs := libpthread
 extra-libs-others := $(extra-libs)
diff --git a/sysdeps/x86/bits/threadstypes.h b/sysdeps/x86/bits/threadstypes.h
new file mode 100644
index 0000000..6a7a68a
--- /dev/null
+++ b/sysdeps/x86/bits/threadstypes.h
@@ -0,0 +1,116 @@ 
+/* Copyright (C) 2002-2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C 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.
+
+   The GNU C 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 the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _BITS_THREADSTYPES_H
+#define _BITS_THREADSTYPES_H 1
+
+#include <bits/wordsize.h>
+
+
+#ifdef __x86_64__
+# if __WORDSIZE == 64
+#  define __SIZEOF_MTX_T 40
+#  define __SIZEOF_CND_T 48
+# else
+#  define __SIZEOF_MTX_T 32
+#  define __SIZEOF_CND_T 48
+# endif
+#else
+# define __SIZEOF_MTX_T 24
+# define __SIZEOF_CND_T 48
+#endif
+
+
+#ifdef __x86_64__
+typedef struct __pthread_internal_list
+{
+  struct __pthread_internal_list *__prev;
+  struct __pthread_internal_list *__next;
+} __pthread_list_t;
+#else
+typedef struct __pthread_internal_slist
+{
+  struct __pthread_internal_slist *__next;
+} __pthread_slist_t;
+#endif
+
+
+/* Data structure for C11 mtx_t. It's a copy of pthread_mutex_t to
+   make both types compatible*/
+
+typedef union
+{
+  struct __pthread_mutex_s
+  {
+    int __lock;
+    unsigned int __count;
+    int __owner;
+#ifdef __x86_64__
+    unsigned int __nusers;
+#endif
+    /* KIND must stay at this position in the structure to maintain
+       binary compatibility.  */
+    int __kind;
+#ifdef __x86_64__
+    short __spins;
+    short __elision;
+    __pthread_list_t __list;
+# define __PTHREAD_MUTEX_HAVE_PREV 1
+/* Mutex __spins initializer used by PTHREAD_MUTEX_INITIALIZER.  */
+# define __PTHREAD_SPINS             0, 0
+#else
+    unsigned int __nusers;
+    __extension__ union
+    {
+      struct
+      {
+ short __espins;
+ short __elision;
+# define __spins __elision_data.__espins
+# define __elision __elision_data.__elision
+# define __PTHREAD_SPINS         { 0, 0 }
+      } __elision_data;
+      __pthread_slist_t __list;
+    };
+#endif
+  } __data;
+  char __size[__SIZEOF_MTX_T];
+  long int __align;
+} pthread_mutex_t;
+
+
+/* Data structure for C11 cnd_t. A copy of pthread_cond_t
+   to make them compatible.  */
+
+typedef union
+{
+  struct
+  {
+    int __lock;
+    unsigned int __futex;
+    __extension__ unsigned long long int __total_seq;
+    __extension__ unsigned long long int __wakeup_seq;
+    __extension__ unsigned long long int __woken_seq;
+    void *__mutex;
+    unsigned int __nwaiters;
+    unsigned int __broadcast_seq;
+  } __data;
+  char __size[__SIZEOF_CND_T];
+  __extension__ long long int __align;
+} cnd_t;
+
+#endif /* bits/threadstypes.h */