diff options
Diffstat (limited to 'debian/patches/0006-include-add-refcounts_demote-that-demotes-a-hard-ref.patch')
-rw-r--r-- | debian/patches/0006-include-add-refcounts_demote-that-demotes-a-hard-ref.patch | 115 |
1 files changed, 0 insertions, 115 deletions
diff --git a/debian/patches/0006-include-add-refcounts_demote-that-demotes-a-hard-ref.patch b/debian/patches/0006-include-add-refcounts_demote-that-demotes-a-hard-ref.patch deleted file mode 100644 index 2c1fcd3b..00000000 --- a/debian/patches/0006-include-add-refcounts_demote-that-demotes-a-hard-ref.patch +++ /dev/null @@ -1,115 +0,0 @@ -From a1f4af1716aa9c00358816ab7f82dac2cabdd961 Mon Sep 17 00:00:00 2001 -From: Justus Winter <4winter@informatik.uni-hamburg.de> -Date: Tue, 13 May 2014 23:04:40 +0200 -Subject: [PATCH 06/13] include: add refcounts_demote that demotes a hard - reference - -refcounts_demote atomically demotes a hard reference to a weak one. -This reduces the number of required atomic operations from three to -two when a hard reference is dropped and a dropweak routine is -installed. - -* include/refcount.h (refcounts_demote): New function. -* libports/port-deref.c (ports_port_deref): Use the new function. ---- - include/refcount.h | 39 +++++++++++++++++++++++++++++++++++++++ - libports/port-deref.c | 18 +++++++++--------- - 2 files changed, 48 insertions(+), 9 deletions(-) - -diff --git a/include/refcount.h b/include/refcount.h -index 0816220..2aafb9e 100644 ---- a/include/refcount.h -+++ b/include/refcount.h -@@ -77,8 +77,18 @@ 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. This way we can implement atomically demoting -+ a hard reference to a weak reference. See 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 -@@ -127,6 +137,35 @@ refcounts_deref (refcounts_t *ref, struct references *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 = ~0 } }; -+ union _references r; -+ r.value = __atomic_add_fetch (&ref->value, op.value, __ATOMIC_RELAXED); -+ assert (r.references.hard != UINT32_MAX -+ && r.references.weak != UINT32_MAX); -+ 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 -diff --git a/libports/port-deref.c b/libports/port-deref.c -index dd38f55..b97dd13 100644 ---- a/libports/port-deref.c -+++ b/libports/port-deref.c -@@ -27,21 +27,21 @@ ports_port_deref (void *portstruct) - struct port_info *pi = portstruct; - struct references result; - -- /* If we need to call the dropweak routine, we need to hold one -- reference while doing so. We use a weak reference for this -- purpose, which we acquire before we release our hard reference. -- The order is important here to prevent a race. */ -- if (pi->class->dropweak_routine) -- refcounts_ref_weak (&pi->refcounts, NULL); -- -- refcounts_deref (&pi->refcounts, &result); -- - if (pi->class->dropweak_routine) - { -+ /* If we need to call the dropweak routine, we need to hold one -+ reference while doing so. We use a weak reference for this -+ purpose, which we acquire by demoting our hard reference to a -+ weak one. */ -+ refcounts_demote (&pi->refcounts, &result); -+ - if (result.hard == 0 && result.weak > 1) - (*pi->class->dropweak_routine) (pi); -+ - refcounts_deref_weak (&pi->refcounts, &result); - } -+ else -+ refcounts_deref (&pi->refcounts, &result); - - if (result.hard == 0 && result.weak == 0) - _ports_complete_deallocate (pi); --- -2.0.0.rc0 - |