[funini.com] -> [kei@sodan] -> Kernel Reading

root/include/linux/freezer.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. frozen
  2. freezing
  3. set_freeze_flag
  4. clear_freeze_flag
  5. thaw_process
  6. try_to_freeze
  7. freezer_do_not_count
  8. freezer_count
  9. freezer_should_skip
  10. set_freezable
  11. set_freezable_with_signal
  12. frozen
  13. freezing
  14. set_freeze_flag
  15. clear_freeze_flag
  16. thaw_process
  17. refrigerator
  18. freeze_processes
  19. thaw_processes
  20. try_to_freeze
  21. freezer_do_not_count
  22. freezer_count
  23. freezer_should_skip
  24. set_freezable
  25. set_freezable_with_signal

/* Freezer declarations */

#ifndef FREEZER_H_INCLUDED
#define FREEZER_H_INCLUDED

#include <linux/sched.h>
#include <linux/wait.h>

#ifdef CONFIG_PM_SLEEP
/*
 * Check if a process has been frozen
 */
static inline int frozen(struct task_struct *p)
{
        return p->flags & PF_FROZEN;
}

/*
 * Check if there is a request to freeze a process
 */
static inline int freezing(struct task_struct *p)
{
        return test_tsk_thread_flag(p, TIF_FREEZE);
}

/*
 * Request that a process be frozen
 */
static inline void set_freeze_flag(struct task_struct *p)
{
        set_tsk_thread_flag(p, TIF_FREEZE);
}

/*
 * Sometimes we may need to cancel the previous 'freeze' request
 */
static inline void clear_freeze_flag(struct task_struct *p)
{
        clear_tsk_thread_flag(p, TIF_FREEZE);
}

/*
 * Wake up a frozen process
 *
 * task_lock() is taken to prevent the race with refrigerator() which may
 * occur if the freezing of tasks fails.  Namely, without the lock, if the
 * freezing of tasks failed, thaw_tasks() might have run before a task in
 * refrigerator() could call frozen_process(), in which case the task would be
 * frozen and no one would thaw it.
 */
static inline int thaw_process(struct task_struct *p)
{
        task_lock(p);
        if (frozen(p)) {
                p->flags &= ~PF_FROZEN;
                task_unlock(p);
                wake_up_process(p);
                return 1;
        }
        clear_freeze_flag(p);
        task_unlock(p);
        return 0;
}

extern void refrigerator(void);
extern int freeze_processes(void);
extern void thaw_processes(void);

static inline int try_to_freeze(void)
{
        if (freezing(current)) {
                refrigerator();
                return 1;
        } else
                return 0;
}

/*
 * The PF_FREEZER_SKIP flag should be set by a vfork parent right before it
 * calls wait_for_completion(&vfork) and reset right after it returns from this
 * function.  Next, the parent should call try_to_freeze() to freeze itself
 * appropriately in case the child has exited before the freezing of tasks is
 * complete.  However, we don't want kernel threads to be frozen in unexpected
 * places, so we allow them to block freeze_processes() instead or to set
 * PF_NOFREEZE if needed and PF_FREEZER_SKIP is only set for userland vfork
 * parents.  Fortunately, in the ____call_usermodehelper() case the parent won't
 * really block freeze_processes(), since ____call_usermodehelper() (the child)
 * does a little before exec/exit and it can't be frozen before waking up the
 * parent.
 */

/*
 * If the current task is a user space one, tell the freezer not to count it as
 * freezable.
 */
static inline void freezer_do_not_count(void)
{
        if (current->mm)
                current->flags |= PF_FREEZER_SKIP;
}

/*
 * If the current task is a user space one, tell the freezer to count it as
 * freezable again and try to freeze it.
 */
static inline void freezer_count(void)
{
        if (current->mm) {
                current->flags &= ~PF_FREEZER_SKIP;
                try_to_freeze();
        }
}

/*
 * Check if the task should be counted as freezeable by the freezer
 */
static inline int freezer_should_skip(struct task_struct *p)
{
        return !!(p->flags & PF_FREEZER_SKIP);
}

/*
 * Tell the freezer that the current task should be frozen by it
 */
static inline void set_freezable(void)
{
        current->flags &= ~PF_NOFREEZE;
}

/*
 * Tell the freezer that the current task should be frozen by it and that it
 * should send a fake signal to the task to freeze it.
 */
static inline void set_freezable_with_signal(void)
{
        current->flags &= ~(PF_NOFREEZE | PF_FREEZER_NOSIG);
}

/*
 * Freezer-friendly wrappers around wait_event_interruptible() and
 * wait_event_interruptible_timeout(), originally defined in <linux/wait.h>
 */

#define wait_event_freezable(wq, condition)                             \
({                                                                      \
        int __retval;                                                   \
        do {                                                            \
                __retval = wait_event_interruptible(wq,                 \
                                (condition) || freezing(current));      \
                if (__retval && !freezing(current))                     \
                        break;                                          \
                else if (!(condition))                                  \
                        __retval = -ERESTARTSYS;                        \
        } while (try_to_freeze());                                      \
        __retval;                                                       \
})


#define wait_event_freezable_timeout(wq, condition, timeout)            \
({                                                                      \
        long __retval = timeout;                                        \
        do {                                                            \
                __retval = wait_event_interruptible_timeout(wq,         \
                                (condition) || freezing(current),       \
                                __retval);                              \
        } while (try_to_freeze());                                      \
        __retval;                                                       \
})
#else /* !CONFIG_PM_SLEEP */
static inline int frozen(struct task_struct *p) { return 0; }
static inline int freezing(struct task_struct *p) { return 0; }
static inline void set_freeze_flag(struct task_struct *p) {}
static inline void clear_freeze_flag(struct task_struct *p) {}
static inline int thaw_process(struct task_struct *p) { return 1; }

static inline void refrigerator(void) {}
static inline int freeze_processes(void) { BUG(); return 0; }
static inline void thaw_processes(void) {}

static inline int try_to_freeze(void) { return 0; }

static inline void freezer_do_not_count(void) {}
static inline void freezer_count(void) {}
static inline int freezer_should_skip(struct task_struct *p) { return 0; }
static inline void set_freezable(void) {}
static inline void set_freezable_with_signal(void) {}

#define wait_event_freezable(wq, condition)                             \
                wait_event_interruptible(wq, condition)

#define wait_event_freezable_timeout(wq, condition, timeout)            \
                wait_event_interruptible_timeout(wq, condition, timeout)

#endif /* !CONFIG_PM_SLEEP */

#endif  /* FREEZER_H_INCLUDED */

/* [<][>][^][v][top][bottom][index][help] */

[funini.com] -> [kei@sodan] -> Kernel Reading