On Tue, Dec 1, 2020 at 5:48 AM Martin Pieuchot <m...@openbsd.org> wrote:
...

> exit1() for a multi-threaded process does the following:
>
>         atomic_setbits_int(&p->p_flag, P_WEXIT);
>         single_thread_check(p, 0);  // directly or via single_thread_set()
>         SMR_TAILQ_REMOVE_LOCKED(&pr->ps_threads, p, p_thr_link);
>
> Note that exit1() can't be called in parallel.
>

Well, multiple threads in a process can easily hit exit1() practically
concurrently, under the limitations of the kernel lock.  If anything in
exit1() sleeps, it has to be ready for some other thread to start into
exit1()!


If exit1() is called with EXIT_NORMAL, the current thread will start by
> setting `ps_single' then iterate over `ps_thread'.  This is done before
> updating `ps_thread' so there's no race in that case.
>
> If exit1() is called with EXIT_THREAD, the current thread might end up
> removing itself from `ps_thread' while another one is iterating over it.
> Since we're currently concerned about the iteration in single_thread_set()
> notice that `P_WEXIT' is checked first.  So if my understanding is correct
> is should be enough to do the following:
>
>         SMR_TAILQ_REMOVE_LOCKED(&pr->ps_threads, p, p_thr_link);
>         smr_barrier();
>
> That would delays exit1() a bit but doesn't involve callback which is
> IMHO simpler.
>
> Did I miss anything?
>

What does it take to be sure that an "is empty" (or "only contains one")
test is _really_ true with SMR?

Philip

Reply via email to