Date: Tue, 8 Sep 2015 08:41:07 +0000 (UTC) From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r287556 - head/lib/libthr/thread Message-ID: <201509080841.t888f76o082185@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kib Date: Tue Sep 8 08:41:07 2015 New Revision: 287556 URL: https://svnweb.freebsd.org/changeset/base/287556 Log: In the pthread_once(), if the initializer has already run, then the calling thread is supposed to see accesses issued by the initializer. This means that the read of the once_control->state variable should have an acquire semantic. Use atomic_thread_fence_acq() when the value read is ONCE_DONE, instead of straightforward atomic_load_acq(), to only put a barrier when needed (*). On the other hand, the updates of the once_control->state with the intermediate progress state do not need to synchronize with other state accesses, remove _acq suffix. Reviewed by: alc (previous version) Suggested by: alc (*) Sponsored by: The FreeBSD Foundation MFC after: 1 week Modified: head/lib/libthr/thread/thr_once.c Modified: head/lib/libthr/thread/thr_once.c ============================================================================== --- head/lib/libthr/thread/thr_once.c Tue Sep 8 08:06:20 2015 (r287555) +++ head/lib/libthr/thread/thr_once.c Tue Sep 8 08:41:07 2015 (r287556) @@ -68,13 +68,15 @@ _pthread_once(pthread_once_t *once_contr for (;;) { state = once_control->state; - if (state == ONCE_DONE) + if (state == ONCE_DONE) { + atomic_thread_fence_acq(); return (0); + } if (state == ONCE_NEVER_DONE) { - if (atomic_cmpset_acq_int(&once_control->state, state, ONCE_IN_PROGRESS)) + if (atomic_cmpset_int(&once_control->state, state, ONCE_IN_PROGRESS)) break; } else if (state == ONCE_IN_PROGRESS) { - if (atomic_cmpset_acq_int(&once_control->state, state, ONCE_WAIT)) + if (atomic_cmpset_int(&once_control->state, state, ONCE_WAIT)) _thr_umtx_wait_uint(&once_control->state, ONCE_WAIT, NULL, 0); } else if (state == ONCE_WAIT) { _thr_umtx_wait_uint(&once_control->state, state, NULL, 0);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201509080841.t888f76o082185>