[BACK]Return to kern_mutex.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / kern

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

Diff for /src/sys/kern/kern_mutex.c between version 1.21.2.4 and 1.22

version 1.21.2.4, 2008/02/18 21:06:46 version 1.22, 2007/11/07 00:23:22
Line 1 
Line 1 
 /*      $NetBSD$        */  /*      $NetBSD$        */
   
 /*-  /*-
  * Copyright (c) 2002, 2006, 2007, 2008 The NetBSD Foundation, Inc.   * Copyright (c) 2002, 2006, 2007 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 59  __KERNEL_RCSID(0, "$NetBSD$");
Line 59  __KERNEL_RCSID(0, "$NetBSD$");
 #include <sys/systm.h>  #include <sys/systm.h>
 #include <sys/lockdebug.h>  #include <sys/lockdebug.h>
 #include <sys/kernel.h>  #include <sys/kernel.h>
 #include <sys/atomic.h>  
 #include <sys/intr.h>  
 #include <sys/lock.h>  
   
 #include <dev/lockstat.h>  #include <dev/lockstat.h>
   
 #include <machine/lock.h>  #include <sys/intr.h>
   
 /*  /*
  * When not running a debug kernel, spin mutexes are not much   * When not running a debug kernel, spin mutexes are not much
Line 81  __KERNEL_RCSID(0, "$NetBSD$");
Line 78  __KERNEL_RCSID(0, "$NetBSD$");
  */   */
   
 #define MUTEX_WANTLOCK(mtx)                                     \  #define MUTEX_WANTLOCK(mtx)                                     \
     LOCKDEBUG_WANTLOCK(MUTEX_DEBUG_P(mtx), (mtx),               \      LOCKDEBUG_WANTLOCK(MUTEX_GETID(mtx),                        \
         (uintptr_t)__builtin_return_address(0), 0)          (uintptr_t)__builtin_return_address(0), 0)
 #define MUTEX_LOCKED(mtx)                                       \  #define MUTEX_LOCKED(mtx)                                       \
     LOCKDEBUG_LOCKED(MUTEX_DEBUG_P(mtx), (mtx),                 \      LOCKDEBUG_LOCKED(MUTEX_GETID(mtx),                          \
         (uintptr_t)__builtin_return_address(0), 0)          (uintptr_t)__builtin_return_address(0), 0)
 #define MUTEX_UNLOCKED(mtx)                                     \  #define MUTEX_UNLOCKED(mtx)                                     \
     LOCKDEBUG_UNLOCKED(MUTEX_DEBUG_P(mtx), (mtx),               \      LOCKDEBUG_UNLOCKED(MUTEX_GETID(mtx),                        \
         (uintptr_t)__builtin_return_address(0), 0)          (uintptr_t)__builtin_return_address(0), 0)
 #define MUTEX_ABORT(mtx, msg)                                   \  #define MUTEX_ABORT(mtx, msg)                                   \
     mutex_abort(mtx, __func__, msg)      mutex_abort(mtx, __func__, msg)
Line 157  do {         \
Line 154  do {         \
   
 #define MUTEX_OWNER(owner)                                              \  #define MUTEX_OWNER(owner)                                              \
         (owner & MUTEX_THREAD)          (owner & MUTEX_THREAD)
   #define MUTEX_OWNED(owner)                                              \
           (owner != 0)
 #define MUTEX_HAS_WAITERS(mtx)                                          \  #define MUTEX_HAS_WAITERS(mtx)                                          \
         (((int)(mtx)->mtx_owner & MUTEX_BIT_WAITERS) != 0)          (((int)(mtx)->mtx_owner & MUTEX_BIT_WAITERS) != 0)
   
 #define MUTEX_INITIALIZE_ADAPTIVE(mtx, dodebug)                         \  #define MUTEX_INITIALIZE_ADAPTIVE(mtx, id)                              \
 do {                                                                    \  do {                                                                    \
         if (dodebug)                                                    \          (mtx)->mtx_id = (id);                                           \
                 (mtx)->mtx_owner |= MUTEX_BIT_DEBUG;                    \  
 } while (/* CONSTCOND */ 0);  } while (/* CONSTCOND */ 0);
   
 #define MUTEX_INITIALIZE_SPIN(mtx, dodebug, ipl)                        \  #define MUTEX_INITIALIZE_SPIN(mtx, id, ipl)                             \
 do {                                                                    \  do {                                                                    \
         (mtx)->mtx_owner = MUTEX_BIT_SPIN;                              \          (mtx)->mtx_owner = MUTEX_BIT_SPIN;                              \
         if (dodebug)                                                    \  
                 (mtx)->mtx_owner |= MUTEX_BIT_DEBUG;                    \  
         (mtx)->mtx_ipl = makeiplcookie((ipl));                          \          (mtx)->mtx_ipl = makeiplcookie((ipl));                          \
           (mtx)->mtx_id = (id);                                           \
         __cpu_simple_lock_init(&(mtx)->mtx_lock);                       \          __cpu_simple_lock_init(&(mtx)->mtx_lock);                       \
 } while (/* CONSTCOND */ 0)  } while (/* CONSTCOND */ 0)
   
 #define MUTEX_DESTROY(mtx)                                              \  #define MUTEX_DESTROY(mtx)                                              \
 do {                                                                    \  do {                                                                    \
         (mtx)->mtx_owner = MUTEX_THREAD;                                \          (mtx)->mtx_owner = MUTEX_THREAD;                                \
           (mtx)->mtx_id = -1;                                             \
 } while (/* CONSTCOND */ 0);  } while (/* CONSTCOND */ 0);
   
 #define MUTEX_SPIN_P(mtx)               \  #define MUTEX_SPIN_P(mtx)               \
Line 185  do {         \
Line 183  do {         \
 #define MUTEX_ADAPTIVE_P(mtx)           \  #define MUTEX_ADAPTIVE_P(mtx)           \
     (((mtx)->mtx_owner & MUTEX_BIT_SPIN) == 0)      (((mtx)->mtx_owner & MUTEX_BIT_SPIN) == 0)
   
 #define MUTEX_DEBUG_P(mtx)      (((mtx)->mtx_owner & MUTEX_BIT_DEBUG) != 0)  #define MUTEX_GETID(mtx)                ((mtx)->mtx_id)
 #if defined(LOCKDEBUG)  
 #define MUTEX_OWNED(owner)              (((owner) & ~MUTEX_BIT_DEBUG) != 0)  
 #define MUTEX_INHERITDEBUG(new, old)    (new) |= (old) & MUTEX_BIT_DEBUG  
 #else /* defined(LOCKDEBUG) */  
 #define MUTEX_OWNED(owner)              ((owner) != 0)  
 #define MUTEX_INHERITDEBUG(new, old)    /* nothing */  
 #endif /* defined(LOCKDEBUG) */  
   
 static inline int  static inline int
 MUTEX_ACQUIRE(kmutex_t *mtx, uintptr_t curthread)  MUTEX_ACQUIRE(kmutex_t *mtx, uintptr_t curthread)
 {  {
         int rv;          int rv;
         uintptr_t old = 0;          rv = MUTEX_CAS(&mtx->mtx_owner, 0UL, curthread);
         uintptr_t new = curthread;  
   
         MUTEX_INHERITDEBUG(old, mtx->mtx_owner);  
         MUTEX_INHERITDEBUG(new, old);  
         rv = MUTEX_CAS(&mtx->mtx_owner, old, new);  
         MUTEX_RECEIVE(mtx);          MUTEX_RECEIVE(mtx);
         return rv;          return rv;
 }  }
Line 220  MUTEX_SET_WAITERS(kmutex_t *mtx, uintptr
Line 206  MUTEX_SET_WAITERS(kmutex_t *mtx, uintptr
 static inline void  static inline void
 MUTEX_RELEASE(kmutex_t *mtx)  MUTEX_RELEASE(kmutex_t *mtx)
 {  {
         uintptr_t new;  
   
         MUTEX_GIVE(mtx);          MUTEX_GIVE(mtx);
         new = 0;          mtx->mtx_owner = 0;
         MUTEX_INHERITDEBUG(new, mtx->mtx_owner);  
         mtx->mtx_owner = new;  
 }  }
   
 static inline void  static inline void
Line 257  __strong_alias(mutex_spin_exit,mutex_vec
Line 239  __strong_alias(mutex_spin_exit,mutex_vec
 void    mutex_abort(kmutex_t *, const char *, const char *);  void    mutex_abort(kmutex_t *, const char *, const char *);
 void    mutex_dump(volatile void *);  void    mutex_dump(volatile void *);
 int     mutex_onproc(uintptr_t, struct cpu_info **);  int     mutex_onproc(uintptr_t, struct cpu_info **);
   static struct lwp *mutex_owner(wchan_t);
   
 lockops_t mutex_spin_lockops = {  lockops_t mutex_spin_lockops = {
         "Mutex",          "Mutex",
Line 275  syncobj_t mutex_syncobj = {
Line 258  syncobj_t mutex_syncobj = {
         turnstile_unsleep,          turnstile_unsleep,
         turnstile_changepri,          turnstile_changepri,
         sleepq_lendpri,          sleepq_lendpri,
         (void *)mutex_owner,          mutex_owner,
 };  };
   
 /*  /*
Line 308  void
Line 291  void
 mutex_abort(kmutex_t *mtx, const char *func, const char *msg)  mutex_abort(kmutex_t *mtx, const char *func, const char *msg)
 {  {
   
         LOCKDEBUG_ABORT(mtx, (MUTEX_SPIN_P(mtx) ?          LOCKDEBUG_ABORT(MUTEX_GETID(mtx), mtx, (MUTEX_SPIN_P(mtx) ?
             &mutex_spin_lockops : &mutex_adaptive_lockops), func, msg);              &mutex_spin_lockops : &mutex_adaptive_lockops), func, msg);
         /* NOTREACHED */          /* NOTREACHED */
 }  }
Line 325  mutex_abort(kmutex_t *mtx, const char *f
Line 308  mutex_abort(kmutex_t *mtx, const char *f
 void  void
 mutex_init(kmutex_t *mtx, kmutex_type_t type, int ipl)  mutex_init(kmutex_t *mtx, kmutex_type_t type, int ipl)
 {  {
         bool dodebug;          u_int id;
   
         memset(mtx, 0, sizeof(*mtx));          memset(mtx, 0, sizeof(*mtx));
   
Line 335  mutex_init(kmutex_t *mtx, kmutex_type_t 
Line 318  mutex_init(kmutex_t *mtx, kmutex_type_t 
                 break;                  break;
         case MUTEX_DEFAULT:          case MUTEX_DEFAULT:
         case MUTEX_DRIVER:          case MUTEX_DRIVER:
                 if (ipl == IPL_NONE || ipl == IPL_SOFTCLOCK ||                  switch (ipl) {
                     ipl == IPL_SOFTBIO || ipl == IPL_SOFTNET ||                  case IPL_NONE:
                     ipl == IPL_SOFTSERIAL) {  
                         type = MUTEX_ADAPTIVE;                          type = MUTEX_ADAPTIVE;
                 } else {                          break;
                   default:
                         type = MUTEX_SPIN;                          type = MUTEX_SPIN;
                           break;
                 }                  }
                 break;                  break;
         default:          default:
Line 349  mutex_init(kmutex_t *mtx, kmutex_type_t 
Line 333  mutex_init(kmutex_t *mtx, kmutex_type_t 
   
         switch (type) {          switch (type) {
         case MUTEX_NODEBUG:          case MUTEX_NODEBUG:
                 dodebug = LOCKDEBUG_ALLOC(mtx, NULL,                  id = LOCKDEBUG_ALLOC(mtx, NULL,
                     (uintptr_t)__builtin_return_address(0));                      (uintptr_t)__builtin_return_address(0));
                 MUTEX_INITIALIZE_SPIN(mtx, dodebug, ipl);                  MUTEX_INITIALIZE_SPIN(mtx, id, ipl);
                 break;                  break;
         case MUTEX_ADAPTIVE:          case MUTEX_ADAPTIVE:
                 dodebug = LOCKDEBUG_ALLOC(mtx, &mutex_adaptive_lockops,                  id = LOCKDEBUG_ALLOC(mtx, &mutex_adaptive_lockops,
                     (uintptr_t)__builtin_return_address(0));                      (uintptr_t)__builtin_return_address(0));
                 MUTEX_INITIALIZE_ADAPTIVE(mtx, dodebug);                  MUTEX_INITIALIZE_ADAPTIVE(mtx, id);
                 break;                  break;
         case MUTEX_SPIN:          case MUTEX_SPIN:
                 dodebug = LOCKDEBUG_ALLOC(mtx, &mutex_spin_lockops,                  id = LOCKDEBUG_ALLOC(mtx, &mutex_spin_lockops,
                     (uintptr_t)__builtin_return_address(0));                      (uintptr_t)__builtin_return_address(0));
                 MUTEX_INITIALIZE_SPIN(mtx, dodebug, ipl);                  MUTEX_INITIALIZE_SPIN(mtx, id, ipl);
                 break;                  break;
         default:          default:
                 panic("mutex_init: impossible type");                  panic("mutex_init: impossible type");
Line 385  mutex_destroy(kmutex_t *mtx)
Line 369  mutex_destroy(kmutex_t *mtx)
                 MUTEX_ASSERT(mtx, !__SIMPLELOCK_LOCKED_P(&mtx->mtx_lock));                  MUTEX_ASSERT(mtx, !__SIMPLELOCK_LOCKED_P(&mtx->mtx_lock));
         }          }
   
         LOCKDEBUG_FREE(MUTEX_DEBUG_P(mtx), mtx);          LOCKDEBUG_FREE(mtx, MUTEX_GETID(mtx));
         MUTEX_DESTROY(mtx);          MUTEX_DESTROY(mtx);
 }  }
   
Line 509  mutex_vector_enter(kmutex_t *mtx)
Line 493  mutex_vector_enter(kmutex_t *mtx)
         MUTEX_ASSERT(mtx, curthread != 0);          MUTEX_ASSERT(mtx, curthread != 0);
         MUTEX_WANTLOCK(mtx);          MUTEX_WANTLOCK(mtx);
   
   #ifdef LOCKDEBUG
         if (panicstr == NULL) {          if (panicstr == NULL) {
                   simple_lock_only_held(NULL, "mutex_enter");
   #ifdef MULTIPROCESSOR
                 LOCKDEBUG_BARRIER(&kernel_lock, 1);                  LOCKDEBUG_BARRIER(&kernel_lock, 1);
   #else
                   LOCKDEBUG_BARRIER(NULL, 1);
   #endif
         }          }
   #endif
   
         LOCKSTAT_ENTER(lsflag);          LOCKSTAT_ENTER(lsflag);
   
Line 670  mutex_vector_enter(kmutex_t *mtx)
Line 661  mutex_vector_enter(kmutex_t *mtx)
                  * If the waiters bit is not set it's unsafe to go asleep,                   * If the waiters bit is not set it's unsafe to go asleep,
                  * as we might never be awoken.                   * as we might never be awoken.
                  */                   */
                 if ((membar_consumer(), mutex_onproc(owner, &ci)) ||                  if ((mb_read(), mutex_onproc(owner, &ci)) ||
                     (membar_consumer(), !MUTEX_HAS_WAITERS(mtx))) {                      (mb_read(), !MUTEX_HAS_WAITERS(mtx))) {
                         turnstile_exit(mtx);                          turnstile_exit(mtx);
                         continue;                          continue;
                 }                  }
Line 811  mutex_owned(kmutex_t *mtx)
Line 802  mutex_owned(kmutex_t *mtx)
  *      Return the current owner of an adaptive mutex.  Used for   *      Return the current owner of an adaptive mutex.  Used for
  *      priority inheritance.   *      priority inheritance.
  */   */
 lwp_t *  static struct lwp *
 mutex_owner(kmutex_t *mtx)  mutex_owner(wchan_t obj)
 {  {
           kmutex_t *mtx = (void *)(uintptr_t)obj; /* discard qualifiers */
   
         MUTEX_ASSERT(mtx, MUTEX_ADAPTIVE_P(mtx));          MUTEX_ASSERT(mtx, MUTEX_ADAPTIVE_P(mtx));
         return (struct lwp *)MUTEX_OWNER(mtx->mtx_owner);          return (struct lwp *)MUTEX_OWNER(mtx->mtx_owner);

Legend:
Removed from v.1.21.2.4  
changed lines
  Added in v.1.22

CVSweb <webmaster@jp.NetBSD.org>