A π-calculus with limited resources, garbage-collection and guarantees David Teller Abstract. Techniques such as mobility and distribution are often used to overcome limitations of resources such as the amount of memory or the necessity for specialized devices. Indeed, questions related to such limitations are crucial in matters of security, compilation or quality of service. However, few attempts have been made at formalizing the notion of limited resources in process algebras for mobility and distribution. In this paper, we present a π-calculus with semantics for allocation and deallocation of resources, including garbage-collection. We also produce a type system to provide guarantees of respect of complex protocols on resources. We demonstrate the interest of this controlled π-calculus by building a model of a complex resources manager for concurrent systems, with manual and automatic garbage-collection, error-handling and statically distributed and transmitted authorizations and resources. 1 Introduction In modern computer technologies, aspects of mobility, concurrency and distribution are nearly omnipresent. Software deployed on a system has often been built on a different system, possibly using a distributed Compile Farm, and channeled to the end-user through safe or unsafe means. Distributed Domain Name Servers, cache hierarchies or grid supercomputers achieve great efficiency, while consumer electronics is expected to take advantage of Cell [7] technologies in the near future to provide mostly transparent distribution of tasks among dynamically assembled arrays of processors. While these techniques are often used for the sake of convenience, as they correspond to the intuitive way of thinking about some problems, they are also often necessary to overcome limitations on resources. For instance, tasks such as building large software projects or computing large sets of data for numerical analysis typically require amounts of memory or CPU power not found on individual computers, while in many organizations, documents are commonly sent to print servers, as client PCs do not have their own printing resource. Several attempts [6, 8] have been made at modelling the usage of resources for mobility. However, few of these attempts take into account the fact that many resources are both limited and used concurrently. In this study, we attempt to go further, by taking into account notions of 2 David Teller allocation, deallocation, reallocation of previously deallocated resources and garbage-collection. This document presents a process algebra based on the π-calculus, the controlled π calculus, or cπ, built upon ideas previously expressed in the previous incarnation of the controlled π-calculus [11] and in BoCa [2]. The foremost concept is that of resource. Resources are abstract representations of notions such as memory space, file access rights or printers. Resources may be allocated to entities such as variables, file handlers or print requests. The language construction corresponding to entities is the channel name. Thus, allocation and deallocation of resources to entities are modelled by creation and destruction of names. From this conception of resources, we enrich the π-calculus with notions of resource usage, allocation and deallocation. In the controlled π-calculus, if we consider the creation of name a by the transition new a in j −→ (νa)j , new a in j is a process which creates a new name a and then behaves as j while process (νa)j is a process which behaves as j but can use a new channel name a. In turn, process (νa)j uses more resources than j as some resources have been allocated to a. Hence, the transition cannot take place if there are not enough resources available for a. Conversely, if, for any reason, the following transition takes place (νa)j 0 −→ j 0 , the resources held by a have been freed and may be reused by a different process, possibly triggering transitions which were blocked by the lack of resources. The actual instant at which a resource is deallocated depends on a notion of garbage-collection. Although it is simple to remove a name when the corresponding channel has disappeared from any term, this is not the only circumstance in which a channel is never used again. For instance, in the following term, (νa)a?(x).j , the process has allocated resources for a and is expecting some input on a but, since no other process knows of a, the communication will never take place. That channel is therefore useless. A well-chosen garbage-collection scheme may decide to suppress (νa) and effectively remove the whole term, hence releasing resources. Complete enough garbage-collection schemes A π-calculus with limited resources, garbage-collection and guarantees 3 Processes P, Q ::= (νa : r)P | P |Q | i Instructions i, j ::= 0 | new a : r in i | spawn i in j | a?(b).i | a!hbi.i | ∗ i | if a = b then i else j Contexts C[·] ::= (νa : r)C[·] | C[·]|P | P |C[·] | [·] Figure 1: Syntax of cπ. may also free resources held by deadlocks or livelocks. Rather than choosing a specific garbage-collection algorithm, we use a parametric relation GC to determine when a channel may be removed.. This enriched controlled π-calculus is both simpler and more generic than the original cπ as well as more adapted to reasoning and programming with resources than the standard π-calculus. Well-chosen garbagecollectors permit dynamic handling of resources and exception-like error mechanisms. In turn, this allows the writing of processes which enforce resource usage policies. We complete the language by a type system, more powerful than that of the original cπ, to prove statically the respect of some such policies. In section 2, we introduce the revisited controlled π-calculus which we illustrate in section 3 with the example of print spooler, demonstrating possible usages of the primitives and garbage-collection. We then discuss in section 4 properties of the language and its relations with the π-calculus. Section 5 contains a type system for guarantees on resource usage. We conclude this paper by a review of related works and on-going developments. Full proof of properties may be found in the companion report of this paper [13]. 2 The language The syntax of cπ, as presented on figure 1, is similar to that of the πcalculus. We differenciate currently executed processes (P , Q. . . ) from instructions (i, j. . . ) waiting to be executed. Resources (r, s . . . ) are members of the a set of resources S, parameter of the language. Names (a, b. . . ) are elements of an infinite set N which also contains }, or ”null”, the name of deallocated channels, on which it is thus impossible to communicate. Process (νa : r)P holds resource r for its private name a and behaves as P , while process i executes the instructions i. Instruction new a : r in i allocates resource r to name a and proceeds as i, while spawn i in j produces two concurrent threads i and j. The other constructions are identical to their π-calculus counterpart. As a → → → syntactical shortcut, we will write − a for a1 , a2 . . . , an and (ν − a :− r ) for 4 David Teller (νa1 : r1 ) . . . (νan : rn ). The sets f n/bn of free/bound names are defined as in the π-calculus – note that f n((νa : r)i) = f n(new a : r in i) = f n(i)\{a} and that } is always free. The main difference between (ν) and new · · · in as well as between | and spawn · · · in is that the first construct of each pair describes a running process, while the second describes an instanciation instruction. In fact, an implementation of cπ might introduce constructors for new · · · in – representing different methods of generating an name – and for spawn · · · in – representing different natures and locations of instanciated processes. Definition 1 (Set of resources). A set of resources is a set (S, ⊕, ⊥, , >) such that ⊕ is commutative wherever it is defined, with neutral element ⊥, is a preorder on S with minimal element ⊥ and maximal element > and for all x, y, z, whenever x y holds, x ⊕ z y ⊕ z also holds. When x ⊕ x ⊕ · · · ⊕ x is defined, we note this infinite sum ∞ · x. Definition 2 (Resource held). A process P is said to hold resource res(P ), where res is defined by res((νa : r)P ) = res(P ) ⊕ r res(P |Q) = res(P ) ⊕ res(Q) res(i) =0 Note that the resource held by a process may change with time. Semantics The structural equivalence is defined as the smallest equivalence ≡, compatible with the axioms of figure 2 and with α-conversion of bound names. Resource-unaware semantics are defined as the smallest relation −→pre compatible with the axioms of figure 3. (νa : r)(νb : s)P ≡ (νb : s)(νa : r)P ∗t ≡ t| ∗ t a∈ / f v(Q) P ≡Q P ≡Q ((νa : r)P )|Q ≡ (νa : r)(P |Q) P |R ≡ Q|R (νa : r)P ≡ (νa : r)Q Figure 2: Structural equivalence of cπ. The semantics are very similar to those of a π-calculus with structural equivalence. Note, however, that we do not have (νa : r)0 ≡ 0, as (νa : r)0 holds resource r, while the right side holds no resource. As opposed to the A π-calculus with limited resources, garbage-collection and guarantees 5 previous incarnation of cπ, we do not specify (νa : r)0 −→pre 0 either, rather leaving this task to the parametric garbage-collection scheme. Rule Spawn executes the spawning of a new thread, while rule Channel executes the creation of a new channel, hence consuming resources. Rules Receive and Send differ from their π-calculus counterparts only insofar as no communication is allowed on a destroyed channel. Processes waiting for communication on } are rather garbage-collected by Gc-Receive, Gc-Send, Gc-RReceive and Gc-RSend. The destruction of a channel – and the corresponding release of resources held by the process – is handled by Gc-Deallocate. This rule depends on a parametric relation GC , which determines when a set of names can be removed. Note that, as opposed to the π-calculus, a name can be removed although it still appears syntactically in the term. This allows well-chosen garbage-collectors to clean processes such as (νa : r)a?(b).t and replace them by 0, as well as more complex scenarios. We provide more complete examples in section 3. Also note that it is possible to compare any names. In particular, if x = } then i else j will reduce to i if x has been destroyed and to j otherwise. In this respect, channel names behave as weak references in many programming languages. Definition 3 (Resource-aware Labelled Transition Semantics). The resource-aware LTS of an instance of cπ on the set of resources S with • GC a garbage-collector GC is defined by the relation 7−→ where α P −→pre Q res(Q) n α;n GC P 7−→ Q Note that, if the set of resources is infinite, many reductions of a process P into a process Q may be expressed with an infinite number of different labels. Definition 4 (Resource-aware semantics). The resource-aware semantics of an instance of cπ on the set of resources S with a resource limit of n ∈ S and with a garbage-collector GC is defined by the relation −→GC where n τ ;n GC P 7−→ Q Q P −→GC n Resource-aware semantics take into account the fact that a system has limited resources. When a resource is not available for a transition, that transition does not take place. Note that n represents a limit on the to- 6 David Teller tal level of resource used – for instance, the physical amount of memory on the computer running the program – and does not change during the reduction. On the other hand, the number of resources currently used, materialized by res(P ) and then res(Q) varies with time, increasing as a consequence of allocations and decreasing as a consequence of deallocations. As we will see in section 3, the garbage-collector can be used to provide error-handling mechanisms in case of resource exhaustion. 3 Example: A print spooler In this section, we attempt to model a simple print spooler – most of the techniques we expose here would be equally useful in the case of a system memory manager or any resource broker. This spooler maintains a pool of available printers, receives requests from clients and return a handler to any non-busy printer. Whenever the caller has finished with the printer, this resource is returned to the pool. If some requests had been put on hold, one of them is then unblocked and fulfilled. Figure 4 presents the low-level components of our spooler as well as the expected behaviour of a client. For the sake of simplicity, in the course of this example, we extend the syntax of cπ to support n-ary communications. The main components are P ush, a macro used to add (or return) a printer to the pool and P op, a macro used to take a printer from the pool, itself represented by P ool. The term Client is an example of a possible client: it sends a request on the predefined channel alloc, waits for the pair printer, destructor, uses printer as necessary, then deallocates by calling destructor and proceeds without using printer anymore. Straightfoward model Numerous strategies are possible for the ”implementation” of the print spooler. Figure 5 presents one possible technique: allocating a printer implies giving the client full access, while calling the destructor returns that printer to the pool, without any check. Garbage-collection scheme 1 permits garbage-collection of intermediate channels such as destructor, whenever they are not referenced anymore. The printer re-pooling strategy is unsafe, as a malicious or ill-written client may never call destructor, may call it several times or may continue to use the printer afterwards – this technique is therefore similar to free() in C. The garbage-collection scheme, similar to that of the traditional π-calculus, can prove insufficient if the client, for some reason, syntactically continues to reference destructor even though it does not use it anymore. Such a mechanism is commonly found in programming languages, implemented as a reference-counter in Python, Visual Basic or C++ frameworks such as Microsoft’s Com or Mozilla’s XPCom, and is A π-calculus with limited resources, garbage-collection and guarantees 7 often considered a simpler (and sometimes faster) alternative to full-scale garbage-collectors, although it cannot handle complex scenarios, such as cycles of references. Complex model Figure 6 presents a more complex print spooler, which takes advantage of garbage-collection to provide safe re-pooling and errorhandling. Macro F inalize h.i behaves in a way similar to finalization in numerous garbage-collected languages: this process waits until h has been deallocated and then triggers i. Instead of giving full access to printers, at each request, the spooler generates a new handler handler, which the client may use to send documents to one printer. Upon reception on destructor, the spooler triggers the destruction of handler – we will detail later how the destruction is implemented. Whenever handler is destroyed, whether the destruction was caused by a call on destructor or by any operation of garbage-collection, F inalize handler.P ush x triggers P ush x, hence returning the printer to the pool. Let us now consider name sigmem. For now, let us assume that sigmem is deallocated in case of emergency, whenever the system lacks memory. Process F inalize sigmem. · · · then triggers the destruction of handler – hence, the re-pooling of the printer – and somehow handles the error caused by the lack of resources. Note that, although names sigmem or delete are agreed-upon, they are not special names as }. Their behaviours are determined by the specific garbage-collection scheme we use for this example. This relation is defined by several rules: it permits automatically deallocating nonreferenced names (1), as well as names only referenced in receptions (2, 3) or finalizations (4). Any name may also be manually destroyed by emitting it on channel delete (5). Deallocation of names may also be used to react to a specific state of the system – here, lack of memory: if the resource usage of the proces exceeds a given limit M emory Limit, an agreed-upon name signal is deallocated (6). The re-pooling strategy itself is safe, insofar as a printer may only be returned once to the pool, and cannot be used again by the client once it is returned, until the client requests a new printer and receives a new handler. The technique used here may be seen as a combination of usage of manual and automatic garbage-collection and finalization, as well as a manner of concurrent exception-handling, in which the destruction of handler serves as throwing, and its finalization as catching. Note that, as in our previous works [11], and by opposition to most garbage-collected programming languages (including Java, C# and OCaml), 8 David Teller finalisation is safe, insofar as resurrection of an entity [1] is impossible. Also note that, by opposition to the first version of cπ, finalisation is a macro rather than a primitive of the language. As we will see in section 5, finalization can be taken into account by a type system, providing guarantees on reuse of resources. Also note that other operations and situations can be modelled by slightly more complex garbage-collection schemes, such as channel failure or prioritization of a specific task. 4 Properties Proposition 1 (cπ can contain π). There is a ”good” encoding of the π-calculus to an instance of cπ. We produce a simple encoding of a monadic synchronous π-calculus with structural equivalence and guarded replication, without choice, with a set of names not containing }, to an instance of cπ with the trivial set of resources and a garbage-collector of unused names. This encoding preserves termination, reduction, structure, distribution, structural equivalence and barbs. Proposition 2 (More resources give more freedom). If S is a set of resources and if r and s are elements of S such that r s GC then, for any garbage-collection scheme GC, −→GC r ⊆−→s . If r ≺ s, we GC GC further have −→r (−→s . The inclusion derives directly from the definition of −→GC r . The nonequality can be proved by examining process (νa : s)(a?(x) | a!h}i), as and one step of reduction in −→GC this process has no reduction in −→GC s . r As in the π-calculus, we may observe behaviours of terms in cπ using barbs and simulations. Definition 5 (Simulation). For a resource-aware instance of cπ on the set of resources S and with garbage-collection relation GC, a relation R is a simulation if, whenever l GC l GC (P, Q) ∈ R, if P 7−→ P 0 then there is some Q0 such that Q 7−→ Q0 0 0 and (P , Q ) ∈ R. We then write P ≤ Q and we say that Q simulates P . Note that, by opposition to π-calculus simulations, label l contains informations on the set of resources used. Definition 6 (Contextual garbage-collection). Let us consider a set of resources S, a garbage-collection scheme GC and a simulation relation . Scheme GC is said to be contextual wrt if and only if, for any A π-calculus with limited resources, garbage-collection and guarantees 9 set of processes P and Q such that P Q and any context C[•], we also have C[P ] C[Q]. Theorem 1 (Contextuality of simulation). In any set of resources, the empty garbage-collection scheme is contextual with respect to the simulation relation ≤. Definition 7 (Sound, complete). For any simulation relation , a garbage-collection scheme GC is sound → → w.r.t. if and only if, for any − a and P such that P GC − a , we have −−−−→ − − → (ν a : r)P P {a ← }}. A garbage-collection scheme GC is complete if and only if it contains all sound garbage-collection schemes. Soundness is often a desirable property as it guarantees that the garbagecollector will not remove behaviours. Note that soundness involves a preorder rather than an equivalence, as an equivalence would be contradictory with the use of finalizers such as defined on figure 6. Also note that not all useful garbage-collectors are sound – for instance, error-handlers as defined in 6. Proposition 3 (Trivial garbage-collectors). The empty garbage-collector is sound but incomplete, while the full garbagecollector is complete but unsound. Theorem 2 (Perfect garbage-collection). Sound and complete garbage-collection is undecidable. Proposition 4 (Actual garbage-collection). Informally, the Garbage-Collection of Jvm, .Net’s Cli or OCaml is both unsound and incomplete. Note that this is only an informal proposition as our “proof” only consists in a few counter-examples. Our definition of soundness and completeness supposes the definition of a weak simulation relation on these languages, using standard input/output as observable. Unsoundness All three platforms have unsafe weak references, which can be dereferenced even when they point to null. Therefore, assuming that weak is a weak reference, let us consider an extract such as • Java/Jvm String s = weak.get().toString(); out.println("Action"); • C#/Cli 10 David Teller string s = weak.get().target; Console.WriteLine("Action"); • OCaml match Weak.get weak 0 with Some x -> print\_endline "Action";; If the garbage-collector has removed the object referenced by weak, a null-pointer or match-failure exception will prevent the observable output "Action" from being performed. More complete examples are provided in the annex. Incompleteness As garbage-collection relies purely on the analysis of stack and heap, in the following example, the value of s is never recovered: boolean value = true; final String s = "useless"; while(value) ; System.out.println(s); 5 A type system for resource guarantees The semantics of cπ are parametrized on a notion of resources. Using parametric garbage-collection and terms such as F inalize permit to write term which take into account allocation of resources as well as deallocations and reuse. We now introduce a type system to provide guarantees on the usage of such resources. T ::= Bound(t, λ) r ∈ S, λ : N −→ r N ::= N ame(C, r) e ∈ S C ::= Chan(N, g, d) g, d ∈ S | Ssh Judgement Γ ` P : Bound(t, λ) states that, under environment Γ, P can be evaluated as a process which may be executed without starvation using no other resource than t and may have reused resources of external entities as specified by λ. In particular, if λ(a) = la , after the deallocation of a, P may reuse at most la of the resources originally allocated to a. The judgement Γ ` a : N ame(C, r) states that, according to Γ, a is the name of an entity using resource r, with role C. If C is Chan(N, g, λ), a is a communication channel, which can be used to communicate names of type N , to transfer resource g from the sender to the receiver, some of which may be deallocated and reused as per λ. Conversely, if C is Ssh, a is not a channel and cannot be used for communication. A π-calculus with limited resources, garbage-collection and guarantees 11 Figure 7 presents an extract of this type system. For the sake of readability, we slighly alter the syntax to allow writing new a : N in · · · and (νa : N ). When necessary, we will write 0λ for the function defined on N whose value is uniformly ⊥ and a 7→ r for the function defined on N whose value is r for a and ⊥ for everything else. The companion report also offers an extension of this type system in which resources may be – statically – exchanged both ways during communication. Lemma 1 (Weakening). If Γ is an environment and P a process such that Γ ` P : Bound(t, λ), then, for any t0 t and any λ0 λ, we have Γ ` P : Bound(t0 , λ0 ). Theorem 3 (Subject Reduction). If P is a process, if Γ ` P : Bound(r, λ) and P −→∗ P 0 then there is a r0 and a λ0 such that Γ ` Bound(r0 , λ0 ), Σx∈N λ(x) Σx∈N λ0 (x) and r ⊕ Σx∈N λ(x) r0 ⊕ Σx∈N λ0 (x). Theorem 4 (Subject Reduction (closed)). If P is a process, if Γ ` P : Bound(r, 0λ ) and P −→∗ P 0 then Γ ` P 0 : Bound(r, 0λ ). The closed Subject Reduction theorem is a direct corollary of the complete Subject Reduction theorem, and corresponds to a system closed as far as resource deallocation is concerned, as it does not reuse resources held by free names. The more general case where λ is not necessarily 0λ also covers transitory states between the deallocation of a name and the reuse of resources previously held by that name. Theorem 5 (Resource control). If S is a set of resources, if GC is a garbage-collection scheme, if P is a process, if P −→GC∗ P 0 and if Γ ` P : Bound(r, 0λ ) then we also have > GC∗ 0 P −→r0 P . Proposition 5 (Finalization). We can always derive Γ ` i : Bound(r ⊕ rn , λ) r0 r, λ0 λ ⊕ x 7→ rn Γ ` F inalize x.i : Bound(r0 , λ0 ) Proposition 6 (Examples). Typing the print spooler permits us to determine the following properties: 1. The spooler uses at most n printers. 2. Each incoming call causes the allocation of at most one handler. 3. There can be at most n handlers running at any time. 12 David Teller 4. The spooler allocates handlers only on demand. 5. The spooler sends messages to the printer only when requested to do so by a client. To prove these properties, we use the set of resources N4 where Γ ` P : Bound((p, h, k, m), λ) means that P uses resources to allocate at most p printers, h handlers, k handlers and m messages. In particular, most of these properties take advantage of the possibility of (statically) transferring resources or authorizations during communications. 6 Conclusions We have presented the new controlled π-calculus, a π-calculus altered to take into account allocation of resources, resource-bounded execution and garbage-collection. We have shown how to use this calculus to represent a complex bounded resources manager – in this case, a print spooler – with both manual and automatic garbage-collection and several forms of error-handling, including reaction to the absence of some resources. Furthermore, we have developped a rich type system to guarantee properties of resource management in this controlled π-calculus, including a novel manner of statically typing exchange of resources. Applying this type system to the bounded resources manager, we have managed to extract properties of resource-boundedness and static transfer of authorizations. This work builds on our previous experiences [14, 10, 11] with resource control for concurrent and distributed systems. In relation to these developments, it improves our definition of garbage-collection and of resourcerelated simulations, it removes the necessity of deallocators built-in the language, it starts to deal with error-handling and it adds the notions of transfer of resources. Other approaches of resource management have been proposed. The BoCa [2] calculus is a variant of Mobile Ambients with a notion of resources which can be dynamically transferred, acquired or released, while our work provides both dynamic and static notions of resources, guarantees and transfers. The Mobile Resource Guarantees [6] project builds on a linear type system to provide guarantees of safe memory deallocation and reuse as well as memory bounds in a single-threaded ML dialect. The Vault project [3] uses in a multithreaded yet safe subset of C and a complex type system to guarantee that resources are in a correct state whenever they are used. TyPiCal [8] has comparable aims with the π-calculus. None of these works, however, takes into account garbage-collection. Several other, mostly dynamic, solutions have been offered, from Guardians A π-calculus with limited resources, garbage-collection and guarantees 13 for Mobile Ambients [4] to JML or Spec#’s design-by-contract. These works, however, fail to provide static guarantees, behavioral observation of resources or to take into account deallocation and reuse. Future developments As we mentioned, in an implementation of cπ, instanciation instructions would be accompanied by constructors. Although we have not dealt with this issue, a number of processes such as the print spooler can be seen as constructors for resources, which brings a number of question – firstly, whether it is possible to write a constructor in cπ, how such a constructor should be defined, invoked, and what properties it should have. Closely related is the question of transformation and composition of resources. While some resources, such as hard drive space and perhaps some authorizations, can be composed into bigger resources, and while we can take this into account at the level of typing, at the level of the language, we have no way of express such behaviour. Similarely, while some resources can be transformed by operations – such as a file becoming an opened file, our definition of resources is insufficient to model this. We are currently investigating these problems, as well as that of generalizing the notion of static resource exchange to more than two participants, perhaps using some form of n-ary communication as seen in the Join-Calculus [5] or in the Kell-Calculus [9]. Garbage-collection schemes raise another series of questions. As we have seen, our definitions of soundness and completeness of a garbagecollector are too restrictive for common garbage-collectors such as those found in Java, C# or OCaml. We thus hope to better criteria to classify such services. More importantly, we have observed that nearly all the garbage-collection schemes we have been using in our examples, both in this document and during our research, could be classified as simple cases of patternmatching. We wonder whether this observation can be generalized and if a ”useful” set of garbage-collectors can be easily defined. In particular, we have attempted to define stack-based as well as regions-based techniques as instances of and preliminary results lead us to believe in the feasibility of the task. References [1] K. Arnold and J. Gosling. The Java Programming Language. Addison-Wesley, 1998. [2] F. Barbanera, M. Bugliesi, M. Dezani, and V. Sassone. A calculus of bounded capacities. In Proceedings of Advances in Computing Science, 9th Asian Comput- 14 [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] David Teller ing Science Conference, ASIAN’03, volume 2896 of Lecture Notes in Computer Science. Springer, 2003. R. DeLine and M. Fahndrich. Enforcing high-level protocols in low-level software. In SIGPLAN Conference on Programming Language Design and Implementation, 2001. G. Ferrari, E. Moggi, and R. Pugliese. Guardians for ambient-based monitoring. In V. Sassone, editor, F-WAN: Foundations of Wide Area Network Computing, number 66 in ENTCS. Elsevier Science, 2002. C. Fournet and G. Gonthier. The reflexive cham and the join-calculus. In Proceedings of the 23rd ACM SIGPLAN-SIGACT symposium on Principles of programming languages. ACM Press, 1996. M. Hofmann. A type system for bounded space and functional in-place update– extended abstract. Nordic Journal of Computing, 7(4), Autumn 2000. An earlier version appeared in ESOP2000. H. P. Hofstee. Power efficient processor architecture and the cell processor. In HPCA, pages 258–262. IEEE Computer Society, 2005. N. Kobayashi. TyPiCal: Type-based static analyzer for the pi-calculus. J.-B. Stefani. A calculus of kells. In V. Sassone, editor, Electronic Notes in Theoretical Computer Science, volume 85. Elsevier, 2003. D. Teller. Formalisms for mobile resource control. In Proceedings of FGC’03, volume 85 of ENCS. Elsevier, 2003. D. Teller. Resource recovery in the π-calculus. In Proceedings of the 3rd IFIP International Conference on Theoretical Computer Science, 2004. tbp. D. Teller. Ressources limitées pour la mobilité: Utilisation, réutilisation, garanties. PhD thesis, École Doctorale MathIF, 2004. D. Teller. A pi-calculus with limited resources, garbage-collection and guarantees. Technical Report 4/2005, University of Sussex, 2005. D. Teller, P. Zimmer, and D. Hirschkoff. Using Ambients to Control Resources. In Proceedings of the 13th International Conference on Concurrency Theory, volume 2421 of Lecture Notes in Computer Science. Springer-Verlag, 2002. A π-calculus with limited resources, garbage-collection and guarantees α a?(b) P −→pre P 0 R-Par a!hbi P −→ pre P 0 R-Comm α P |Q −→pre P 0 |Q Q −→ pre Q0 P |Q −→pre P 0 |Q0 P −→pre P 0 R-Entity (νa : r)P −→pre (νa : r)P 0 α P −→pre P 0 R-Hide P ≡ P0 R-Equiv α Q0 ≡ Q P 0 −→pre Q0 α P −→pre Q R-Spawn τ spawn i in j −→pre i|j R-Alloc τ new a : r in i −→pre (νa : r)i a 6= } R-Receive a∈ /α α (νa : r)P −→pre (νa : r)P 0 a 6= } R-Send a?(c) a?(b).i −→ pre i{b ← c} a!hci a!hci.i −→ pre i τ R-Then if a = a then i else j −→pre i a 6= b R-Else τ if a = b then i else j −→pre j Gc-Deallocate → − τ → → → (ν − a :− r )P −→pre P {− a ← }} τ Gc-Receive }?(x)i −→pre 0 τ Gc-RReceive ∗}?(x)t −→pre 0 Figure 3: P GC − a−:→r τ Gc-Send }!hxit −→pre 0 τ Gc-RSend ∗}!hxit −→pre 0 Resource-unaware semantics of cπ. 15 16 David Teller P ush p = printer!hpi P op (x).i = printer?(x).i P ool = (νchan p1 : P rinter)P ush p1 | · · · | (νchan pn : P rinter)P ush pn Client = new request in .alloc!hrequesti. request?(printer, destructor).Print.destructor!hi.Proceed Figure 4: Building blocks of the print spooler. BRM Driver1 = ∗alloc?(request).new destructor in .P op (x).( request!hx, destructori | destructor?().P ush x ) Garbage-Collection 1 : ∀x, ∀P, P 1 {x : } ⇐⇒ x ∈ / f v(P ) Figure 5: Model of a print spooler F inalize h.i = (νlock : ⊥)lock!hi | !lock?().if h = } then i else lock!hi BRM Driver = ∗alloc(request).P op (x).new destructor in new handler : Handler in new sigmem : M EM } in ( | request!hhandler, destructori.!handler?(y).x!hyi | destructor?().delete!hhandleri | F inalize handler.P ush x | F inalize sigmem.delete!hhandleri.Handle resource error ) The Garbage-Collection relation is the smallest err verifying (1) ∀x, ∀P, x ∈ / f n(P ) ⇒ P err {x} (2) ∀x, ∀P, i, ⇒ P err {x} ⇒ P | x?(y).i err {x} (3) ∀x, ∀P, i, ⇒ P err {x} ⇒ P | ∗ x?(y).i err {x} (4) ∀x, ∀P, i, ⇒ P err {x} ⇒ P | F inalize x.i err {x} (5) ∀x, ∀P, i, delete!hai.i | P err {a : Handler} (6) res(P ) M emory Limit ⇒ P err {sigmem : M EM } Figure 6: ers A print spooler with error-handling and without dangling point- A π-calculus with limited resources, garbage-collection and guarantees t0 ra ⊕ tP T-New 17 Γ ` P : Bound(tP , λ) λ(a) ra ∀x 6= a, λ0 (x) λ(x) Γ ` (νa : N ame( , ra ))P : Bound(t0 , λ0 ) Γ ` P : Bound(tP , λP ) t0 tP ⊕ tQ T-Par Γ ` Q : Bound(tQ , λQ ) λ0 λP ⊕ λQ Γ ` P |Q : Bound(t0 , λ0 ) a 6= } b 6= } Γ ` a : N ame( ) Γ ` i : Bound(t, λ) Γ ` j : Bound(t, λ) Γ ` b : N ame( ) T-If Γ ` if a = b then i else j : Bound(t, λ) a 6= } Γ ` a : N ame( ) Γ ` i : Bound(tj ⊕ s, λi ) Γ ` j : Bound(tj , λj ) λ0 λi ⊕ a 7→ s λ0 λj T-IfNull Γ ` if a = } then i else j : Bound(tj , λj ) Γ ` i : Bound(ti , λi ) T-AlwaysNull Γ ` if } = } then i else j : Bound(ti , λi ) Γ ` a : N ame(Chan(N, r, d), ) Γ, b : N ` i : Bound(t, λ) t0 ⊕ r t λ0 λ\{b} λ(b) d T-Receive Γ ` a?(b).i : Bound(t0 , λ0 ) b 6= } Γ ` a : N ame(Chan(N, r, d), ) Γ ` i : Bound(t, λ) t0 t ⊕ r λ0 λ ⊕ (b 7→ d) T-Send Γ ` a!hbi.i : Bound(t0 , λ0 ) Γ ` a : N ame(Chan(N, r, d), ) Γ ` i : Bound(t, λ) Γ`b:N t0 t ⊕ r ⊕ d λ0 λ T-SendNull Γ ` a!h}i.i : Bound(t0 , λ0 ) Γ ` i : Bound(t, λ) T-Repl Figure 7: t0 ∞ · t 0 λ0 ∞ · λ 0 Γ ` ∗i : Bound(t , λ ) Type system for resource guarantees Γ`b:N 18 David Teller A π-calculus with limited resources, garbage-collection and guarantees A 19 Encoding π in cπ (theorem 1) We use a monadic synchronous π-calculus with structural equivalence (rather than structural congruence) and guarded replication and we assume that the set of names does not contain }. The set of resources is the singleton {⊥} with trivial rules. We define our encoding [[ ]]p by the following equations [[0]]p [[P |Q]]p [[(νa)P ]]p [[!P ]]p [[α.P ]]p =0 = [[P ]]p | [[Q]]p = (νa : ⊥) [[P ]]p =! [[P ]]t = α. [[P ]]t [[0]]t [[P |Q]]t [[(νa)P ]]t [[!P ]]t [[α.P ]]t =0 = spawn [[P ]]t in . [[Q]]t = (νa : ⊥) [[P ]]t =! [[P ]]t = α. [[P ]]t Lemma 2 (Substitutions). For any P , x and y, [[P {x ← y}]] = [[P ]] {x ← y}. Trivial. Lemma 3 (Threads to processes). For any P , either [[P ]]t = [[P ]]p or [[P ]]t −→ [[P ]]p . Trivial. Lemma 4 (Structural equivalence). For all P and Q, if P ≡ Q then [[P ]]p ≡ [[Q]]p . We prove this by induction on the structure of a proof of P ≡ Q. The only subtleties are Replication If P =!α.R and Q =!α.R|R, we have [[P ]]p =! [[α.R]]t and ! [[α.R]]t ≡! [[α.R]]t |α. [[R]]t . By definition of the encoding, α. [[R]]t = [[α.R]]p . Hence, [[P ]]p ≡ [[Q]]p . Garbage-collection If P = (νa)0 and Q = 0 then [[P ]]p = [[Q]]p . Lemma 5 (Null values). For any P and p such that [[P ]]p −→ ∗p, p does not contain any occurrence of }. Trivial. Proposition 7 (Soundness). For all processes P and Q of the π-calculus such that P −→ Q, we have [[P ]]p −→ [[Q]]p . 20 David Teller We prove this by induction on the structure of a proof of P −→ Q. Communication If P = a?(x).R | a!hyi.S and Q = R{x ← y} | S, we have [[P ]]p = a?(x). [[R]]t | a!hyi. [[S]]t and [[Q]]p = [[R{x ← y}]]t | [[S]]t . By one communication and the substitution lemma, we have [[P ]]p −→ [[Q]]q . Structural equivalence If P ≡ P 0 , P 0 −→ Q0 and Q0 ≡ Q, by induction hypothesis, [[P 0 ]]p −→ [[Q0 ]]p . By lemma 4, we conclude the case. Proposition 8 (Completeness). For every process P of the π-calculus, if [[P ]]p −→ q then there exists Q in the π-calculus such that P −→ Q and q = [[Q]]p . By induction on a proof of [[P ]]p −→ q. By 5, we know that there is no occurrence of } hence no use of the Gc-* transitions. A π-calculus with limited resources, garbage-collection and guarantees B 21 Simulation l Lemma 6 (Resource in a simulation). If P ≤ Q and P 7−→ P 0 then l there exists a Q0 such that Q 7−→ Q0 and res(Q0 ) res(P 0 ). l α By definition, P 7−→ P 0 iff l = α; n, P −→pre P 0 and n res(P 0 ). In α;n particular, if P 7−→ P 0 , we can also have P α;res(P 0 ) 7−→ P 0 . Since P Q, α;res(P 0 ) l there exists some Q0 such that Q 7−→ Q0 . By definition, Q 7−→ Q0 iff α l = α; n, Q −→pre Q0 and n res(Q0 ). In particular, this means that res(P 0 ) res(Q0 ). B.1 Simulation is contextual (theorem 1) Let us define R as the smallest relation such that 1. ∀P, Q, P ≤ Q ⇒ P RQ 2. ∀P, Q, RP RQ ⇒ P |RRQ|R 3. ∀P, QP RQ ⇒ (νa : r)P R(νa : r)Q 4. ∀P, Q, P 0 , Q0 P RQ ∧ P 0 ≡ P ∧ Q0 ≡ Q ⇒ P 0 ∇Q0 . l Let us now prove that, for any A, B in R, if A 7−→ A0 then there is l some B 0 such that B 7−→ B 0 and A0 , B 0 ∈ R. We prove this by induction on a proof of A, B ∈ R. l Rule 1 If A ≤ B then there exists some B 0 such that B 7−→ B 0 and A0 ≤ B 0 . By rule 1, we also have A0 , B 0 ∈ R. Rule 2 Let us write A = P |R and B = Q|R where P, Q ∈ R. If l A 7−→ A0 , then l i either P 7−→ P 0 and A0 = P 0 |R l 1. or R 7−→ R0 and A0 = P |R0 α;m α;n 2. or P 7−→ P 0 , R 7−→ R0 , l = τ ; and A0 = P 0 |R0 l 3. or A ≡ A0 , A0 7−→ A00 and A00 ≡ A0 . l Sub-case i. Since P, Q ∈ R and P 7−→ P 0 , by induction hypothesis, l we may write Q 7−→ Q0 where P 0 , Q0 ∈ R. By rule 2, we also have P 0 |R, Q0 |R ∈ R, which proves the subcase. Sub-case ii. case. By rule 2, we also have P |R0 , Q|R0 ∈ R, which proves the 22 David Teller Similar to case i.+ii. Sub-case iii. Subcase iv. Among the families of all possible A0 and A00 , let us choose l one of each such that a proof of A0 7−→ A00 does not require any application of structural equivalence. By rule 4, we also have A0 , B ∈ R. Therefore, by l induction hypothesis, there is some B 0 such that B 7−→ B 0 and A00 , B 0 ∈ R. By rule 4, we deduce that A0 , B 0 ∈ R. This concludes the case. Rule 3 Let us write A = (νa : r)P and B = (νa : r)Q with P, Q ∈ R. α;n If A 7−→ A0 then α;m i either P 7−→ P 0 with a ∈ / α and n res(P 0 ) ⊕ r l 1. or A ≡ A0 , A0 7−→ A00 and A00 ≡ A0 . α; Sub-case i. Since P, Q ∈ R and P 7−→ P 0 , by induction hypothesis, we α; / α, we also have Q 7−→ Q0 for some Q0 such that P 0 , Q0 ∈ R. Since a ∈ α;s 0 0 deduce that for any s res(Q ) ⊕ r, (νa : r)Q 7−→ (νa : r)Q . By lemma 6, we may choose Q0 such that res(Q0 ) res(P 0 ). In particular, since n res(P 0 ) ⊕ r, with s = n, we have s res(Q0 ) ⊕ r. l In other words, with B 0 = (νa : r)Q0 , we have B 7−→ B 0 , which proves the sub-case. Subcase ii. As subcase iv. of rule 2. Rule 4 As subcase iv. of rule 2. We conclude that R is a simulation. In particular, we may now prove the theorem by induction on the structure of C[]. Trivial case If C[•] = •, we have C[P ] = P and C[Q] = Q, the case is trivial. Parallel composition If C[•] = • | R, we have C[P ] = P | R and C[Q] = Q |R. By definition of R, since P, Q ∈ R, we also have P | R, Q | R ∈ R. Hence, we have P |R ≤ Q|R. Name hiding If C[•] = (νa : r)•, we have C[P ] = (νa : r)P and C[Q] = (νa : r)Q. By definition of R, since P, Q ∈ R, we also have C[P ], C[Q] ∈ R. Hence, we have C[P ] ≤ C[Q]. A π-calculus with limited resources, garbage-collection and guarantees C 23 Subject Reduction of the type system C.1 Auxiliary lemmas If λ is a function from the set of names to the set of resources, we define λ\S as • ∀y ∈ S, λ\S(y) = ⊥ • ∀y ∈ / S, λ\S(y) = λ(y). Further, we define λ{a ← b} as λ\{a} ⊕ b 7→ λ(a). Lemma 7 (Substitution preserves typing). If a 6= }, if Γ, x : N ` P : Bound(t, λ) and if Γ ` a : N , then we have Γ ` P {x ← a} : Bound(t, λ\{x} ⊕ a 7→ λ(x)) . This is proved by structural induction on a proof of Γ, x : N ` P : ∆ Bound(t, λ). The only tricky case is that of P = if x = } then i else j. Let us write Γ, x : N ` i : Bound(t ⊕ s, λi ) Γ, x : N ` j : Bound(t, λj ) Γ` a:N λ λi ⊕ x 7→ s λ λj By induction hypothesis, we have Γ ` i{x ← a} : Bound(t ⊕ s, λ0i ) and Γ ` j{x ← a} : Bound(t, λ0j ), where λ0i = λi \{x} ⊕ a 7→ λi (x) and λ0j = λj \{x} ⊕ a 7→ λj (x). Let us note λ0 = λ\{x} ⊕ a 7→ λ(x). For any y distinct of x and a, λ0 (y) = λ(y) and λ(y) λj (y) = λ0j (y), λ(y) (λi ⊕ x 7→ s)(y) = λ0i (y). We also have λ0 (x) = λ0i (x) = λ0j (x) = ⊥. In addition, we have λ0 (a) = λ(a) ⊕ λ(x). Hence, λ0 (a) λj (a) ⊕ λj (x) = λ0j (a) and λ0 (a) λi (a)⊕λi (x)⊕s = λ0i (a)⊕λi (a). From this, we deduce that λ0 λ0i ⊕a 7→ s and λ0 λ0j . We can thus apply rule T-If and deduce that Γ ` (if x = } then i else j){x ← a} : Bound(t, λ0 ). Which proves the case. Lemma 8 (Deallocation lemma). If Γ, a : r ` P : Bound(t, λ), then Γ ` P {a ← }} : Bound(t ⊕ λ(a), λ\{a}). We prove this lemma by structural induction on a proof of Γ, a : r ` P : ∆ Bound(t, λ). The only tricky cases are that of P = if a = b then i else j ∆ or P = b!hai.i, which we will explore thus: 24 David Teller 1. if a = b then i else j, both a and b are non-} and a 6= b 2. if a = b then i else j, both a and b are non-} and a = b 3. if a = b then i else j, a is non-} while b = } 4. b!hai.i, b 6= a 5. b!hai.i, b = a. Case 1 Let us write Γ, a : r ` i : Bound(t, λ) Γ, a : r ` j : Bound(t, λ) By induction hypothesis, we deduce that Γ ` i{a ← }} : Bound(t ⊕ λ(a), λ\{a}) and Γ ` j{a ← }} : Bound(t ⊕ λ(a), λ\{a}). We can thus apply T-IfNull, using s = ⊥ and deduce Γ ` (if a = b then i else j){a ← }} : Bound(t ⊕ λ(a), λ\{a}) , which proves the case. Case 2 Let us write Γ, a : r ` i : Bound(t, λ) Γ, a : r ` j : Bound(t, λ) By induction hypothesis, we deduce that Γ ` i{a ← }} : Bound(t ⊕ λ(a), λ\{a}). We can thus apply T-AlwaysNull and deduce Γ ` (if a = a then i else j){a ← }} : Bound(t ⊕ λ(a), λ\{a}) , which proves the case. Case 3 Let us write Γ, a : r ` i : Bound(tj ⊕ s, λi ) Γ, a : r ` j : Bound(tj , λj ) λ λi ⊕ a 7→ s λ λj t tj By induction hypothesis, we deduce that Γ ` i{a ← }} : Bound(tj ⊕ s ⊕ λi (a), λi \{a}). We can thus apply T-AlwaysNull and deduce Γ ` (if a = } then i else j){a ← }} : Bound(tj ⊕ s ⊕ λi (a), λi \{a}). Since λ(a) λi (a) ⊕ s, t ⊕ λ(a) ti ⊕ s ⊕ λi (a). In addition, λ λi ⊕ a 7→ s and λi ⊕ a 7→ s\{a} = λi \{a}. We then deduce that Γ ` (if a = } then i else j){a ← }} : Bound(t ⊕ λ(a), λ\{a}) , which proves the case. A π-calculus with limited resources, garbage-collection and guarantees 25 Case 4 Same story... Case 5 Same story, as } can have any type. Lemma 9 (Equivalence preserves typing). If P ≡ Q and Γ ` P : T then Γ ` Q : T . Proof by a simple induction. The α-equivalence derives from the substitution lemma (lemma 7) – note that we cannot substitute } during α-conversion. C.2 Main proof Proved by induction on the structure of a proof of P −→ Q. Let us define the weight of T by weight(Bound(t, λ)) = t ⊕ Σx∈N λ(x). Instanciation Case R-Spawn is trivial as the typing rule for spawn i in j is identical to that of i | j. Case R-Alloc is trivial as the typing rule for new a : N in i is identical to that of (νa : N )i. ∆ Tests Let us write P = if a = b then i else j. We have the following cases: • a = b and a 6= } • a = b and a = } • a 6= b, with a 6= } and b 6= } • a 6= b, with a = } and b 6= } • a 6= b, with a 6= } and b = } If a = b and a 6= }, by T-If, the type of P is identical to the type of i. Since P −→ i, the case is proved. If a = b and a = }, by T-AlwaysNull, the type of P is identical to the type of i. Since P −→ i, the case is proved. If a 6= b, with a 6= } and b 6= }, by T-If, the type of P is identical to the type of j. Since P −→ j, the case is proved. If a 6= b, with a = } and b 6= }, we have Γ ` j : Bound(t, λj ), Γ ` P : Bound(t, λ) with λ λj . Since P −→ j, the case is proved. If a 6= b, with a 6= } and b = }, the case is identical. Communication Let us write Γ, x : N ` i : Bound(t ⊕ r, λ ⊕ λa ) Γ` a : N ame(Chan(N, r, λa ), ) Γ ` j : Bound(tj , λj ) Γ` b:N 26 David Teller Typing P Typing a?(x).i Γ, x : N `i : Bound(t ⊕ r, λ ⊕ λa ) Γ `a : N ame(Chan(N, r, λa ), ) ⇒ Γ `a?(x).i : Bound(t1 , λ1 ) Where t1 t λ1 λ Γ `j : Γ `a : Γ `b : ⇒ Γ `a!hbi.j : Where Typing a!hbi.j Bound(tj , λj ) N ame(Chan(N, r, λa ), ) N Bound(t2 , λ2 ) t2 tj ⊕ r λ2 λj ⊕ λa Γ `a?(x).i : Γ `: ⇒ Γ `P : Where Typing P Bound(t1 , λ1 ) Bound(t2 , λ2 ) Bound(t3 , λ3 ) t3 t1 ⊕ t2 λ3 λ1 ⊕ λ2 By hypothesis By hypothesis By T-Rcv By By By By hypothesis hypothesis hypothesis T-Snd See above See above By T-Par Typing Q Typing i{x ← b} Γ, x : N `i{x ← b} : Bound(t ⊕ r, λ ⊕ λa ) ⇒ Γ `i : Bound(t ⊕ r, λb ) Where λb = (λ ⊕ λa ){x ← b} Typing Q Γ `i{x ← b} : Bound(t ⊕ r, λb ) Γ `j : Bound(tj , λj ) Since t3 ⊕ t1 ⊕ t2 t2 tj ⊕ r t1 t Since λ3 λ1 ⊕ λ2 λ1 λ λ2 λj ⊕ λa ⇒ Γ `Q : Bound(t3 , λ3 {x ← a}) By hypothesis By Substitution See above By hypothesis By T-Par A π-calculus with limited resources, garbage-collection and guarantees 27 The case is proved. Structure Proof of the various structural cases are identical to the corresponding proofs in our previous works [12]. Garbage-collection Cases GC-Receive, GC-Send, GC-RReceive and GC-RSend are trivial as Q is 0, which can always be typed, with any type. ∆ For case GC-Deallocate, let us consider P = (ν − a−:→r)Q and assume −−−−→ that one step of garbage-collection will cause P −→ Q{a ← }}. Let us write Γ` P : Bound(tP , λP ) −−→ Γ, a : r Q : Bound(tQ , λQ ) t P tQ ⊕ Σ a r a → λP λQ \− a − Since all terms are finite, in particular, a−:→r is a finite set. We can thus iterate on all names of − a−:→r. By successive applications of the deallocation −−−−→ → − − λ(b), λ\ a ). lemma, we deduce Γ ` Q{a ← }} : Bound(t ⊕ Σ → b∈ a By rule T-New, since P can be typed in Γ, we deduce that ∀b ∈ −−−−→ → − → − − a , λ(b) rb . We thus have Γ ` Q{a ← }} : Bound(tQ ⊕Σb∈→ a rb , λQ \ a ). → − In particular, since, by hypothesis, we have λQ \ a λP and tQ ⊕ − Σb∈→ a rb tP , we conclude the case. The induction is thus proved. Hence the subject-reduction property. D Resource control Lemma 10 (Resource total). If Γ ` P : Bound(r, 0λ ) then res(P ) r. Trivial. D.1 Main proof From the Resource total lemma and subject-reduction, we conclude the resource control theorem. 28 David Teller A π-calculus with limited resources, garbage-collection and guarantees E 29 Typing examples E.1 Finalization We have Loop = N ame(Chan( , r0 , λ0 ), ⊥) Γ` i : Bound(r ⊕ rn , λ) r0 r λ0 λ ⊕ x 7→ rn Γ `0 Γ `loop ⇒ Γ `loop!hi Typing loop!hi : Bound(⊥, 0λ ) : N ame(Chan( , r0 , λ0 ), ) : Bound(r0 , λ0 ) By T-Nil By hypothesis By T-Snd Typing if x = } then i else loop!hi Γ `loop!hi : Bound(r0 , λ0 ) Γ `i : Bound(r0 ⊕ rn , λ) ⇒ Γ `if x = } then i else loop!hi : Bound(r0 , λ0 ) See above By hypothesis By T-IfNull Typing loop?().if x = } then i else loop!hi Γ `if x = } then i else loop!hi : Bound(r0 , λ0 ) Γ `loop : N ame(Chan( , r0 , λ0 ), ) ⇒ Γ `loop?(). · · · : Bound(⊥, 0λ ) See above By hypothesis By T-Rcv Typing !loop?().if x = } then i else loop!hi Γ `loop?(). · · · : Bound(⊥, 0λ ) ⇒ Γ `!loop?(). · · · : Bound(⊥, 0λ ) See above By T-Bang Typing !loop?().if x = } then i else loop!hi | loop!hi Γ `!loop?(). · · · : Bound(⊥, 0λ ) See above Γ `loop!hi : Bound(r0 , λ0 ) See above ⇒ Γ `!loop?() · · · | loop!hi : Bound(r0 , λ0 ) By T-Par Γ `!loop?() · · · | loop!hi ⇒ Γ `(νloop : Loop)(· · · ) E.2 Typing F inalize x.i : Bound(r0 , λ0 ) : Bound(r0 , λ0 ) Print spooler The reduction is quite long but absolutely straightforward. See above 30 F David Teller Unsoundness of garbage-collectors In all these programs garbage-collection causes the program to print exeo and quit. It would be easy to modify the programs to cause more subtle/grave mis-behaviours. F.1 Java The examples have been tested under Linux [...] 2.6.9-11.EL #1 Fri May 20 18:17:57 EDT 2005 i686 i686 i386 GNU/Linux with java version "1.4.2_05" Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_05-b04) BEA WebLogic JRockit(TM) 1.4.2_05 JVM R24.4.1-1 (build ari-38317-20041124-1225-linux-ia32, Native T and a stack size of 16Mb. Finalization On our test configuration, the example triggers the “exeo” behavior after 21766 iterations. public c l a s s F i n a l i z e C o u n t e r E x a m p l e { public s t a t i c void main ( f i n a l S t r i n g a r g s [ ] ) { { f i n a l F i n a l i z e C o u n t e r E x a m p l e r e f e r e n t = new F i n a l i z e C o u n t e r E x a m p l e ( ) ; } int i = 0 ; Object [ ] junk = null ; while ( true ) { junk = f i l l m e m o r y ( junk ) ; System . out . p r i n t l n ( ” I t e r a t i n g ( ”+(++i )+” ) ” ) ; } } public s t a t i c f i n a l Object [ ] f i l l m e m o r y ( f i n a l Object [ ] p r e v i o u s ) { Object [ ] junk = new Object [ 1 0 0 ] ; junk [ 0 ] = p r e v i o u s ; return junk ; } A π-calculus with limited resources, garbage-collection and guarantees 31 public void f i n a l i z e ( ) { System . out . p r i n t l n ( ” Garbage−c o l l e c t i o n e xe c ute d , exeo . ” ) ; System . e x i t ( 0 ) ; } } Weak References On our test configuration, the example triggers the “exeo” behavior after 21765 iterations. import j a v a . l a n g . r e f . ∗ ; public c l a s s WeakCounterExample { public s t a t i c void main ( f i n a l S t r i n g a r g s [ ] ) { f i n a l R e f e r e n c e weak = new WeakReference (new Object ( ) ) ; int i = 0 ; Object [ ] junk = null ; while ( true ) { junk = f i l l m e m o r y ( junk ) ; f i n a l Object r e f e r e n t = weak . g e t ( ) ; i f ( r e f e r e n t==null ) { System . out . p r i n t l n ( ” Garbage−c o l l e c t i o n e xe c ute d , exeo ” ) ; System . e x i t ( 0 ) ; } else System . out . p r i n t l n ( ” I t e r a t i n g ( ”+(++i )+” ) ” ) ; } } public s t a t i c f i n a l Object [ ] f i l l m e m o r y ( f i n a l Object [ ] p r e v i o u s ) { Object [ ] junk = new Object [ 1 0 0 ] ; junk [ 0 ] = p r e v i o u s ; return junk ; } } 32 David Teller F.2 OCaml The examples have been tested under Linux [...] 2.6.9-11.EL #1 Fri May 20 18:17:57 EDT 2005 i686 i686 i386 GNU/Linux with Objective Caml version 3.08.3 using the bytecode compiler, running the program in a shell with a total amount of virtual memory limited to 12Mb through ulimit -v and with option --fill 1. Finalization On our test configuration, the example triggers the “exeo” behavior after 190 iterations. (∗ I n i t i a l i z e t h e f i n a l i z e r ∗) = let = let f i n a l i z e r P r i n t f . p r i n t f ” Garbage−c o l l e c t i o n has taken p l a c e , exeo . \ n” ; exit 0 and u s e l e s s v a l u e = Array . c r e a t e 1 ” This i s a p r e t t y u s e l e s s v a l u e . ” in Gc . f i n a l i s e f i n a l i z e r u s e l e s s v a l u e (∗ C r e a t e s l a r g e amount o f j u n k d a t a t o f o r c e g a r b a g e −c o l l e c t i o n . ∗) let fill memory n = l e t rec aux i l = i f i = 0 then l else aux ( i − 1 ) ( ( Array . make 1 0 0 ”Junk data ” ) : : l ) in aux n [ ] let main loop n = l e t rec aux l i = P r i n t f . p r i n t f ” Garbage−c o l l e c t i o n has not taken p l a c e y e t . I t e r a t i n g (% i ) . \ n” i ; aux ( ( f i l l m e m o r y n ) : : l ) ( i +1) in aux [ ] 1 A π-calculus with limited resources, garbage-collection and guarantees 33 l e t main = let f i l l i n g = r e f 1000 in Arg . p a r s e [ ”−− f i l l ” , ( Arg . S e t i n t f i l l i n g ) , ”Number o f chunks o f junk data t o produce i n an attempt t o t r i g g e r garbage−c o l l e c t ] − > ()) ” Counter−example based on weak−r e f e r e n c e s f o r OCaml ’ s garbage−c o l l e c t o ( fun main loop ! f i l l i n g Weak References On our test configuration, the example triggers the “exeo” behavior after 202 iterations. (∗ I n i t i a l i z e t h e weak r e f e r e n c e ∗) let weak reference = l e t weak = Weak . c r e a t e 1 and u s e l e s s v a l u e = Array . c r e a t e 1 ”The weak r e f e r e n c e i s in Weak . s e t weak 0 ( Some u s e l e s s v a l u e ) ; weak s t i l l defined ” (∗ C r e a t e s l a r g e amount o f j u n k d a t a t o f o r c e g a r b a g e −c o l l e c t i o n . ∗) let fill memory n = l e t rec aux i l = i f i = 0 then l else aux ( i − 1 ) ( ( Array . make 1 0 0 ”Junk data ” ) : : l ) in aux n [ ] (∗ I n c r e a s e memory consumption u n t i l t h e weak r e f e r e n c e i s g a r b a g e −c o l l e c t e d . ∗) let main loop n = l e t rec aux l i = P r i n t f . p r i n t f ” I t e r a t i n g % i \n” i ; 34 David Teller match Weak . g e t w e a k r e f e r e n c e 0 with Some v −> print string (v .(0)); print newline ( ) ; aux ( ( f i l l m e m o r y n ) : : l ) ( i +1) | −> P r i n t f . p r i n t f ” Garbage−c o l l e c t i o n has taken p l a c e , exeo . \ n” in aux [ ] 1 l e t main = let f i l l i n g = r e f 1000 in Arg . p a r s e [ ”−− f i l l ” , ( Arg . S e t i n t f i l l i n g ) , ”Number o f chunks o f junk data t o produce i n an attempt t o t r i g g e r garbage−c o l ] − > ()) ( fun ” Counter−example based on weak−r e f e r e n c e s f o r OCaml ’ s garbage−c o l l e c t o r ’ s s o u n main loop ! f i l l i n g