[libdispatch-changes] [155] trunk/src
source_changes at macosforge.org
source_changes at macosforge.org
Sat Nov 14 15:54:01 PST 2009
Revision: 155
http://trac.macosforge.org/projects/libdispatch/changeset/155
Author: kvv at apple.com
Date: 2009-11-14 15:53:59 -0800 (Sat, 14 Nov 2009)
Log Message:
-----------
10.6.2: Fix a performance regression in the dispatch_queue_pust_list fast path.
<rdar://problem/7217227>
Modified Paths:
--------------
trunk/src/queue.c
trunk/src/queue_internal.h
Modified: trunk/src/queue.c
===================================================================
--- trunk/src/queue.c 2009-11-14 21:24:14 UTC (rev 154)
+++ trunk/src/queue.c 2009-11-14 23:53:59 UTC (rev 155)
@@ -620,6 +620,22 @@
_dispatch_dispose(dq);
}
+DISPATCH_NOINLINE
+void
+_dispatch_queue_push_list_slow(dispatch_queue_t dq, struct dispatch_object_s *obj)
+{
+ // The queue must be retained before dq_items_head is written in order
+ // to ensure that the reference is still valid when _dispatch_wakeup is
+ // called. Otherwise, if preempted between the assignment to
+ // dq_items_head and _dispatch_wakeup, the blocks submitted to the
+ // queue may release the last reference to the queue when invoked by
+ // _dispatch_queue_drain. <rdar://problem/6932776>
+ _dispatch_retain(dq);
+ dq->dq_items_head = obj;
+ _dispatch_wakeup(dq);
+ _dispatch_release(dq);
+}
+
DISPATCH_NOINLINE
static void
_dispatch_barrier_async_f_slow(dispatch_queue_t dq, void *context, dispatch_function_t func)
Modified: trunk/src/queue_internal.h
===================================================================
--- trunk/src/queue_internal.h 2009-11-14 21:24:14 UTC (rev 154)
+++ trunk/src/queue_internal.h 2009-11-14 23:53:59 UTC (rev 155)
@@ -95,6 +95,7 @@
void _dispatch_queue_init(dispatch_queue_t dq);
void _dispatch_queue_drain(dispatch_queue_t dq);
void _dispatch_queue_dispose(dispatch_queue_t dq);
+void _dispatch_queue_push_list_slow(dispatch_queue_t dq, struct dispatch_object_s *obj);
void _dispatch_queue_serial_drain_till_empty(dispatch_queue_t dq);
void _dispatch_force_cache_cleanup(void);
@@ -105,17 +106,14 @@
struct dispatch_object_s *prev, *head = _head._do, *tail = _tail._do;
tail->do_next = NULL;
- _dispatch_retain(dq);
prev = fastpath(dispatch_atomic_xchg(&dq->dq_items_tail, tail));
if (prev) {
// if we crash here with a value less than 0x1000, then we are at a known bug in client code
// for example, see _dispatch_queue_dispose or _dispatch_atfork_child
prev->do_next = head;
} else {
- dq->dq_items_head = head;
- _dispatch_wakeup(dq);
+ _dispatch_queue_push_list_slow(dq, head);
}
- _dispatch_release(dq);
}
#define _dispatch_queue_push(x, y) _dispatch_queue_push_list((x), (y), (y))
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/libdispatch-changes/attachments/20091114/0f8e5a46/attachment.html>
More information about the libdispatch-changes
mailing list