Home |
RTKernel-32 Programming Manual Multitasking, Real-Time, and RTKernel-32 Spinlocks Alternate APIs for RTKernel-32 |
SpinlocksSpinlocks should be used to protect global data accessed by tasks and interrupt handlers. Semaphores and Win32 Critical Sections may block the calling task, so they cannot be used in interrupt handlers for mutual exclusion. Spinlocks may be used here. Conceptually, A spinlock is a variable which is set and read with an atomic operation. When a spinlock is locked, value 1 is written to the spinlock and the previous value stored is retrieved at the same time. If the read value was zero, the lock was successfully acquired. Otherwise, the operation is retried until it succeeds, hoping that the lock held by another CPU in a multiprocessor environment will eventually release it. To guard against interrupt handlers from entering a spinlock-protected code sequence, interrupts are disabled by the locking operation. Releasing a spinlock merely requires storing value zero in the spinlock and restoring the interrupt enable state. The implementation of RTKernel-32's spinlock is actually a bit more complex. Unlike traditional spinlocks (as, for example, those offered by RTTarget-32), RTKernel-32's spinlocks guarantee FIFO access. CPUs queued on a spinlock are granted access in the order they started spinning. In addition, each CPU spins on a different variable located in a unique cache line, significantly reducing cache trashing. However, RTKernel-32 spinlocks need significantly more RAM than RTTarget-32) spinlocks. Depending on the number of CPUs, a few hundred bytes up to about 1k of RAM may be required per lock. Spinlocks must be allocated with function RTKCreateSpinlock. Tasks as well as interrupt handlers should call RTKLockSpinlock to lock and RTKReleaseSpinlock to release the spinlock. Recursive (nested) locking is not supported. While a spinlock is locked, interrupts must not be enabled, and no RTKernel-32 API function may be called. The RTKernel-32 Debug Version will insert tracer events into the trace buffer for every lock and release operation. In addition, another "spin wait" event is recorded when RTKLockSpinlock fails to lock the spinlock immediately and has to go into a spin loop, indicating a high degree of congestion. As another debugging aid, the Debug Version can record the maximum time a spinlock was ever locked, if RTKConfig flag RF_LCPUTIME is set. Function RTKGetSpinlockTime can retrieve this time. Section Multiprocessor Applications discusses how spinlocks should be used.
|