Author: Thang Minh Le thangmle@gmail.com

REAL-TIME COMPUTING Real-time computing is not a new topic in computer science. It originally emerged from the need of building systems where timing constraint was critical. The concept of fast response time has been around since 1940s. According to [1], Laptante believed that the first ‘real-time’ system was built in project Whirlwind during Second World War. For decades, real-time computing has drawn a lot of attentions from researchers. Substantial improvements have been introduced to the field in order to achieve better results in term of efficiency and reliability. Despite all effort has been made, the topic is still remained challenging to researchers at all time. Real-time system is an interesting topic. A system claims to be real-time if it is designed to operate within a real-time domain. This domain is constructed by cascading the real-time requirement of one component to all of other components to which it interacts in the system. The cascading process continues and applies to all related components including hardware devices. Because of this unique restrict of real-time systems, in the 1960s, real-time computers were considered the largest most complex technical systems ever conceived [1]. In contrast with realtime systems, non-real-time systems do not require all of their components to operate in realtime manner. In fact, it is preferred to have them operating in non-real-time for better performance. Real-time systems are used in most embedded devices which are designed for their own purpose. Real-time software industry has moved to a better standardized way which adopts real-time operating system (RTOS) as an operating system for real-time embedded devices. A RTOS is designed to meet certain real-time requirements in order to provide a desired runtime environment to its applications. Real-time applications are different in their own will. However, real-time operating systems seem to share the same set of requirements with respect to real-time computing. The most important contract of a RTOS to its applications is to provide a deterministic or predictable response time per executing task. This is directly derived from the POSIX definition of real-time in operating system: “the ability of the operating system to provide a required level of service in a bounded response time” [2]. Accordingly, real-time application designers must be able to determine the amount of the worst case execution time per task. In hard real-time systems, this amount must be bounded for all time. In soft real-time systems, this restriction is relaxed a bit to allow unbounded worst case execution time from time to time. It must be clear that real-time should not be confused with getting immediate results/responses. It is simply because a faster response time can be achieved by running an application on a super-computer compared with a desktop computer. However, such achievement does not mean the application is executing in real-time manner. Indeed, it is suggested that response time must be bounded and the range is a function of the application the computer is serving [1]. POSIX REAL-TIME EXTENSION POSIX, as it stands for Portable Operating System Interface for UNIX, is an evolving set of standard APIs. The main purpose of POSIX standards is to promote portability of applications among operating systems. POSIX achieve its goal by standardizing operating system interface 2

and environment based on UNIX. POSIX adopts open software architecture to address issues of interoperability and portability. It defines a standard way for an application to interface with the operating system. Operating systems conforms to POSIX standards must implement their services following the definition and interface defined in corresponding POSIX APIs. It is to guarantee that the use of the same API in different POSIX compliant systems retrieves the same result. The original POSIX standard was first published in 1990. It is now a family of over 30 specifications for everything ranging from basic operating system services to testing the conformance to the standard.

Including in POSIX standards is POSIX real-time extension which takes an important role in standardizing real-time operating systems. Finding a common interface suitable for real-time applications is far more challenging. These applications usually demand low latency and efficient execution. Meanwhile, the POSIX basic standard is too heavy causing compliant systems to perform poorly in real-time requirement. As a result, real-time applications tend to call internal interfaces provided by the RTOS to achieve efficiency. In addition, there exists a large number of real-time operating systems with variations in their implementation makes a portable task for real-time applications unforeseeable. Facing with these issues, a working group was established in POSIX to “develop standards which are the minimum syntactic and semantics changes or additions to POSIX standards to support portability of applications with real-time requirements” [2]. A series of POSIX real-time standards were released including:
• • • • • •

IEEE Std 1003.1b-1993 Real-time Extension IEEE Std 1003.1c-1995 Threads IEEE Std 1003.1d-1999 Additional Real-time Extensions IEEE Std 1003.1j-2000 Advanced Real-time Extensions IEEE Std 1003.1q-2000 Tracing IEEE Std 1003.13-1998 Real-time Application Environment Profiles (AEPs)


POSIX real-time extension 1003.1b and 1003.1c are most commonly implemented in real-time operating systems. They were approved by IEEE and ISO/IEC and have been integrated into POSIX 1003.1 base standard. POSIX 1003.1b covers the most important part of real-time operating system. For this reason, this study mainly focuses on POSIX real-time extension 1003.1b which includes: Real-time signals: additional signals with multiple levels of priority. Clock and Timer: periodic timer delivery with the help of POSIX signals. Shared Memory and Memory Locking: sharing memory and prevent virtual memory swapping in/out. Priority Scheduling: fixed priority pre-emptive scheduling with a minimum of 32 priority levels. POSIX 1003.13 is another important standard which is also briefly discussed in this study.


POSIX 1003.1b
Real-time Signal Signal in POSIX standard is a notifying mechanism used in inter-process communication. A signal is generated as a result of the event that causes the signal first occurs. Events can be either internal or external. Such these events can be anything from detection of hardware faults to timer expiration. An operating system sends a notification message to a process under the format of POSIX signal based upon a particular event. When the process accepts the signal and handles it, the signal handler associated with this signal is entered. This progress is similar to the system entering an interrupt handler as the result of receiving an interrupt. Signal is an important concept in operating system design. POSIX defined a list of standard signals which represented a set of common events and recommended POSIX compliant operating systems should at least support these. Many signals defined in POSIX 1003.1 are primarily reserved for operating system. SIGURS1 and SIGUSR2 signals are the two used by applications. Signals can be generated in synchronous manner, asynchronous manner or explicitly by a process or a thread. Traditional signals presents “some drawbacks to be used in real-time application: too few number of signals for application use, no priority on signal delivery, limited information content associated to signal, signal lost due to not queuing, among other problems” [3]. POSIX 1003.1b extended the standard signal structure by adding more signals for application use. The macros SIGRTMIN and SIGRTMAX specify a range of signal numbers that are reserved for application use. RTOS must support at least RTSIG_MAX signal numbers. Another important feature introduced signal real-time extension is the ability to queue real-time signals. “Historical implementations of signals, using the signal() function, have shortcomings that make them unreliable for many application uses” [2]. To address this reliable issue, real-time signals are now queued in the system. When a process is blocked and unable to handle generated signals designated to it, these signals will be queued by the operating system. Once the process is able to handle signals, these signals will be de-queued and are delivered to the process without any lost. The delivery of queued signals follows the


lowest-numbered signal first mechanism. This feature allows applications to use number to be a signal priority. Signals might be failed to be queued in cases when there is no free space in the queue. SIGQUEUE_MAX is used to define maximum size of the queue. Union sigval was introduced in real-time signal extension. The union is used to pass a value along with a signal. As a result, signals now can have extra information associated with them. This information then can be used to help applications to identify the source of the signal. Sigwaitinfo() and sigtimedwait() were added to support real-time signals. Sigwaitinfo() is similar to the existing sigwait() but it is more dedicated to handle real-time signal which has the ability to return additional information. Sigtimedwait() is the same as sigwaitinfo() with additional feature which allows process/thread to wait within timeout unit. In brief, introducing queuing feature for real-time signals is a big improvement. However, it also creates some disadvantages: In term of performance, “queuing a signal implies reduced performance in a securityconscious implementation as the access permissions between the sender and receiver have to be checked on each send when the pid is resolved into a target process” [2]. Another aspect is the size of the queue is fixed. Without setting correct value for the queue’s size, signal might get lost. However, running into this situation might be rare thanks to only signals with sa_flags field set to SA_SIGINFO are queued. Queuing duplicated signal is another problem. Duplicated signals existing in the queue are considered wasted and might cause some overhead due to the same signal handler being executed many times. In most cases, these re-executions are unnecessary and should be avoided. Using signal number to be the priority level when delivering the signal to a process from the queue is misleading. In software design, the same field serving two different purposes is ‘double duties’ which is not recommended. A better way is to use ‘signal owner’ concept to obtain signal priority value. “The signal owner is defined as the thread that installed the signal handler last, or that made a call to any of sigwait() functions last” [3]. Signal when it stands alone outside of its creation context has no meaning of priority level. In this case, it is reasonable to use its signal number as its priority level. However, when considering its creation context, the use of signal number for its priority level is inappropriate. The context in which a signal is generated is very important. A signal generated during performing a high priority task must have higher priority than the same signal (same signal number) generated during performing a lower priority task. In this case, the two signals have the same signal number but they must have different priority levels. It is important that signal structure should have an extra field to store its priority value which must be different from its signal number. The priority level of a signal can be obtained by using ‘signal owner’ concept or inheriting from its creation process by default or being explicitly set to a correct value at runtime by applications. Also, real-time signal should have a field to indicate ‘deadline’ value which should be relative to its creation time. It is not necessary that two signals which are created at the same time and have the same signal number must have the same deadline. Again, the context when a signal is created might affect its deadline value. Real-time tasks thrive to finish within their deadline. So do realtime signals. The interval of time when a real-time signal is created till it is accepted is undetermined in most POSIX compliant real-time systems. During this time, the signal is in pending state. The pending period is longer or shorter depends on the implementation and the workload of the system at that time. POSIX standard does not clearly mention when a signal 6

must be delivered to its targeted process. Hence, ‘deadline’ field is necessary since real-time applications can depend on this value to determine whether a signal is already expired when it is accepted and perform necessary logic accordingly. Priority scheduling Scheduling is the heart of real-time operating systems. Because of its importance, it has been the most discussed topic since the beginning of real-time computing. Scheduling research has been split into two categories: runtime scheduling and pre-runtime scheduling. In term of runtime scheduling approach, priority based scheduling is the most widely adopted in many RTOSs. POSIX real-time extension used priority scheduling as the standard scheduling for its compliant systems. Real-time specification for Java (RTSJ) also adopted priority based scheduling as its standard scheduling. Priority based scheduling is proven to be a good candidate for runtime scheduling in RTOS. The most importance of priority scheduling supporting real-time requirements is that “it is deterministic: the highest-priority process is always run and, among processes of equal priority, the process that has been runnable for the longest time is executed first” [2]. In priority scheduling, a real-time application is responsible for controlling the execution sequence of its processes to meet the correctness and response time requirements. The real-time application gains this control through the value it set to processes’ priority. It is the responsibility of application logic to make rational priority assignments. RTOS, in return, must respect process priority value and perform scheduling processes: System scheduler always dispatches a process that has the highest (generally the most time-critical) priority among all runnable processes in the system. In fixed priority scheduling system, process priority must not be altered. By default, SCHED_FIFO is used to resolve the case of processes having the same priority value. Besides, POSIX 1003.1b requires these basic scheduling polices supported in its compliant RTOS: SCHED_RR: Round robin scheduling policy. SCHED_SPORADIC: Sporadic server scheduling policy. SCHED_OTHER: Another scheduling policy. While POSIX 1003.1 provided details of process preemption behavior, it did not mention the expectation for resource preemption. Preempting a process without handling its holding resources leads to the well-known priority inversion problem. The problem relates to resource contention where a low priority process whose holds a lock on a resource is preempted by a higher priority task which, in turn, is locked by the lower priority process during acquiring lock on the same resource. Two scenarios can happen in priority inversion. They were defined in [4] as follow: Bounded priority inversion, shown in Figure 1, occurs when low-priority Task L acquires a lock on a shared resource, but before releasing the resource is preempted by highpriority Task H. Task H attempts to acquire the resource but is forced to wait for Task L to finish its critical section. Task L continues running until it releases the resource, at which point Task H acquires the resource and resumes executing. The worst-case wait time for Task H is equal to the length of the critical section of Task L. 7

Unbounded priority inversion, shown in Figure 2, occurs when an intervening task extends a bounded priority inversion, possibly forever. In the previous example, suppose medium-priority Task M preempts Task L during the execution of Task L's critical section. Task M runs until it relinquishes control of the processor. Only when Task M turns over control can Task L finish executing its critical section and release the shared resource. This extension of the critical region leads to unbounded priority inversion. When Task L releases the resource, Task H can finally acquire the resource and resume execution. The worst-case wait time for Task H is now equal to the sum of the worst-case execution times of Task M and the critical section of Task L.

Priority ceiling protocol and priority inheritance protocol are the two most known solutions to priority inversion problem. The two protocols work by temporarily changing process priority at runtime. This effectively violates the requirement of fixed priority scheduling as applications should control process priority not RTOSs. Changing priority of a process without thoroughly testing it might cause unexpected behaviors. Although priority ceiling and priority inheritance both prevent unbounded priority inversion, neither protocol prevents bounded priority inversion. It's generally simpler to avoid priority inversion than to solve it in software [4]. If priority inversion is impossible to avoid, it is sufficient that the two processes involved in the problem perform some agreement upon executing either priority ceiling protocol or priority inheritance protocol. This way forces real-time application implementations to be well-prepared in handling this problem if it ever occurs. Despite all of the advantages when using priority based scheduling in RTOS, there are some concerns regarding this scheduling. Using priority based scheduling might not suitable for hard real-time system. Priority is somewhat unrelated to real-time. Using priority based scheduling as a solution to meet real-time requirements is unclear. The correctness of this approach has not been proved in any papers. Real-time by its definition is the ability of determining the worst case execution time of a task. However, using priority alone can only satisfy the real-time requirement of the highest priority task in a system. Once the highest task is available, it is executed immediately and hence the waiting time factor can be eliminated. In contrast, a real-time task which has lower priority has its execution time unbounded since there is no way to know when this task will be executed. In priority based scheduling, a real-time application is responsible for determining when its processes will run in relation to each other. This task is not trivial. In hard real-time systems with high computational complexity, finding an off-line feasible schedule for a set of processes which must satisfy all of their constraints and deadlines is easily proved to be NP-hard matter [5]. Given this, finding a proper priority scheme for a real-time application in hard real-time requirement at runtime is even harder leading to impossible. It is because there is no guarantee that using priority based scheduling at runtime satisfies all timing constraints [6]. In soft realtime requirement, priority based scheduling is sufficient. Nevertheless, one can take advantage of pre-run-time scheduling algorithm to help in finding priority scheme for a set of processes of a 8

given real-time application. Such an example of pre-run-time scheduling algorithm was described in [5]. Shared Memory & Memory Locking Memory management is another important aspect of real-time application. POSIX real-time extension introduced some great features including memory locking, memory mapped file and memory protection to manage memory more efficiently. In-used memory of a process might be paged out in the case of shortage of physical memory. Paging in/out memory produces unpredictable latency which is not acceptable in real-time systems. To prevent this happens, POSIX real-time extension defined memory locking using mlock(), munlock(), mlockall() and munlockall(). Upon successful return from mlock(), pages in the specified range shall be locked and memory-resident. In munlock(), pages in the specified range shall be unlocked with respect to the address space of the process. Using mlockall() function with MCL_CURRENT set, all currently mapped pages of the process' address space shall be memory-resident and locked. When munlockall() function returns, all currently mapped pages of the process' address space shall be unlocked with respect to the process' address space. Real-time processes usually work together, hence, they need to access each other resource. Interprocess communication must be done in efficient manner satisfying real-time requirements. Real-time signals can be used for this purpose. However, using this approach introduces unnecessary overhead. For more efficient communication among real-time processes, POSIX real-time extension defined shared memory feature which allow multiple processes access the shared data. The shared memory can be done through mmap() which maps a regular file/shared memory objects or typed memory objects to memory. Clock and Timer Time is the essence of real-time systems. Expressing absolute time in sub-millisecond precision is an absolute minimum requirement. Many advanced techniques have been introduced to improve hardware speed. Nowadays, processors can easily reach GHz in speed. Difference by nanoseconds can be computed on such environment. Nanosecond precision has precedent and allows the implementation to provide time-based services, such as timers, using whatever precision it is capable of while the application requirements are expressed to an arbitrary level of precision. For this purpose, POSIX defines structure timespec as follow:
time_t tv_sec – Seconds long tv_nsec – Nanoseconds

Time in POSIX has nanosecond resolution, which satisfies most real-time application requirements. POSIX real-time extension also defined a set of new functions to take the advantage of high resolution timer. These new functions allow timer events can be created that notify a process of timer expirations. Such these functions are timer_settime(), timer_gettime(), timer_getoverrun(). The advantage of nanosecond resolution and the ability of creating real-time signals for timer expiration ease the task of implementing periodic events in real-time applications. However, it is a bit overhead the way POSIX using 64-bit long for nanoseconds. It would be better to revise a bit by using 64-bit for milliseconds and 32-bit for nanoseconds. On fast processors, timing difference in real-time computing is usually from milliseconds to nanoseconds. Hence, expressing time in milliseconds and nanoseconds is more suitable than in seconds and nanoseconds. RTSJ is currently using 64-bit milliseconds and 32-bit nanoseconds. 9

Bollella, in [7], observed that 64-bit real-time clock based in nanoseconds had insufficient range in some situations.

POSIX 1003.13
Besides POSIX 1003.1b, POSIX real-time Application Environment Profiles (AEPs) defined in POSIX 1003.13 is another important feature. It was introduced to compromise the heavyweight of POSIX 1003.1 standard. Some embedded systems have very limited hardware components and hence, it is not feasible for these systems implementing all of POSIX basic standard 1003.1. To address this issue, AEPs define different profiles based on hardware constraints of devices. Within a certain profile, RTOS is only required to implement a subset of POSIX 1003.1 standards to be compliant. Four real-time AEPs are being defined in POSIX 1003.13: Minimum System: systems with no memory management unit (MMU), no file system, no I/O terminal. Only one process is allowed, but multi-threads can run concurrently. Real-time controller: it is similar to minimum system profile but adding file system and I/O terminal. Only one process but multiple threads are allowed. Dedicated system: representing large embedded systems with no file system. These systems have multiple processes and threads running concurrently. Multi-purpose system: it is for large real-time systems with all features supported


POSIX 1003.1b covered many important aspects of real-time computing. The standard was created based on open architecture design with no explicit or implicit references to how the standard should be implemented. Adding real-time signal features into traditional signal without breaking the existing standard was a big achievement. It is shown that the standards defined in POSIX have been taken carefully so that they are flexible to further required works. POSIX standards have a large impact on industrial software standard. However, history shows that the process of POSIX is a bit slow to keep pace with technical trends. Nowadays, it is crucial for industrial vendors to quickly react to new innovations and launch products to the market sooner better than later. POSIX standards provide little help in this type of business. Nevertheless, the work in POSIX standards is a great success.

[1] Phillip A. Laplante, Eileen P. Rose and Maria Gracia-Watson - An historical survey of early realtime computing developments in the U.S. – Real-time Systems, vol.8, 199-213, 1995. [2] IEEE Std 1003.1 – 2008, The Open Group Base Specifications, Issue 7 [3] Arnoldo Diaz, Ismael Ripoll and Alfons Crespo – On Integrating POSIX Signals into a Real-time operating system. [4] Kyle Renwick and Bill Renwick - How to use priority inheritance, Embedded System Design (http://www.embedded.com/columns/technicalinsights/20600062?_requestid=846574) [5] Jia Xu, David Lorge Parnas – Scheduling Processes with Release Times, Deadlines, Precedence, and Exclusion Relations – IEEE Transactions on Software Engineering, vol.16, no.3, 1990 [6] Jia Xu, David Lorge Parnas – On Satisfying Timing Constraints in Hard-Real-Time Systems, IEEE Transactions on Software Engineering, vol.19, no.1, 1993 [7] Greg Bollella – Real-time Specification for Java version 1.0, 2000 [8] Michael Gonzalez Harbour – Real-time POSIX: An Overview


Sign up to vote on this title
UsefulNot useful

Master Your Semester with Scribd & The New York Times

Special offer for students: Only $4.99/month.

Master Your Semester with a Special Offer from Scribd & The New York Times

Cancel anytime.