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(¬ifier->link); 162: notifier->ops = ops; 163: } 164: 165: #endif 166: 167: #endif /* __LINUX_PREEMPT_H */ 168: