[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.56 and 1.65

version 1.56, 2013/09/22 14:55:07 version 1.65, 2017/05/01 21:35:25
Line 75  __KERNEL_RCSID(0, "$NetBSD$");
Line 75  __KERNEL_RCSID(0, "$NetBSD$");
 #define MUTEX_WANTLOCK(mtx)                                     \  #define MUTEX_WANTLOCK(mtx)                                     \
     LOCKDEBUG_WANTLOCK(MUTEX_DEBUG_P(mtx), (mtx),               \      LOCKDEBUG_WANTLOCK(MUTEX_DEBUG_P(mtx), (mtx),               \
         (uintptr_t)__builtin_return_address(0), 0)          (uintptr_t)__builtin_return_address(0), 0)
   #define MUTEX_TESTLOCK(mtx)                                     \
       LOCKDEBUG_WANTLOCK(MUTEX_DEBUG_P(mtx), (mtx),               \
           (uintptr_t)__builtin_return_address(0), -1)
 #define MUTEX_LOCKED(mtx)                                       \  #define MUTEX_LOCKED(mtx)                                       \
     LOCKDEBUG_LOCKED(MUTEX_DEBUG_P(mtx), (mtx), NULL,           \      LOCKDEBUG_LOCKED(MUTEX_DEBUG_P(mtx), (mtx), NULL,           \
         (uintptr_t)__builtin_return_address(0), 0)          (uintptr_t)__builtin_return_address(0), 0)
Line 82  __KERNEL_RCSID(0, "$NetBSD$");
Line 85  __KERNEL_RCSID(0, "$NetBSD$");
     LOCKDEBUG_UNLOCKED(MUTEX_DEBUG_P(mtx), (mtx),               \      LOCKDEBUG_UNLOCKED(MUTEX_DEBUG_P(mtx), (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(__func__, __LINE__, mtx, msg)
   
 #if defined(LOCKDEBUG)  #if defined(LOCKDEBUG)
   
Line 113  do {        \
Line 116  do {        \
 #endif  /* DIAGNOSTIC */  #endif  /* DIAGNOSTIC */
   
 /*  /*
    * Some architectures can't use __cpu_simple_lock as is so allow a way
    * for them to use an alternate definition.
    */
   #ifndef MUTEX_SPINBIT_LOCK_INIT
   #define MUTEX_SPINBIT_LOCK_INIT(mtx)    __cpu_simple_lock_init(&(mtx)->mtx_lock)
   #endif
   #ifndef MUTEX_SPINBIT_LOCKED_P
   #define MUTEX_SPINBIT_LOCKED_P(mtx)     __SIMPLELOCK_LOCKED_P(&(mtx)->mtx_lock)
   #endif
   #ifndef MUTEX_SPINBIT_LOCK_TRY
   #define MUTEX_SPINBIT_LOCK_TRY(mtx)     __cpu_simple_lock_try(&(mtx)->mtx_lock)
   #endif
   #ifndef MUTEX_SPINBIT_LOCK_UNLOCK
   #define MUTEX_SPINBIT_LOCK_UNLOCK(mtx)  __cpu_simple_unlock(&(mtx)->mtx_lock)
   #endif
   
   #ifndef MUTEX_INITIALIZE_SPIN_IPL
   #define MUTEX_INITIALIZE_SPIN_IPL(mtx, ipl) \
                                           ((mtx)->mtx_ipl = makeiplcookie((ipl)))
   #endif
   
   /*
  * Spin mutex SPL save / restore.   * Spin mutex SPL save / restore.
  */   */
   
Line 120  do {        \
Line 145  do {        \
 do {                                                                    \  do {                                                                    \
         struct cpu_info *x__ci;                                         \          struct cpu_info *x__ci;                                         \
         int x__cnt, s;                                                  \          int x__cnt, s;                                                  \
         s = splraiseipl(mtx->mtx_ipl);                                  \          s = splraiseipl(MUTEX_SPIN_IPL(mtx));                           \
         x__ci = curcpu();                                               \          x__ci = curcpu();                                               \
         x__cnt = x__ci->ci_mtx_count--;                                 \          x__cnt = x__ci->ci_mtx_count--;                                 \
         __insn_barrier();                                               \          __insn_barrier();                                               \
Line 162  do {         \
Line 187  do {         \
         (mtx)->mtx_owner = MUTEX_BIT_SPIN;                              \          (mtx)->mtx_owner = MUTEX_BIT_SPIN;                              \
         if (!dodebug)                                                   \          if (!dodebug)                                                   \
                 (mtx)->mtx_owner |= MUTEX_BIT_NODEBUG;                  \                  (mtx)->mtx_owner |= MUTEX_BIT_NODEBUG;                  \
         (mtx)->mtx_ipl = makeiplcookie((ipl));                          \          MUTEX_INITIALIZE_SPIN_IPL((mtx), (ipl));                        \
         __cpu_simple_lock_init(&(mtx)->mtx_lock);                       \          MUTEX_SPINBIT_LOCK_INIT((mtx));                                 \
 } while (/* CONSTCOND */ 0)  } while (/* CONSTCOND */ 0)
   
 #define MUTEX_DESTROY(mtx)                                              \  #define MUTEX_DESTROY(mtx)                                              \
Line 179  do {         \
Line 204  do {         \
 #define MUTEX_DEBUG_P(mtx)      (((mtx)->mtx_owner & MUTEX_BIT_NODEBUG) == 0)  #define MUTEX_DEBUG_P(mtx)      (((mtx)->mtx_owner & MUTEX_BIT_NODEBUG) == 0)
 #if defined(LOCKDEBUG)  #if defined(LOCKDEBUG)
 #define MUTEX_OWNED(owner)              (((owner) & ~MUTEX_BIT_NODEBUG) != 0)  #define MUTEX_OWNED(owner)              (((owner) & ~MUTEX_BIT_NODEBUG) != 0)
 #define MUTEX_INHERITDEBUG(new, old)    (new) |= (old) & MUTEX_BIT_NODEBUG  #define MUTEX_INHERITDEBUG(n, o)        (n) |= (o) & MUTEX_BIT_NODEBUG
 #else /* defined(LOCKDEBUG) */  #else /* defined(LOCKDEBUG) */
 #define MUTEX_OWNED(owner)              ((owner) != 0)  #define MUTEX_OWNED(owner)              ((owner) != 0)
 #define MUTEX_INHERITDEBUG(new, old)    /* nothing */  #define MUTEX_INHERITDEBUG(n, o)        /* nothing */
 #endif /* defined(LOCKDEBUG) */  #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;          uintptr_t oldown = 0;
         uintptr_t new = curthread;          uintptr_t newown = curthread;
   
         MUTEX_INHERITDEBUG(old, mtx->mtx_owner);          MUTEX_INHERITDEBUG(oldown, mtx->mtx_owner);
         MUTEX_INHERITDEBUG(new, old);          MUTEX_INHERITDEBUG(newown, oldown);
         rv = MUTEX_CAS(&mtx->mtx_owner, old, new);          rv = MUTEX_CAS(&mtx->mtx_owner, oldown, newown);
         MUTEX_RECEIVE(mtx);          MUTEX_RECEIVE(mtx);
         return rv;          return rv;
 }  }
Line 211  MUTEX_SET_WAITERS(kmutex_t *mtx, uintptr
Line 236  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;          uintptr_t newown;
   
         MUTEX_GIVE(mtx);          MUTEX_GIVE(mtx);
         new = 0;          newown = 0;
         MUTEX_INHERITDEBUG(new, mtx->mtx_owner);          MUTEX_INHERITDEBUG(newown, mtx->mtx_owner);
         mtx->mtx_owner = new;          mtx->mtx_owner = newown;
 }  
   
 static inline void  
 MUTEX_CLEAR_WAITERS(kmutex_t *mtx)  
 {  
         /* nothing */  
 }  }
 #endif  /* __HAVE_SIMPLE_MUTEXES */  #endif  /* __HAVE_SIMPLE_MUTEXES */
   
Line 245  __strong_alias(mutex_spin_enter,mutex_ve
Line 264  __strong_alias(mutex_spin_enter,mutex_ve
 __strong_alias(mutex_spin_exit,mutex_vector_exit);  __strong_alias(mutex_spin_exit,mutex_vector_exit);
 #endif  #endif
   
 static void             mutex_abort(kmutex_t *, const char *, const char *);  static void     mutex_abort(const char *, size_t, kmutex_t *, const char *);
 static void             mutex_dump(volatile void *);  static void     mutex_dump(volatile void *);
   
 lockops_t mutex_spin_lockops = {  lockops_t mutex_spin_lockops = {
         "Mutex",          "Mutex",
Line 291  mutex_dump(volatile void *cookie)
Line 310  mutex_dump(volatile void *cookie)
  *      we ask the compiler to not inline it.   *      we ask the compiler to not inline it.
  */   */
 void __noinline  void __noinline
 mutex_abort(kmutex_t *mtx, const char *func, const char *msg)  mutex_abort(const char *func, size_t line, kmutex_t *mtx, const char *msg)
 {  {
   
         LOCKDEBUG_ABORT(mtx, (MUTEX_SPIN_P(mtx) ?          LOCKDEBUG_ABORT(func, line, mtx, (MUTEX_SPIN_P(mtx) ?
             &mutex_spin_lockops : &mutex_adaptive_lockops), func, msg);              &mutex_spin_lockops : &mutex_adaptive_lockops), msg);
 }  }
   
 /*  /*
Line 367  mutex_destroy(kmutex_t *mtx)
Line 386  mutex_destroy(kmutex_t *mtx)
                 MUTEX_ASSERT(mtx, !MUTEX_OWNED(mtx->mtx_owner) &&                  MUTEX_ASSERT(mtx, !MUTEX_OWNED(mtx->mtx_owner) &&
                     !MUTEX_HAS_WAITERS(mtx));                      !MUTEX_HAS_WAITERS(mtx));
         } else {          } else {
                 MUTEX_ASSERT(mtx, !__SIMPLELOCK_LOCKED_P(&mtx->mtx_lock));                  MUTEX_ASSERT(mtx, !MUTEX_SPINBIT_LOCKED_P(mtx));
         }          }
   
         LOCKDEBUG_FREE(MUTEX_DEBUG_P(mtx), mtx);          LOCKDEBUG_FREE(MUTEX_DEBUG_P(mtx), mtx);
Line 416  mutex_oncpu(uintptr_t owner)
Line 435  mutex_oncpu(uintptr_t owner)
  *   *
  *      Support routine for mutex_enter() that must handle all cases.  In   *      Support routine for mutex_enter() that must handle all cases.  In
  *      the LOCKDEBUG case, mutex_enter() is always aliased here, even if   *      the LOCKDEBUG case, mutex_enter() is always aliased here, even if
  *      fast-path stubs are available.  If an mutex_spin_enter() stub is   *      fast-path stubs are available.  If a mutex_spin_enter() stub is
  *      not available, then it is also aliased directly here.   *      not available, then it is also aliased directly here.
  */   */
 void  void
Line 443  mutex_vector_enter(kmutex_t *mtx)
Line 462  mutex_vector_enter(kmutex_t *mtx)
                 MUTEX_SPIN_SPLRAISE(mtx);                  MUTEX_SPIN_SPLRAISE(mtx);
                 MUTEX_WANTLOCK(mtx);                  MUTEX_WANTLOCK(mtx);
 #ifdef FULL  #ifdef FULL
                 if (__cpu_simple_lock_try(&mtx->mtx_lock)) {                  if (MUTEX_SPINBIT_LOCK_TRY(mtx)) {
                         MUTEX_LOCKED(mtx);                          MUTEX_LOCKED(mtx);
                         return;                          return;
                 }                  }
Line 462  mutex_vector_enter(kmutex_t *mtx)
Line 481  mutex_vector_enter(kmutex_t *mtx)
                 do {                  do {
                         if (panicstr != NULL)                          if (panicstr != NULL)
                                 break;                                  break;
                         while (__SIMPLELOCK_LOCKED_P(&mtx->mtx_lock)) {                          while (MUTEX_SPINBIT_LOCKED_P(mtx)) {
                                 SPINLOCK_BACKOFF(count);                                  SPINLOCK_BACKOFF(count);
 #ifdef LOCKDEBUG  #ifdef LOCKDEBUG
                                 if (SPINLOCK_SPINOUT(spins))                                  if (SPINLOCK_SPINOUT(spins))
                                         MUTEX_ABORT(mtx, "spinout");                                          MUTEX_ABORT(mtx, "spinout");
 #endif  /* LOCKDEBUG */  #endif  /* LOCKDEBUG */
                         }                          }
                 } while (!__cpu_simple_lock_try(&mtx->mtx_lock));                  } while (!MUTEX_SPINBIT_LOCK_TRY(mtx));
   
                 if (count != SPINLOCK_BACKOFF_MIN) {                  if (count != SPINLOCK_BACKOFF_MIN) {
                         LOCKSTAT_STOP_TIMER(lsflag, spintime);                          LOCKSTAT_STOP_TIMER(lsflag, spintime);
Line 518  mutex_vector_enter(kmutex_t *mtx)
Line 537  mutex_vector_enter(kmutex_t *mtx)
                         continue;                          continue;
                 }                  }
                 if (__predict_false(panicstr != NULL)) {                  if (__predict_false(panicstr != NULL)) {
                         kpreempt_enable();                          KPREEMPT_ENABLE(curlwp);
                         return;                          return;
                 }                  }
                 if (__predict_false(MUTEX_OWNER(owner) == curthread)) {                  if (__predict_false(MUTEX_OWNER(owner) == curthread)) {
Line 695  mutex_vector_exit(kmutex_t *mtx)
Line 714  mutex_vector_exit(kmutex_t *mtx)
   
         if (MUTEX_SPIN_P(mtx)) {          if (MUTEX_SPIN_P(mtx)) {
 #ifdef FULL  #ifdef FULL
                 if (__predict_false(!__SIMPLELOCK_LOCKED_P(&mtx->mtx_lock))) {                  if (__predict_false(!MUTEX_SPINBIT_LOCKED_P(mtx))) {
                         if (panicstr != NULL)                          if (panicstr != NULL)
                                 return;                                  return;
                         MUTEX_ABORT(mtx, "exiting unheld spin mutex");                          MUTEX_ABORT(mtx, "exiting unheld spin mutex");
                 }                  }
                 MUTEX_UNLOCKED(mtx);                  MUTEX_UNLOCKED(mtx);
                 __cpu_simple_unlock(&mtx->mtx_lock);                  MUTEX_SPINBIT_LOCK_UNLOCK(mtx);
 #endif  #endif
                 MUTEX_SPIN_SPLRESTORE(mtx);                  MUTEX_SPIN_SPLRESTORE(mtx);
                 return;                  return;
Line 717  mutex_vector_exit(kmutex_t *mtx)
Line 736  mutex_vector_exit(kmutex_t *mtx)
         MUTEX_DASSERT(mtx, curthread != 0);          MUTEX_DASSERT(mtx, curthread != 0);
         MUTEX_ASSERT(mtx, MUTEX_OWNER(mtx->mtx_owner) == curthread);          MUTEX_ASSERT(mtx, MUTEX_OWNER(mtx->mtx_owner) == curthread);
         MUTEX_UNLOCKED(mtx);          MUTEX_UNLOCKED(mtx);
   #if !defined(LOCKDEBUG)
           __USE(curthread);
   #endif
   
 #ifdef LOCKDEBUG  #ifdef LOCKDEBUG
         /*          /*
Line 791  mutex_owned(kmutex_t *mtx)
Line 813  mutex_owned(kmutex_t *mtx)
         if (MUTEX_ADAPTIVE_P(mtx))          if (MUTEX_ADAPTIVE_P(mtx))
                 return MUTEX_OWNER(mtx->mtx_owner) == (uintptr_t)curlwp;                  return MUTEX_OWNER(mtx->mtx_owner) == (uintptr_t)curlwp;
 #ifdef FULL  #ifdef FULL
         return __SIMPLELOCK_LOCKED_P(&mtx->mtx_lock);          return MUTEX_SPINBIT_LOCKED_P(mtx);
 #else  #else
         return 1;          return 1;
 #endif  #endif
Line 812  mutex_owner(kmutex_t *mtx)
Line 834  mutex_owner(kmutex_t *mtx)
 }  }
   
 /*  /*
    * mutex_ownable:
    *
    *      When compiled with DEBUG and LOCKDEBUG defined, ensure that
    *      the mutex is available.  We cannot use !mutex_owned() since
    *      that won't work correctly for spin mutexes.
    */
   int
   mutex_ownable(kmutex_t *mtx)
   {
   
   #ifdef LOCKDEBUG
           MUTEX_TESTLOCK(mtx);
   #endif
           return 1;
   }
   
   /*
  * mutex_tryenter:   * mutex_tryenter:
  *   *
  *      Try to acquire the mutex; return non-zero if we did.   *      Try to acquire the mutex; return non-zero if we did.
Line 827  mutex_tryenter(kmutex_t *mtx)
Line 866  mutex_tryenter(kmutex_t *mtx)
         if (MUTEX_SPIN_P(mtx)) {          if (MUTEX_SPIN_P(mtx)) {
                 MUTEX_SPIN_SPLRAISE(mtx);                  MUTEX_SPIN_SPLRAISE(mtx);
 #ifdef FULL  #ifdef FULL
                 if (__cpu_simple_lock_try(&mtx->mtx_lock)) {                  if (MUTEX_SPINBIT_LOCK_TRY(mtx)) {
                         MUTEX_WANTLOCK(mtx);                          MUTEX_WANTLOCK(mtx);
                         MUTEX_LOCKED(mtx);                          MUTEX_LOCKED(mtx);
                         return 1;                          return 1;
Line 884  mutex_spin_retry(kmutex_t *mtx)
Line 923  mutex_spin_retry(kmutex_t *mtx)
         do {          do {
                 if (panicstr != NULL)                  if (panicstr != NULL)
                         break;                          break;
                 while (__SIMPLELOCK_LOCKED_P(&mtx->mtx_lock)) {                  while (MUTEX_SPINBIT_LOCKED_P(mtx)) {
                         SPINLOCK_BACKOFF(count);                          SPINLOCK_BACKOFF(count);
 #ifdef LOCKDEBUG  #ifdef LOCKDEBUG
                         if (SPINLOCK_SPINOUT(spins))                          if (SPINLOCK_SPINOUT(spins))
                                 MUTEX_ABORT(mtx, "spinout");                                  MUTEX_ABORT(mtx, "spinout");
 #endif  /* LOCKDEBUG */  #endif  /* LOCKDEBUG */
                 }                  }
         } while (!__cpu_simple_lock_try(&mtx->mtx_lock));          } while (!MUTEX_SPINBIT_LOCK_TRY(mtx));
   
         LOCKSTAT_STOP_TIMER(lsflag, spintime);          LOCKSTAT_STOP_TIMER(lsflag, spintime);
         LOCKSTAT_EVENT(lsflag, mtx, LB_SPIN_MUTEX | LB_SPIN, 1, spintime);          LOCKSTAT_EVENT(lsflag, mtx, LB_SPIN_MUTEX | LB_SPIN, 1, spintime);

Legend:
Removed from v.1.56  
changed lines
  Added in v.1.65

CVSweb <webmaster@jp.NetBSD.org>