Software Design Considerations for SMP Embedded Systems

While designing software for symmetric-multiprocessing systems, developers should be aware of the software design issues that they could encounter.

By Prasheeba Devi and Amit Sureka

The number of peripherals that are supported in today's multicore processors is quickly increasing. Symmetric-multiprocessing (SMP) software is expected to be quickly available to support these peripherals. While developing software for SMP systems (or migrating legacy software to SMP systems), software developers must consider some common design issues. Doing so will help to reduce the software-development cycle time.

Specifically, special consideration must be given to the following:

  • Handling of task priority or implicit synchronization

  • Spinlocks and synchronization

  • Synchronization between tasks sharing memory

  • Synchronization between tasks and ISRs sharing memory

  • Synchronization between ISRs sharing memory

Task-Priority Handling or Implicit Synchronization

In a uniprocessor environment, the software design can assume that a lower-priority task will not execute when a higher-priority task is ready to execute. In SMP systems, however, the scheduler can schedule the lower-priority task to another processor. As a result, this assumption is no longer valid. The design of SMP software must not have any assumptions based on the task priority. In other words, there should not be any implicit synchronization.

Spinlocks and Synchronization

Spinlock is a special variable that can be used for synchronization between tasks, between tasks and ISRs, or between ISRs. When a task (or ISR) tries to acquire a spinlock and no other task (or ISR) is holding that spinlock, it becomes readily available. If any other task (or ISR) tries to acquire this spinlock, it makes the CPU continuously spin for the lock to be released by the other task (or ISR).

The SMP-capable operating system generally provides two types of spinlocks:

  • Type 1: This type of spinlock is to be used by tasks only. The task spinning on this lock can be interrupted but not pre-empted.
  • Type 2: This spinlock can be used by both tasks and ISRs. The task spinning on this lock cannot be interrupted or pre-empted.

Any of the above types of spinlocks can be used based on the design requirements.

Synchronization Between Tasks Sharing Memory

In a uniprocessor environment, one and only one task executes at a given point in time. In uniprocessor systems, raising the task priorities and disabling the interrupts would have handled synchronization amongst tasks. As tasks of different priorities can execute simultaneously in an SMP system, however, such implicit locking mechanisms cannot be used. Type 1 Spinlock and other synchronization mechanisms, such as semaphores, message queues, etc., must be used. Spinlock mechanisms are supposed to be faster than semaphores or message queues.

Synchronization Between Tasks and ISRs Sharing Memory

In a uniprocessor environment, it is a common practice to disable interrupts in the task before accessing the memory that's shared between the ISR and tasks. In an SMP system, such an approach may lead to unpredictable behavior. It would disable the interrupt on the CPU on which the task is running while the ISR may be serviced by another processor. As a result, disabling interrupts cannot be used as a synchronization mechanism between tasks and ISRs in SMP systems. Instead, Type 2 Spinlock must be used.

Synchronization Between ISRs Sharing Memory

In a uniprocessor environment, synchronization among nested ISRs can be handled by disabling the interrupts. In an SMP system, however, this approach disables interrupts on the processor on which the ISR is executing. Meanwhile, another ISR can execute on another processor, which can lead to unpredictable behavior. Even if the OS provides the support for disabling the interrupts on all of the processors, it must not be used. Disabling the interrupts could considerably degrade the system performance. The best way to handle ISR synchronization is to use the Type 2 Spinlock.

Care While Using Spinlocks

If the usage of spinlocks isn't designed properly, it can lead to deadlock situations. Spinlocks must therefore be used with care. A few considerations should be heeded while using them:

  • A spinlock must not be acquired recursively, as the processor would be continuously spinning on the lock with no one to release the lock.
  • Spinlocks should be used only to protect a smaller piece of code. Holding a spinlock for longer durations can lead to slower system performance. (For example, if Task T1 has acquired a spinlock and another task—T2, executing on another processor—tries to acquire the spinlock, it will not be available. The CPU spins for the lock to be available. If T1 holds the spinlock for a longer time, the other processor simply spins, doing nothing effectively.)
  • Acquiring another spinlock while holding a spinlock is allowed, but one must make sure that no other task or ISR performs a reverse of the same operation. (For example, if Task T1 acquires spinlock s1 and then acquires spinlock s2, and another task—T2—acquires spinlock s2 and spinlock s1, there will be a deadlock situation.)

If the above-mentioned guidelines are followed by SMP software developers in their design phases, they will reduce possible errors. In doing so, they also will cut down on the efforts spent on software debugging.

Prasheeba Devi is an architect at Wipro Technologies. She holds a Bachelors Degree in Electronics and Communication Engineering. Her interests include OS kernel architecture and multiprocessing systems.

Amit Sureka is a Module Leader at Wipro Technologies. He holds a Bachelor Degree in Computer Science and Engineering. His interest includes Embedded Systems and Operating System Concepts.