diff options
Diffstat (limited to 'debian/patches/libports-lockless-refcounting.patch')
-rw-r--r-- | debian/patches/libports-lockless-refcounting.patch | 351 |
1 files changed, 0 insertions, 351 deletions
diff --git a/debian/patches/libports-lockless-refcounting.patch b/debian/patches/libports-lockless-refcounting.patch deleted file mode 100644 index dbfe0314..00000000 --- a/debian/patches/libports-lockless-refcounting.patch +++ /dev/null @@ -1,351 +0,0 @@ -commit f5d4ef14bb47294046d98c06478b0b58c97cf521 -Author: Justus Winter <4winter@informatik.uni-hamburg.de> -Date: Sat May 3 01:02:35 2014 +0200 - - libports: implement lockless reference counting - - * libports/refcount.h: New file with reference counting primitives. - * libports/ports.h (struct port_info): Use the new type. - * libports/bucket-iterate.c: Adjust accordingly. - * libports/complete-deallocate.c: Likewise. - * libports/create-internal.c: Likewise. - * libports/get-right.c: Likewise. - * libports/import-port.c: Likewise. - * libports/lookup-port.c: Likewise. - * libports/port-deref-weak.c: Likewise. - * libports/port-deref.c: Likewise. - * libports/port-ref-weak.c: Likewise. - * libports/port-ref.c: Likewise. - * libports/reallocate-from-external.c: Likewise. - * libports/transfer-right.c: Likewise. - * utils/rpctrace.c: Likewise. - -diff --git a/libports/bucket-iterate.c b/libports/bucket-iterate.c -index 498cf13..38a9f7a 100644 ---- a/libports/bucket-iterate.c -+++ b/libports/bucket-iterate.c -@@ -55,7 +55,7 @@ _ports_bucket_class_iterate (struct port_bucket *bucket, - - if (class == 0 || pi->class == class) - { -- pi->refcnt++; -+ ports_port_ref (pi); - p[n] = pi; - n++; - } -diff --git a/libports/complete-deallocate.c b/libports/complete-deallocate.c -index 8ce095b..7e7d467 100644 ---- a/libports/complete-deallocate.c -+++ b/libports/complete-deallocate.c -@@ -35,6 +35,8 @@ _ports_complete_deallocate (struct port_info *pi) - pi->port_right = MACH_PORT_NULL; - } - -+ pthread_mutex_lock (&_ports_lock); -+ - *pi->prevp = pi->next; - if (pi->next) - pi->next->prevp = pi->prevp; -diff --git a/libports/create-internal.c b/libports/create-internal.c -index 8551297..d56637c 100644 ---- a/libports/create-internal.c -+++ b/libports/create-internal.c -@@ -54,8 +54,7 @@ _ports_create_port_internal (struct port_class *class, - } - - pi->class = class; -- pi->refcnt = 1; -- pi->weakrefcnt = 0; -+ refcount_init (&pi->refcounts, 1, 0); - pi->cancel_threshold = 0; - pi->mscount = 0; - pi->flags = 0; -diff --git a/libports/get-right.c b/libports/get-right.c -index 89050c6..42bfa2b 100644 ---- a/libports/get-right.c -+++ b/libports/get-right.c -@@ -41,7 +41,7 @@ ports_get_right (void *port) - if ((pi->flags & PORT_HAS_SENDRIGHTS) == 0) - { - pi->flags |= PORT_HAS_SENDRIGHTS; -- pi->refcnt++; -+ ports_port_ref (pi); - err = mach_port_request_notification (mach_task_self (), - pi->port_right, - MACH_NOTIFY_NO_SENDERS, -diff --git a/libports/import-port.c b/libports/import-port.c -index 226f47e..5c66685 100644 ---- a/libports/import-port.c -+++ b/libports/import-port.c -@@ -48,8 +48,7 @@ ports_import_port (struct port_class *class, struct port_bucket *bucket, - return ENOMEM; - - pi->class = class; -- pi->refcnt = 1 + !!stat.mps_srights; -- pi->weakrefcnt = 0; -+ refcount_init (&pi->refcounts, 1 + !!stat.mps_srights, 0); - pi->cancel_threshold = 0; - pi->mscount = stat.mps_mscount; - pi->flags = stat.mps_srights ? PORT_HAS_SENDRIGHTS : 0; -diff --git a/libports/lookup-port.c b/libports/lookup-port.c -index f79f6f0..289369f 100644 ---- a/libports/lookup-port.c -+++ b/libports/lookup-port.c -@@ -44,7 +44,7 @@ ports_lookup_port (struct port_bucket *bucket, - pi = 0; - - if (pi) -- pi->refcnt++; -+ ports_port_ref (pi); - - pthread_mutex_unlock (&_ports_lock); - -diff --git a/libports/port-deref-weak.c b/libports/port-deref-weak.c -index beb4842..48e5354 100644 ---- a/libports/port-deref-weak.c -+++ b/libports/port-deref-weak.c -@@ -25,12 +25,8 @@ void - ports_port_deref_weak (void *portstruct) - { - struct port_info *pi = portstruct; -- -- pthread_mutex_lock (&_ports_lock); -- assert (pi->weakrefcnt); -- pi->weakrefcnt--; -- if (pi->refcnt == 0 && pi->weakrefcnt == 0) -+ struct refs result; -+ refcount_deref_weak (&pi->refcounts, &result); -+ if (result.hard == 0 && result.weak == 0) - _ports_complete_deallocate (pi); -- else -- pthread_mutex_unlock (&_ports_lock); - } -diff --git a/libports/port-deref.c b/libports/port-deref.c -index cf9b238..056159c 100644 ---- a/libports/port-deref.c -+++ b/libports/port-deref.c -@@ -26,25 +26,19 @@ ports_port_deref (void *portstruct) - { - struct port_info *pi = portstruct; - int trieddroppingweakrefs = 0; -+ struct refs result; - - retry: -- -- pthread_mutex_lock (&_ports_lock); -- -- if (pi->refcnt == 1 && pi->weakrefcnt -+ refcount_deref (&pi->refcounts, &result); -+ if (result.hard == 0 && result.weak > 1 - && pi->class->dropweak_routine && !trieddroppingweakrefs) - { -- pthread_mutex_unlock (&_ports_lock); -+ refcount_ref (&pi->refcounts, NULL); - (*pi->class->dropweak_routine) (pi); - trieddroppingweakrefs = 1; - goto retry; - } -- -- assert (pi->refcnt); - -- pi->refcnt--; -- if (pi->refcnt == 0 && pi->weakrefcnt == 0) -+ if (result.hard == 0 && result.weak == 0) - _ports_complete_deallocate (pi); -- else -- pthread_mutex_unlock (&_ports_lock); - } -diff --git a/libports/port-ref-weak.c b/libports/port-ref-weak.c -index c7d3c69..8b75005 100644 ---- a/libports/port-ref-weak.c -+++ b/libports/port-ref-weak.c -@@ -25,9 +25,7 @@ void - ports_port_ref_weak (void *portstruct) - { - struct port_info *pi = portstruct; -- -- pthread_mutex_lock (&_ports_lock); -- assert (pi->refcnt || pi->weakrefcnt); -- pi->weakrefcnt++; -- pthread_mutex_unlock (&_ports_lock); -+ struct refs result; -+ refcount_ref_weak (&pi->refcounts, &result); -+ assert (result.hard > 0 || result.weak > 1); - } -diff --git a/libports/port-ref.c b/libports/port-ref.c -index 92b7118..6310902 100644 ---- a/libports/port-ref.c -+++ b/libports/port-ref.c -@@ -25,9 +25,7 @@ void - ports_port_ref (void *portstruct) - { - struct port_info *pi = portstruct; -- -- pthread_mutex_lock (&_ports_lock); -- assert (pi->refcnt || pi->weakrefcnt); -- pi->refcnt++; -- pthread_mutex_unlock (&_ports_lock); -+ struct refs result; -+ refcount_ref (&pi->refcounts, &result); -+ assert (result.hard > 1 || result.weak > 0); - } -diff --git a/libports/ports.h b/libports/ports.h -index 7f13124..7088b2d 100644 ---- a/libports/ports.h -+++ b/libports/ports.h -@@ -22,12 +22,15 @@ - #define _HURD_PORTS_ - - #include <mach.h> -+#include <stdint.h> - #include <stdlib.h> - #include <hurd.h> - #include <hurd/ihash.h> - #include <mach/notify.h> - #include <pthread.h> - -+#include "refcount.h" -+ - /* These are global values for common flags used in the various structures. - Not all of these are meaningful in all flag fields. */ - #define PORTS_INHIBITED 0x0100 /* block RPC's */ -@@ -39,8 +42,7 @@ - struct port_info - { - struct port_class *class; -- int refcnt; -- int weakrefcnt; -+ reference_counts refcounts; - mach_port_mscount_t mscount; - mach_msg_seqno_t cancel_threshold; - int flags; -diff --git a/libports/reallocate-from-external.c b/libports/reallocate-from-external.c -index 8cccb2a..4dfc59c 100644 ---- a/libports/reallocate-from-external.c -+++ b/libports/reallocate-from-external.c -@@ -53,7 +53,7 @@ ports_reallocate_from_external (void *portstruct, mach_port_t receive) - else if (((pi->flags & PORT_HAS_SENDRIGHTS) == 0) && stat.mps_srights) - { - pi->flags |= PORT_HAS_SENDRIGHTS; -- pi->refcnt++; -+ ports_port_ref (pi); - } - - pi->port_right = receive; -diff --git a/libports/refcount.h b/libports/refcount.h -new file mode 100644 -index 0000000..43da5b4 ---- /dev/null -+++ b/libports/refcount.h -@@ -0,0 +1,72 @@ -+#ifndef _PORTS_REFCOUNT_H_ -+#define _PORTS_REFCOUNT_H_ -+ -+typedef uint64_t reference_counts; -+ -+struct refs { -+ uint32_t hard; -+ uint32_t weak; -+}; -+ -+union _refs { -+ struct refs refs; -+ reference_counts rc; -+}; -+ -+extern inline void -+refcount_init (reference_counts *ref, uint32_t hard, uint32_t weak) -+{ -+ ((union _refs *) ref)->refs = -+ (struct refs) { .hard = hard, .weak = weak }; -+} -+ -+extern inline void -+refcount_ref (reference_counts *ref, struct refs *result) -+{ -+ const union _refs op = { .refs = { .hard = 1 } }; -+ reference_counts r = __atomic_add_fetch (ref, op.rc, __ATOMIC_RELAXED); -+ if (result) -+ ((union _refs *) result)->rc = r; -+} -+ -+extern inline void -+refcount_deref (reference_counts *ref, struct refs *result) -+{ -+ const union _refs op = { .refs = { .hard = 1 } }; -+ ((union _refs *) result)->rc = -+ __atomic_sub_fetch (ref, op.rc, __ATOMIC_RELAXED); -+} -+ -+extern inline void -+refcount_ref_weak (reference_counts *ref, struct refs *result) -+{ -+ const union _refs op = { .refs = { .weak = 1 } }; -+ ((union _refs *) result)->rc = -+ __atomic_add_fetch (ref, op.rc, __ATOMIC_RELAXED); -+} -+ -+extern inline void -+refcount_deref_weak (reference_counts *ref, struct refs *result) -+{ -+ const union _refs op = { .refs = { .weak = 1 } }; -+ ((union _refs *) result)->rc = -+ __atomic_sub_fetch (ref, op.rc, __ATOMIC_RELAXED); -+} -+ -+extern inline uint32_t -+refcount_hard_refs (reference_counts *ref) -+{ -+ union _refs result; -+ result.rc = __atomic_load_n (ref, __ATOMIC_RELAXED); -+ return result.refs.hard; -+} -+ -+extern inline uint32_t -+refcount_weak_refs (reference_counts *ref) -+{ -+ union _refs result; -+ result.rc = __atomic_load_n (ref, __ATOMIC_RELAXED); -+ return result.refs.weak; -+} -+ -+#endif /* _PORTS_REFCOUNT_H_ */ -diff --git a/libports/transfer-right.c b/libports/transfer-right.c -index 72488a9..f4e0c86 100644 ---- a/libports/transfer-right.c -+++ b/libports/transfer-right.c -@@ -66,7 +66,7 @@ ports_transfer_right (void *tostruct, - else if (((topi->flags & PORT_HAS_SENDRIGHTS) == 0) && hassendrights) - { - topi->flags |= PORT_HAS_SENDRIGHTS; -- topi->refcnt++; -+ ports_port_ref (topi); - } - } - -diff --git a/utils/rpctrace.c b/utils/rpctrace.c -index fc913e3..248d4e2 100644 ---- a/utils/rpctrace.c -+++ b/utils/rpctrace.c -@@ -431,7 +431,8 @@ destroy_receiver_info (struct receiver_info *info) - while (send_wrapper) - { - struct sender_info *next = send_wrapper->next; -- assert (TRACED_INFO (send_wrapper)->pi.refcnt == 1); -+ assert (refcount_hard_refs (&TRACED_INFO (send_wrapper)->pi.refcounts) -+ == 1); - /* Reset the receive_right of the send wrapper in advance to avoid - * destroy_receiver_info is called when the port info is destroyed. */ - send_wrapper->receive_right = NULL; -@@ -848,7 +849,10 @@ rewrite_right (mach_port_t *right, mach_msg_type_name_t *type, - hurd_ihash_locp_remove (&traced_names, receiver_info->locp); - - send_wrapper2 = get_send_wrapper (receiver_info, dest, &rr); -- assert (TRACED_INFO (send_wrapper2)->pi.refcnt == 1); -+ assert ( -+ refcount_hard_refs (&TRACED_INFO (send_wrapper2)->pi.refcounts) -+ == 1); -+ - name = TRACED_INFO (send_wrapper2)->name; - TRACED_INFO (send_wrapper2)->name = NULL; - /* send_wrapper2 isn't destroyed normally, so we need to unlink |