summaryrefslogtreecommitdiff
path: root/debian/patches/0001-libshouldbeinlibc-move-the-reference-counting-primit.patch
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches/0001-libshouldbeinlibc-move-the-reference-counting-primit.patch')
-rw-r--r--debian/patches/0001-libshouldbeinlibc-move-the-reference-counting-primit.patch733
1 files changed, 0 insertions, 733 deletions
diff --git a/debian/patches/0001-libshouldbeinlibc-move-the-reference-counting-primit.patch b/debian/patches/0001-libshouldbeinlibc-move-the-reference-counting-primit.patch
deleted file mode 100644
index da210e9b..00000000
--- a/debian/patches/0001-libshouldbeinlibc-move-the-reference-counting-primit.patch
+++ /dev/null
@@ -1,733 +0,0 @@
-From 0d3b80f04a1caee51b9995c9626838f85295bb06 Mon Sep 17 00:00:00 2001
-From: Justus Winter <4winter@informatik.uni-hamburg.de>
-Date: Sun, 23 Nov 2014 19:09:51 +0100
-Subject: [PATCH hurd 01/28] libshouldbeinlibc: move the reference counting
- primitives here
-
-Declare all functions `extern inline' instead of `static inline'.
-This allows us to use them in functions declared as `extern inline'.
-
-* libshouldbeinlibc/refcount.h: Move here, and declare all functions
-`extern inline'.
-* libshouldbeinlibc/refcount.c: And define the functions here.
-* libshouldbeinlibc/Makefile: Add `refcount.{c,h}'.
----
- include/refcount.h | 320 ------------------------------------------
- libshouldbeinlibc/Makefile | 8 +-
- libshouldbeinlibc/refcount.c | 23 +++
- libshouldbeinlibc/refcount.h | 326 +++++++++++++++++++++++++++++++++++++++++++
- 4 files changed, 355 insertions(+), 322 deletions(-)
- delete mode 100644 include/refcount.h
- create mode 100644 libshouldbeinlibc/refcount.c
- create mode 100644 libshouldbeinlibc/refcount.h
-
-diff --git a/include/refcount.h b/include/refcount.h
-deleted file mode 100644
-index ebde42d..0000000
---- a/include/refcount.h
-+++ /dev/null
-@@ -1,320 +0,0 @@
--/* Lock-less reference counting primitives
--
-- Copyright (C) 2014 Free Software Foundation, Inc.
--
-- Written by Justus Winter <4winter@informatik.uni-hamburg.de>
--
-- This file is part of the GNU Hurd.
--
-- The GNU Hurd is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License as
-- published by the Free Software Foundation; either version 2, or (at
-- your option) any later version.
--
-- The GNU Hurd 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
-- General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>. */
--
--#ifndef _HURD_REFCOUNT_H_
--#define _HURD_REFCOUNT_H_
--
--#include <assert.h>
--#include <limits.h>
--#include <stdint.h>
--
--/* Simple reference counting. */
--
--/* An opaque type. You must not access these values directly. */
--typedef unsigned int refcount_t;
--
--/* Initialize REF with REFERENCES. REFERENCES must not be zero. */
--static inline void
--refcount_init (refcount_t *ref, unsigned int references)
--{
-- assert (references > 0 || !"references must not be zero!");
-- *ref = references;
--}
--
--/* Increment REF. Return the result of the operation. This function
-- uses atomic operations. It is not required to serialize calls to
-- this function.
--
-- This is the unsafe version of refcount_ref. refcount_ref also
-- checks for use-after-free errors. When in doubt, use that one
-- instead. */
--static inline unsigned int
--refcount_unsafe_ref (refcount_t *ref)
--{
-- unsigned int r;
-- r = __atomic_add_fetch (ref, 1, __ATOMIC_RELAXED);
-- assert (r != UINT_MAX || !"refcount overflowed!");
-- return r;
--}
--
--/* Increment REF. Return the result of the operation. This function
-- uses atomic operations. It is not required to serialize calls to
-- this function. */
--static inline unsigned int
--refcount_ref (refcount_t *ref)
--{
-- unsigned int r;
-- r = refcount_unsafe_ref (ref);
-- assert (r != 1 || !"refcount detected use-after-free!");
-- return r;
--}
--
--/* Decrement REF. Return the result of the operation. This function
-- uses atomic operations. It is not required to serialize calls to
-- this function. */
--static inline unsigned int
--refcount_deref (refcount_t *ref)
--{
-- unsigned int r;
-- r = __atomic_sub_fetch (ref, 1, __ATOMIC_RELAXED);
-- assert (r != UINT_MAX || !"refcount underflowed!");
-- return r;
--}
--
--/* Return REF. This function uses atomic operations. It is not
-- required to serialize calls to this function. */
--static inline unsigned int
--refcount_references (refcount_t *ref)
--{
-- return __atomic_load_n (ref, __ATOMIC_RELAXED);
--}
--
--/* Reference counting with weak references. */
--
--/* An opaque type. You must not access these values directly. */
--typedef union _references refcounts_t;
--
--/* Instead, the functions manipulating refcounts_t values write the
-- results into this kind of objects. */
--struct references {
-- /* We chose the layout of this struct so that when it is used in the
-- union _references, the hard reference counts occupy the least
-- significant bits. We rely on this layout for atomic promotion
-- and demotion of references. See refcounts_promote and
-- refcounts_demote for details. */
--#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
-- uint32_t hard;
-- uint32_t weak;
--#else
-- uint32_t weak;
-- uint32_t hard;
--#endif
--};
--
--/* We use a union to convert struct reference values to uint64_t which
-- we can manipulate atomically. While this behavior is not
-- guaranteed by the C standard, it is supported by all major
-- compilers. */
--union _references {
-- struct references references;
-- uint64_t value;
--};
--
--/* Initialize REF with HARD and WEAK references. HARD and WEAK must
-- not both be zero. */
--static inline void
--refcounts_init (refcounts_t *ref, uint32_t hard, uint32_t weak)
--{
-- assert ((hard != 0 || weak != 0) || !"references must not both be zero!");
-- ref->references = (struct references) { .hard = hard, .weak = weak };
--}
--
--/* Increment the hard reference count of REF. If RESULT is not NULL,
-- the result of the operation is written there. This function uses
-- atomic operations. It is not required to serialize calls to this
-- function.
--
-- This is the unsafe version of refcounts_ref. refcounts_ref also
-- checks for use-after-free errors. When in doubt, use that one
-- instead. */
--static inline void
--refcounts_unsafe_ref (refcounts_t *ref, struct references *result)
--{
-- const union _references op = { .references = { .hard = 1 } };
-- union _references r;
-- r.value = __atomic_add_fetch (&ref->value, op.value, __ATOMIC_RELAXED);
-- assert (r.references.hard != UINT32_MAX || !"refcount overflowed!");
-- if (result)
-- *result = r.references;
--}
--
--/* Increment the hard reference count of REF. If RESULT is not NULL,
-- the result of the operation is written there. This function uses
-- atomic operations. It is not required to serialize calls to this
-- function. */
--static inline void
--refcounts_ref (refcounts_t *ref, struct references *result)
--{
-- struct references r;
-- refcounts_unsafe_ref (ref, &r);
-- assert (! (r.hard == 1 && r.weak == 0)
-- || !"refcount detected use-after-free!");
-- if (result)
-- *result = r;
--}
--
--/* Decrement the hard reference count of REF. If RESULT is not NULL,
-- the result of the operation is written there. This function uses
-- atomic operations. It is not required to serialize calls to this
-- function. */
--static inline void
--refcounts_deref (refcounts_t *ref, struct references *result)
--{
-- const union _references op = { .references = { .hard = 1 } };
-- union _references r;
-- r.value = __atomic_sub_fetch (&ref->value, op.value, __ATOMIC_RELAXED);
-- assert (r.references.hard != UINT32_MAX || !"refcount underflowed!");
-- if (result)
-- *result = r.references;
--}
--
--/* Promote a weak reference to a hard reference. If RESULT is not
-- NULL, the result of the operation is written there. This function
-- uses atomic operations. It is not required to serialize calls to
-- this function. */
--static inline void
--refcounts_promote (refcounts_t *ref, struct references *result)
--{
-- /* To promote a weak reference, we need to atomically subtract 1
-- from the weak reference count, and add 1 to the hard reference
-- count.
--
-- We can subtract by 1 by adding the two's complement of 1 = ~0 to
-- a fixed-width value, discarding the overflow.
--
-- We do the same in our uint64_t value, but we have chosen the
-- layout of struct references so that when it is used in the union
-- _references, the weak reference counts occupy the most
-- significant bits. When we add ~0 to the weak references, the
-- overflow will be discarded as unsigned arithmetic is modulo 2^n.
-- So we just add a hard reference. In combination, this is the
-- desired operation. */
-- const union _references op =
-- { .references = { .weak = ~0U, .hard = 1} };
-- union _references r;
-- r.value = __atomic_add_fetch (&ref->value, op.value, __ATOMIC_RELAXED);
-- assert (r.references.hard != UINT32_MAX || !"refcount overflowed!");
-- assert (r.references.weak != UINT32_MAX || !"refcount underflowed!");
-- if (result)
-- *result = r.references;
--}
--
--/* Demote a hard reference to a weak reference. If RESULT is not
-- NULL, the result of the operation is written there. This function
-- uses atomic operations. It is not required to serialize calls to
-- this function. */
--static inline void
--refcounts_demote (refcounts_t *ref, struct references *result)
--{
-- /* To demote a hard reference, we need to atomically subtract 1 from
-- the hard reference count, and add 1 to the weak reference count.
--
-- We can subtract by 1 by adding the two's complement of 1 = ~0 to
-- a fixed-width value, discarding the overflow.
--
-- We do the same in our uint64_t value, but we have chosen the
-- layout of struct references so that when it is used in the union
-- _references, the hard reference counts occupy the least
-- significant bits. When we add ~0 to the hard references, it will
-- overflow into the weak references. This is the desired
-- operation. */
-- const union _references op = { .references = { .hard = ~0U } };
-- union _references r;
-- r.value = __atomic_add_fetch (&ref->value, op.value, __ATOMIC_RELAXED);
-- assert (r.references.hard != UINT32_MAX || !"refcount underflowed!");
-- assert (r.references.weak != UINT32_MAX || !"refcount overflowed!");
-- if (result)
-- *result = r.references;
--}
--
--/* Increment the weak reference count of REF. If RESULT is not NULL,
-- the result of the operation is written there. This function uses
-- atomic operations. It is not required to serialize calls to this
-- function.
--
-- This is the unsafe version of refcounts_ref_weak.
-- refcounts_ref_weak also checks for use-after-free errors. When in
-- doubt, use that one instead. */
--static inline void
--refcounts_unsafe_ref_weak (refcounts_t *ref, struct references *result)
--{
-- const union _references op = { .references = { .weak = 1 } };
-- union _references r;
-- r.value = __atomic_add_fetch (&ref->value, op.value, __ATOMIC_RELAXED);
-- assert (r.references.weak != UINT32_MAX || !"refcount overflowed!");
-- if (result)
-- *result = r.references;
--}
--
--/* Increment the weak reference count of REF. If RESULT is not NULL,
-- the result of the operation is written there. This function uses
-- atomic operations. It is not required to serialize calls to this
-- function. */
--static inline void
--refcounts_ref_weak (refcounts_t *ref, struct references *result)
--{
-- struct references r;
-- refcounts_unsafe_ref_weak (ref, &r);
-- assert (! (r.hard == 0 && r.weak == 1)
-- || !"refcount detected use-after-free!");
-- if (result)
-- *result = r;
--}
--
--/* Decrement the weak reference count of REF. If RESULT is not NULL,
-- the result of the operation is written there. This function uses
-- atomic operations. It is not required to serialize calls to this
-- function. */
--static inline void
--refcounts_deref_weak (refcounts_t *ref, struct references *result)
--{
-- const union _references op = { .references = { .weak = 1 } };
-- union _references r;
-- r.value = __atomic_sub_fetch (&ref->value, op.value, __ATOMIC_RELAXED);
-- assert (r.references.weak != UINT32_MAX || !"refcount underflowed!");
-- if (result)
-- *result = r.references;
--}
--
--/* Store the current reference counts of REF in RESULT. This function
-- uses atomic operations. It is not required to serialize calls to
-- this function. */
--static inline void
--refcounts_references (refcounts_t *ref, struct references *result)
--{
-- union _references r;
-- r.value =__atomic_load_n (&ref->value, __ATOMIC_RELAXED);
-- *result = r.references;
--}
--
--/* Return the hard reference count of REF. This function uses atomic
-- operations. It is not required to serialize calls to this
-- function. */
--static inline uint32_t
--refcounts_hard_references (refcounts_t *ref)
--{
-- struct references result;
-- refcounts_references (ref, &result);
-- return result.hard;
--}
--
--/* Return the weak reference count of REF. This function uses atomic
-- operations. It is not required to serialize calls to this
-- function. */
--static inline uint32_t
--refcounts_weak_references (refcounts_t *ref)
--{
-- struct references result;
-- refcounts_references (ref, &result);
-- return result.weak;
--}
--
--#endif /* _HURD_REFCOUNT_H_ */
-diff --git a/libshouldbeinlibc/Makefile b/libshouldbeinlibc/Makefile
-index 14a7939..633d60e 100644
---- a/libshouldbeinlibc/Makefile
-+++ b/libshouldbeinlibc/Makefile
-@@ -27,9 +27,13 @@ SRCS = termsize.c timefmt.c exec-reauth.c maptime-funcs.c \
- idvec-impgids.c idvec-verify.c idvec-rep.c \
- ugids.c ugids-argp.c ugids-rep.c ugids-verify.c ugids-subtract.c \
- ugids-auth.c ugids-xinl.c ugids-merge.c ugids-imply.c ugids-posix.c \
-- ugids-verify-auth.c nullauth.c
-+ ugids-verify-auth.c nullauth.c \
-+ refcount.c \
-+
- installhdrs = idvec.h timefmt.h maptime.h \
-- wire.h portinfo.h portxlate.h cacheq.h ugids.h nullauth.h
-+ wire.h portinfo.h portxlate.h cacheq.h ugids.h nullauth.h \
-+ refcount.h \
-+
- installhdrsubdir = .
-
- OBJS = $(SRCS:.c=.o)
-diff --git a/libshouldbeinlibc/refcount.c b/libshouldbeinlibc/refcount.c
-new file mode 100644
-index 0000000..17e01c5
---- /dev/null
-+++ b/libshouldbeinlibc/refcount.c
-@@ -0,0 +1,23 @@
-+/* Lock-less reference counting primitives
-+
-+ Copyright (C) 2014 Free Software Foundation, Inc.
-+
-+ Written by Justus Winter <4winter@informatik.uni-hamburg.de>
-+
-+ This file is part of the GNU Hurd.
-+
-+ The GNU Hurd is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU General Public License as
-+ published by the Free Software Foundation; either version 2, or (at
-+ your option) any later version.
-+
-+ The GNU Hurd 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
-+ General Public License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>. */
-+
-+#define REFCOUNT_DEFINE_EI
-+#include "refcount.h"
-diff --git a/libshouldbeinlibc/refcount.h b/libshouldbeinlibc/refcount.h
-new file mode 100644
-index 0000000..e8b0f5b
---- /dev/null
-+++ b/libshouldbeinlibc/refcount.h
-@@ -0,0 +1,326 @@
-+/* Lock-less reference counting primitives
-+
-+ Copyright (C) 2014 Free Software Foundation, Inc.
-+
-+ Written by Justus Winter <4winter@informatik.uni-hamburg.de>
-+
-+ This file is part of the GNU Hurd.
-+
-+ The GNU Hurd is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU General Public License as
-+ published by the Free Software Foundation; either version 2, or (at
-+ your option) any later version.
-+
-+ The GNU Hurd 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
-+ General Public License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>. */
-+
-+#ifndef _HURD_REFCOUNT_H_
-+#define _HURD_REFCOUNT_H_
-+
-+#ifdef REFCOUNT_DEFINE_EI
-+#define REFCOUNT_EI
-+#else
-+#define REFCOUNT_EI __extern_inline
-+#endif
-+
-+#include <assert.h>
-+#include <limits.h>
-+#include <stdint.h>
-+
-+/* Simple reference counting. */
-+
-+/* An opaque type. You must not access these values directly. */
-+typedef unsigned int refcount_t;
-+
-+/* Initialize REF with REFERENCES. REFERENCES must not be zero. */
-+REFCOUNT_EI void
-+refcount_init (refcount_t *ref, unsigned int references)
-+{
-+ assert (references > 0 || !"references must not be zero!");
-+ *ref = references;
-+}
-+
-+/* Increment REF. Return the result of the operation. This function
-+ uses atomic operations. It is not required to serialize calls to
-+ this function.
-+
-+ This is the unsafe version of refcount_ref. refcount_ref also
-+ checks for use-after-free errors. When in doubt, use that one
-+ instead. */
-+REFCOUNT_EI unsigned int
-+refcount_unsafe_ref (refcount_t *ref)
-+{
-+ unsigned int r;
-+ r = __atomic_add_fetch (ref, 1, __ATOMIC_RELAXED);
-+ assert (r != UINT_MAX || !"refcount overflowed!");
-+ return r;
-+}
-+
-+/* Increment REF. Return the result of the operation. This function
-+ uses atomic operations. It is not required to serialize calls to
-+ this function. */
-+REFCOUNT_EI unsigned int
-+refcount_ref (refcount_t *ref)
-+{
-+ unsigned int r;
-+ r = refcount_unsafe_ref (ref);
-+ assert (r != 1 || !"refcount detected use-after-free!");
-+ return r;
-+}
-+
-+/* Decrement REF. Return the result of the operation. This function
-+ uses atomic operations. It is not required to serialize calls to
-+ this function. */
-+REFCOUNT_EI unsigned int
-+refcount_deref (refcount_t *ref)
-+{
-+ unsigned int r;
-+ r = __atomic_sub_fetch (ref, 1, __ATOMIC_RELAXED);
-+ assert (r != UINT_MAX || !"refcount underflowed!");
-+ return r;
-+}
-+
-+/* Return REF. This function uses atomic operations. It is not
-+ required to serialize calls to this function. */
-+REFCOUNT_EI unsigned int
-+refcount_references (refcount_t *ref)
-+{
-+ return __atomic_load_n (ref, __ATOMIC_RELAXED);
-+}
-+
-+/* Reference counting with weak references. */
-+
-+/* An opaque type. You must not access these values directly. */
-+typedef union _references refcounts_t;
-+
-+/* Instead, the functions manipulating refcounts_t values write the
-+ results into this kind of objects. */
-+struct references {
-+ /* We chose the layout of this struct so that when it is used in the
-+ union _references, the hard reference counts occupy the least
-+ significant bits. We rely on this layout for atomic promotion
-+ and demotion of references. See refcounts_promote and
-+ refcounts_demote for details. */
-+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
-+ uint32_t hard;
-+ uint32_t weak;
-+#else
-+ uint32_t weak;
-+ uint32_t hard;
-+#endif
-+};
-+
-+/* We use a union to convert struct reference values to uint64_t which
-+ we can manipulate atomically. While this behavior is not
-+ guaranteed by the C standard, it is supported by all major
-+ compilers. */
-+union _references {
-+ struct references references;
-+ uint64_t value;
-+};
-+
-+/* Initialize REF with HARD and WEAK references. HARD and WEAK must
-+ not both be zero. */
-+REFCOUNT_EI void
-+refcounts_init (refcounts_t *ref, uint32_t hard, uint32_t weak)
-+{
-+ assert ((hard != 0 || weak != 0) || !"references must not both be zero!");
-+ ref->references = (struct references) { .hard = hard, .weak = weak };
-+}
-+
-+/* Increment the hard reference count of REF. If RESULT is not NULL,
-+ the result of the operation is written there. This function uses
-+ atomic operations. It is not required to serialize calls to this
-+ function.
-+
-+ This is the unsafe version of refcounts_ref. refcounts_ref also
-+ checks for use-after-free errors. When in doubt, use that one
-+ instead. */
-+REFCOUNT_EI void
-+refcounts_unsafe_ref (refcounts_t *ref, struct references *result)
-+{
-+ const union _references op = { .references = { .hard = 1 } };
-+ union _references r;
-+ r.value = __atomic_add_fetch (&ref->value, op.value, __ATOMIC_RELAXED);
-+ assert (r.references.hard != UINT32_MAX || !"refcount overflowed!");
-+ if (result)
-+ *result = r.references;
-+}
-+
-+/* Increment the hard reference count of REF. If RESULT is not NULL,
-+ the result of the operation is written there. This function uses
-+ atomic operations. It is not required to serialize calls to this
-+ function. */
-+REFCOUNT_EI void
-+refcounts_ref (refcounts_t *ref, struct references *result)
-+{
-+ struct references r;
-+ refcounts_unsafe_ref (ref, &r);
-+ assert (! (r.hard == 1 && r.weak == 0)
-+ || !"refcount detected use-after-free!");
-+ if (result)
-+ *result = r;
-+}
-+
-+/* Decrement the hard reference count of REF. If RESULT is not NULL,
-+ the result of the operation is written there. This function uses
-+ atomic operations. It is not required to serialize calls to this
-+ function. */
-+REFCOUNT_EI void
-+refcounts_deref (refcounts_t *ref, struct references *result)
-+{
-+ const union _references op = { .references = { .hard = 1 } };
-+ union _references r;
-+ r.value = __atomic_sub_fetch (&ref->value, op.value, __ATOMIC_RELAXED);
-+ assert (r.references.hard != UINT32_MAX || !"refcount underflowed!");
-+ if (result)
-+ *result = r.references;
-+}
-+
-+/* Promote a weak reference to a hard reference. If RESULT is not
-+ NULL, the result of the operation is written there. This function
-+ uses atomic operations. It is not required to serialize calls to
-+ this function. */
-+REFCOUNT_EI void
-+refcounts_promote (refcounts_t *ref, struct references *result)
-+{
-+ /* To promote a weak reference, we need to atomically subtract 1
-+ from the weak reference count, and add 1 to the hard reference
-+ count.
-+
-+ We can subtract by 1 by adding the two's complement of 1 = ~0 to
-+ a fixed-width value, discarding the overflow.
-+
-+ We do the same in our uint64_t value, but we have chosen the
-+ layout of struct references so that when it is used in the union
-+ _references, the weak reference counts occupy the most
-+ significant bits. When we add ~0 to the weak references, the
-+ overflow will be discarded as unsigned arithmetic is modulo 2^n.
-+ So we just add a hard reference. In combination, this is the
-+ desired operation. */
-+ const union _references op =
-+ { .references = { .weak = ~0U, .hard = 1} };
-+ union _references r;
-+ r.value = __atomic_add_fetch (&ref->value, op.value, __ATOMIC_RELAXED);
-+ assert (r.references.hard != UINT32_MAX || !"refcount overflowed!");
-+ assert (r.references.weak != UINT32_MAX || !"refcount underflowed!");
-+ if (result)
-+ *result = r.references;
-+}
-+
-+/* Demote a hard reference to a weak reference. If RESULT is not
-+ NULL, the result of the operation is written there. This function
-+ uses atomic operations. It is not required to serialize calls to
-+ this function. */
-+REFCOUNT_EI void
-+refcounts_demote (refcounts_t *ref, struct references *result)
-+{
-+ /* To demote a hard reference, we need to atomically subtract 1 from
-+ the hard reference count, and add 1 to the weak reference count.
-+
-+ We can subtract by 1 by adding the two's complement of 1 = ~0 to
-+ a fixed-width value, discarding the overflow.
-+
-+ We do the same in our uint64_t value, but we have chosen the
-+ layout of struct references so that when it is used in the union
-+ _references, the hard reference counts occupy the least
-+ significant bits. When we add ~0 to the hard references, it will
-+ overflow into the weak references. This is the desired
-+ operation. */
-+ const union _references op = { .references = { .hard = ~0U } };
-+ union _references r;
-+ r.value = __atomic_add_fetch (&ref->value, op.value, __ATOMIC_RELAXED);
-+ assert (r.references.hard != UINT32_MAX || !"refcount underflowed!");
-+ assert (r.references.weak != UINT32_MAX || !"refcount overflowed!");
-+ if (result)
-+ *result = r.references;
-+}
-+
-+/* Increment the weak reference count of REF. If RESULT is not NULL,
-+ the result of the operation is written there. This function uses
-+ atomic operations. It is not required to serialize calls to this
-+ function.
-+
-+ This is the unsafe version of refcounts_ref_weak.
-+ refcounts_ref_weak also checks for use-after-free errors. When in
-+ doubt, use that one instead. */
-+REFCOUNT_EI void
-+refcounts_unsafe_ref_weak (refcounts_t *ref, struct references *result)
-+{
-+ const union _references op = { .references = { .weak = 1 } };
-+ union _references r;
-+ r.value = __atomic_add_fetch (&ref->value, op.value, __ATOMIC_RELAXED);
-+ assert (r.references.weak != UINT32_MAX || !"refcount overflowed!");
-+ if (result)
-+ *result = r.references;
-+}
-+
-+/* Increment the weak reference count of REF. If RESULT is not NULL,
-+ the result of the operation is written there. This function uses
-+ atomic operations. It is not required to serialize calls to this
-+ function. */
-+REFCOUNT_EI void
-+refcounts_ref_weak (refcounts_t *ref, struct references *result)
-+{
-+ struct references r;
-+ refcounts_unsafe_ref_weak (ref, &r);
-+ assert (! (r.hard == 0 && r.weak == 1)
-+ || !"refcount detected use-after-free!");
-+ if (result)
-+ *result = r;
-+}
-+
-+/* Decrement the weak reference count of REF. If RESULT is not NULL,
-+ the result of the operation is written there. This function uses
-+ atomic operations. It is not required to serialize calls to this
-+ function. */
-+REFCOUNT_EI void
-+refcounts_deref_weak (refcounts_t *ref, struct references *result)
-+{
-+ const union _references op = { .references = { .weak = 1 } };
-+ union _references r;
-+ r.value = __atomic_sub_fetch (&ref->value, op.value, __ATOMIC_RELAXED);
-+ assert (r.references.weak != UINT32_MAX || !"refcount underflowed!");
-+ if (result)
-+ *result = r.references;
-+}
-+
-+/* Store the current reference counts of REF in RESULT. This function
-+ uses atomic operations. It is not required to serialize calls to
-+ this function. */
-+REFCOUNT_EI void
-+refcounts_references (refcounts_t *ref, struct references *result)
-+{
-+ union _references r;
-+ r.value =__atomic_load_n (&ref->value, __ATOMIC_RELAXED);
-+ *result = r.references;
-+}
-+
-+/* Return the hard reference count of REF. This function uses atomic
-+ operations. It is not required to serialize calls to this
-+ function. */
-+REFCOUNT_EI uint32_t
-+refcounts_hard_references (refcounts_t *ref)
-+{
-+ struct references result;
-+ refcounts_references (ref, &result);
-+ return result.hard;
-+}
-+
-+/* Return the weak reference count of REF. This function uses atomic
-+ operations. It is not required to serialize calls to this
-+ function. */
-+REFCOUNT_EI uint32_t
-+refcounts_weak_references (refcounts_t *ref)
-+{
-+ struct references result;
-+ refcounts_references (ref, &result);
-+ return result.weak;
-+}
-+
-+#endif /* _HURD_REFCOUNT_H_ */
---
-2.1.3
-