Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 26 Nov 1999 22:08:29 -0500
From:      "Daniel M. Eischen" <eischen@vigrid.com>
To:        Julian Elischer <julian@whistle.com>
Cc:        arch@freebsd.org
Subject:   Re: Threads stuff
Message-ID:  <383F4B2D.C0E9182F@vigrid.com>
References:  <Pine.BSF.4.10.9911261633040.544-100000@current1.whistle.com>

next in thread | previous in thread | raw e-mail | index | archive | help
Julian Elischer wrote:
> 
> firstly:
> 
>  You HAVE to sing this to get the full effect....
>                    -(-(--_
>                  / ( (    \       DO-RE-MI  BEER,by Homer J. Simpson.
>                 |          |
>                 |          |      DOUGH... the stuff...
>                 |     __  __)          that buys me beer...
>                 |    /  \/  \     RAY..... the guy that
>                /\/\ (o   )o  )    sells me beer...
>               /c    \__/ --.      ME...... the guy...
>               (              )    who drinks the beer,
>                \_   _-------'     FAR..... the distance to my beer.
>                 |  /         \    SO...... I think I'll have a beer.
>                 | | '\_______)    LA...... La, la la la la beer
>                 |  \_____)        TEA..... no thanks,
>                 |_____ |                   I'm drinking beer...
>                 |______/\/\       That will bring us back to...
>                /         \             (Looks into an empty glass)
>                                   D'OH!
> 
> Now that we have that out of the way:
> 
> On Fri, 26 Nov 1999, Daniel M. Eischen wrote:
> 
> > Julian Elischer wrote:
> > >
> > > > 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?
> > >
> > > When the syscall blocks, the saved information above is to be turned into
> > > a full frame. The PC (eip) is added (pointing to where we want it to
> > > resume when the IO completes) and the thread is set up looking as though
> > > it's waiting on it's  IO completion block. The UTS gets (actualy should
> > > already know) the KSE-ID.
> > >
> > > On completion of the IO, the io completion block is updated
> > > just as it would have been had the syscall not blocked, and
> > > the KSE is hung off the  subprocess. When the subprocess is next run,
> > > an upcall is made to the UTS, with some ID to let it know which
> > > completion block to look at. This is simply the same as is some
> > > other thread had released a mutex. The whole KSE in fact need not be hung
> > > off the subproc because all that is needed is the single mutex address
> > > to report.
> >
> > So when the IO completion block is updated, how exactly is the
> > the thread continued?  It _has_ to go back into the kernel in
> > order to resume.  I don't see the similarity between threads
> > blocked in userland (on a mutex) and threads blocked in the
> > kernel.
> 
> The thread context is entirely in user space.
> it is waitomg on a mutex that will tell it that some other thread
> (in this cas the kernel)  has completed tranfering the data it requested
> and has updated the io status block.
> 
> it was 'transformed' to this when it was reported blocked by the
> first upcall. Since most of the status was alreday present on the (user)
> stack, all that was required at that time was it's entry into the
> mutex hash table and it's eip to be modified so that when it is run it
> thinks it has completed the IO. it will then proceed exactly as though
> the IO had been completed synchronously.. i.e. checks the status in the
> IO status block and retunrs to it's caller.
> 
> Each thread has a pernamently assigned IO status block and it's errno
> lives there. The contents of the IO status block are updated when the
> KSE that was blocked returns. SInce it was blocked it then hangs itself
> (or a proxy) off the sub-proc "unblocked" queue. Had it not blocked,
> it would simply update the status block and retunr to the userland
> which would check the status and return to the caller.
> 
> code path in library for (write);
> 
>         set IO status to 'incomplete'
>         setjmp(mycontext)  /* save all the regs in thread context*/
>         set saved  mycontext->eip to point to 'A'
>         call kernel
>         lngjmp (mycontext)
>         /* notreached */
> 
> B:
>         while status == incomplete
>                 wait on mutex in IO status block
> A:
>         check status
>         return to calling code
> 
> ----
> 
> when the thread is reported blocked:
> the return mycontect->eip is changed from "A" to "B"
> code is run to put the thread into whatever
> structures the UTS maintains for mutexes. That completes all processing.
> It then goes on to schedule another thread.
> from the thread's point of view, it has just woken up from waiting
> on a mutex. The IO is mysteriously complete.
> 
> >
> > > > 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.
> > >
> > > If the userland context of the thread looks just like the context of
> > > any other thread, then you just run it.
> > > When the thread is reported as blocked, you fiddle the context it left
> > > behind to make it look like it's blocked on a mutex on the io completion
> > > block.  when the syscall completes, the result is the equivalent of
> > > releasing that mutex. i.e. the thread continues.
> >
> > What I don't quite see yet is how you resume a thread at the kernel
> > level.  You can't just "run the thread" after the IO control block
> > was updated indicating that the thread unblocked.  You need to resume
> > the thread within the kernel.  As long as you need a kernel call to
> > resume/cancel a blocked thread, why try to hide it behind smoke and
> > mirrors ;-)
> 
> No you don't need to go back to the kernel.
> All kernel processing has completed.
> All your upcall needs is the address of the IO completion block that contains
> the mutex to release. All copyin()s and copyout()s have been completed, and the
> IO status block has been updated, just as if the call would
> have been synchronous. (in fact the code that did it didn't know that it
> was not going to go back to the user.)
> just before it was going to go back to the user, it checked a bit and
> discoverd that instead, it should hang itself (or a small struct holding the
> address of the IO completion block) off the subproc. (If the latter the
> KSE can actually be freed now). At some stage in the future (maybe immediatly)
> an upcall reports to the UTS the addresses of all completed IO status blocks,
> and the UTS releases all the mutexes.
> 
> >
> > Dan Eischen
> > eischen@vigrid.com
> >
> >
> >
> >
> > To Unsubscribe: send mail to majordomo@FreeBSD.org
> > with "unsubscribe freebsd-arch" in the body of the message
> >




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?383F4B2D.C0E9182F>