0001
0002 #ifndef _LINUX_RCUWAIT_H_
0003 #define _LINUX_RCUWAIT_H_
0004
0005 #include <linux/rcupdate.h>
0006 #include <linux/sched/signal.h>
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 struct rcuwait {
0017 struct task_struct __rcu *task;
0018 };
0019
0020 #define __RCUWAIT_INITIALIZER(name) \
0021 { .task = NULL, }
0022
0023 static inline void rcuwait_init(struct rcuwait *w)
0024 {
0025 w->task = NULL;
0026 }
0027
0028
0029
0030
0031
0032 static inline int rcuwait_active(struct rcuwait *w)
0033 {
0034 return !!rcu_access_pointer(w->task);
0035 }
0036
0037 extern int rcuwait_wake_up(struct rcuwait *w);
0038
0039
0040
0041
0042
0043
0044
0045 static inline void prepare_to_rcuwait(struct rcuwait *w)
0046 {
0047 rcu_assign_pointer(w->task, current);
0048 }
0049
0050 extern void finish_rcuwait(struct rcuwait *w);
0051
0052 #define rcuwait_wait_event(w, condition, state) \
0053 ({ \
0054 int __ret = 0; \
0055 prepare_to_rcuwait(w); \
0056 for (;;) { \
0057
0058
0059
0060 \
0061 set_current_state(state); \
0062 if (condition) \
0063 break; \
0064 \
0065 if (signal_pending_state(state, current)) { \
0066 __ret = -EINTR; \
0067 break; \
0068 } \
0069 \
0070 schedule(); \
0071 } \
0072 finish_rcuwait(w); \
0073 __ret; \
0074 })
0075
0076 #endif