Changeset a9f1372 in mainline for kernel/generic/src/synch/spinlock.c


Ignore:
Timestamp:
2010-05-25T18:35:36Z (15 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
b7398c0
Parents:
0095368
Message:

Move the irq_spinlock code to spinlock.c for better debuggability.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/synch/spinlock.c

    r0095368 ra9f1372  
    169169#endif
    170170
     171/** Initialize interrupts-disabled spinlock
     172 *
     173 * @param lock IRQ spinlock to be initialized.
     174 * @param name IRQ spinlock name.
     175 *
     176 */
     177void irq_spinlock_initialize(irq_spinlock_t *lock, const char *name)
     178{
     179        spinlock_initialize(&(lock->lock), name);
     180        lock->guard = false;
     181        lock->ipl = 0;
     182}
     183
     184/** Lock interrupts-disabled spinlock
     185 *
     186 * Lock a spinlock which requires disabled interrupts.
     187 *
     188 * @param lock    IRQ spinlock to be locked.
     189 * @param irq_dis If true, interrupts are actually disabled
     190 *                prior locking the spinlock. If false, interrupts
     191 *                are expected to be already disabled.
     192 *
     193 */
     194void irq_spinlock_lock(irq_spinlock_t *lock, bool irq_dis)
     195{
     196        if (irq_dis) {
     197                ipl_t ipl = interrupts_disable();
     198                spinlock_lock(&(lock->lock));
     199               
     200                lock->guard = true;
     201                lock->ipl = ipl;
     202        } else {
     203                ASSERT_IRQ_SPINLOCK(interrupts_disabled(), lock);
     204               
     205                spinlock_lock(&(lock->lock));
     206                ASSERT_IRQ_SPINLOCK(!lock->guard, lock);
     207        }
     208}
     209
     210/** Unlock interrupts-disabled spinlock
     211 *
     212 * Unlock a spinlock which requires disabled interrupts.
     213 *
     214 * @param lock    IRQ spinlock to be unlocked.
     215 * @param irq_res If true, interrupts are restored to previously
     216 *                saved interrupt level.
     217 *
     218 */
     219void irq_spinlock_unlock(irq_spinlock_t *lock, bool irq_res)
     220{
     221        ASSERT_IRQ_SPINLOCK(interrupts_disabled(), lock);
     222       
     223        if (irq_res) {
     224                ASSERT_IRQ_SPINLOCK(lock->guard, lock);
     225               
     226                lock->guard = false;
     227                ipl_t ipl = lock->ipl;
     228               
     229                spinlock_unlock(&(lock->lock));
     230                interrupts_restore(ipl);
     231        } else {
     232                ASSERT_IRQ_SPINLOCK(!lock->guard, lock);
     233                spinlock_unlock(&(lock->lock));
     234        }
     235}
     236
     237/** Lock interrupts-disabled spinlock
     238 *
     239 * Lock an interrupts-disabled spinlock conditionally. If the
     240 * spinlock is not available at the moment, signal failure.
     241 * Interrupts are expected to be already disabled.
     242 *
     243 * @param lock IRQ spinlock to be locked conditionally.
     244 *
     245 * @return Zero on failure, non-zero otherwise.
     246 *
     247 */
     248int irq_spinlock_trylock(irq_spinlock_t *lock)
     249{
     250        ASSERT_IRQ_SPINLOCK(interrupts_disabled(), lock);
     251        int rc = spinlock_trylock(&(lock->lock));
     252       
     253        ASSERT_IRQ_SPINLOCK(!lock->guard, lock);
     254        return rc;
     255}
     256
     257/** Pass lock from one interrupts-disabled spinlock to another
     258 *
     259 * Pass lock from one IRQ spinlock to another IRQ spinlock
     260 * without enabling interrupts during the process.
     261 *
     262 * The first IRQ spinlock is supposed to be locked.
     263 *
     264 * @param unlock IRQ spinlock to be unlocked.
     265 * @param lock   IRQ spinlock to be locked.
     266 *
     267 */
     268void irq_spinlock_pass(irq_spinlock_t *unlock, irq_spinlock_t *lock)
     269{
     270        ASSERT_IRQ_SPINLOCK(interrupts_disabled(), unlock);
     271       
     272        /* Pass guard from unlock to lock */
     273        bool guard = unlock->guard;
     274        ipl_t ipl = unlock->ipl;
     275        unlock->guard = false;
     276       
     277        spinlock_unlock(&(unlock->lock));
     278        spinlock_lock(&(lock->lock));
     279       
     280        ASSERT_IRQ_SPINLOCK(!lock->guard, lock);
     281       
     282        if (guard) {
     283                lock->guard = true;
     284                lock->ipl = ipl;
     285        }
     286}
     287
     288/** Hand-over-hand locking of interrupts-disabled spinlocks
     289 *
     290 * Implement hand-over-hand locking between two interrupts-disabled
     291 * spinlocks without enabling interrupts during the process.
     292 *
     293 * The first IRQ spinlock is supposed to be locked.
     294 *
     295 * @param unlock IRQ spinlock to be unlocked.
     296 * @param lock   IRQ spinlock to be locked.
     297 *
     298 */
     299void irq_spinlock_exchange(irq_spinlock_t *unlock, irq_spinlock_t *lock)
     300{
     301        ASSERT_IRQ_SPINLOCK(interrupts_disabled(), unlock);
     302       
     303        spinlock_lock(&(lock->lock));
     304        ASSERT_IRQ_SPINLOCK(!lock->guard, lock);
     305       
     306        /* Pass guard from unlock to lock */
     307        if (unlock->guard) {
     308                lock->guard = true;
     309                lock->ipl = unlock->ipl;
     310                unlock->guard = false;
     311        }
     312       
     313        spinlock_unlock(&(unlock->lock));
     314}
     315
    171316/** @}
    172317 */
Note: See TracChangeset for help on using the changeset viewer.