Functional Modelling of Operating Systems

Despite the constant efforts of coming up with new ideas and approaches, operating systems’ development has continued to be based on the same fundamental technologies of the 1970s, when the UNIX operating system and the C programming language were first developed. However, there are certain segments of the market, where companies and software engineers are fed up with C and its derivatives, and they are seeking something that promises more automation in the development of low-level systems. A classic layout of complex software, such as operating systems, usually involves a set of fine-tuned performance-optimized routines that are combined and controlled from an upper layer in a lightweight fashion. As the complexity grows, reliable operation, portability, and maintainability become a major concern. However, this can be tamed by abstracting away from the platform-dependent details by modelling the components and their relation on a higher level. Using a functional programming language combined with the technique of language embedding may be an answer to the question of how to implement such a solution. In this design, the component descriptions may be captured adequately by an embedded domain-specific language that compiles to a lower-level language but there also has to be mechanism for composition and thereby obtaining a complete working system out of them. The Flow language is introduced through a motivating example which is also featured in the thesis. It also describes the major elements in the resulting computation model, e.g. tasks, channels, and the execution of tasks. Though its focus is on the applicability of the approach in relation of arbitrary Haskell-embedded domain-specific language as that is one of the main concerns in the adaption among third-party developers. Thus, Feldspar (Functional Embedded Language for Digital Signal Processing and Parallelism) is used as prime example for a domain-specific language to be applied in conjunction with the Flow. During the work on the design and implementation of a coordination language framework for embedded domain-specific languages we briefly touch on the issue of executing specialized task graphs. In our model, we create a set of workers (executors) dynamically picked and executed DSL programs (tasks) as part of a dataflow graph. The number of workers matched the number of processing units of the given hardware in the ideal case. This last aspect may contribute to lowering the expectations from the supporting run-time environment, eventually making the compiled graphs standalone on top of the bare metal. However, during the preliminary performance tests, we observed that our first na¨ive stab at scheduling execution of graphs did not scale well for multiple workers – which is not surprising as relations between tasks induced by data dependencies in the dataflow graph are not respected. To provide guarantees for that, tasks are partitioned into pools, although the optimal organization of pools is hard to achieve automatically. Hence we decided to create another embedded domain-specific functional language to provide a way for the programmer to express heuristics on how dataflow graphs are scheduled, which lead us to the concept of “declarative scheduling”. Declarative scheduling allows the implementation of domain-specific scheduling constraints that helps to abstract away from the low-level scheduling details and rather focuses on the protocol implementation itself. Also, an extension is proposed to the above model, where a tuning for performance based on certain properties is enabled which shows how a practitioner may profit from describing the application on a higher level and leaving the details to an appropriate compiler.