Ah, ok, immediately after I sent this I happened to find a paragraph that said if you try to kill your parent and all their descendants, you'll get to yourself and stop. I'm not sure if that's intended or "intended" (ie that's what it did so that's in the spec), but at least that clarifies things.
Gabe On Wed, Jun 27, 2018 at 10:07 PM Gabe Black <[email protected]> wrote: > Hi systemc gurus. I have a question about systemc processes throwing > exceptions at each other, including the sc_unwind_exception when calling > kill() or reset() on a process handle. > > What *should* happen when you call, for instance, kill() on your parent > process and tell it to include descendants? As far as I can tell, that > will, through tail recursion, descend into the hierarchy and start killing > at the most descended child. I'll assume all child processes are threads > just to simplify the discussion since thread vs. method behavior is > different. > > When it gets to a particular child, it will mark that child's > "m_throw_status" as THROW_KILL, telling it to throw a killing exception > when it wakes up. It will then adjust the run queue order so that that > process is next, and it is second in line. It then suspends itself, letting > the target child run. That child wakes up in the suspend_me method, and > then it checks its m_throw_status, see's it's supposed to kill itself, and > throws a relevant sc_unwind_exception. Then once that process is dead, the > next thread in the queue is the one that is driving the whole process, and > it gets run again to continue the cycle of infanticide. > > There is a check which makes sure no process which is currently > "unwinding", ie which is in the process of dealing with an > sc_unwind_exception, is affected by a call to kill() or reset(), but > there's no check that the process being killed is not the process who is > driving the whole proceedings if it is, at some point it will mark *itself* > as THROW_KILL, mark itself to be next (that case is handled separately in > the scheduling logic), and then suspend itself to immediately wake up > again. It will then see that it's supposed to THROW_KILL, which I think it > will, immediately stopping the function walking through children. > > So if you have a hierarchy of processes like this: > > A -> B -> C > > And while running B you call A.kill() and include descendants, you'll kill > B and C, but not A. That seems wrong. Is there some way that this all works > out that I'm not seeing, or some rule I can't find which says this is an > illegal situation? Is this the intended behavior somehow? > > I think there are a lot of other corner cases which come from running the > exception dispersing code from one of the potential (direct or indirect) > targets. Another one would be, what if the exception you're throwing was > stack allocated, you catch an exception yourself, and now the exception you > were throwing earlier has been deallocated? That can't happen under the > current scheme since you'd just stop throwing it at all when you caught > your own exception, but it would be a problem if the previous behavior was > "corrected" to include all the initial targets of the kill, reset, etc. > > Also what happens if the process hierarchy changes while an exception is > being propagated? I have a feeling some loop somewhere might skip new > processes, or fall off the end of an array or something. If there was a > rule or check somewhere that disallowed that it wouldn't be a problem, but > I don't see anything like that. > > Gabe > _______________________________________________ gem5-dev mailing list [email protected] http://m5sim.org/mailman/listinfo/gem5-dev
