Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 26 Nov 1999 18:07:32 -0500
From:      "Daniel M. Eischen" <eischen@vigrid.com>
To:        freebsd-arch@freebsd.org
Subject:   [Fwd: Threads stuff]
Message-ID:  <383F12B4.DB0AC9C0@vigrid.com>

next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------0B9A3253ADCB1E12297D5F04
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

 
--------------0B9A3253ADCB1E12297D5F04
Content-Type: message/rfc822
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

Return-Path: <eischen@vigrid.com>
Received: from vigrid.com (pm3-pt30.pcnet.net [206.105.29.104])
	by pcnet1.pcnet.com (8.8.7/PCNet) with ESMTP id SAA21196;
	Fri, 26 Nov 1999 18:00:30 -0500 (EST)
Sender: deischen@pcnet.com
Message-ID: <383F1109.48AB132D@vigrid.com>
Date: Fri, 26 Nov 1999 18:00:25 -0500
From: "Daniel M. Eischen" <eischen@vigrid.com>
X-Mailer: Mozilla 4.5 [en] (X11; I; FreeBSD 4.0-CURRENT i386)
X-Accept-Language: en
MIME-Version: 1.0
To: Julian Elischer <julian@whistle.com>
Subject: Re: Threads stuff
References: <Pine.BSF.4.10.9911261302570.544-100000@current1.whistle.com>
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
X-Mozilla-Status2: 00000000

Julian Elischer wrote:
> 
> > No, those are blocked in kernel space.  Their respective KSEs are
> > shown hung off of proc P1 and P2.  Oops, the kse_blockedq and
> > kse_unblockedq tags on proc P1 are reversed.  P1->kse_blockedq
> > should read kse_unblockedq, and P1->kse_unblockedq should read
> > kse_blockedq.
> 
> ok but then in your diagram you should show some threads blocked in
> userland as well.

OK

> > Threads blocked in user space (let's say waiting on a mutex), don't
> > have a KSE.
> 
> exactly.
> 
> But I was thinking of what context the UTS had access to for the thread.
> For example, could the UTS time-out an IO and return a 'failed' result
> and restart a thread that  had made an IO request, even though the IO
> hadn't returned? If all the context that was needed to restart a thread
> blocked in the kernel was available to teh UTS then that saved thread info
> must be pretty much the same as what a thread blocked in the userland must
> be.

For the most part, the UTS doesn't need the context for threads blocked
on I/O.  It just needs to know how to resume and cancel them.  If we
optimize for the common case, then we don't need to make the context
of the blocked thread available to the UTS.  For threads that are
preempted, the UTS only needs the program counter.

If you wanted to be able to time-out an I/O from the UTS (not a common
case, we don't do it now), you could then add a system call to return
the context of a blocked thread based on its unique KSE ID.  This could
also be used to retrieve the context of a thread that was preempted in
the unlikely chance it was in a critical region.

For threads that block in the kernel, we also need to save the kernel
register set and stack.  This will be stored in a KSE and we'll switch
to a different KSE to return back to userland.  The UTS still needs
some way of identifying the KSE to be resumed.  In your new syscall
gate, are you returning something back from the kernel that can be
used to identify the KSE that blocked?

> > I don't think we want to require a kernel call to resume a thread
> > that is blocked in user space, right?  And I really don't think we
> > want KSEs for every thread in an application, right?
> 
> no, though you are suggesting it in other email because you say you need
> to block/unblock signals, and your {s,g}et_context calls would require it.

In an MT application, I think we can ignore signal masks for individual
threads.  As long as we have a method that lets the UTS act as signal
proxy anyways.  Actually, we should be able to safely use _setjmp/_longjmp
instead of setjmp/longjmp now in libc_r.  The UTS wouldn't use {g,s}etcontext
other than for initially creating the UTS event handlers.

> >
> > So other than the above, threads blocked in user space and threads
> > blocked in kernel space are exactly the same.  There will just be
> > a flag and perhaps KSE ID in the user thread struct to indicate
> > whether it can be resumed with a _longjmp or a thread_resume(2).
> 
> After a UTS has been notified that a thread has blocked in the kernel,
> it should end up being identical to one that is blocked in user space,
> except it is waiting on an event that the kernel must supply
> (i.e. an IO completion block or something.)
> 
> Until it is notified of the blocking it is 'running'

Right.

> > Hmm, I was under the impression it was on the USER stack.  Isn't
> > that why we have to copyin/copyout to access the trapframe from
> > the kernel?
> 
> I need my x86 book, but it's at work..
> 
> /*
>  * Call gate entry for FreeBSD ELF Linux/NetBSD syscall (int 0x80)
>  */
>         SUPERALIGN_TEXT
> IDTVEC(int0x80_syscall)
>         subl    $8,%esp                 /* skip over tf_trapno and tf_err
> */

At this point, doesn't %esp point at the user stack?  Or does the
int 0x80 somehow change the segments to be kernel segments?

>         pushal                  <----
>         pushl   %ds                     <----
>         pushl   %es                     <----
>         pushl   %fs                     <----
>         movl    $KDSEL,%eax             /* switch to kernel segments */

The above comment is what confuses me.  This makes me think that the
push{al,l} statements above work on the user stack.

> we've already switched to the kernel stack.
> and we save all the regs (pushal) abd then the segment registers.
> the stack segment has already been changed I think.

OK, so the int 0x80 trap does switch segment registers and we
are already on the kernel stack by the time that int0x80_syscall
is entered?

> 
> Of course if I need my x86 book it might not work for alpha..
> but if the syscall itself did: (this is my version of the 'syscall()' syscall.)
> ENTRY(syscall)
>         pop     %ecx    /* rta */
>         pop     %eax    /* syscall number */
>         push    %ecx
>         pushal                  <-----------
>         pushl   %ds             <-----------
>         pushl   %es             <-----------
>         pushl   %fs             <-----------
>         KERNCALL
>         call _UTS_syscall_end   <-----------  may decide to schedule something else.

What information is passed to _UTS_syscall_end?  In the case that the
thread blocks, is event information passed?

>         popal                   <-----------
>         popl    %fs             <-----------
>         popl    %es             <-----------
>         popl    %ds             <-----------
>         push    %ecx    /* need to push a word to keep stack frame intact
>                            upon return; the word must be the return address. */
>         jb      1f
>         ret
> 1:
>         PIC_PROLOGUE
>         jmp     PIC_PLT(HIDENAME(cerror)) <-- not needed.. already in return status b
> 
> then the same stuff would not be needed in the first code segment
> and all that context would be available to the UTS immediatly without
> needing it to cross the kernel boundary at all.

Why does the UTS need any of this, though?  It just needs notification
that the thread blocked and some "thingy" that can be used to resume
or cancel it?

> The only problem I see is we would have to be very careful about getting a pagefault
> while saving it.. pagefaults on stack segments are allowed to block?

Sounds OK to me.  I think the "Adding SA to Mach 3.0" paper talked about
how pagefaults were handled.

> > I think I follow you, but diagrams would help :-)  Would there be some
> > sort of unique ID returned from a blocked syscall, so that the UTS could
> > later resume/cancel the thread?
> 
> the blockage notification is from the syscall you think you are doing.

How do you resume the thread?  Longjmp'ing to the blocked system call
won't work because the kernel doesn't know if it's a new system call
or one that is being resumed.

Dan Eischen
eischen@vigrid.com


--------------0B9A3253ADCB1E12297D5F04--





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?383F12B4.DB0AC9C0>