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;