File: /Users/paulross/dev/linux/linux-3.13/include/linux/preempt.h

Green shading in the line number column means the source is part of the translation unit, red means it is conditionally excluded. Highlighted line numbers link to the translation unit page. Highlighted macros link to the macro page.

       1: #ifndef __LINUX_PREEMPT_H
       2: #define __LINUX_PREEMPT_H
       3: 
       4: /*
       5:  * include/linux/preempt.h - macros for accessing and manipulating
       6:  * preempt_count (used for kernel preemption, interrupt count, etc.)
       7:  */
       8: 
       9: #include <linux/linkage.h>
      10: #include <linux/list.h>
      11: 
      12: /*
      13:  * We use the MSB mostly because its available; see <linux/preempt_mask.h> for
      14:  * the other bits -- can't include that header due to inclusion hell.
      15:  */
      16: #define PREEMPT_NEED_RESCHED    0x80000000
      17: 
      18: #include <asm/preempt.h>
      19: 
      20: #if defined(CONFIG_DEBUG_PREEMPT) || defined(CONFIG_PREEMPT_TRACER)
      21: extern void preempt_count_add(int val);
      22: extern void preempt_count_sub(int val);
      23: #define preempt_count_dec_and_test() ({ preempt_count_sub(1); should_resched(); })
      24: #else
      25: #define preempt_count_add(val)    __preempt_count_add(val)
      26: #define preempt_count_sub(val)    __preempt_count_sub(val)
      27: #define preempt_count_dec_and_test() __preempt_count_dec_and_test()
      28: #endif
      29: 
      30: #define __preempt_count_inc() __preempt_count_add(1)
      31: #define __preempt_count_dec() __preempt_count_sub(1)
      32: 
      33: #define preempt_count_inc() preempt_count_add(1)
      34: #define preempt_count_dec() preempt_count_sub(1)
      35: 
      36: #ifdef CONFIG_PREEMPT_COUNT
      37: 
      38: #define preempt_disable() \
      39: do { \
      40:     preempt_count_inc(); \
      41:     barrier(); \
      42: } while (0)
      43: 
      44: #define sched_preempt_enable_no_resched() \
      45: do { \
      46:     barrier(); \
      47:     preempt_count_dec(); \
      48: } while (0)
      49: 
      50: #define preempt_enable_no_resched() sched_preempt_enable_no_resched()
      51: 
      52: #ifdef CONFIG_PREEMPT
      53: #define preempt_enable() \
      54: do { \
      55:     barrier(); \
      56:     if (unlikely(preempt_count_dec_and_test())) \
      57:         __preempt_schedule(); \
      58: } while (0)
      59: 
      60: #define preempt_check_resched() \
      61: do { \
      62:     if (should_resched()) \
      63:         __preempt_schedule(); \
      64: } while (0)
      65: 
      66: #else
      67: #define preempt_enable() preempt_enable_no_resched()
      68: #define preempt_check_resched() do { } while (0)
      69: #endif
      70: 
      71: #define preempt_disable_notrace() \
      72: do { \
      73:     __preempt_count_inc(); \
      74:     barrier(); \
      75: } while (0)
      76: 
      77: #define preempt_enable_no_resched_notrace() \
      78: do { \
      79:     barrier(); \
      80:     __preempt_count_dec(); \
      81: } while (0)
      82: 
      83: #ifdef CONFIG_PREEMPT
      84: 
      85: #ifndef CONFIG_CONTEXT_TRACKING
      86: #define __preempt_schedule_context() __preempt_schedule()
      87: #endif
      88: 
      89: #define preempt_enable_notrace() \
      90: do { \
      91:     barrier(); \
      92:     if (unlikely(__preempt_count_dec_and_test())) \
      93:         __preempt_schedule_context(); \
      94: } while (0)
      95: #else
      96: #define preempt_enable_notrace() preempt_enable_no_resched_notrace()
      97: #endif
      98: 
      99: #else /* !CONFIG_PREEMPT_COUNT */
     100: 
     101: /*
     102:  * Even if we don't have any preemption, we need preempt disable/enable
     103:  * to be barriers, so that we don't have things like get_user/put_user
     104:  * that can cause faults and scheduling migrate into our preempt-protected
     105:  * region.
     106:  */
     107: #define preempt_disable()            barrier()
     108: #define sched_preempt_enable_no_resched()    barrier()
     109: #define preempt_enable_no_resched()        barrier()
     110: #define preempt_enable()            barrier()
     111: #define preempt_check_resched()            do { } while (0)
     112: 
     113: #define preempt_disable_notrace()        barrier()
     114: #define preempt_enable_no_resched_notrace()    barrier()
     115: #define preempt_enable_notrace()        barrier()
     116: 
     117: #endif /* CONFIG_PREEMPT_COUNT */
     118: 
     119: #ifdef CONFIG_PREEMPT_NOTIFIERS
     120: 
     121: struct preempt_notifier;
     122: 
     123: /**
     124:  * preempt_ops - notifiers called when a task is preempted and rescheduled
     125:  * @sched_in: we're about to be rescheduled:
     126:  *    notifier: struct preempt_notifier for the task being scheduled
     127:  *    cpu:  cpu we're scheduled on
     128:  * @sched_out: we've just been preempted
     129:  *    notifier: struct preempt_notifier for the task being preempted
     130:  *    next: the task that's kicking us out
     131:  *
     132:  * Please note that sched_in and out are called under different
     133:  * contexts.  sched_out is called with rq lock held and irq disabled
     134:  * while sched_in is called without rq lock and irq enabled.  This
     135:  * difference is intentional and depended upon by its users.
     136:  */
     137: struct preempt_ops {
     138:     void (*sched_in)(struct preempt_notifier *notifier, int cpu);
     139:     void (*sched_out)(struct preempt_notifier *notifier,
     140:               struct task_struct *next);
     141: };
     142: 
     143: /**
     144:  * preempt_notifier - key for installing preemption notifiers
     145:  * @link: internal use
     146:  * @ops: defines the notifier functions to be called
     147:  *
     148:  * Usually used in conjunction with container_of().
     149:  */
     150: struct preempt_notifier {
     151:     struct hlist_node link;
     152:     struct preempt_ops *ops;
     153: };
     154: 
     155: void preempt_notifier_register(struct preempt_notifier *notifier);
     156: void preempt_notifier_unregister(struct preempt_notifier *notifier);
     157: 
     158: static inline void preempt_notifier_init(struct preempt_notifier *notifier,
     159:                      struct preempt_ops *ops)
     160: {
     161:     INIT_HLIST_NODE(&notifier->link);
     162:     notifier->ops = ops;
     163: }
     164: 
     165: #endif
     166: 
     167: #endif /* __LINUX_PREEMPT_H */
     168: