Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 11 Jul 2001 08:41:37 -0400 (EDT)
From:      Daniel Eischen <eischen@vigrid.com>
To:        Julian Elischer <julian@elischer.org>
Cc:        Jason Evans <jasone@canonware.com>, arch@FreeBSD.ORG
Subject:   Re: help needed in threads.. (Signals)
Message-ID:  <Pine.SUN.3.91.1010711081420.15505C-100000@pcnet1.pcnet.com>
In-Reply-To: <3B4BDBB1.AF248E58@elischer.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, 10 Jul 2001, Julian Elischer wrote:
> Julian Elischer wrote:
> to continue my own thoughts:
> 
> The reasoning for interrupting syscalls is so that a program can decide to 
> abort or do other syscalls, because there is no sureness that the syscall 
> doesnt hold resources. In our case if we run the signal handler in a separate 
> kernel thread (an upcall) we really don't care what the other syscalls are doing
> in fact if we didcare it would be a bug.
> 
> ( If it comes to the user boundary before doing the signal then 
> it has cleaned everything up and cannot be holding resources.)
> 
> The only reason that a user would want a signal sent to a particular thread
> in this case would be toachieve what was originally the side effect of
> interrupting
> the syscall. The handler could be run from any thread's stack as long as it
> could do it's work. I think therefore that one way to do what we want would be
> to
> simply do the handler directly from the upcall, and then interrupt
> the appropriate thread if it happens to be in the kernel. In other words
> we explicitly create the side-effect if asked to do so.
> 
> I guess that the restartabiliy is so that arbitrary unaltered programs
> can be stopped with SIGSTOP and restarted with SIGCONT, without 
> needing to handle these situations. A restartable syscall in threads is easy....
> don't interrupt it in the first place!. If the thread decides to do something
> that
> causes teh program to exit, then that syscall will have to be cleaned up in
> exactly the same manner as all the others.
> (which brings up the case of what to do if one thread is in an UNINTERRUPTABLE
> syscall when another does an exit().)

You can't really handle the signal in _any_ stack or thread.  It really
has to be handled in the one thread that should get the signal.  And
if that thread is blocked in the kernel, then you need to make its
context current before running the handler.  Please remember that
the UTS does _not_ know if the thread has longjmp'd (or equivalent)
out of the handler.

	static int
	some_rtn(int fd)
	{
		char	buf[1024];
		int	ret;
		jmp_buf	jb;

		if (setjmp(jb) == 0)
			ret = read(fd, buf, sizeof(buf));
		else
			ret = -1;
		return (ret);
	}

Now substitute a compiler generated __builtin_setjmp() instead of
setjmp (in case you were to argue that the threads library could
wrap setjmp/longjmp).  I know that the Ada compiler (GNAT) uses
this for implementing exception blocks, and I had to make libc_r
work so that it did not have to know if a signal handler did
an abnormal return.

In the example above, read() is reading into a stack variable.
You can't run the handler while the kernel is potentially
corrupting the stack.  The blocked thread in the kernel _must_
be suspended.

And what happens if you don't make the blocked thread (context)
in the kernel current before running the handler?  Since the
blocked thread (in the kernel) can't be resumed until the
handler returns, and since the UTS may have no idea if the
handler has abnormally returned via some type of longjmp,
the blocked thread in the kernel can be there until the
application ends.  And this can happen repeatedly.

-- 
Dan Eischen

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-arch" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.SUN.3.91.1010711081420.15505C-100000>