wingo pushed a commit to branch wip-whippet
in repository guile.

commit 2162d2b7db3891c82639b93b685670db7f7e1a14
Author: Andy Wingo <wi...@pobox.com>
AuthorDate: Tue Jul 15 09:19:43 2025 +0200

    Move some port flag handling to ports-internal.h
    
    It was already private via BUILDING_LIBGUILE.
    
    * libguile/ports-internal.h (enum scm_port_flags): New type.
    (scm_port_tag_word, scm_port_has_flag, scm_port_set_flags): Atomic
    routines to check and update tag word.
    * libguile/ports.c (scm_i_finalize_port, scm_i_write_bytes): Use new
    routines to manage finalizing bit.
    * libguile/ports.h (SCM_PORT_FINALIZING_P, SCM_SET_PORT_FINALIZING):
    Remove internal definitions.
---
 libguile/ports-internal.h | 37 +++++++++++++++++++++++++++++++++++++
 libguile/ports.c          |  7 ++++---
 libguile/ports.h          |  9 ---------
 3 files changed, 41 insertions(+), 12 deletions(-)

diff --git a/libguile/ports-internal.h b/libguile/ports-internal.h
index fba84d10f..6ce76a690 100644
--- a/libguile/ports-internal.h
+++ b/libguile/ports-internal.h
@@ -24,6 +24,7 @@
 
 #include <assert.h>
 #include <iconv.h>
+#include <stdatomic.h>
 #include <string.h>
 
 #include "libguile/bytevectors.h"
@@ -335,6 +336,17 @@ scm_port_buffer_putback (SCM buf, const uint8_t *src, 
size_t count,
            src, count);
 }
 
+enum scm_port_flags {
+  SCM_F_PORT_OPEN = SCM_OPN,
+  SCM_F_PORT_READING = SCM_RDNG,
+  SCM_F_PORT_WRITING = SCM_WRTNG,
+  SCM_F_PORT_UNBUFFERED = SCM_BUF0,
+  SCM_F_PORT_LINE_BUFFERED = SCM_BUFLINE,
+
+ /* Port is being closed via GC. */
+  SCM_F_PORT_FINALIZING = SCM_F_PORT_LINE_BUFFERED << 1
+};
+
 struct scm_t_port
 {
   scm_t_bits tag_and_flags;
@@ -400,6 +412,31 @@ struct scm_t_port
   SCM alist;
 };
 
+static inline scm_t_bits
+scm_port_tag_word (struct scm_t_port *port)
+{
+  /* A relaxed load, because we want the compiler to be able to coalesce
+     multiple loads without intervening atomics.  */
+  return atomic_load_explicit ((_Atomic scm_t_bits*) &port->tag_and_flags,
+                               memory_order_relaxed);
+}
+
+static inline int
+scm_port_has_flag (struct scm_t_port *port, scm_t_bits flag)
+{
+  return (scm_port_tag_word (port) & flag) != 0;
+}
+
+static inline void
+scm_port_set_flags (struct scm_t_port *port, scm_t_bits flags)
+{
+  scm_t_bits tag_word = scm_port_tag_word (port);
+  while ((tag_word & flags) != flags)
+    if (atomic_compare_exchange_weak ((_Atomic scm_t_bits*) 
&port->tag_and_flags,
+                                      &tag_word, tag_word | flags))
+      return;
+}
+
 #define SCM_UNICODE_BOM  0xFEFFUL  /* Unicode byte-order mark */
 
 #define SCM_FILENAME(x)           (SCM_PORT (x)->file_name)
diff --git a/libguile/ports.c b/libguile/ports.c
index e83c5601b..de6a4e4cf 100644
--- a/libguile/ports.c
+++ b/libguile/ports.c
@@ -756,7 +756,7 @@ scm_i_finalize_port (struct scm_thread *thread, SCM port)
 
   if (SCM_OPENP (port))
     {
-      SCM_SET_PORT_FINALIZING (port);
+      scm_port_set_flags (scm_to_port (port), SCM_F_PORT_FINALIZING);
       close_port (port, 0);
       scm_gc_ports_collected++;
     }
@@ -2879,7 +2879,8 @@ static void
 scm_i_write_bytes (SCM port, SCM src, size_t start, size_t count)
 {
   size_t written = 0;
-  scm_t_port_type *ptob = SCM_PORT_TYPE (port);
+  scm_t_port *p = SCM_PORT (port);
+  scm_t_port_type *ptob = p->ptob;
 
   if (count > SCM_BYTEVECTOR_LENGTH (src))
     fprintf (stderr, "count: %zu %zu\n", count, scm_c_bytevector_length (src));
@@ -2895,7 +2896,7 @@ scm_i_write_bytes (SCM port, SCM src, size_t start, 
size_t count)
 
       if (ret == (size_t) -1)
         {
-          if (SCM_PORT_FINALIZING_P (port))
+          if (scm_port_has_flag (p, SCM_F_PORT_FINALIZING))
             {
               /* This port is being closed because it became unreachable
                  and was finalized, but it has buffered output, and the
diff --git a/libguile/ports.h b/libguile/ports.h
index f55604772..322079e42 100644
--- a/libguile/ports.h
+++ b/libguile/ports.h
@@ -40,9 +40,6 @@
 #define SCM_WRTNG      (1U<<10) /* Is it writable? */
 #define SCM_BUF0       (1U<<11) /* Is it unbuffered? */
 #define SCM_BUFLINE     (1U<<12) /* Is it line-buffered? */
-#ifdef BUILDING_LIBGUILE
-#define SCM_F_PORT_FINALIZING (1U<<13) /* Port is being closed via GC. */
-#endif
 
 #define SCM_PORTP(x) (SCM_HAS_TYP7 (x, scm_tc7_port))
 #define SCM_OPPORTP(x) (SCM_PORTP (x) && (SCM_CELL_WORD_0 (x) & SCM_OPN))
@@ -54,12 +51,6 @@
 #define SCM_CLOSEDP(x) (!SCM_OPENP (x))
 #define SCM_CLR_PORT_OPEN_FLAG(p) \
   SCM_SET_CELL_WORD_0 ((p), SCM_CELL_WORD_0 (p) & ~SCM_OPN)
-#ifdef BUILDING_LIBGUILE
-#define SCM_PORT_FINALIZING_P(x) \
-  (SCM_CELL_WORD_0 (x) & SCM_F_PORT_FINALIZING)
-#define SCM_SET_PORT_FINALIZING(p) \
-  SCM_SET_CELL_WORD_0 ((p), SCM_CELL_WORD_0 (p) | SCM_F_PORT_FINALIZING)
-#endif
 
 typedef struct scm_t_port_type scm_t_port_type;
 typedef struct scm_t_port scm_t_port;

Reply via email to