include/linux/preempt.h
changeset 0 aa628870c1d3
equal deleted inserted replaced
-1:000000000000 0:aa628870c1d3
       
     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/thread_info.h>
       
    10 #include <linux/linkage.h>
       
    11 #include <linux/list.h>
       
    12 
       
    13 #if defined(CONFIG_DEBUG_PREEMPT) || defined(CONFIG_PREEMPT_TRACER)
       
    14   extern void add_preempt_count(int val);
       
    15   extern void sub_preempt_count(int val);
       
    16 #else
       
    17 # define add_preempt_count(val)	do { preempt_count() += (val); } while (0)
       
    18 # define sub_preempt_count(val)	do { preempt_count() -= (val); } while (0)
       
    19 #endif
       
    20 
       
    21 #define inc_preempt_count() add_preempt_count(1)
       
    22 #define dec_preempt_count() sub_preempt_count(1)
       
    23 
       
    24 #define preempt_count()	(current_thread_info()->preempt_count)
       
    25 
       
    26 #ifdef CONFIG_PREEMPT
       
    27 
       
    28 asmlinkage void preempt_schedule(void);
       
    29 
       
    30 #define preempt_disable() \
       
    31 do { \
       
    32 	inc_preempt_count(); \
       
    33 	barrier(); \
       
    34 } while (0)
       
    35 
       
    36 #define preempt_enable_no_resched() \
       
    37 do { \
       
    38 	barrier(); \
       
    39 	dec_preempt_count(); \
       
    40 } while (0)
       
    41 
       
    42 #define preempt_check_resched() \
       
    43 do { \
       
    44 	if (unlikely(test_thread_flag(TIF_NEED_RESCHED))) \
       
    45 		preempt_schedule(); \
       
    46 } while (0)
       
    47 
       
    48 #define preempt_enable() \
       
    49 do { \
       
    50 	preempt_enable_no_resched(); \
       
    51 	barrier(); \
       
    52 	preempt_check_resched(); \
       
    53 } while (0)
       
    54 
       
    55 /* For debugging and tracer internals only! */
       
    56 #define add_preempt_count_notrace(val)			\
       
    57 	do { preempt_count() += (val); } while (0)
       
    58 #define sub_preempt_count_notrace(val)			\
       
    59 	do { preempt_count() -= (val); } while (0)
       
    60 #define inc_preempt_count_notrace() add_preempt_count_notrace(1)
       
    61 #define dec_preempt_count_notrace() sub_preempt_count_notrace(1)
       
    62 
       
    63 #define preempt_disable_notrace() \
       
    64 do { \
       
    65 	inc_preempt_count_notrace(); \
       
    66 	barrier(); \
       
    67 } while (0)
       
    68 
       
    69 #define preempt_enable_no_resched_notrace() \
       
    70 do { \
       
    71 	barrier(); \
       
    72 	dec_preempt_count_notrace(); \
       
    73 } while (0)
       
    74 
       
    75 /* preempt_check_resched is OK to trace */
       
    76 #define preempt_enable_notrace() \
       
    77 do { \
       
    78 	preempt_enable_no_resched_notrace(); \
       
    79 	barrier(); \
       
    80 	preempt_check_resched(); \
       
    81 } while (0)
       
    82 
       
    83 #else
       
    84 
       
    85 #define preempt_disable()		do { } while (0)
       
    86 #define preempt_enable_no_resched()	do { } while (0)
       
    87 #define preempt_enable()		do { } while (0)
       
    88 #define preempt_check_resched()		do { } while (0)
       
    89 
       
    90 #define preempt_disable_notrace()		do { } while (0)
       
    91 #define preempt_enable_no_resched_notrace()	do { } while (0)
       
    92 #define preempt_enable_notrace()		do { } while (0)
       
    93 
       
    94 #endif
       
    95 
       
    96 #ifdef CONFIG_PREEMPT_NOTIFIERS
       
    97 
       
    98 struct preempt_notifier;
       
    99 
       
   100 /**
       
   101  * preempt_ops - notifiers called when a task is preempted and rescheduled
       
   102  * @sched_in: we're about to be rescheduled:
       
   103  *    notifier: struct preempt_notifier for the task being scheduled
       
   104  *    cpu:  cpu we're scheduled on
       
   105  * @sched_out: we've just been preempted
       
   106  *    notifier: struct preempt_notifier for the task being preempted
       
   107  *    next: the task that's kicking us out
       
   108  */
       
   109 struct preempt_ops {
       
   110 	void (*sched_in)(struct preempt_notifier *notifier, int cpu);
       
   111 	void (*sched_out)(struct preempt_notifier *notifier,
       
   112 			  struct task_struct *next);
       
   113 };
       
   114 
       
   115 /**
       
   116  * preempt_notifier - key for installing preemption notifiers
       
   117  * @link: internal use
       
   118  * @ops: defines the notifier functions to be called
       
   119  *
       
   120  * Usually used in conjunction with container_of().
       
   121  */
       
   122 struct preempt_notifier {
       
   123 	struct hlist_node link;
       
   124 	struct preempt_ops *ops;
       
   125 };
       
   126 
       
   127 void preempt_notifier_register(struct preempt_notifier *notifier);
       
   128 void preempt_notifier_unregister(struct preempt_notifier *notifier);
       
   129 
       
   130 static inline void preempt_notifier_init(struct preempt_notifier *notifier,
       
   131 				     struct preempt_ops *ops)
       
   132 {
       
   133 	INIT_HLIST_NODE(&notifier->link);
       
   134 	notifier->ops = ops;
       
   135 }
       
   136 
       
   137 #endif
       
   138 
       
   139 #endif /* __LINUX_PREEMPT_H */