コード例 #1
0
/* Delete a POSIX.1b interval timer. */
asmlinkage long
sys_timer_delete(timer_t timer_id)
{
	struct k_itimer *timer;
	long flags;

retry_delete:
	timer = lock_timer(timer_id, &flags);
	if (!timer)
		return -EINVAL;

	if (timer_delete_hook(timer) == TIMER_RETRY) {
		unlock_timer(timer, flags);
		goto retry_delete;
	}

	spin_lock(&current->sighand->siglock);
	list_del(&timer->list);
	spin_unlock(&current->sighand->siglock);
	/*
	 * This keeps any tasks waiting on the spin lock from thinking
	 * they got something (see the lock code above).
	 */
	if (timer->it_process) {
		if (timer->it_sigev_notify == (SIGEV_SIGNAL|SIGEV_THREAD_ID))
			put_task_struct(timer->it_process);
		timer->it_process = NULL;
	}
	unlock_timer(timer, flags);
	release_posix_timer(timer, IT_ID_SET);
	return 0;
}
コード例 #2
0
/* Delete a POSIX.1b interval timer. */
SYSCALL_DEFINE1(timer_delete, timer_t, timer_id)
{
	struct k_itimer *timer;
	unsigned long flags;

retry_delete:
	timer = lock_timer(timer_id, &flags);
	if (!timer)
		return -EINVAL;

	if (timer_delete_hook(timer) == TIMER_RETRY) {
		unlock_timer(timer, flags);
		goto retry_delete;
	}

	spin_lock(&current->sighand->siglock);
	list_del(&timer->list);
	spin_unlock(&current->sighand->siglock);
	/*
	 * This keeps any tasks waiting on the spin lock from thinking
	 * they got something (see the lock code above).
	 */
	timer->it_signal = NULL;

	unlock_timer(timer, flags);
	release_posix_timer(timer, IT_ID_SET);
	return 0;
}
コード例 #3
0
/* Get the time remaining on a POSIX.1b interval timer. */
SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id,
		struct itimerspec __user *, setting)
{
	struct itimerspec cur_setting;
	struct k_itimer *timr;
	struct k_clock *kc;
	unsigned long flags;
	int ret = 0;

	timr = lock_timer(timer_id, &flags);
	if (!timr)
		return -EINVAL;

	kc = clockid_to_kclock(timr->it_clock);
	if (WARN_ON_ONCE(!kc || !kc->timer_get))
		ret = -EINVAL;
	else
		kc->timer_get(timr, &cur_setting);

	unlock_timer(timr, flags);

	if (!ret && copy_to_user(setting, &cur_setting, sizeof (cur_setting)))
		return -EFAULT;

	return ret;
}
コード例 #4
0
ファイル: timer.c プロジェクト: AgamAgarwal/minix
/*****************************************************************************
 *    remove_timer                                                           *
 ****************************************************************************/
static void remove_timer(int id)
{
	/* removes a timer from the timer list */
	struct ddekit_timer_s *l,*m;  
	
	lock_timer();

	for (l = &list; l &&  l->next && l->next->id!=id; l = l->next )
		;

	if (l && l->next) {
		m = l->next;

		DDEBUG_MSG_VERBOSE(
		    "deleting  timer at for tick: %d fn: %p, (now: %d)\n",
			m->exp, m->fn, jiffies);

		l->next = m->next;
		DDEBUG_MSG_TIMER(m);

		ddekit_simple_free(m); 
	}
	
	unlock_timer();
}
コード例 #5
0
ファイル: timer.c プロジェクト: AgamAgarwal/minix
/*****************************************************************************
 *    _ddekit_timer_update                                                   *
 ****************************************************************************/
void _ddekit_timer_update()
{
	lock_timer();

	static myclock_t next_timout;
	if(list.next)
	{
		if(!_ddekit_timer_pending || list.next->exp < next_timout) {
			
			unsigned to = list.next->exp - jiffies;
			
			_ddekit_timer_pending = 1;
			
			if (list.next->exp <= jiffies) {
				DDEBUG_MSG_WARN("Timeout lies in past to %d, now: %d",
					list.next->exp, jiffies);
				to = 1;
			}
			
			sys_setalarm(to, 0 /* REL */);

			DDEBUG_MSG_VERBOSE("requesting alarm for clock tick %d , now %d",
				list.next->exp, jiffies);
		}
		next_timout = list.next->exp;
	}
	unlock_timer(); 
}
コード例 #6
0
ファイル: timer.c プロジェクト: AgamAgarwal/minix
/*****************************************************************************
 *    insert_timer                                                           *
 ****************************************************************************/
static int insert_timer(struct ddekit_timer_s *t)
{ 
	/* inserts a timer to the timer list */
	int ret;
	
	lock_timer(); 
	
	struct ddekit_timer_s *l;
	
	for (l = &list; l->next && l->next->exp <= t->exp; l = l->next) {
			
	}
	
	t->next = l->next;  
	l->next = t;
	
	t->id   = ret = _id;
	
	_id++;
	
	if (_id==0) { 
		DDEBUG_MSG_WARN("Timer ID overflow...");
	}

	DDEBUG_MSG_TIMER(t);

	unlock_timer();

	return ret;
}
コード例 #7
0
ファイル: timer.c プロジェクト: AgamAgarwal/minix
/*****************************************************************************
 *    ddekit_timer_pending                                                   *
 ****************************************************************************/
int ddekit_timer_pending(int timer)
{ 
	int ret=0;
	struct ddekit_timer_s *t;
	lock_timer();
	for (t=list.next; t; t = t->next) { 
		if (t->id==timer) {  
			ret = 1;
		}
			
	}
	unlock_timer();
	return ret;
}
コード例 #8
0
/*
 * Get the number of overruns of a POSIX.1b interval timer.  This is to
 * be the overrun of the timer last delivered.  At the same time we are
 * accumulating overruns on the next timer.  The overrun is frozen when
 * the signal is delivered, either at the notify time (if the info block
 * is not queued) or at the actual delivery time (as we are informed by
 * the call back to do_schedule_next_timer().  So all we need to do is
 * to pick up the frozen overrun.
 */
SYSCALL_DEFINE1(timer_getoverrun, timer_t, timer_id)
{
	struct k_itimer *timr;
	int overrun;
	unsigned long flags;

	timr = lock_timer(timer_id, &flags);
	if (!timr)
		return -EINVAL;

	overrun = timr->it_overrun_last;
	unlock_timer(timr, flags);

	return overrun;
}
コード例 #9
0
/*
 * Get the number of overruns of a POSIX.1b interval timer.  This is to
 * be the overrun of the timer last delivered.  At the same time we are
 * accumulating overruns on the next timer.  The overrun is frozen when
 * the signal is delivered, either at the notify time (if the info block
 * is not queued) or at the actual delivery time (as we are informed by
 * the call back to do_schedule_next_timer().  So all we need to do is
 * to pick up the frozen overrun.
 */
asmlinkage long
sys_timer_getoverrun(timer_t timer_id)
{
	struct k_itimer *timr;
	int overrun;
	long flags;

	timr = lock_timer(timer_id, &flags);
	if (!timr)
		return -EINVAL;

	overrun = timr->it_overrun_last;
	unlock_timer(timr, flags);

	return overrun;
}
コード例 #10
0
ファイル: posix-timers.c プロジェクト: garyvan/openwrt-1.6
/* Set a POSIX.1b interval timer */
SYSCALL_DEFINE4(timer_settime, timer_t, timer_id, int, flags,
		const struct itimerspec __user *, new_setting,
		struct itimerspec __user *, old_setting)
{
	struct k_itimer *timr;
	struct itimerspec new_spec, old_spec;
	int error = 0;
	unsigned long flag;
	struct itimerspec *rtn = old_setting ? &old_spec : NULL;
	struct k_clock *kc;

	if (!new_setting)
		return -EINVAL;

	if (copy_from_user(&new_spec, new_setting, sizeof (new_spec)))
		return -EFAULT;

	if (!timespec_valid(&new_spec.it_interval) ||
	    !timespec_valid(&new_spec.it_value))
		return -EINVAL;
retry:
	timr = lock_timer(timer_id, &flag);
	if (!timr)
		return -EINVAL;

	rcu_read_lock();
	kc = clockid_to_kclock(timr->it_clock);
	if (WARN_ON_ONCE(!kc || !kc->timer_set))
		error = -EINVAL;
	else
		error = kc->timer_set(timr, flags, &new_spec, rtn);

	unlock_timer(timr, flag);
	if (error == TIMER_RETRY) {
		timer_wait_for_callback(kc, timr);
		rtn = NULL;	// We already got the old time...
		rcu_read_unlock();
		goto retry;
	}
	rcu_read_unlock();

	if (old_setting && !error &&
	    copy_to_user(old_setting, &old_spec, sizeof (old_spec)))
		error = -EFAULT;

	return error;
}
コード例 #11
0
/*
 * This function is exported for use by the signal deliver code.  It is
 * called just prior to the info block being released and passes that
 * block to us.  It's function is to update the overrun entry AND to
 * restart the timer.  It should only be called if the timer is to be
 * restarted (i.e. we have flagged this in the sys_private entry of the
 * info block).
 *
 * To protect aginst the timer going away while the interrupt is queued,
 * we require that the it_requeue_pending flag be set.
 */
void do_schedule_next_timer(struct siginfo *info)
{
	struct k_itimer *timr;
	unsigned long flags;

	timr = lock_timer(info->si_tid, &flags);

	if (timr && timr->it_requeue_pending == info->si_sys_private) {
		if (timr->it_clock < 0)
			posix_cpu_timer_schedule(timr);
		else
			schedule_next_timer(timr);

		info->si_overrun = timr->it_overrun_last;
	}

	unlock_timer(timr, flags);
}
コード例 #12
0
ファイル: timer.c プロジェクト: AgamAgarwal/minix
/*****************************************************************************
 *    get_next                                                               *
 ****************************************************************************/
static struct ddekit_timer_s * get_next( myclock_t exp )
{  
	/*
	 * this one get the next timer, which's timeout expired,
	 * returns NULL if no timer is pending
	 */
	struct ddekit_timer_s * ret = 0;
	lock_timer();
	if (list.next)
	{ 
		if (list.next->exp <= exp)
		{ 
			ret  = list.next;
			list.next = ret->next;
		}
	}
	unlock_timer();
	return ret;
}
コード例 #13
0
ファイル: posix-timers.c プロジェクト: AvengerMoJo/apc-8750
/* Get the time remaining on a POSIX.1b interval timer. */
SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id,
		struct itimerspec __user *, setting)
{
	struct k_itimer *timr;
	struct itimerspec cur_setting;
	unsigned long flags;

	timr = lock_timer(timer_id, &flags);
	if (!timr)
		return -EINVAL;

	CLOCK_DISPATCH(timr->it_clock, timer_get, (timr, &cur_setting));

	unlock_timer(timr, flags);

	if (copy_to_user(setting, &cur_setting, sizeof (cur_setting)))
		return -EFAULT;

	return 0;
}
コード例 #14
0
/* Set a POSIX.1b interval timer */
SYSCALL_DEFINE4(timer_settime, timer_t, timer_id, int, flags,
		const struct itimerspec __user *, new_setting,
		struct itimerspec __user *, old_setting)
{
	struct k_itimer *timr;
	struct itimerspec new_spec, old_spec;
	int error = 0;
	unsigned long flag;
	struct itimerspec *rtn = old_setting ? &old_spec : NULL;

	if (!new_setting)
		return -EINVAL;

	if (copy_from_user(&new_spec, new_setting, sizeof (new_spec)))
		return -EFAULT;

	if (!timespec_valid(&new_spec.it_interval) ||
	    !timespec_valid(&new_spec.it_value))
		return -EINVAL;
retry:
	timr = lock_timer(timer_id, &flag);
	if (!timr)
		return -EINVAL;

	error = CLOCK_DISPATCH(timr->it_clock, timer_set,
			       (timr, flags, &new_spec, rtn));

	unlock_timer(timr, flag);
	if (error == TIMER_RETRY) {
		hrtimer_wait_for_timer(&timr->it.real.timer);
		rtn = NULL;	// We already got the old time...
		goto retry;
	}

	if (old_setting && !error &&
	    copy_to_user(old_setting, &old_spec, sizeof (old_spec)))
		error = -EFAULT;

	return error;
}
コード例 #15
0
SYSCALL_DEFINE1(timer_delete, timer_t, timer_id)
{
	struct k_itimer *timer;
	unsigned long flags;

retry_delete:
	timer = lock_timer(timer_id, &flags);
	if (!timer)
		return -EINVAL;

	if (timer_delete_hook(timer) == TIMER_RETRY) {
		unlock_timer(timer, flags);
		goto retry_delete;
	}

	spin_lock(&current->sighand->siglock);
	list_del(&timer->list);
	spin_unlock(&current->sighand->siglock);
	timer->it_signal = NULL;

	unlock_timer(timer, flags);
	release_posix_timer(timer, IT_ID_SET);
	return 0;
}