Isolated Actors for Race-Free Concurrent Programming
Total Page:16
File Type:pdf, Size:1020Kb
Isolated Actors for Race-Free Concurrent Programming THÈSE NO 4874 (2010) PRÉSENTÉE LE 26 NOVEMBRE 2010 À LA FACULTÉ INFORMATIQUE ET COMMUNICATIONS LABORATOIRE DE MÉTHODES DE PROGRAMMATION 1 PROGRAMME DOCTORAL EN INFORMATIQUE, COMMUNICATIONS ET INFORMATION ÉCOLE POLYTECHNIQUE FÉDÉRALE DE LAUSANNE POUR L'OBTENTION DU GRADE DE DOCTEUR ÈS SCIENCES PAR Philipp HALLER acceptée sur proposition du jury: Prof. B. Faltings, président du jury Prof. M. Odersky, directeur de thèse Prof. D. Clarke, rapporteur Prof. V. Kuncak, rapporteur Prof. P. Müller, rapporteur Suisse 2010 ii Abstract Message-based concurrency using actors has the potential to scale from multi- core processors to distributed systems. However, several challenges remain until actor-based programming can be applied on a large scale. First, actor implementations must be efficient and highly scalable to meet the demands of large-scale distributed applications. Existing implementations for mainstream platforms achieve high performance and scalability only at the cost of flexibility and ease of use: the control inversion introduced by event-driven designs and the absence of fine-grained message filtering complicate the logic of application programs. Second, common requirements pertaining to performance and interoperability make programs prone to concurrency bugs: reusing code that relies on lower-level synchronization primitives may introduce livelocks; passing mutable messages by reference may lead to data races. This thesis describes the design and implementation of Scala Actors. Our sys- tem offers the efficiency and scalability required by large-scale production sys- tems, in some cases exceeding the performance of state-of-the-art JVM-based ac- tor implementations. At the same time, the programming model (a) avoids the control inversion of event-driven designs, and (b) supports a flexible message re- ception operation. Thereby, we provide experimental evidence that Erlang-style actors can be implemented on mainstream platforms with only a modest overhead compared to simpler actor abstractions based on inversion of control. A novel integration of event-based and thread-based models of concurrency enables a safe reuse of lock-based code from inside actors. Finally, we introduce a new type-based approach to actor isolation which avoids data races using unique object references. Simple, static capabilities are used to enforce a flexible notion of uniqueness and at-most-once consumption of unique references. Our main point of innovation is a novel way to support internal aliasing of unique references which leads to a surprisingly simple type system, for which we provide a complete soundness proof. Using an implementation as a plug-in for the EPFL Scala compiler, we show that the type system can be in- tegrated into full-featured languages. Practical experience with collection classes iii iv ABSTRACT and actor-based concurrent programs suggests that the system allows type check- ing real-world Scala code with only few changes. Keywords: Concurrent programming, actors, threads, events, join patterns, chords, aliasing, linear types, unique pointers, capabilities Kurzfassung Nachrichtenbasierte Nebenläufigkeit mit Aktoren hat das Potential von Mehrkern- Prozessoren hin zu verteilten System zu skalieren. Es gibt jedoch noch mehrere Herausforderungen zu meistern bis aktorenbasierte Programmierung im grossen Massstab angewandt werden kann. Zum einen werden effiziente Implementierungen benötigt, die hochgradig skalier- bar sind, um den Anforderungen moderner verteilter Anwendungen gerecht zu werden. Existierende Implementierungen für verbreitete Plattformen erreichen hohe Leistung und Skalierbarkeit nur auf Kosten von Flexibilität und Benutzbarkeit: Die Steuerfluss-Inversion, die ereignisbasierte Entwürfe mit sich bringen, und das Fehlen von feingranularer Nachrichtenfilterung führen oft dazu, dass die Anwen- dungslogik deutlich komplizierter wird. Zum anderen bringen Leistungs- und Interoperabilitätsanforderungen oft eine erhöhte Anfälligkeit für Synchronisierungsfehler mit sich: Die Wiederverwen- dung von Quellcode, der auf Synchronisierungsmechanismen einer niedrigeren Abstraktionsebene basiert, kann Livelocks zur Folge haben; das Senden von Ref- erenzen auf nichtkonstante Daten als Nachrichten kann zu Dataraces führen. Diese Dissertation beschreibt den Entwurf und die Implementierung von Scala Actors. Unser System stellt die Effizienz und Skalierbarkeit zur Verfügung, die für grosse Systeme in Produktionsumgebungen erforderlich ist, wobei in manchen Fällen die Leistung anderer Javabasierter Aktorimplementierungen deutlich übertrof- fen wird. Gleichzeitig wird vom Programmiermodell (a) die Steuerfluss-Inversion ereignisbasierter Entwürfe vermieden, und (b) eine flexible Nachrichtenempfang- soperation unterstützt. Damit zeigen wir mit Hilfe experimenteller Ergebnisse, dass Erlang-Aktoren mit nur geringem Overhead im Vergleich zu einfacheren Programmiermodellen, die auf Steuerfluss-Inversion basieren, auf weitverbreit- eten Plattformen implementiert werden können. Eine neuartige Integration von ereignisbasierten und threadbasierten Nebenläufigkeitsmodellen erlaubt eine sichere Wiederverwendung von lockbasiertem Quellcode innerhalb von Aktoren. Im letzten Teil der Dissertation führen wir einen neuen typbasierten Ansatz zur Isolierung von Aktoren ein, bei dem Dataraces mit Hilfe von eindeutigen Objek- treferenzen vermieden werden. Einfache, statische Capabilities werden genutzt v vi KURZFASSUNG um sowohl eine flexible Form von Referenzeindeutigkeit als auch den höchstens einmaligen Verbrauch eindeutiger Referenzen sicherzustellen. Unsere wichtig- ste Innovation ist eine neuartige Methode, internes Aliasing eindeutiger Referen- zen zu erlauben, was zu einem erstaunlich einfachen Typsystem führt; wir stellen einen vollständigen Beweis der Typsicherheit unseres Systems zur Verfügung. Mit Hilfe einer Implementierung als Plugin für den EPFL Scala-Compiler zeigen wir, dass das Typsystem in umfangreiche, produktionsreife Sprachen integriert wer- den kann. Praktische Experimente mit Collections und aktorbasierten, nebenläu- figen Programmen zeigen, dass das System die Typprüfung praktisch benutzbaren Scala-Quellcodes erlaubt, wobei nur wenige zusätzliche Änderungen benötigt wer- den. Stichwörter: Nebenläufige Programmierung, Aktoren, Threads, Ereignisse, Join- Kalkül, Chords, Alias-Analyse, Lineare Typen, Eindeutige Referenzen, Capabili- ties Acknowledgements I am deeply indebted to my advisor Martin Odersky for his support and insight, without which this dissertation would not have been possible. More than once he encouraged me to work out another less-than-half-baked idea which ended up getting published, and eventually formed the heart of this thesis. I’d like to thank the past and present members of the Scala team at EPFL for providing an outstanding research environment. I want to thank Tom Van Cutsem for sharing his passion for concurrent pro- gramming, and for his contributions to a joint paper which forms the basis of chapter 3 of this dissertation. I’d also like to thank my other committee members Dave Clarke, Peter Müller, and Viktor Kuncak for their time and helpful feedback on drafts of the material presented in this dissertation. Finally, my deepest thanks go to my family and friends for enjoying the highs of doctoral school together with me, and for supporting me during the unavoidable lows. vii viii ACKNOWLEDGEMENTS List of Figures 2.1 Example: orders and cancellations . 10 2.2 Extending actors with new behavior . 14 2.3 Extending the ManagedBlocker trait for implementing blocking actor operations . 23 2.4 Producer that generates all values in a tree in in-order . 24 2.5 Implementation of the producer and coordinator actors . 25 2.6 Implementation of the coordinator actor using react ........ 25 2.7 Thread-based pipes . 27 2.8 Event-driven pipes . 28 2.9 Actor-based pipes . 30 2.10 Throughput (number of message passes per second) when passing a single message around a ring of processes . 34 2.11 Network scalability benchmark, single-threaded . 36 2.12 Network scalability benchmark, multi-threaded . 37 3.1 The abstract super class of synchronous and asynchronous events . 53 3.2 A class implementing synchronous events . 54 4.1 Running tests and reporting results . 66 4.2 Comparing (a) external uniqueness and (b) separate uniqueness () unique reference, ! legal reference, 99K illegal reference) . 68 4.3 Core language syntax . 73 4.4 Syntax for heaps, environments, and dynamic capabilities . 75 4.5 Language syntax extension for concurrent programming with actors 89 4.6 Concurrent program showing the use of actor, receive, and the send operator (!)........................... 90 4.7 Definitions of auxiliary predicates for well-formed actors . 94 4.8 Leaking a managed resource . 97 ix x LIST OF FIGURES List of Tables 4.1 Proposals for uniqueness: types and unique objects . 61 4.2 Proposals for uniqueness: encapsulation and annotations . 62 xi xii LIST OF TABLES Contents Abstract iii Kurzfassung v Acknowledgements vii 1 Introduction 1 1.1 Contributions . .3 1.1.1 Design and implementation of programming models for concurrency . .3 1.1.2 Static type systems . .4 1.1.3 Publications . .5 1.2 Outline of the Dissertation . .6 2 Integrating Threads and Events 7 2.1 The Scala Actors Library . .8 2.1.1 The receive operation . 12 2.1.2 Extending actor behavior . 13 2.2 Unified Actor Model and Implementation . 14 2.2.1 Threads vs. events . 15 2.2.2 Unified actor model . 15 2.2.3 Implementation . 16 2.2.4 Composing