Skip to content

Commit

Permalink
select: Introduce a hrtimeout function
Browse files Browse the repository at this point in the history
This patch adds a schedule_hrtimeout() function, to be used by select() and
poll() in a later patch. This function works similar to schedule_timeout()
in most ways, but takes a timespec rather than jiffies.

With a lot of contributions/fixes from Thomas

Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
  • Loading branch information
Arjan van de Ven committed Sep 6, 2008
1 parent 70bb089 commit 7bb6743
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 0 deletions.
2 changes: 2 additions & 0 deletions include/linux/hrtimer.h
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,8 @@ extern long hrtimer_nanosleep_restart(struct restart_block *restart_block);
extern void hrtimer_init_sleeper(struct hrtimer_sleeper *sl,
struct task_struct *tsk);

extern int schedule_hrtimeout(ktime_t *expires, const enum hrtimer_mode mode);

/* Soft interrupt function to run the hrtimer queues: */
extern void hrtimer_run_queues(void);
extern void hrtimer_run_pending(void);
Expand Down
65 changes: 65 additions & 0 deletions kernel/hrtimer.c
Original file line number Diff line number Diff line change
Expand Up @@ -1678,3 +1678,68 @@ void __init hrtimers_init(void)
#endif
}

/**
* schedule_hrtimeout - sleep until timeout
* @expires: timeout value (ktime_t)
* @mode: timer mode, HRTIMER_MODE_ABS or HRTIMER_MODE_REL
*
* Make the current task sleep until the given expiry time has
* elapsed. The routine will return immediately unless
* the current task state has been set (see set_current_state()).
*
* You can set the task state as follows -
*
* %TASK_UNINTERRUPTIBLE - at least @timeout time is guaranteed to
* pass before the routine returns.
*
* %TASK_INTERRUPTIBLE - the routine may return early if a signal is
* delivered to the current task.
*
* The current task state is guaranteed to be TASK_RUNNING when this
* routine returns.
*
* Returns 0 when the timer has expired otherwise -EINTR
*/
int __sched schedule_hrtimeout(ktime_t *expires,
const enum hrtimer_mode mode)
{
struct hrtimer_sleeper t;

/*
* Optimize when a zero timeout value is given. It does not
* matter whether this is an absolute or a relative time.
*/
if (expires && !expires->tv64) {
__set_current_state(TASK_RUNNING);
return 0;
}

/*
* A NULL parameter means "inifinte"
*/
if (!expires) {
schedule();
__set_current_state(TASK_RUNNING);
return -EINTR;
}

hrtimer_init_on_stack(&t.timer, CLOCK_MONOTONIC, mode);
t.timer.expires = *expires;

hrtimer_init_sleeper(&t, current);

hrtimer_start(&t.timer, t.timer.expires, mode);
if (!hrtimer_active(&t.timer))
t.task = NULL;

if (likely(t.task))
schedule();

hrtimer_cancel(&t.timer);
destroy_hrtimer_on_stack(&t.timer);

__set_current_state(TASK_RUNNING);

return !t.task ? 0 : -EINTR;
}
EXPORT_SYMBOL_GPL(schedule_hrtimeout);

0 comments on commit 7bb6743

Please sign in to comment.