[BACK]Return to pthread_rwlock.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / lib / libpthread

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/lib/libpthread/pthread_rwlock.c between version 1.40 and 1.41

version 1.40, 2020/05/16 22:53:37 version 1.41, 2020/06/01 11:44:59
Line 1 
Line 1 
 /*      $NetBSD$ */  /*      $NetBSD$ */
   
 /*-  /*-
  * Copyright (c) 2002, 2006, 2007, 2008 The NetBSD Foundation, Inc.   * Copyright (c) 2002, 2006, 2007, 2008, 2020 The NetBSD Foundation, Inc.
  * All rights reserved.   * All rights reserved.
  *   *
  * This code is derived from software contributed to The NetBSD Foundation   * This code is derived from software contributed to The NetBSD Foundation
Line 56  __RCSID("$NetBSD$");
Line 56  __RCSID("$NetBSD$");
   
 static int pthread__rwlock_wrlock(pthread_rwlock_t *, const struct timespec *);  static int pthread__rwlock_wrlock(pthread_rwlock_t *, const struct timespec *);
 static int pthread__rwlock_rdlock(pthread_rwlock_t *, const struct timespec *);  static int pthread__rwlock_rdlock(pthread_rwlock_t *, const struct timespec *);
 static void pthread__rwlock_early(void *);  static void pthread__rwlock_early(pthread_t, pthread_rwlock_t *,
       pthread_mutex_t *);
   
 int     _pthread_rwlock_held_np(pthread_rwlock_t *);  int     _pthread_rwlock_held_np(pthread_rwlock_t *);
 int     _pthread_rwlock_rdheld_np(pthread_rwlock_t *);  int     _pthread_rwlock_rdheld_np(pthread_rwlock_t *);
Line 218  pthread__rwlock_rdlock(pthread_rwlock_t 
Line 219  pthread__rwlock_rdlock(pthread_rwlock_t 
                 ptr->ptr_nreaders++;                  ptr->ptr_nreaders++;
                 self->pt_rwlocked = _RW_WANT_READ;                  self->pt_rwlocked = _RW_WANT_READ;
                 self->pt_sleepobj = &ptr->ptr_rblocked;                  self->pt_sleepobj = &ptr->ptr_rblocked;
                 self->pt_early = pthread__rwlock_early;  
                 error = pthread__park(self, interlock, &ptr->ptr_rblocked,                  error = pthread__park(self, interlock, &ptr->ptr_rblocked,
                     ts, 0);                      ts, 0);
   
                   if (self->pt_sleepobj != NULL) {
                           pthread__rwlock_early(self, ptr, interlock);
                   }
   
                 /* Did we get the lock? */                  /* Did we get the lock? */
                 if (self->pt_rwlocked == _RW_LOCKED) {                  if (self->pt_rwlocked == _RW_LOCKED) {
 #ifndef PTHREAD__ATOMIC_IS_MEMBAR  #ifndef PTHREAD__ATOMIC_IS_MEMBAR
Line 339  pthread__rwlock_wrlock(pthread_rwlock_t 
Line 343  pthread__rwlock_wrlock(pthread_rwlock_t 
                 PTQ_INSERT_TAIL(&ptr->ptr_wblocked, self, pt_sleep);                  PTQ_INSERT_TAIL(&ptr->ptr_wblocked, self, pt_sleep);
                 self->pt_rwlocked = _RW_WANT_WRITE;                  self->pt_rwlocked = _RW_WANT_WRITE;
                 self->pt_sleepobj = &ptr->ptr_wblocked;                  self->pt_sleepobj = &ptr->ptr_wblocked;
                 self->pt_early = pthread__rwlock_early;  
                 error = pthread__park(self, interlock, &ptr->ptr_wblocked,                  error = pthread__park(self, interlock, &ptr->ptr_wblocked,
                     ts, 0);                      ts, 0);
   
                   if (self->pt_sleepobj != NULL) {
                           pthread__rwlock_early(self, ptr, interlock);
                   }
   
                 /* Did we get the lock? */                  /* Did we get the lock? */
                 if (self->pt_rwlocked == _RW_LOCKED) {                  if (self->pt_rwlocked == _RW_LOCKED) {
 #ifndef PTHREAD__ATOMIC_IS_MEMBAR  #ifndef PTHREAD__ATOMIC_IS_MEMBAR
Line 358  pthread__rwlock_wrlock(pthread_rwlock_t 
Line 365  pthread__rwlock_wrlock(pthread_rwlock_t 
         }          }
 }  }
   
   
 int  int
 pthread_rwlock_trywrlock(pthread_rwlock_t *ptr)  pthread_rwlock_trywrlock(pthread_rwlock_t *ptr)
 {  {
Line 563  pthread_rwlock_unlock(pthread_rwlock_t *
Line 569  pthread_rwlock_unlock(pthread_rwlock_t *
  * removed from the waiters lists.   * removed from the waiters lists.
  */   */
 static void  static void
 pthread__rwlock_early(void *obj)  pthread__rwlock_early(pthread_t self, pthread_rwlock_t *ptr,
       pthread_mutex_t *interlock)
 {  {
         uintptr_t owner, set, new, next;          uintptr_t owner, set, newval, next;
         pthread_rwlock_t *ptr;          pthread_queue_t *queue;
         pthread_t self;  
         u_int off;  
   
         self = pthread__self();          pthread_mutex_lock(interlock);
           if ((queue = self->pt_sleepobj) == NULL) {
         switch (self->pt_rwlocked) {                  pthread_mutex_unlock(interlock);
         case _RW_WANT_READ:                  return;
                 off = offsetof(pthread_rwlock_t, ptr_rblocked);  
                 break;  
         case _RW_WANT_WRITE:  
                 off = offsetof(pthread_rwlock_t, ptr_wblocked);  
                 break;  
         default:  
                 pthread__errorfunc(__FILE__, __LINE__, __func__,  
                     "bad value of pt_rwlocked");  
                 off = 0;  
                 /* NOTREACHED */  
                 break;  
         }          }
           PTQ_REMOVE(queue, self, pt_sleep);
         /* LINTED mind your own business */          self->pt_sleepobj = NULL;
         ptr = (pthread_rwlock_t *)((uint8_t *)obj - off);  
         owner = (uintptr_t)ptr->ptr_owner;          owner = (uintptr_t)ptr->ptr_owner;
   
         if ((owner & RW_THREAD) == 0) {          if ((owner & RW_THREAD) == 0) {
Line 604  pthread__rwlock_early(void *obj)
Line 597  pthread__rwlock_early(void *obj)
                 set = 0;                  set = 0;
   
         for (;; owner = next) {          for (;; owner = next) {
                 new = (owner & ~(RW_HAS_WAITERS | RW_WRITE_WANTED)) | set;                  newval = (owner & ~(RW_HAS_WAITERS | RW_WRITE_WANTED)) | set;
                 next = rw_cas(ptr, owner, new);                  next = rw_cas(ptr, owner, newval);
                 if (owner == next)                  if (owner == next)
                         break;                          break;
         }          }
           pthread_mutex_unlock(interlock);
 }  }
   
 int  int

Legend:
Removed from v.1.40  
changed lines
  Added in v.1.41

CVSweb <webmaster@jp.NetBSD.org>