site_archiver@lists.apple.com Delivered-To: darwin-kernel@lists.apple.com -- Terry _______________________________________________ Do not post admin requests to the list. They will be ignored. Darwin-kernel mailing list (Darwin-kernel@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/darwin-kernel/site_archiver%40lists.a... On Dec 16, 2006, at 9:51 AM, Joseph Oreste Bruni wrote: On Dec 15, 2006, at 8:24 PM, Terry Lambert wrote: Let me say up front that I don't believe this is a kernel problem, and the "showallstacks" command should confirm that there are still stacks running in the process. You may end up (if it has already been taken off the active process list) having to track down the task from the zombie list, if it doesn't show up in the task list - meaning it won't show in the "showallstacks". Perhaps I don't understand at Apple's implementation layer what happens to a thread during a pthread_join(). My understanding of pthread_join() is that the calling thread blocks until the referenced thread terminates either explicitly by a call to pthread_exit(), implicitly by returning from the thread's main routine, or by terminating at a cancellation point after having been cancelled, that pthread_join() is analogous to waitpid() (without the WNOHANG option). So, a stack continues to exist even after it has been joined? Are stacks then cleaned up asynchronously? Or is there a subsequent *_np API I need to call to get stacks to get cleaned up? Every thread that I created I successfully joined without exception since I logged the thread IDs and accounted for them all. The answer to this question depends on whether you are using user managed stacks. If you are not using user managed stacks (i.e. you did not use pthread_attr_setstack()), then the stack will be freed automatically, either when you exit (if it's a detached thread), when you join the thread successfully (if it's not a detached thread) or on process exit. If you explicitly manage the stacks yourself instead, then you pass the address of an allocated stack (and should probably call pthread_attr_setstacksize() when you call pthread_attr_setstackaddr(), if you make your area anything other than DEFAULT_STACK_SIZE, which is 512K). But for most uses, it's cleaned up for you (this all happens in user space in Libc, so it's not hung in the kernel over this particular issue). I'll see what I can do about the kernel debugging. Assuming there is yet another thread hanging around, I have no idea what I would be changing in my code beyond what I'm doing now. There are a lot of things that could cause this to be a problem; for example, if you have a thread blocked on a semaphore owned by a thread that you destroy; there's no resource tracking that would cause that thread to wake up until someone (*anyone* with rights on it) decrements the semaphore, or the pthread in question is signalled via pthread_kill(). Using "top", the number of threads ("#TH") in the running program is exactly equal to the number I'm creating plus the main thread, so I have no idea what other threads could be hiding. If a process is in P_WEXIT, by the time it gets to where it's going to exit, there should be 1 thread on its way back through the AST to calling proc_exit() (this _does_ happen in the kernel). Effectively, you have to drain out all other active threads for the thread that called exit() to run to completion to an actual exit of the process. P_EXIT is generally never visible unless you hit at exactly the right submicrosecond in a single threaded program; for a multithreaded program, the state lasts until the other threads which are blocked in the kernel unblock and terminate. This email sent to site_archiver@lists.apple.com