On Wed, Jul 17, 2013 at 10:42 AM, Sandro Magi <[email protected]>wrote:
> I'm confused by what seems to be a topic-shift. We started by discussing > finalization on task-local resources, but you're here discussing > finalization that falls entirely outside this scope. > Or perhaps I am confused. This, of course, has *never* happened before. :-) :-) >From my perspective, the confusion starts with using the word "finalization" in the context of task exit. There are two things that this might mean, and I'm not sure which one was intended: 1. Execution of finalizer code within the task before the task vanishes. This is "finalization" in the sense that the GC world uses the term. 2. Cleanup of underlying OS/runtime/whatever as a consequence of task exit. In the OS world this is sometimes referred to as "resource cleanup", and it happens at a layer of the system that is logically below the application. Indeed, the whole point of this cleanup is that the process is no longer around, and can't clean up after itself. Can I suggest that we reserve "finalization" for discussion of in-app activities (GC style), and use "task cleanup" or "resource cleanup" to refer to what happens in the next layer down on task exit/destroy? But I think there was a second, simultaneous confusion, because it wasn't clear to me whether the "task" we are discussing has some relationship to an underlying (kernel or runtime) thread or is just a runtime trick in the language runtime. If it has an underlying (kernel) thread, then it has an identity that is recognizable by the layer beneath the application, and the task is thereby able to hold kernel-layer resources directly. Conversely, if there is no association between a language layer task and a kernel layer thread, then either a task cannot hold kernel resources or the runtime has to implement some form of tracking to remember which runtime-owned resources were associated with that runtime-implemented task. Which can be done, but it's tricky. To add to the confusion: if the runtime is tracking the association, then we can indeed talk about finalization in the first (GC) sense happening for purposes of task resource cleanup, but in that case it happens in the task management subsystem of the language runtime. As a matter of implementation, it probably makes more sense for the task runtime to simply run through the per-task resource tracking data and close things down explicitly. In the "close things down explicitly" scenario, I *really* want to avoid using the term finalization - that term is already bound for other uses. Regardless of the implementation, finalization (in the sense of 1) is *never * prompt. In all practical implementations, resource reclamation *is* prompt, up to release of certain low-level resources associated with hardware devices or network connections. In some cases the release of those must be delayed until timeouts are satisfied or the hardware state machine moves to a suitable state for resource teardown. I think that's below the level you're concerned about. It's "prompt enough". By definition, I expect all finalization of task-local resources to > happen within a task scope before it exits. The point is what semantics > one should expect when one receives a "task X exited" indication: should > all resources held by X always be finalized and reclaimed at this point? > It seems so, just as we would expect from OS processes. > I think you are engaged in a layering confusion. If a task exits voluntarily, then of course finalization (1 above) and resource cleanup (2 above) can occur without difficulty. The finalization phase will not be prompt, because finalization is never prompt, but I don't think that really gets in the way of what you are saying. The contract requirement is that finalization be completed before exit. Note, however, that this may require several GC passes, because progressive finalizations may release more heap resources, and the release of those resources, in turn, may trigger further finalization. So there are some gory ugly details there, and it's possible that an object requiring finalization remains "live" until the lights are turned off for that task. Once the task is done, that finalizer can't run. The "fix" for this is to make sure that the voluntary exit conditions and behavior are well-specified. BUT If a task exits *involuntarily* - that is, it is *killed* - that is another matter entirely. When we kill a task we are performing an operation at the kernel layer of abstraction, and we are requiring, affirmatively, that no further instructions in that task be executed. In consequence, finalization (in the GC sense, which runs within the task, by definition) will not, cannot, and must not be run. kernel-layer resource reclamation, or comparable reclamation in the language-level task runtime, is fine and * should* be run. Whether that reclamation is prompt is a consequence of the underlying (kernel or language) runtime implementation. Your expectation of promptness is reasonable, and I agree that it's good policy and good practice, but it's not really something that the next layer up (the task layer) is entitled to specify. Jonathan
_______________________________________________ bitc-dev mailing list [email protected] http://www.coyotos.org/mailman/listinfo/bitc-dev
