From owner-freebsd-arch Fri Jan 4 18:49:33 2002 Delivered-To: freebsd-arch@freebsd.org Received: from rwcrmhc53.attbi.com (rwcrmhc53.attbi.com [204.127.198.39]) by hub.freebsd.org (Postfix) with ESMTP id F41BD37C05B for ; Fri, 4 Jan 2002 18:40:08 -0800 (PST) Received: from InterJet.elischer.org ([12.232.206.8]) by rwcrmhc53.attbi.com (InterMail vM.4.01.03.27 201-229-121-127-20010626) with ESMTP id <20020105024007.NABW20122.rwcrmhc53.attbi.com@InterJet.elischer.org> for ; Sat, 5 Jan 2002 02:40:07 +0000 Received: from localhost (localhost.elischer.org [127.0.0.1]) by InterJet.elischer.org (8.9.1a/8.9.1) with ESMTP id SAA30686 for ; Fri, 4 Jan 2002 18:30:44 -0800 (PST) Date: Fri, 4 Jan 2002 18:30:43 -0800 (PST) From: Julian Elischer To: arch@freebsd.org Subject: freeing thread structures. Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-arch@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG Well I have the KSE kernel (with a lot of changes needed for multiple threads per process) up into single user mode. But here I hit a roadblock. It's been visible for a while but I had hoped that by the time I got here, I'd have seen an "nice" solution. When we free process structures after an exit(), we do it from the 'wait()'. There will always be one wait() for each exit(), even if it has to be done by init. But now the tricky question: where can we safely free items owned by a thread when a thread exits (including the last one freed by exit()). Here is a qhick rundown on the problem. When a thread (in the kernel) exits, the last thing it does is call thread_exit(), which calls cpu_throw() which is an alias for the second half of switch(). (It doesn't bother to save the context of the dying thread, just loads a new one). Obviously however the resources of the thread cannot be freed until the new context has been loaded, as it's still running on the old one until then. In mi_switch AFTER the switch to the new thread has been completed, (which is one possibility) the sched lock is held, so freeing any resource that wants to own a normal sleeping mutex would seem to be an instant panic. ANother possibility is to simply queue it for later freeing by another entity, but I REALLY would rather avoid having a reaper thread (or init) do it. John Baldwin has been talking abotu the possibility of puting it in a function called switch_exit() that can be called after switch has completed. Looking at that idea I think it has basically the same problem. I can't see it being able to release the sched lock. As a case in point the thread has a pointer to the processes ucred and this needs to do a crfree(). This in turn tries to get the mutex in the ucred. The thread itself is allocated from a zone (or maybe some other system in the future) which will inevitably have a mutex. In addition there is the kv space allocated to the stack and pcb, which probably will also require some such mutex safety. The question is is there some place on the outgoing side of mi_switch where we can guarantee that we do not have the sched lock? it doesn't look like it to me, but I might be wrong. Does anyone have any real cool ideas? BTW current state if I can get around this is that I have individual scheduling for threads and there is no more code in the scheduler that assumes that there is only one thread per proc. (well, very little code...). I'm about ready to add the syscalls to allow system calls to become asynchronous and to allow the upcalls when that happens. The code to actually DO the upcalls is in place as is the code to copy out the results of the async syscalls. (of course it's all untested, and some of it looks a bit "green".) To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-arch" in the body of the message