We decided to take a look at the architecture of the Android Kernel. We selected the panda configuration for no particular reason - any other configuration would have worked just as well. The kernel code is written in C and it is derived from the Linux kernel. So, our approach will work on any configuration of the generic Linux kernel, as well.
Now we all know that C/C++ is a complex language and so we expect the analysis to be hard. But that difficulty just refers to the parser. Armed with the Clang parser we felt confident and were pleased that we didn't run into any issues. Our goal was to examine all the C/C++ source files that go in the panda configuration and to understand their inter-relationships. To do this, it was necessary to figure out what files are included or excluded from the panda build. And then there were issues dealing with how all the files were compiled, included and linked. That all took effort. The resulting picture showed how coupled the Linux kernel is.
First, let's acknowledge that the Linux kernel is well-written. What goes into it is tightly controlled. Given its importance in the IT infrastructure of the world, that is just what one would hope. Let us also remember that many of the modularity mechanisms in use today were invented in Unix. The notion of device drivers that plug into an Operating System was popularized by Unix and is commonplace today. Application pipes were pioneered by Unix. And yet, the Linux kernel itself has poor modularity.
Part of the problem is that that when Unix/Linux kernels were developed programming language support for modularity was poor. For instance, C does not have the notion of an interface and so dependency inversion is not naturally supported (it is possible, however). And, Linux has no real modularity mechanisms to verify or enforce modularity.
Dependency Map for the Panda configuration of the Android Kernel
A few things become apparent after a partitioning algorithm is applied. This partitioning algorithm reorders the subsystems based on dependencies, revealing what is "lower" and what is "higher." In an ideal implementation, the developers of the higher layer need only understand the API of the lower layers, while the developers of the lower layers need to worry about the higher layers only when an interface is affected. In a coupled system developers need to understand both layers making the job of understanding the impact of change considerably harder. Indeed, in the Android kernel where nearly all the layers are coupled, developers may sometimes have to understand thousands of files to feel confident about their changes.
This also means is that the intent behind the decomposition has been lost. For instance, 'arch.arm' is so strongly coupled with 'kernel' that it is hard for developers to understand one without understanding the other. Notice how even the 'drivers' are coupled to rest of the system. I experimented by creating a separate layer for the base layer of the drivers and I even moved some of the basic drivers such as 'char' and 'tty' and yet the coupling remained. Sadly, even some of the newer drivers are also coupled to the kernel.
All this goes to show that unless there is a focus on architecture definition and validation, even the best managed software systems will experience architectural erosion over time.
If you would like to discuss the methodology of this study or if you would like to replicate the results on your own, please contact me (neeraj dot sangal at lattix dot com). You can peruse a Lattix white paper on the Android kernel for some more details.
Johan van den Muijsenberg just published (in Dutch) his analysis of ArgoUML in a magazine published by the Java User Group in Netherlands. The brilliance of Johan's analysis is in how logically straightforward it is and how that analysis yields clearly identifiable architectural issues and fixes. It is yet another example of how easily architecture erodes from its intended design. If more teams were to focus on fixing "bugs" in architecture, they would reap rich dividends in improved quality and productivity.
My main complaint is why Dutch readers should be the only ones to benefit from this interesting and useful article. Here is a Google translation into English.
The writers of Star Trek Voyager envisioned a game that was worthy of challenging the superior mind and intellect of a Vulcan. They called it Kal-toh. To the human eye, Kal-toh looks to be a high-tech fusion of Jenga and chess. Lieutenant Tuvok of the starship Voyager would be quick to tell you "Kal-toh is to chess as chess is to tic-tac-toe.”
In Kal-toh, the players are presented with rod like game pieces that are in total chaos. This could be compared to legacy code with no discernable architecture or documentation – spaghetti code or a big ball of mud. The object of Kal-toh is to move the pieces (systems and subsystems) until a perfect structure or architecture is formed. The challenge in Kal-toh, as in Software Architecture Design, is that if you move the wrong piece, the entire structure can collapse.
Kal-toh and Software Architecture are based on very similar principles. An experienced Kal-toh player has the ability to visualize the complexity in the Kal-toh puzzle. Without fully understanding how the Kal-toh pieces interact with each other there is no road map to create stability in the structure.
Visualizing software systems is hard because there are a very large number of elements with dependencies on each other. Therefore, the ability to scale is critical. Furthermore, the purpose of visualization is to reveal the architecture. This means that it is important to not just draw the dependencies but to show where dependencies are missing and to highlight the problematic dependencies.
Lattix has pioneered an award winning approach for large scale visualization based on a Dependency Structure Matrix (DSM). Lattix incorporates hierarchy in the display, while showing the architectural decomposition and the dependencies at the same time. Built-in algorithms help discover architecture. What-if capabilities allow users to modify the current structure to reflect the desired architecture. Users get a big picture view while still identifying problematic dependencies. Lattix also provides an intuitive Conceptual Architecture diagram that takes some of the lessons of a DSM and makes them accessible to a wider audience.
If you are interested in learning how to visualize the complexity in your code with DSM, request an evaluation of Lattix Architect. You will also find additional information on Lattix and DSM on our videos page.
Let me leave you with a Star Trek quote. Lieutenant Tuvok said “Kal-toh is not about striving for balance. It is about finding the seeds of order, even in the midst of profound chaos." The same can be said about Lattix.