Пример #1
0
static void 
thr_suspender(void *arg)
{
	struct thread *td = (struct thread *) arg;
	int error;

	for (;;) {
		if (QUIT == 1)
			break;
		error = kthread_suspend(td, 10*hz);
		if (error != 0 && QUIT == 0) {
			if (error == EWOULDBLOCK)
				panic("Ooops: kthread deadlock\n");
			else 
				panic("kthread_suspend error: %d\n", error);
			break;
		}
	}

	mtx_lock(&test_global_lock);
	test_thrcnt--;
	wakeup(&global_condvar);
	mtx_unlock(&test_global_lock);

	kthread_exit();
}
Пример #2
0
/*!
 * Suspend thread until given time elapses
 * \param clockid Clock to use
 * \param flags Flags (TIMER_ABSTIME)
 * \param request Suspend duration
 * \param remain Remainder time if interrupted during suspension
 * \return status
 */
int sys__clock_nanosleep ( void *p )
{
	clockid_t clockid;
	int flags;
	timespec_t *request;
	timespec_t *remain;

	int retval = EXIT_SUCCESS;
	kthread_t *kthread = kthread_get_active ();
	ktimer_t *ktimer;
	sigevent_t evp;
	itimerspec_t itimer;

	clockid =	*( (clockid_t *) p );	p += sizeof (clockid_t);
	flags =		*( (int *) p );		p += sizeof (int);
	request =	*( (timespec_t **) p );	p += sizeof (timespec_t *);
	remain =	*( (timespec_t **) p );

	ASSERT_ERRNO_AND_EXIT (
	    (clockid==CLOCK_REALTIME || clockid==CLOCK_MONOTONIC) &&
	    request && TIME_IS_SET(request),
	    EINVAL
	);

	/* Timers are used for "sleep" operations through steps 1-4 */

	/* 1. create timer, but not arm it yet */
	evp.sigev_notify = SIGEV_WAKE_THREAD;
	evp.sigev_value.sival_ptr = kthread;
	evp.sigev_notify_function = kclock_wake_thread;

	retval += ktimer_create ( clockid, &evp, &ktimer, kthread );
	ASSERT ( retval == EXIT_SUCCESS );

	/* save remainder location, if provided */
	ktimer->param = remain;

	/* 2. suspend thread */
	kthread_set_private_param ( kthread, ktimer );
	retval += kthread_suspend ( kthread, kclock_interrupt_sleep, ktimer );
	ASSERT ( retval == EXIT_SUCCESS );

	/* 3. arm timer */
	TIME_RESET ( &itimer.it_interval );
	itimer.it_value = *request;

	retval += ktimer_settime ( ktimer, flags, &itimer, NULL );
	ASSERT ( retval == EXIT_SUCCESS );

	/* 4. pick other thread as active */
	kthreads_schedule ();

	EXIT ( retval );
}
Пример #3
0
/*!
 * Wait for signal
 * \param set Signals thread is waiting for
 * \param info Where to save caught signal
 * \return signal number if signal is caught,
 *         -1 otherwise and appropriate error number is set
 */
int sys__sigwaitinfo ( void *p )
{
	sigset_t *set;
	siginfo_t *info;

	kthread_t *kthread;
	ksignal_handling_t *sh;
	ksiginfo_t *ksig, *next;
	int retval;

	set =   *( (sigset_t **) p );		p += sizeof (sigset_t *);
	info =  *( (siginfo_t **) p );

	ASSERT_ERRNO_AND_EXIT ( set, EINVAL );
	set = U2K_GET_ADR ( set, kthread_get_process (NULL) );
	ASSERT_ERRNO_AND_EXIT ( set, EINVAL );

	if ( info )
		info = U2K_GET_ADR ( info, kthread_get_process (NULL) );

	kthread = kthread_get_active ();
	sh = kthread_get_sigparams ( kthread );

	/* first, search for such signal in pending signals */
	ksig = list_get ( &sh->pending_signals, FIRST );
	while ( ksig )
	{
		next = list_get_next ( &ksig->list );

		if ( sigtestset ( set, ksig->siginfo.si_signo ) )
		{
			retval = ksig->siginfo.si_signo;
			if ( info )
				*info = ksig->siginfo;

			list_remove ( &sh->pending_signals, 0, &ksig->list );
			kfree ( ksig );

			EXIT2 ( EXIT_SUCCESS, retval );
		}

		ksig = next;
	}

	/*
	 * if no pending signal found that matches given mask
	 * suspend thread until signal is received
	 */
	kthread_suspend ( kthread, ksignal_received_signal, NULL );
	kthreads_schedule ();

	EXIT ( EINTR ); /* if other events wake thread */
}
Пример #4
0
void
kthread_shutdown(void *arg, int howto)
{
	struct thread *td;
	int error;

	if (panicstr)
		return;

	td = (struct thread *)arg;
	printf("Waiting (max %d seconds) for system thread `%s' to stop... ",
	    kproc_shutdown_wait, td->td_name);
	error = kthread_suspend(td, kproc_shutdown_wait * hz);

	if (error == EWOULDBLOCK)
		printf("timed out\n");
	else
		printf("done\n");
}