/*!
 * Process syscalls
 * (syscall is forwarded from arch interrupt subsystem to k_syscall)
 */
void k_syscall ( uint irqn )
{
	int id, retval;
	void *act_thr, *context, *params;

	ASSERT ( irqn == SOFTWARE_INTERRUPT );

	act_thr = k_get_active_thread ();
	context = k_get_thread_context ( act_thr );

	id = arch_syscall_get_id ( context );

	ASSERT ( id >= 0 && id < SYSFUNCS );

	params = arch_syscall_get_params ( context );

	retval = k_sysfunc[id] ( params );

	if ( id != THREAD_EXIT )
		arch_syscall_set_retval ( context, retval );
}
Пример #2
0
/*! Callback function called when a signal is delivered to suspended thread */
static int ksignal_received_signal ( kthread_t *kthread, void *param )
{
	siginfo_t *sig;
	context_t *context;
	uint sysid;
	void *p;
	sigset_t *set;
	siginfo_t *info;
	int retval = EXIT_SUCCESS;

	ASSERT ( kthread );

	/* thread waked by signal or other event? */
	if ( param == NULL )
	{
		kthread_set_errno ( kthread, EINTR );
		kthread_set_syscall_retval ( kthread, EXIT_FAILURE );

		return EXIT_FAILURE; /* other event interrupted thread */
	}

	/* signal interrupted, but did thread waited for this signal? */
	sig = param;

	/* get syscall which caused thread to be suspend */
	context = kthread_get_context ( kthread );
	sysid = arch_syscall_get_id ( context );

	switch ( sysid )
	{
	case SIGWAITINFO: /* sigwaitinfo */
		p = arch_syscall_get_params ( context );

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

		ASSERT ( set );
		set = U2K_GET_ADR ( set, kthread_get_process (NULL) );
		ASSERT ( set );

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

		retval = EXIT_FAILURE;

		if ( sigtestset ( set, sig->si_signo ) )
		{
			retval = sig->si_signo;
			kthread_set_syscall_retval ( kthread, retval );

			if ( info )
				*info = *sig;

			kthread_set_errno ( kthread, EXIT_SUCCESS );

			/* resume with thread */
			kthread_move_to_ready ( kthread, LAST );

			kthreads_schedule ();

			return EXIT_SUCCESS;
		}
		else {
			/* not waiting for this signal */
			return EXIT_FAILURE;
		}
	default:
		return EXIT_FAILURE;
	}
}