There may be no such thing as completely portable code, but with the release of a new Linux version of a component library to developers, writing portable, adaptable code just got easier. A noncommercial product, the Intel operating system independent (OSI) library implementation called CompLib has been used by Intel developers to port their applications from one platform to another. Now this rigorously tested and effective tool is available to any software engineer wanting access to a critical resource for creating more flexible, robust applications.
With today's large and complex applications, there are strong incentives to reuse and port code to new platforms. A lack of readily available OSI libraries has hindered efforts to generate applications that can easily port from one system to another. But by using CompLib, a developer can do more than write code that is just adapted to new operating systems.
What Is CompLib?
CompLib is an operating system independent (OSI) library of functions that abstracts the OS services and performs some porting tasks for you. It includes abstractions for common OS primitives, such as memory allocation, deallocation, spinlocks, semaphores, timers, events, and so on. In addition, CompLib also abstracts compiler directives to hide differences between different compilers and tools. One example of this is the directive that lets the writer pack a structure.
For example, Figure 1 below shows a segment of code that allocates memory and checks the value of the returned pointer. In Figure 1, the code is implemented using #ifdef's to make it portable across several different OSes. Figure 2 shows the same code written using CompLib. Notice that cl_malloc() is implemented for each OS. It is evident from looking at the code that the code is not only portable and extendible to a new OS–by implementing a flavor of CompLib for that new OS–but it will also be easy to read and maintain.
With an OSI library such as CompLib, developers can now write most or all of their drivers and applications independent of the operating system. Once they implement CompLib functions in the base code, they can move between platforms fairly quickly.
The Intel OSI reference implementation, CompLib, currently supports four OSes: Windows, Linux, EFI (Extensible Firmware Interface), and VxWorks. The Linux version of CompLib is now available (free) online for developers to use.
Advantages to Porting Code
Although portable code is not appropriate for all projects, it does have its advantages, including:
- OS flexibility–in today's competitive environment, generally an application or software stack must be able to run on different platforms.
- Rapid development–time to market (TTM) can be significantly improved, especially once developers get used to the library primitives.
- Robust code–porting to and testing code on multiple platforms helps find bugs and increase the quality of the overall application. In particular, subtle bugs that are not immediately visible in one platform
can be obvious or even critical on a second platform.
- Efficiency and maintainability–bugs, especially design bugs, can be found and fixed once for all platforms.
- Decreased ramp-up time–engineers often move on to other projects, leaving behind their legacy design for the next developer who must now port the application. When code is designed to be portable, it is both easier to read and easier to change, which can significantly reduce the ramp-up time engineers need to get familiar with the project.
Using an OSI Library
Intel developers who work on the InfiniBand software stack have been using CompLib for some time. Their experience with porting shows that other developers should keep some considerations in mind when using CompLib or any other similar OSI library. They offer the following advice:
- Don't use one ported version of the code as the basis for a port to yet another platform. Use a single version of the code as the basis from which each of the other versions will be ported.
- Use memory tracking, such as tracking spinlock usage, to make the code much easier to debug.
- Avoid ugly #ifdef's all over the code. These make the code unreadable and hard to understand. For example, Figure 1 shows a piece of code written with #ifdefs for multiple OSes in order to make the code portable. Figure 2 shows what the code would look like when written to link to an OSI library. Note how easy it would be to read, understand, modify (port), and maintain the code shown in Figure 2.
- Always prototype your functions. This is especially important when moving an application from 32-bit architecture to 64-bit architecture.
- Be aware of compiler-specific and platform-specific tools and variations. Using these will make the code less portable. For example, avoid using compiler-specific directives for packing in common code. Watch out for differences in function calls, system error logging, GUI libraries, and so on.
- Use ANSI (American National Standards Institute) or another well-known syntax.
- When extending the CompLib to a new platform, make sure it is thoroughly tested on the new platform before using it.
Developers can search online for articles that describe these and other porting problems, by platform and in detail (see the More Info section).
Should You Port?
Writing adaptable code is always a good idea, but in some cases it is better to rewrite the code than port it. The decision to write portable code should depend on several factors, including the size and purpose of the project, the number and specific type of platforms on which you intend to run the code, and the performance requirements of the application.
For example, if your project is only 300 or 500 lines of code, the overhead of learning to write to an OSI library may not be worth the extra effort. Or perhaps you're writing a driver for a speed-path operation and you know the driver will run on leading-edge architecture. You want that driver to be as fast as possible, so to optimize for speed you might write parts of the driver in architecture-dependent assembly language. In this case, because speed is the main issue, the driver's performance considerations outweigh the coding advantages gained by designing for portability. Similar optimizations are often used in modern operating systems, such as Linux.
Issues with Porting
As with any type of design work, porting is a process with many issues, including platform, tool, and language compatibility. Even the language of the primary code and not just the ported code can have an impact on adaptability. For example, C++ may not be the best choice for the primary code for an application that must be run in the Linux kernel.
Other issues may also arise from differences in architectures and tools. Some of the function calls made in Windows do not have a correlation in Linux, and such differences can mean that porting from Windows to Linux can be problematic, time-consuming, and complex.
There are three main issues with porting code:
Initial design overhead
The cost of porting code is the measure of how much it costs to move a piece of code from one platform (OS or architecture) to another, as compared to the cost of rewriting the same piece of code for the new platform. There can be significant costs in writing code that will be easy to port to new platforms. For fairly large and complex projects, the costs associated with the initial design phase might be justifiable. If the project is fairly simple, rewriting the code might be a better option instead.
Variations in architectures and tools
Variations in architectures and tools can be a problem. Such differences can include byte order, memory alignment requirements, pointer sizes, and bit packing. In general, developers should also avoid compiler-specific directives such as pragma packing. If pragma packing is required, then that code should be abstracted for each OS or platform under consideration.
Software that is highly adaptable might not offer the highest performance on every platform. A reduction in performance may be seen because the code does not use architecture, tool, or language-specific optimizations. If the performance reduction is unacceptable, developers might need to write some parts of the software in architecture-, tool- or language-specific sections.
It is important for developers to understand that there is no such thing as completely portable code. They can't know about every platform, compiler, or tool in industry. What developers can do is write code that is adaptable to new platforms, and the Intel® CompLib can help make that process easier.
CompLib Is Fast and Effective
Intel's experience with using the CompLib has been excellent. An Intel engineer recently used CompLib to port the InfiniBand software stack from a Windows-based platform to a Linux platform. A single engineer was able to port, test, and fully verify the drivers and services on the new platform in just a couple of days. The engineer was also able to port the software stack from the 32-bit Linux platform to a 64-bit Linux platform. This project was completed (ported, tested, and fully verified) in just half a day.
The Intel experience shows just how effective a well-designed OSI library can be, especially when the porting considerations are kept in mind. Because the Intel Component Library is now available online, developers across the industry can use the same process to make porting their own applications a faster, easier task.
Porting is attractive to developers because it can eliminate the need for duplicating code. Unfortunately, with so many platforms, architectures, and tools in the market, developers can find it difficult to port from one operating system to the next. But what may surprise developers is that some porting problems can be avoided simply through planning.
Before starting to implement code, developers must remember that their applications will probably run on more than one platform. Developers must start thinking in terms of adaptable code, and of how they can make drivers and applications platform-independent. They should no longer limit themselves to a single OS.
The Intel OSI library gives developers an effective tool to help with the porting process. Developers can download this library today and start learning how to implement it in their own applications.
The InfiniBand Component Library (CompLib) is available free online. The master index is located on the SourceForge.net InfiniBand site.
There are many articles in both print and online sources that describe the advantages and disadvantages of porting, problems typically seen in porting, special considerations for moving from one architecture to another, and so on. M. D. Geib's article, titled “Writing Easily Portable Code,” is currently available online in PDF format. Another good article is on the Game Developer's Conference Web site, which is hosted by Gama Network.
Developers might also consider checking out the following books:
- POSIX Programmer's Guide: Writing Portable UNIX Programs With the POSIX. 1 Standard, which is intended as an explanation of the POSIX standard and as a reference for the POSIX.1 programming library. The reference guide was written by Donald A. Lewine (edited by Dale Dougherty), published in 1991, by O'Reilly & Associates, Incorporated.
- C and UNIX Programming: A Comprehensive Guide, by N. S. Kutti, published in 2002, by the Cote Literary Group.
Ravi Murty has been with Intel for four years as senior network software engineer. Currently, he works on adaptive radio architectures at the Network Architecture Lab within the Corporate Technology Group. Previously, he worked in the Enterprise Platforms Group writing Linux drivers for InfiniBand technology. Prior to Intel, he worked with Qualcomm and Ericsson on various commercial CDMA base stations. Murty has received several awards, including an Intel business-group award in 2001 for his work on InfiniBand technology. He has also had two papers published in the Journal of Parallel Computing. Murty earned his B.S. in computer science and engineering from the Andhra University in India, and his M.S. in computer science from the University of Missouri, Rolla. He is a member of the InfiniBand Trade Association.
Ashok Raj has been with Intel for four years as a staff software engineer. Currently, he works on enhancing the Linux Operating System for enterprise features. Previously, Raj worked in the Enterprise Platforms Group as a team leader, developing Linux drivers for InfiniBand Technology. Prior to Intel, he worked with Pyramid Technologies and specialized in distributed mass-storage technologies and various storage solutions. Raj has received several awards, including an Intel business-group award in 2001 for his work on InfiniBand* technology. He was a speaker at the Intel Developer Forum (IDF) in 2001, and has published an article in EE Times on InfiniBand technology. He has four patents pending. Raj earned an M.Tech. in computer science and engineering from the Anna University, India.
Copyright © Intel Corporation 2003. All rights reserved. Reproduced by LinuxDevices.com with permission. This article was originally published in Intel's [email protected] Magazine.
This article was originally published on LinuxDevices and has been donated to the open source community by QuinStreet Inc. Please visit LinuxToday.com for up-to-date news and articles about Linux and open source.