This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: Synchronizing auxiliary mutex data
On Tue, 20 Jun 2017, Torvald Riegel wrote:
> > Plain accesses to fields like __data.owner are fine as long as they all are
> > within critical sections set up by LLL_MUTEX_{LOCK,UNLOCK}, but there are some
> > outside of them. So e.g. in nptl/pthread_mutex_lock:
> >
> > 95 else if (__builtin_expect (PTHREAD_MUTEX_TYPE (mutex)
> > 96 == PTHREAD_MUTEX_RECURSIVE_NP, 1))
> > 97 {
> > 98 /* Recursive mutex. */
> > 99 pid_t id = THREAD_GETMEM (THREAD_SELF, tid);
> > 100
> > 101 /* Check whether we already hold the mutex. */
> > 102 if (mutex->__data.__owner == id)
> > 103 {
> > 104 /* Just bump the counter. */
> > 105 if (__glibc_unlikely (mutex->__data.__count + 1 == 0))
> > 106 /* Overflow of the counter. */
> > 107 return EAGAIN;
> > 108
> > 109 ++mutex->__data.__count;
> > 110
> > 111 return 0;
> > 112 }
> > 113
> > 114 /* We have to get the mutex. */
> > 115 LLL_MUTEX_LOCK (mutex);
> > 116
> > 117 assert (mutex->__data.__owner == 0);
> >
> > afaict the access at line 102 can invoke undefined behavior due to a data race.
>
> All of them can. Even if the access is in the critical section, because
> it's not atomic, the compiler is technically allowed to use it as
> scratch space for a while.
No, the compiler could only use that scratch space within that critical section,
and thus other threads wouldn't be able to observe that.
Generally the compiler can't introduce data races, so in the quoted code snippet
the compiler can't introduce spurious writes to __owner outside of the critical
section (as the original code only reads it), and may introduce spurious writes
to __count only under __owner==id condition.
Alexander