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


Ignore:
Timestamp:
2009-08-21T14:08:20Z (15 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
a71c158
Parents:
af8e565
Message:

extend the spinlock interface (static spinlocks, statically declared spinlocks with user-defined name)
ignore deadlock detection on all spinlocks whose name begins with "*" (this is more generic than a hardwired list of spinlocks to ignore)
printf_lock is not required to be public anymore

File:
1 edited

Legend:

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

    raf8e565 r90c8b8d  
    4545#include <symtab.h>
    4646
    47 #ifdef CONFIG_FB
    48 #include <genarch/fb/fb.h>
    49 #endif
    50 
    5147#ifdef CONFIG_SMP
    5248
    5349/** Initialize spinlock
    5450 *
    55  * Initialize spinlock.
     51 * @param sl Pointer to spinlock_t structure.
    5652 *
    57  * @param sl Pointer to spinlock_t structure.
    5853 */
    59 void spinlock_initialize(spinlock_t *sl, char *name)
     54void spinlock_initialize(spinlock_t *lock, char *name)
    6055{
    61         atomic_set(&sl->val, 0);
     56        atomic_set(&lock->val, 0);
    6257#ifdef CONFIG_DEBUG_SPINLOCK
    63         sl->name = name;
    64 #endif 
     58        lock->name = name;
     59#endif
    6560}
     61
     62#ifdef CONFIG_DEBUG_SPINLOCK
    6663
    6764/** Lock spinlock
     
    7168 * possible occurence of deadlock.
    7269 *
    73  * @param sl Pointer to spinlock_t structure.
     70 * @param lock Pointer to spinlock_t structure.
     71 *
    7472 */
    75 #ifdef CONFIG_DEBUG_SPINLOCK
    76 void spinlock_lock_debug(spinlock_t *sl)
     73void spinlock_lock_debug(spinlock_t *lock)
    7774{
    7875        size_t i = 0;
    7976        bool deadlock_reported = false;
    80 
     77       
    8178        preemption_disable();
    82         while (test_and_set(&sl->val)) {
    83 
     79        while (test_and_set(&lock->val)) {
    8480                /*
    85                  * We need to be careful about printf_lock and fb_lock.
    86                  * Both of them are used to report deadlocks via
    87                  * printf() and fb_putchar().
     81                 * We need to be careful about particular locks
     82                 * which are directly used to report deadlocks
     83                 * via printf() (and recursively other functions).
     84                 * This conserns especially printf_lock and the
     85                 * framebuffer lock.
    8886                 *
     87                 * Any lock whose name is prefixed by "*" will be
     88                 * ignored by this deadlock detection routine
     89                 * as this might cause an infinite recursion.
    8990                 * We trust our code that there is no possible deadlock
    90                  * caused by these two locks (except when an exception
    91                  * is triggered for instance by printf() or fb_putchar()).
    92                  * However, we encountered false positives caused by very
    93                  * slow VESA framebuffer interaction (especially when
     91                 * caused by these locks (except when an exception
     92                 * is triggered for instance by printf()).
     93                 *
     94                 * We encountered false positives caused by very
     95                 * slow framebuffer interaction (especially when
    9496                 * run in a simulator) that caused problems with both
    95                  * printf_lock and fb_lock.
     97                 * printf_lock and the framebuffer lock.
    9698                 *
    97                  * Possible deadlocks on both printf_lock and fb_lock
    98                  * are therefore not reported as they would cause an
    99                  * infinite recursion.
    10099                 */
    101                 if (sl == &printf_lock)
     100                if (lock->name[0] == '*')
    102101                        continue;
    103 #ifdef CONFIG_FB
    104                 if (sl == &fb_lock)
    105                         continue;
    106 #endif
     102               
    107103                if (i++ > DEADLOCK_THRESHOLD) {
    108104                        printf("cpu%u: looping on spinlock %" PRIp ":%s, "
    109                             "caller=%" PRIp "(%s)\n", CPU->id, sl, sl->name,
     105                            "caller=%" PRIp "(%s)\n", CPU->id, lock, lock->name,
    110106                            CALLER, symtab_fmt_name_lookup(CALLER));
    111107                       
     
    114110                }
    115111        }
    116 
     112       
    117113        if (deadlock_reported)
    118114                printf("cpu%u: not deadlocked\n", CPU->id);
    119 
     115       
    120116        /*
    121117         * Prevent critical section code from bleeding out this way up.
     
    123119        CS_ENTER_BARRIER();
    124120}
     121
    125122#endif
    126123
     
    131128 * signal failure.
    132129 *
    133  * @param sl Pointer to spinlock_t structure.
     130 * @param lock Pointer to spinlock_t structure.
    134131 *
    135132 * @return Zero on failure, non-zero otherwise.
     133 *
    136134 */
    137 int spinlock_trylock(spinlock_t *sl)
     135int spinlock_trylock(spinlock_t *lock)
    138136{
    139         int rc;
     137        preemption_disable();
     138        int rc = !test_and_set(&lock->val);
    140139       
    141         preemption_disable();
    142         rc = !test_and_set(&sl->val);
    143 
    144140        /*
    145141         * Prevent critical section code from bleeding out this way up.
    146142         */
    147143        CS_ENTER_BARRIER();
    148 
     144       
    149145        if (!rc)
    150146                preemption_enable();
Note: See TracChangeset for help on using the changeset viewer.