[libdispatch-dev] _dispatch_queue_wakeup_global/_dispatch_worker_thread2 use of dgq_pending - question
Hi, I am spending a bit of time investigating possible improvements to libpthread_workqueue and reviewed some of the libdispatch code and found one small thing I didn’t quite understand (but it might simply be my lack of understanding the semantics of the gcc atomic ops fully): ------------ queue.c: 1490: void 1491: _dispatch_worker_thread2(void *context) { . . . 1502: qc->dgq_pending = 0; —————— Shouldn’t this be set using atomic primitives to ensure visibility of the update of dgq_pending? (_dispatch_queue_wakeup_global() uses dispatch_atomic_cmpxchg() to set this) I would have expected something like (#ifdef:ed here to not warn when running without pthread workqueues, as it would be called by a path that doesn’t set dgq_pending): —— #if HAVE_PTHREAD_WORKQUEUES if (dispatch_atomic_cmpxchg(&qc->dgq_pending, 1, 0)) // zero out, ensure visibility { _dispatch_debug("got new worker thread for global queue: %p", dq); } else { _dispatch_debug(“unexpectedly got a new worker thread for global queue: %p", dq); } #endif —— Any enlightenment appreciated. Thanks, Joakim
On Feb 14, 2011, at 4:20 AM, Joakim Johansson wrote:
Hi,
I am spending a bit of time investigating possible improvements to libpthread_workqueue and reviewed some of the libdispatch code and found one small thing I didn’t quite understand (but it might simply be my lack of understanding the semantics of the gcc atomic ops fully):
------------ queue.c: 1490: void 1491: _dispatch_worker_thread2(void *context) { . . . 1502: qc->dgq_pending = 0; ——————
Shouldn’t this be set using atomic primitives to ensure visibility of the update of dgq_pending?
Joakim, The short answer: libdispatch requires cache-coherent memory. The longer answer is that cache-coherent memory implicitly ensures that the store to memory is visible to other processors. davez
(_dispatch_queue_wakeup_global() uses dispatch_atomic_cmpxchg() to set this)
I would have expected something like (#ifdef:ed here to not warn when running without pthread workqueues, as it would be called by a path that doesn’t set dgq_pending): —— #if HAVE_PTHREAD_WORKQUEUES if (dispatch_atomic_cmpxchg(&qc->dgq_pending, 1, 0)) // zero out, ensure visibility { _dispatch_debug("got new worker thread for global queue: %p", dq); } else { _dispatch_debug(“unexpectedly got a new worker thread for global queue: %p", dq); } #endif ——
Any enlightenment appreciated.
Thanks,
Joakim
_______________________________________________ libdispatch-dev mailing list libdispatch-dev@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/libdispatch-dev
Thanks Dave for clarifying - for anyone else who needs to brush up on fundamentals, there is http://en.wikipedia.org/wiki/Cache_coherence and http://os.inf.tu-dresden.de/Studium/DOS/SS2010/02-Coherency.pdf (p. 30 and forward) and more... Cheers, Joakim On 14 feb 2011, at 17.35, Dave Zarzycki wrote:
Joakim,
The short answer: libdispatch requires cache-coherent memory. The longer answer is that cache-coherent memory implicitly ensures that the store to memory is visible to other processors.
davez
participants (2)
-
Dave Zarzycki
-
Joakim Johansson