Date: Mon, 7 Apr 2003 07:53:21 -0400 (EDT) From: Daniel Eischen <eischen@pcnet1.pcnet.com> To: Julian Elischer <julian@elischer.org> Cc: freebsd-threads@freebsd.org Subject: Re: PS_BLOCKED Message-ID: <Pine.GSO.4.10.10304070730480.9723-100000@pcnet1.pcnet.com> In-Reply-To: <Pine.BSF.4.21.0304062258430.55025-100000@InterJet.elischer.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Sun, 6 Apr 2003, Julian Elischer wrote: > > On Sun, 6 Apr 2003, Daniel Eischen wrote: > > > On Sun, 6 Apr 2003, Julian Elischer wrote: > > > > > > If you have this behaviour, please make it an option. Possibly > > > One way to do this would be to call kse_create, with the > > > 'new-ksegrp' flag set but the mailbox pointer set to NULL. > > > > > > However why do you want to use kse_release for this. > > > If you have only one thread in the KSEGRP then I'd call this > > > "usleep()". > > > > It's so that the common code (called by both scope system > > threads and scope process threads) can be the same. I don't > > want to have to add checks all over the place to see if the > > KSE is bound to a thread or not. Also, nanosleep doesn't > > work well because you can't wake it up with a KSE mailbox > > (kse_wakeup), plus there's a race condition if you try and > > wake it up before it actually gets to the kernel to sleep. > > The kse_wakeup() call is latched, so if it gets to the kernel > > first, the next kse_release() will notice it. > > you cannot wake up a thread with no upcall mailbox using kse_wakeup > because there is no thread mailbox address to match. There is a kse mailbox, but no thread mailbox. I'm trying to wakeup a KSE. What I do for multiple threaded KSEs is: upcall_start(struct kse_mailbox *kse_mbox) { struct kse *curkse = (struct kse *)kse_mbx->km_udata; check_completed(kse); check_waitq(kse); ... while ((td_run = runq_first(kse->k_kseg) == NULL) { get_smallest_thread_wakeup_time(kse, &time_to_sleep); kse->k_waiting = 1; kse_release(&time_to_sleep) } /* switch to thread td_run */ } Although, for multiple threaded KSEs, the "while" loop only executes once because kse_release just causes another upcall. If another KSE makes a thread runnable in the first KSEs KSEG's runq, then it wakes up that KSE: _thr_setrunnable(struct kse *curkse, struct pthread *thread) { SCHED_LOCK(curkse); runq_insert(thread->kseg, thread); SCHED_UNLOCK(curkse); if ((thread->kse->k_kseg != curkse->k_kseg) && (thread->kse->k_waiting != 0)) { thread->kse->k_waiting = 0; kse_wakeup(&thread->kse->k_mbox); } } or something like that. For a single threaded KSE/KSEG, I don't want the upcall but I still want to use kse_release(). I need to be able to wakeup that KSE so that it may continue it's thread (it could be the thread was in pthread_cond_wait() and it was signalled by a thread in another KSE). And I don't want upcalls on this KSE because there is only one thread; I don't want the overhead of the upcall and its stack. And in order to prevent upcalls, I have to make sure the kse mailbox has NULL in km_curthread. That's the solution I'm looking for. I think kse_wakeup() should be tweakable so that I don't get an upcall. -- Dan Eischen
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.GSO.4.10.10304070730480.9723-100000>