[libfortran] Restore bootstrap on FreeBSD (hopefully)

Message ID 2eaedfee-b767-4405-8a52-6a5393dab7d3@tkoenig.net
State New
Headers
Series [libfortran] Restore bootstrap on FreeBSD (hopefully) |

Commit Message

Thomas König Jan. 9, 2026, 7:57 p.m. UTC
  As analyzed by Steve, on freebsd __gthread_t is a pointer type.
I thought it the cleanest solution to remove the #ifdef in gfc_unit,
make the "self" member a intptr_t and cast the return value of
__gthread_t to that type.

Sorry for breaking bootstrap... the ubiquity of Linux is really
striking here. There are a couple of

Regression-tested on Linux.  FreeBSD should also work, but I'd
like confirmation, if possible. Steve, could you be so kind?

OK for trunk?

Best regards

	Thomas

PR fortran/123512

libgfortran/ChangeLog:

	* io/io.h: Change type of self to intptr_t.
	* io/async.h (LOCK_UNIT): Cast __gthread_self () to intptr_t.
	(TRYLOCK_UNIT): Likewise.
	(OWN_THREAD_ID): Likewise.
  

Comments

Steve Kargl Jan. 9, 2026, 8:55 p.m. UTC | #1
On Fri, Jan 09, 2026 at 08:57:25PM +0100, Thomas König wrote:
> As analyzed by Steve, on freebsd __gthread_t is a pointer type.
> I thought it the cleanest solution to remove the #ifdef in gfc_unit,
> make the "self" member a intptr_t and cast the return value of
> __gthread_t to that type.
> 
> Sorry for breaking bootstrap... the ubiquity of Linux is really
> striking here. There are a couple of
> 
> Regression-tested on Linux.  FreeBSD should also work, but I'd
> like confirmation, if possible. Steve, could you be so kind?
> 
> OK for trunk?
> 

Fixes bootstrap and regression tests cleanly.  Ok to commit.

Nothing to be sorry about!  Things can break
at the top-of-tree.  Plus, I learned something,
from the linux pthread_self() man page:

  POSIX.1 allows an implementation wide freedom in choosing the type
  used to represent a thread ID; for example, representation using
  either an arithmetic type or a structure is permitted.  Therefore,
  variables of type pthread_t can't portably be compared using the C
  equality operator (==); use pthread_equal(3) instead.

  Thread identifiers should be considered opaque: any attempt to use
  a thread ID other than in pthreads calls is nonportable and can
  lead to unspecified results.
  
Thomas König Jan. 9, 2026, 9:07 p.m. UTC | #2
Am 09.01.26 um 20:57 schrieb Thomas König:
> Regression-tested on Linux.  FreeBSD should also work, but I'd
> like confirmation, if possible. Steve, could you be so kind?

Committed as r16-6670-g0a98b1a6ac91cb1aa0f89f7dcdb9c35daa88c2a1
after Steve's OK. Thanks for the review!

Best regards

	Thomas
  
Rainer Orth Jan. 10, 2026, 8:50 a.m. UTC | #3
Hi Thomas,

> Am 09.01.26 um 20:57 schrieb Thomas König:
>> Regression-tested on Linux.  FreeBSD should also work, but I'd
>> like confirmation, if possible. Steve, could you be so kind?
>
> Committed as r16-6670-g0a98b1a6ac91cb1aa0f89f7dcdb9c35daa88c2a1
> after Steve's OK. Thanks for the review!

FWIW, this patch also fixed the Darwin bootstrap.

Thanks.
	Rainer
  

Patch

diff --git a/libgfortran/io/async.h b/libgfortran/io/async.h
index 265f248950d..03f0546868a 100644
--- a/libgfortran/io/async.h
+++ b/libgfortran/io/async.h
@@ -246,11 +246,11 @@ 
   } while (0)
 
 
 #define LOCK_UNIT(unit) do {		\
     LOCK (&(unit)->lock);		\
-    (unit)->self = __gthread_self ();	\
+    (unit)->self = (intptr_t) __gthread_self ();	\
   } while (0)
 
 #ifdef __GTHREAD_RWLOCK_INIT
 #define RWLOCK_DEBUG_ADD(rwlock) do {		\
     aio_rwlock_debug *n;				\
@@ -388,15 +388,15 @@ 
 
 /* When pthreads are not active, we do not touch the lock for locking /
    unlocking; the only use for this is checking for recursion.  */
 
 #define LOCK_UNIT(unit) do {					\
-  if (__gthread_active_p ()) {					\
-    LOCK (&(unit)->lock); (unit)->self = __gthread_self ();	\
-  } else {							\
-    (unit)->self = 1;						\
-  }								\
+    if (__gthread_active_p ()) {					\
+      LOCK (&(unit)->lock); (unit)->self = (intptr_t) __gthread_self (); \
+    } else {								\
+      (unit)->self = 1;							\
+    }									\
   } while(0)
 #else
 
 #define LOCK_UNIT(unit) do { \
     (unit)->self = 1;	     \
@@ -428,11 +428,11 @@ 
 #define TRYLOCK_UNIT(unit) ({					\
       int res;							\
       if (__gthread_active_p ()) {				\
 	res = __gthread_mutex_trylock (&(unit)->lock);		\
 	if (!res)						\
-	  (unit)->self = __gthread_self ();			\
+	  (unit)->self = (intptr_t) __gthread_self ();		\
       }								\
       else {							\
 	res = (unit)->self;					\
 	(unit)->self = 1;					\
       }								\
@@ -553,11 +553,11 @@  extern __thread gfc_unit *thread_unit;
 
 /* When threading is not active, or there is no thread system, we fake the ID
    to be 1.  */
 
 #ifdef __GTHREADS_CXX0X
-#define OWN_THREAD_ID (__gthread_active_p () ? __gthread_self () : 1)
+#define OWN_THREAD_ID (__gthread_active_p () ? (intptr_t) __gthread_self () : 1)
 #else
 #define OWN_THREAD_ID 1
 #endif
 
 enum aio_do {
diff --git a/libgfortran/io/io.h b/libgfortran/io/io.h
index 029fb6b9414..0458003765f 100644
--- a/libgfortran/io/io.h
+++ b/libgfortran/io/io.h
@@ -726,15 +726,11 @@  typedef struct gfc_unit
      are an unsigned char, EOF, or EOF - 1 used to mark the
      field as not valid.  */
   int last_char;
   bool has_size;
   GFC_IO_INT size_used;
-#ifdef __GTHREADS_CXX0X
-  __gthread_t self;
-#else
-  int self;
-#endif
+  intptr_t self;
 }
 gfc_unit;
 
 typedef struct gfc_saved_unit
 {