/* In all cases the return value is guaranteed to be non-negative.  */
signed long __sched schedule_timeout(signed long timeout)
/* In all cases the return value is guaranteed to be non-negative.  */
signed long __sched schedule_timeout(signed long timeout)
{
	struct timer_list timer;
	unsigned long expire;
	switch (timeout)
	{
	case MAX_SCHEDULE_TIMEOUT:
		schedule();
		goto out;
	default:
		if (timeout < 0) {
			printk(KERN_ERR "schedule_timeout: wrong timeout "
				"value %lx\n", timeout);
			dump_stack();
			current->state = TASK_RUNNING;
			goto out;
		}
	}
	expire = timeout + jiffies;
	setup_timer_on_stack(&timer, process_timeout, (unsigned long)current);
	__mod_timer(&timer, expire, false, TIMER_NOT_PINNED);
	schedule();
	del_singleshot_timer_sync(&timer);
	destroy_timer_on_stack(&timer);
	timeout = expire - jiffies;
 out:
	return timeout < 0 ? 0 : timeout;
}