Date: Wed, 24 Nov 1999 09:03:29 -0500 From: "Daniel M. Eischen" <eischen@vigrid.com> To: Julian Elischer <julian@whistle.com> Cc: freebsd-arch@freebsd.org Subject: Re: Threads Message-ID: <383BF031.B52BC41F@vigrid.com> References: <Pine.BSF.4.10.9911232348550.11412-100000@current1.whistle.com>
next in thread | previous in thread | raw e-mail | index | archive | help
Julian Elischer wrote: > > I think that the easiest context to create is one that you create by just > being there. It's self correcting in the face of compiler changes etc. Well, that's how getcontext and makecontext work also, except the application supplies the stack to use, as opposed to using the current stack. I don't see there being much difference between our ideas. > > > I'm not that fussed about it but it just seems to me that the information > > > being passed back and forth is DIFFERENT than that being passed back and > > > forth in the non-threaded world. > > > > True, but it is passed back and forth in NEW ways. It doesn't affect > > non-MT system calls. > > That's where I disagree. > I think nearly all syscalls can block given page faults etc. and having all > syscalls potentially return via the UTS is going to mean some change > in the kernel/process protocol. I guess we just disagree on how the kernel is entered. I just don't see why we need to change the method of entering the kernel. We just want to switch to a new context (UTS) when a KSE blocks, and that can be done from within the kernel without changing the method entering the kernel. > If a blocked syscall returns, then when it returns the UTS needs to > be able to decide whether it is the most important thread to continue or not. > So it can't just 'return', but has to come back via the UTS. This requires > that things be considerably different. At least this is how I see it. Right. And just because it woke up from a tsleep doesn't mean that it will eventually be able to finish and return to userland. It may encounter more tsleeps before leaving the kernel. The UTS needs to enter the kernel in order to resume the thread. And it needs a way of telling the kernel which blocked KSE to resume. The UTS is notified that a KSE has unblocked, but it doesn't have to immediately resume it - other threads may have higher priority. I think we are in agreement here. I'm just advocating using the stack of the UTS event handler context (in the form of parameters to the event handlers) to tell the UTS that threads have blocked/unblocked in the kernel. There doesn't have to be any magic/wizardry in the system calling convention to do this. The kernel can return directly to the predefined UTS event handlers (also on a predefined stack) and totally bypass the original system call in which it entered the kernel. At some point later, the UTS resumes the (now unblocked) KSE and returns the same way it entered. You also want the ability to inform the UTS of _more_ than just one event at a time. Several KSEs may unblock before a subprocess is run. You should be able to notify the UTS of them all at once. How does that work in your method? > > The UTS knows what thread was running and marks it as blocked > > in the kernel and saves the unique KSE ID. > > > > How does it know what was running? How can it not know? It was the last thread scheduled. It _has_ to know which threads are running on which processes in order to effectively schedule them. Our current threads library knows what thread is currently running - it is kept in _thread_run. We need to be able to retrieve TSD from a register, or perhaps per-process data mapped at the same address but still accessible to other subprocesses. Can we play games with %gs and/or LDTs? On the Alpha, can we just use an S register? I dunno. Another problem that really needs to be solved. > > When the process runs again (or the next subprocess, since you > > can have more than 1 cooperating processes), a new KSE is > > allocated and context is set to the relevent UTS event handler. > > Event information is copied out to the top of the predefined > > user stack, parameters set accordingly, and the kernel returns > > to the UTS event handler. If a thread was preempted for the > > notification, then its context (just like getcontext(2)) is > > also copied out to the UTS event handler user stack. > > I think we agree here. > My only point is that a lot of this can be achieved using stack munging and > that we don't need to create a lot of special frame handling and > context saving if we use the saved state that si already existant in the stacks. I think we can do this with just an ID for a KSE. The kernel will save it's own registers, and it knows where the trapframe is. Can't it just save a pointer to the trapframe in the KSE, switch to a new KSE and the UTS eventhandler frame, and pass an ID for the blocked KSE back out to the UTS event handler? > > The UTS resumes the blocked thread in one of two ways. A new > > system call to resume the KSE identified by it's unique ID is > > one way. The other way is to have the kernel copy the context > > of the unblocked KSE out to the UTS event handler. It can be > > resumed with setcontext(2). > > I think that I'd like to see this shown with simulated stacks and such > in pictures.. I think you and I are in agreement, but having > trouble saying that. :-) Pictures would be nice. I'll work on some over the Thanksgiving break. Dan Eischen eischen@vigrid.com 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?383BF031.B52BC41F>