Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset a9f1372 in mainline


Ignore:
Timestamp:
2010-05-25T18:35:36Z (11 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master
Children:
b7398c0
Parents:
0095368
Message:

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

Location:
kernel/generic
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/include/synch/spinlock.h

    r0095368 ra9f1372  
    277277        IRQ_SPINLOCK_STATIC_INITIALIZE_NAME(lock_name, #lock_name)
    278278
    279 /** Initialize interrupts-disabled spinlock
    280  *
    281  * @param lock IRQ spinlock to be initialized.
    282  * @param name IRQ spinlock name.
    283  *
    284  */
    285 static inline void irq_spinlock_initialize(irq_spinlock_t *lock, const char *name)
    286 {
    287         spinlock_initialize(&(lock->lock), name);
    288         lock->guard = false;
    289         lock->ipl = 0;
    290 }
    291 
    292 /** Lock interrupts-disabled spinlock
    293  *
    294  * Lock a spinlock which requires disabled interrupts.
    295  *
    296  * @param lock    IRQ spinlock to be locked.
    297  * @param irq_dis If true, interrupts are actually disabled
    298  *                prior locking the spinlock. If false, interrupts
    299  *                are expected to be already disabled.
    300  *
    301  */
    302 static inline void irq_spinlock_lock(irq_spinlock_t *lock, bool irq_dis)
    303 {
    304         if (irq_dis) {
    305                 ipl_t ipl = interrupts_disable();
    306                 spinlock_lock(&(lock->lock));
    307                
    308                 lock->guard = true;
    309                 lock->ipl = ipl;
    310         } else {
    311                 ASSERT_IRQ_SPINLOCK(interrupts_disabled(), lock);
    312                
    313                 spinlock_lock(&(lock->lock));
    314                 ASSERT_IRQ_SPINLOCK(!lock->guard, lock);
    315         }
    316 }
    317 
    318 /** Unlock interrupts-disabled spinlock
    319  *
    320  * Unlock a spinlock which requires disabled interrupts.
    321  *
    322  * @param lock    IRQ spinlock to be unlocked.
    323  * @param irq_res If true, interrupts are restored to previously
    324  *                saved interrupt level.
    325  *
    326  */
    327 static inline void irq_spinlock_unlock(irq_spinlock_t *lock, bool irq_res)
    328 {
    329         ASSERT_IRQ_SPINLOCK(interrupts_disabled(), lock);
    330        
    331         if (irq_res) {
    332                 ASSERT_IRQ_SPINLOCK(lock->guard, lock);
    333                
    334                 lock->guard = false;
    335                 ipl_t ipl = lock->ipl;
    336                
    337                 spinlock_unlock(&(lock->lock));
    338                 interrupts_restore(ipl);
    339         } else {
    340                 ASSERT_IRQ_SPINLOCK(!lock->guard, lock);
    341                 spinlock_unlock(&(lock->lock));
    342         }
    343 }
    344 
    345 /** Lock interrupts-disabled spinlock
    346  *
    347  * Lock an interrupts-disabled spinlock conditionally. If the
    348  * spinlock is not available at the moment, signal failure.
    349  * Interrupts are expected to be already disabled.
    350  *
    351  * @param lock IRQ spinlock to be locked conditionally.
    352  *
    353  * @return Zero on failure, non-zero otherwise.
    354  *
    355  */
    356 static inline int irq_spinlock_trylock(irq_spinlock_t *lock)
    357 {
    358         ASSERT_IRQ_SPINLOCK(interrupts_disabled(), lock);
    359         int rc = spinlock_trylock(&(lock->lock));
    360        
    361         ASSERT_IRQ_SPINLOCK(!lock->guard, lock);
    362         return rc;
    363 }
    364 
    365 /** Pass lock from one interrupts-disabled spinlock to another
    366  *
    367  * Pass lock from one IRQ spinlock to another IRQ spinlock
    368  * without enabling interrupts during the process.
    369  *
    370  * The first IRQ spinlock is supposed to be locked.
    371  *
    372  * @param unlock IRQ spinlock to be unlocked.
    373  * @param lock   IRQ spinlock to be locked.
    374  *
    375  */
    376 static inline void irq_spinlock_pass(irq_spinlock_t *unlock,
    377     irq_spinlock_t *lock)
    378 {
    379         ASSERT_IRQ_SPINLOCK(interrupts_disabled(), unlock);
    380        
    381         /* Pass guard from unlock to lock */
    382         bool guard = unlock->guard;
    383         ipl_t ipl = unlock->ipl;
    384         unlock->guard = false;
    385        
    386         spinlock_unlock(&(unlock->lock));
    387         spinlock_lock(&(lock->lock));
    388        
    389         ASSERT_IRQ_SPINLOCK(!lock->guard, lock);
    390        
    391         if (guard) {
    392                 lock->guard = true;
    393                 lock->ipl = ipl;
    394         }
    395 }
    396 
    397 /** Hand-over-hand locking of interrupts-disabled spinlocks
    398  *
    399  * Implement hand-over-hand locking between two interrupts-disabled
    400  * spinlocks without enabling interrupts during the process.
    401  *
    402  * The first IRQ spinlock is supposed to be locked.
    403  *
    404  * @param unlock IRQ spinlock to be unlocked.
    405  * @param lock   IRQ spinlock to be locked.
    406  *
    407  */
    408 static inline void irq_spinlock_exchange(irq_spinlock_t *unlock,
    409     irq_spinlock_t *lock)
    410 {
    411         ASSERT_IRQ_SPINLOCK(interrupts_disabled(), unlock);
    412        
    413         spinlock_lock(&(lock->lock));
    414         ASSERT_IRQ_SPINLOCK(!lock->guard, lock);
    415        
    416         /* Pass guard from unlock to lock */
    417         if (unlock->guard) {
    418                 lock->guard = true;
    419                 lock->ipl = unlock->ipl;
    420                 unlock->guard = false;
    421         }
    422        
    423         spinlock_unlock(&(unlock->lock));
    424 }
     279extern void irq_spinlock_initialize(irq_spinlock_t *, const char *);
     280extern void irq_spinlock_lock(irq_spinlock_t *, bool);
     281extern void irq_spinlock_unlock(irq_spinlock_t *, bool);
     282extern int irq_spinlock_trylock(irq_spinlock_t *);
     283extern void irq_spinlock_pass(irq_spinlock_t *, irq_spinlock_t *);
     284extern void irq_spinlock_exchange(irq_spinlock_t *, irq_spinlock_t *);
    425285
    426286#endif
  • 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.