From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1791) id 5617738A880A; Fri, 20 Aug 2021 17:55:33 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 5617738A880A Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Adhemerval Zanella To: glibc-cvs@sourceware.org Subject: [glibc/azanella/pthread-multiple-fixes] nptl: Handle robust PI mutexes for !__ASSUME_SET_ROBUST_LIST X-Act-Checkin: glibc X-Git-Author: Adhemerval Zanella X-Git-Refname: refs/heads/azanella/pthread-multiple-fixes X-Git-Oldrev: 7ce598e7e1f725dd324840643b9c71c43457598f X-Git-Newrev: 6464efa00e8c0e30061891cff9aa714116291cc0 Message-Id: <20210820175533.5617738A880A@sourceware.org> Date: Fri, 20 Aug 2021 17:55:33 +0000 (GMT) X-BeenThere: glibc-cvs@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Glibc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 20 Aug 2021 17:55:33 -0000 https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=6464efa00e8c0e30061891cff9aa714116291cc0 commit 6464efa00e8c0e30061891cff9aa714116291cc0 Author: Adhemerval Zanella Date: Mon Jun 7 11:52:35 2021 -0300 nptl: Handle robust PI mutexes for !__ASSUME_SET_ROBUST_LIST The robust PI mutexes are signaled by setting the LSB bit to 1, so the code requires to take this consideration before access the __pthread_mutex_s. The code is also simplified: the initialization code is not really required, PD->robust_head.list and PD->robust_list.__next are essentially the same regardless of __PTHREAD_MUTEX_HAVE_PREV, the futex wake is optimized to be issued only when required, and the futex shared bit is set only when required. Checked on a build for m68k-linux-gnu. I also checked on x86_64-linux-gnu by removing the check for !__ASSUME_SET_ROBUST_LIST. Diff: --- nptl/pthread_create.c | 53 ++++++++++++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c index d8ec299cb1..08e5189ad6 100644 --- a/nptl/pthread_create.c +++ b/nptl/pthread_create.c @@ -486,35 +486,36 @@ start_thread (void *arg) exit (0); #ifndef __ASSUME_SET_ROBUST_LIST - /* If this thread has any robust mutexes locked, handle them now. */ -# if __PTHREAD_MUTEX_HAVE_PREV - void *robust = pd->robust_head.list; -# else - __pthread_slist_t *robust = pd->robust_list.__next; -# endif - /* We let the kernel do the notification if it is able to do so. - If we have to do it here there for sure are no PI mutexes involved - since the kernel support for them is even more recent. */ - if (!__nptl_set_robust_list_avail - && __builtin_expect (robust != (void *) &pd->robust_head, 0)) + /* We let the kernel do the notification if it is able to do so on the exit + syscall. Otherwise we need to handle before the thread terminates. */ + void **robust; + while ((robust = pd->robust_head.list) + && robust != (void *) &pd->robust_head) { - do + /* Note: robust PI futexes are signaled by setting bit 0. */ + void **robustp = (void **) ((uintptr_t) robust & ~1UL); + + struct __pthread_mutex_s *mtx = (struct __pthread_mutex_s *) + ((char *) robustp - offsetof (struct __pthread_mutex_s, + __list.__next)); + unsigned int nusers = mtx->__nusers; + int shared = mtx->__kind & 128; + + pd->robust_head.list_op_pending = robust; + pd->robust_head.list = *robustp; + /* Although the list will not be changed at this point, it follows the + expected kernel ABI. */ + __asm ("" ::: "memory"); + + int lock = atomic_exchange_relaxed (&mtx->__lock, FUTEX_OWNER_DIED); + /* Wake any users if mutex is acquired with potential users. */ + if (lock > 1 || nusers != 0) { - struct __pthread_mutex_s *this = (struct __pthread_mutex_s *) - ((char *) robust - offsetof (struct __pthread_mutex_s, - __list.__next)); - robust = *((void **) robust); - -# if __PTHREAD_MUTEX_HAVE_PREV - this->__list.__prev = NULL; -# endif - this->__list.__next = NULL; - - atomic_or (&this->__lock, FUTEX_OWNER_DIED); - futex_wake ((unsigned int *) &this->__lock, 1, - /* XYZ */ FUTEX_SHARED); + if ((uintptr_t) robust & 1) + futex_unlock_pi ((unsigned int *) &mtx->__lock, shared); + else + futex_wake ((unsigned int *) &mtx->__lock, 1, shared); } - while (robust != (void *) &pd->robust_head); } #endif