Ignore:
File:
1 edited

Legend:

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

    r7e752b2 r90c8b8d  
    5252 *
    5353 */
    54 void spinlock_initialize(spinlock_t *lock, const char *name)
     54void spinlock_initialize(spinlock_t *lock, char *name)
    5555{
    5656        atomic_set(&lock->val, 0);
     
    102102               
    103103                if (i++ > DEADLOCK_THRESHOLD) {
    104                         printf("cpu%u: looping on spinlock %p:%s, "
    105                             "caller=%p (%s)\n", CPU->id, lock, lock->name,
    106                             (void *) CALLER, symtab_fmt_name_lookup(CALLER));
     104                        printf("cpu%u: looping on spinlock %" PRIp ":%s, "
     105                            "caller=%" PRIp "(%s)\n", CPU->id, lock, lock->name,
     106                            CALLER, symtab_fmt_name_lookup(CALLER));
    107107                       
    108108                        i = 0;
     
    120120}
    121121
    122 /** Unlock spinlock
    123  *
    124  * Unlock spinlock.
    125  *
    126  * @param sl Pointer to spinlock_t structure.
    127  */
    128 void spinlock_unlock_debug(spinlock_t *lock)
    129 {
    130         ASSERT_SPINLOCK(spinlock_locked(lock), lock);
    131        
    132         /*
    133          * Prevent critical section code from bleeding out this way down.
    134          */
    135         CS_LEAVE_BARRIER();
    136        
    137         atomic_set(&lock->val, 0);
    138         preemption_enable();
    139 }
    140 
    141122#endif
    142123
    143124/** Lock spinlock conditionally
    144125 *
    145  * Lock spinlock conditionally. If the spinlock is not available
    146  * at the moment, signal failure.
     126 * Lock spinlock conditionally.
     127 * If the spinlock is not available at the moment,
     128 * signal failure.
    147129 *
    148130 * @param lock Pointer to spinlock_t structure.
     
    167149}
    168150
    169 /** Find out whether the spinlock is currently locked.
    170  *
    171  * @param lock          Spinlock.
    172  * @return              True if the spinlock is locked, false otherwise.
    173  */
    174 bool spinlock_locked(spinlock_t *lock)
    175 {
    176         return atomic_get(&lock->val) != 0;
    177 }
    178 
    179151#endif
    180 
    181 /** Initialize interrupts-disabled spinlock
    182  *
    183  * @param lock IRQ spinlock to be initialized.
    184  * @param name IRQ spinlock name.
    185  *
    186  */
    187 void irq_spinlock_initialize(irq_spinlock_t *lock, const char *name)
    188 {
    189         spinlock_initialize(&(lock->lock), name);
    190         lock->guard = false;
    191         lock->ipl = 0;
    192 }
    193 
    194 /** Lock interrupts-disabled spinlock
    195  *
    196  * Lock a spinlock which requires disabled interrupts.
    197  *
    198  * @param lock    IRQ spinlock to be locked.
    199  * @param irq_dis If true, interrupts are actually disabled
    200  *                prior locking the spinlock. If false, interrupts
    201  *                are expected to be already disabled.
    202  *
    203  */
    204 void irq_spinlock_lock(irq_spinlock_t *lock, bool irq_dis)
    205 {
    206         if (irq_dis) {
    207                 ipl_t ipl = interrupts_disable();
    208                 spinlock_lock(&(lock->lock));
    209                
    210                 lock->guard = true;
    211                 lock->ipl = ipl;
    212         } else {
    213                 ASSERT_IRQ_SPINLOCK(interrupts_disabled(), lock);
    214                
    215                 spinlock_lock(&(lock->lock));
    216                 ASSERT_IRQ_SPINLOCK(!lock->guard, lock);
    217         }
    218 }
    219 
    220 /** Unlock interrupts-disabled spinlock
    221  *
    222  * Unlock a spinlock which requires disabled interrupts.
    223  *
    224  * @param lock    IRQ spinlock to be unlocked.
    225  * @param irq_res If true, interrupts are restored to previously
    226  *                saved interrupt level.
    227  *
    228  */
    229 void irq_spinlock_unlock(irq_spinlock_t *lock, bool irq_res)
    230 {
    231         ASSERT_IRQ_SPINLOCK(interrupts_disabled(), lock);
    232        
    233         if (irq_res) {
    234                 ASSERT_IRQ_SPINLOCK(lock->guard, lock);
    235                
    236                 lock->guard = false;
    237                 ipl_t ipl = lock->ipl;
    238                
    239                 spinlock_unlock(&(lock->lock));
    240                 interrupts_restore(ipl);
    241         } else {
    242                 ASSERT_IRQ_SPINLOCK(!lock->guard, lock);
    243                 spinlock_unlock(&(lock->lock));
    244         }
    245 }
    246 
    247 /** Lock interrupts-disabled spinlock
    248  *
    249  * Lock an interrupts-disabled spinlock conditionally. If the
    250  * spinlock is not available at the moment, signal failure.
    251  * Interrupts are expected to be already disabled.
    252  *
    253  * @param lock IRQ spinlock to be locked conditionally.
    254  *
    255  * @return Zero on failure, non-zero otherwise.
    256  *
    257  */
    258 int irq_spinlock_trylock(irq_spinlock_t *lock)
    259 {
    260         ASSERT_IRQ_SPINLOCK(interrupts_disabled(), lock);
    261         int rc = spinlock_trylock(&(lock->lock));
    262        
    263         ASSERT_IRQ_SPINLOCK(!lock->guard, lock);
    264         return rc;
    265 }
    266 
    267 /** Pass lock from one interrupts-disabled spinlock to another
    268  *
    269  * Pass lock from one IRQ spinlock to another IRQ spinlock
    270  * without enabling interrupts during the process.
    271  *
    272  * The first IRQ spinlock is supposed to be locked.
    273  *
    274  * @param unlock IRQ spinlock to be unlocked.
    275  * @param lock   IRQ spinlock to be locked.
    276  *
    277  */
    278 void irq_spinlock_pass(irq_spinlock_t *unlock, irq_spinlock_t *lock)
    279 {
    280         ASSERT_IRQ_SPINLOCK(interrupts_disabled(), unlock);
    281        
    282         /* Pass guard from unlock to lock */
    283         bool guard = unlock->guard;
    284         ipl_t ipl = unlock->ipl;
    285         unlock->guard = false;
    286        
    287         spinlock_unlock(&(unlock->lock));
    288         spinlock_lock(&(lock->lock));
    289        
    290         ASSERT_IRQ_SPINLOCK(!lock->guard, lock);
    291        
    292         if (guard) {
    293                 lock->guard = true;
    294                 lock->ipl = ipl;
    295         }
    296 }
    297 
    298 /** Hand-over-hand locking of interrupts-disabled spinlocks
    299  *
    300  * Implement hand-over-hand locking between two interrupts-disabled
    301  * spinlocks without enabling interrupts during the process.
    302  *
    303  * The first IRQ spinlock is supposed to be locked.
    304  *
    305  * @param unlock IRQ spinlock to be unlocked.
    306  * @param lock   IRQ spinlock to be locked.
    307  *
    308  */
    309 void irq_spinlock_exchange(irq_spinlock_t *unlock, irq_spinlock_t *lock)
    310 {
    311         ASSERT_IRQ_SPINLOCK(interrupts_disabled(), unlock);
    312        
    313         spinlock_lock(&(lock->lock));
    314         ASSERT_IRQ_SPINLOCK(!lock->guard, lock);
    315        
    316         /* Pass guard from unlock to lock */
    317         if (unlock->guard) {
    318                 lock->guard = true;
    319                 lock->ipl = unlock->ipl;
    320                 unlock->guard = false;
    321         }
    322        
    323         spinlock_unlock(&(unlock->lock));
    324 }
    325 
    326 /** Find out whether the IRQ spinlock is currently locked.
    327  *
    328  * @param lock          IRQ spinlock.
    329  * @return              True if the IRQ spinlock is locked, false otherwise.
    330  */
    331 bool irq_spinlock_locked(irq_spinlock_t *ilock)
    332 {
    333         return spinlock_locked(&ilock->lock);
    334 }
    335152
    336153/** @}
Note: See TracChangeset for help on using the changeset viewer.