linux/kernel/rtmutex_common.h
<<
>>
Prefs
   1/*
   2 * RT Mutexes: blocking mutual exclusion locks with PI support
   3 *
   4 * started by Ingo Molnar and Thomas Gleixner:
   5 *
   6 *  Copyright (C) 2004-2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
   7 *  Copyright (C) 2006, Timesys Corp., Thomas Gleixner <tglx@timesys.com>
   8 *
   9 * This file contains the private data structure and API definitions.
  10 */
  11
  12#ifndef __KERNEL_RTMUTEX_COMMON_H
  13#define __KERNEL_RTMUTEX_COMMON_H
  14
  15#include <linux/rtmutex.h>
  16
  17/*
  18 * The rtmutex in kernel tester is independent of rtmutex debugging. We
  19 * call schedule_rt_mutex_test() instead of schedule() for the tasks which
  20 * belong to the tester. That way we can delay the wakeup path of those
  21 * threads to provoke lock stealing and testing of  complex boosting scenarios.
  22 */
  23#ifdef CONFIG_RT_MUTEX_TESTER
  24
  25extern void schedule_rt_mutex_test(struct rt_mutex *lock);
  26
  27#define schedule_rt_mutex(_lock)                                \
  28  do {                                                          \
  29        if (!(current->flags & PF_MUTEX_TESTER))                \
  30                schedule();                                     \
  31        else                                                    \
  32                schedule_rt_mutex_test(_lock);                  \
  33  } while (0)
  34
  35#else
  36# define schedule_rt_mutex(_lock)                       schedule()
  37#endif
  38
  39/*
  40 * This is the control structure for tasks blocked on a rt_mutex,
  41 * which is allocated on the kernel stack on of the blocked task.
  42 *
  43 * @list_entry:         pi node to enqueue into the mutex waiters list
  44 * @pi_list_entry:      pi node to enqueue into the mutex owner waiters list
  45 * @task:               task reference to the blocked task
  46 */
  47struct rt_mutex_waiter {
  48        struct plist_node       list_entry;
  49        struct plist_node       pi_list_entry;
  50        struct task_struct      *task;
  51        struct rt_mutex         *lock;
  52#ifdef CONFIG_DEBUG_RT_MUTEXES
  53        unsigned long           ip;
  54        struct pid              *deadlock_task_pid;
  55        struct rt_mutex         *deadlock_lock;
  56#endif
  57};
  58
  59/*
  60 * Various helpers to access the waiters-plist:
  61 */
  62static inline int rt_mutex_has_waiters(struct rt_mutex *lock)
  63{
  64        return !plist_head_empty(&lock->wait_list);
  65}
  66
  67static inline struct rt_mutex_waiter *
  68rt_mutex_top_waiter(struct rt_mutex *lock)
  69{
  70        struct rt_mutex_waiter *w;
  71
  72        w = plist_first_entry(&lock->wait_list, struct rt_mutex_waiter,
  73                               list_entry);
  74        BUG_ON(w->lock != lock);
  75
  76        return w;
  77}
  78
  79static inline int task_has_pi_waiters(struct task_struct *p)
  80{
  81        return !plist_head_empty(&p->pi_waiters);
  82}
  83
  84static inline struct rt_mutex_waiter *
  85task_top_pi_waiter(struct task_struct *p)
  86{
  87        return plist_first_entry(&p->pi_waiters, struct rt_mutex_waiter,
  88                                  pi_list_entry);
  89}
  90
  91/*
  92 * lock->owner state tracking:
  93 */
  94#define RT_MUTEX_OWNER_PENDING  1UL
  95#define RT_MUTEX_HAS_WAITERS    2UL
  96#define RT_MUTEX_OWNER_MASKALL  3UL
  97
  98static inline struct task_struct *rt_mutex_owner(struct rt_mutex *lock)
  99{
 100        return (struct task_struct *)
 101                ((unsigned long)lock->owner & ~RT_MUTEX_OWNER_MASKALL);
 102}
 103
 104static inline struct task_struct *rt_mutex_real_owner(struct rt_mutex *lock)
 105{
 106        return (struct task_struct *)
 107                ((unsigned long)lock->owner & ~RT_MUTEX_HAS_WAITERS);
 108}
 109
 110static inline unsigned long rt_mutex_owner_pending(struct rt_mutex *lock)
 111{
 112        return (unsigned long)lock->owner & RT_MUTEX_OWNER_PENDING;
 113}
 114
 115/*
 116 * PI-futex support (proxy locking functions, etc.):
 117 */
 118extern struct task_struct *rt_mutex_next_owner(struct rt_mutex *lock);
 119extern void rt_mutex_init_proxy_locked(struct rt_mutex *lock,
 120                                       struct task_struct *proxy_owner);
 121extern void rt_mutex_proxy_unlock(struct rt_mutex *lock,
 122                                  struct task_struct *proxy_owner);
 123extern int rt_mutex_start_proxy_lock(struct rt_mutex *lock,
 124                                     struct rt_mutex_waiter *waiter,
 125                                     struct task_struct *task,
 126                                     int detect_deadlock);
 127extern int rt_mutex_finish_proxy_lock(struct rt_mutex *lock,
 128                                      struct hrtimer_sleeper *to,
 129                                      struct rt_mutex_waiter *waiter,
 130                                      int detect_deadlock);
 131
 132#ifdef CONFIG_DEBUG_RT_MUTEXES
 133# include "rtmutex-debug.h"
 134#else
 135# include "rtmutex.h"
 136#endif
 137
 138#endif
 139