diff options
Diffstat (limited to 'include/linux/wait.h')
| -rw-r--r-- | include/linux/wait.h | 125 | 
1 files changed, 117 insertions, 8 deletions
| diff --git a/include/linux/wait.h b/include/linux/wait.h index bd68819f0815..6fb1ba5f9b2f 100644 --- a/include/linux/wait.h +++ b/include/linux/wait.h @@ -25,6 +25,7 @@ struct wait_bit_key {  	void			*flags;  	int			bit_nr;  #define WAIT_ATOMIC_T_BIT_NR	-1 +	unsigned long		private;  };  struct wait_bit_queue { @@ -141,18 +142,19 @@ __remove_wait_queue(wait_queue_head_t *head, wait_queue_t *old)  	list_del(&old->task_list);  } +typedef int wait_bit_action_f(struct wait_bit_key *);  void __wake_up(wait_queue_head_t *q, unsigned int mode, int nr, void *key);  void __wake_up_locked_key(wait_queue_head_t *q, unsigned int mode, void *key);  void __wake_up_sync_key(wait_queue_head_t *q, unsigned int mode, int nr, void *key);  void __wake_up_locked(wait_queue_head_t *q, unsigned int mode, int nr);  void __wake_up_sync(wait_queue_head_t *q, unsigned int mode, int nr);  void __wake_up_bit(wait_queue_head_t *, void *, int); -int __wait_on_bit(wait_queue_head_t *, struct wait_bit_queue *, int (*)(void *), unsigned); -int __wait_on_bit_lock(wait_queue_head_t *, struct wait_bit_queue *, int (*)(void *), unsigned); +int __wait_on_bit(wait_queue_head_t *, struct wait_bit_queue *, wait_bit_action_f *, unsigned); +int __wait_on_bit_lock(wait_queue_head_t *, struct wait_bit_queue *, wait_bit_action_f *, unsigned);  void wake_up_bit(void *, int);  void wake_up_atomic_t(atomic_t *); -int out_of_line_wait_on_bit(void *, int, int (*)(void *), unsigned); -int out_of_line_wait_on_bit_lock(void *, int, int (*)(void *), unsigned); +int out_of_line_wait_on_bit(void *, int, wait_bit_action_f *, unsigned); +int out_of_line_wait_on_bit_lock(void *, int, wait_bit_action_f *, unsigned);  int out_of_line_wait_on_atomic_t(atomic_t *, int (*)(atomic_t *), unsigned);  wait_queue_head_t *bit_waitqueue(void *, int); @@ -854,11 +856,14 @@ int wake_bit_function(wait_queue_t *wait, unsigned mode, int sync, void *key);  		(wait)->flags = 0;					\  	} while (0) + +extern int bit_wait(struct wait_bit_key *); +extern int bit_wait_io(struct wait_bit_key *); +  /**   * wait_on_bit - wait for a bit to be cleared   * @word: the word being waited on, a kernel virtual address   * @bit: the bit of the word being waited on - * @action: the function used to sleep, which may take special actions   * @mode: the task state to sleep in   *   * There is a standard hashed waitqueue table for generic use. This @@ -867,9 +872,62 @@ int wake_bit_function(wait_queue_t *wait, unsigned mode, int sync, void *key);   * call wait_on_bit() in threads waiting for the bit to clear.   * One uses wait_on_bit() where one is waiting for the bit to clear,   * but has no intention of setting it. + * Returned value will be zero if the bit was cleared, or non-zero + * if the process received a signal and the mode permitted wakeup + * on that signal. + */ +static inline int +wait_on_bit(void *word, int bit, unsigned mode) +{ +	if (!test_bit(bit, word)) +		return 0; +	return out_of_line_wait_on_bit(word, bit, +				       bit_wait, +				       mode); +} + +/** + * wait_on_bit_io - wait for a bit to be cleared + * @word: the word being waited on, a kernel virtual address + * @bit: the bit of the word being waited on + * @mode: the task state to sleep in + * + * Use the standard hashed waitqueue table to wait for a bit + * to be cleared.  This is similar to wait_on_bit(), but calls + * io_schedule() instead of schedule() for the actual waiting. + * + * Returned value will be zero if the bit was cleared, or non-zero + * if the process received a signal and the mode permitted wakeup + * on that signal. + */ +static inline int +wait_on_bit_io(void *word, int bit, unsigned mode) +{ +	if (!test_bit(bit, word)) +		return 0; +	return out_of_line_wait_on_bit(word, bit, +				       bit_wait_io, +				       mode); +} + +/** + * wait_on_bit_action - wait for a bit to be cleared + * @word: the word being waited on, a kernel virtual address + * @bit: the bit of the word being waited on + * @action: the function used to sleep, which may take special actions + * @mode: the task state to sleep in + * + * Use the standard hashed waitqueue table to wait for a bit + * to be cleared, and allow the waiting action to be specified. + * This is like wait_on_bit() but allows fine control of how the waiting + * is done. + * + * Returned value will be zero if the bit was cleared, or non-zero + * if the process received a signal and the mode permitted wakeup + * on that signal.   */  static inline int -wait_on_bit(void *word, int bit, int (*action)(void *), unsigned mode) +wait_on_bit_action(void *word, int bit, wait_bit_action_f *action, unsigned mode)  {  	if (!test_bit(bit, word))  		return 0; @@ -880,7 +938,6 @@ wait_on_bit(void *word, int bit, int (*action)(void *), unsigned mode)   * wait_on_bit_lock - wait for a bit to be cleared, when wanting to set it   * @word: the word being waited on, a kernel virtual address   * @bit: the bit of the word being waited on - * @action: the function used to sleep, which may take special actions   * @mode: the task state to sleep in   *   * There is a standard hashed waitqueue table for generic use. This @@ -891,9 +948,61 @@ wait_on_bit(void *word, int bit, int (*action)(void *), unsigned mode)   * wait_on_bit() in threads waiting to be able to set the bit.   * One uses wait_on_bit_lock() where one is waiting for the bit to   * clear with the intention of setting it, and when done, clearing it. + * + * Returns zero if the bit was (eventually) found to be clear and was + * set.  Returns non-zero if a signal was delivered to the process and + * the @mode allows that signal to wake the process. + */ +static inline int +wait_on_bit_lock(void *word, int bit, unsigned mode) +{ +	if (!test_and_set_bit(bit, word)) +		return 0; +	return out_of_line_wait_on_bit_lock(word, bit, bit_wait, mode); +} + +/** + * wait_on_bit_lock_io - wait for a bit to be cleared, when wanting to set it + * @word: the word being waited on, a kernel virtual address + * @bit: the bit of the word being waited on + * @mode: the task state to sleep in + * + * Use the standard hashed waitqueue table to wait for a bit + * to be cleared and then to atomically set it.  This is similar + * to wait_on_bit(), but calls io_schedule() instead of schedule() + * for the actual waiting. + * + * Returns zero if the bit was (eventually) found to be clear and was + * set.  Returns non-zero if a signal was delivered to the process and + * the @mode allows that signal to wake the process. + */ +static inline int +wait_on_bit_lock_io(void *word, int bit, unsigned mode) +{ +	if (!test_and_set_bit(bit, word)) +		return 0; +	return out_of_line_wait_on_bit_lock(word, bit, bit_wait_io, mode); +} + +/** + * wait_on_bit_lock_action - wait for a bit to be cleared, when wanting to set it + * @word: the word being waited on, a kernel virtual address + * @bit: the bit of the word being waited on + * @action: the function used to sleep, which may take special actions + * @mode: the task state to sleep in + * + * Use the standard hashed waitqueue table to wait for a bit + * to be cleared and then to set it, and allow the waiting action + * to be specified. + * This is like wait_on_bit() but allows fine control of how the waiting + * is done. + * + * Returns zero if the bit was (eventually) found to be clear and was + * set.  Returns non-zero if a signal was delivered to the process and + * the @mode allows that signal to wake the process.   */  static inline int -wait_on_bit_lock(void *word, int bit, int (*action)(void *), unsigned mode) +wait_on_bit_lock_action(void *word, int bit, wait_bit_action_f *action, unsigned mode)  {  	if (!test_and_set_bit(bit, word))  		return 0; | 
