Synchronization in Window XP
The Windows XP operating system is a multithreaded kernel that provides support for real-time applications and multiple processors. When the Windows XP kernel accesses a global resource on a uniprocessor system, it temporarily masks interrupts for all interrupt handlers that may also access the global resource On a multiprocessor system, Windows XP protects access to global resources using spinlocks. Just as in Solaris, the kernel uses spinlocks only to protect short code segments. Furthermore, for reasons of efficiency, the kernel ensures that a thread will never be preempted while holding a spinlock. For thread synchronization outside the kernel, Windows XP provides Dispatcher object Using a dispatcher object, threads synchronize according to several different mechanisms, including mutex, semaphores, events, and timers.
The system protects shared data by requiring a thread to gain ownership of a mutex to access the data and to release ownership when it is finished. Semaphores behave as described in Section1.1. by smite are similar to condition variables that is, they may notify a waiting thread when a desired condition occurs. Finally, timers are used to notify one (or more than one) thread that a specified amount of time has expired. Dispatcher objects may be in either a signaled state or a non signaled state. A signal of state indicates that an object is available and a thread will not block when acquiring the object.
A indicates that an object is not available and a thread will block when attempting to acquire the object. We illustrate the state transitions of a mutex lock dispatcher object in figure 1.1 a relationship exists between the state of a dispatcher object and the state of a thread. When a thread blocks on a non signaled dispatcher object, its state changes form ready to waiting and the thread is placed in a waiting queue for that object. When the state for the dispatcher object moves to signaled, the kernel checks whether any threads are waiting to object. If it is yes, the kernel moves one thread -or possibly non signal threads-from the waiting state to the ready state, where they can resume executing.
The number of threads the kernel selects from the waiting queue depends on the type of dispatcher object for which it is waiting. The kernel will select only one thread from the waiting queue for a mutex, since a mutex object may be “owned” by only a single thread. For an event object, the kernel will select all threads that are waiting for the event. We can use a mutex lock as an illustration of dispatcher objects and thread states. If a thread tries to acquire a mutex dispatcher objects that is in a no signaled state, that thread will be suspended and placed in a waiting queue for the mutex object. When the mutex moves to the signaled state (because another thread has released the lock on the mutex), the thread waiting at the front of the queue will be moved from the waiting state to the ready state and will acquire the mutex lock.
Synchronization in Linux
Prior to Version 2.6, Linux was a non preemptive kernel, meaning that a process running in kernel mode could not be preempted -even if a higher-priority process became available to run. Now, however, the Linux kernel is completely preemptive, so the running task can be preempted in the kernel. The Linux kernel provides spinlocks and semaphores (as well as reader writer versions of these two locks) for locking in the kernel on SMP machines with the spinlock mechanism to held spinlock only for short durations. On single-processor machines, spinlocks are inappropriate for use and are replaced by enabling and disabling kernel preemption. That is, on single-processor machines, rather than holding a spinlock, the kernel disables kernel preemption; and rather than releasing the spinlock, it enables kernel preemption. This is summarized below:
Linux uses an interesting approach to disable and enable kernel preemption. It provides two simple system calls-preemptive L disable () and preempt enable ()-for disabling and enabling kernel preemption. In addition, however, the kernel is not preemptible if a kernel-mode task is holding a lock. To enforce this rule, each task has the system has a thread-info structure containing a counter, preempLcount, to indicate the number of locks being held by the task. When a lock is acquired, preempLcount is incremented. It is decremented when a lock is released. If the value of preempt_count for the task currently running is greater than zero, it is not safe to preempt the kernel, as this task currently holds a lock If the count is zero, the kernel can safely be interrupted (assuming there are no outstanding calls to preamp L disable () ). Spinlocks-along with enabling and disabling kernel preemption-are used in the kernel only when a lock (or disabling kernel preemption) is held for a short duration. When a lock must be held for a longer period, semaphores are appropriate for use.
Synchronization in Pthreads
The Pthreads API provides mutex locks, condition variables, and read-write locks for thread synchronization. This API is available for programmers and is not part of any particular kernel. Mutex locks represent the fundamental synchronization technique used with Pthreads. A mutex lock is used to protect critical sections of code-that is, a thread acquires the lock before entering a critical section and releases it upon exiting the critical section. Condition variables in Pthreads behave much as described in Section. Read-write locks behave similarly to the locking mechanism described in this Section.
Many systems that implement Pthreads also provide semaphores, although they are not part of the Pthreads standard and instead belong to the POSIX SEM extension. Other extensions to the Pthreads API include spinlocks, but not all extensions are considered portable from one implementation to another.