Ignore:
File:
1 edited

Legend:

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

    r90c8b8d r7e752b2  
    3636#define KERN_SPINLOCK_H_
    3737
    38 #include <arch/types.h>
     38#include <typedefs.h>
    3939#include <arch/barrier.h>
    4040#include <preemption.h>
    4141#include <atomic.h>
    4242#include <debug.h>
     43#include <arch/asm.h>
    4344
    4445#ifdef CONFIG_SMP
     
    4849       
    4950#ifdef CONFIG_DEBUG_SPINLOCK
    50         char *name;
    51 #endif
     51        const char *name;
     52#endif /* CONFIG_DEBUG_SPINLOCK */
    5253} spinlock_t;
    5354
     
    6061
    6162/*
    62  * SPINLOCK_INITIALIZE is to be used for statically allocated spinlocks.
    63  * It declares and initializes the lock.
     63 * SPINLOCK_INITIALIZE and SPINLOCK_STATIC_INITIALIZE are to be used
     64 * for statically allocated spinlocks. They declare (either as global
     65 * or static) symbol and initialize the lock.
    6466 */
    6567#ifdef CONFIG_DEBUG_SPINLOCK
     
    7779        }
    7880
    79 #define spinlock_lock(lock)  spinlock_lock_debug(lock)
    80 
    81 #else
     81#define ASSERT_SPINLOCK(expr, lock) \
     82        ASSERT_VERBOSE(expr, (lock)->name)
     83
     84#define spinlock_lock(lock)    spinlock_lock_debug((lock))
     85#define spinlock_unlock(lock)  spinlock_unlock_debug((lock))
     86
     87#else /* CONFIG_DEBUG_SPINLOCK */
    8288
    8389#define SPINLOCK_INITIALIZE_NAME(lock_name, desc_name) \
     
    9197        }
    9298
    93 #define spinlock_lock(lock)  atomic_lock_arch(&(lock)->val)
    94 
    95 #endif
     99#define ASSERT_SPINLOCK(expr, lock) \
     100        ASSERT(expr)
     101
     102#define spinlock_lock(lock)    atomic_lock_arch(&(lock)->val)
     103#define spinlock_unlock(lock)  spinlock_unlock_nondebug((lock))
     104
     105#endif /* CONFIG_DEBUG_SPINLOCK */
    96106
    97107#define SPINLOCK_INITIALIZE(lock_name) \
     
    101111        SPINLOCK_STATIC_INITIALIZE_NAME(lock_name, #lock_name)
    102112
    103 extern void spinlock_initialize(spinlock_t *lock, char *name);
    104 extern int spinlock_trylock(spinlock_t *lock);
    105 extern void spinlock_lock_debug(spinlock_t *lock);
     113extern void spinlock_initialize(spinlock_t *, const char *);
     114extern int spinlock_trylock(spinlock_t *);
     115extern void spinlock_lock_debug(spinlock_t *);
     116extern void spinlock_unlock_debug(spinlock_t *);
     117extern bool spinlock_locked(spinlock_t *);
    106118
    107119/** Unlock spinlock
    108120 *
    109  * Unlock spinlock.
     121 * Unlock spinlock for non-debug kernels.
    110122 *
    111123 * @param sl Pointer to spinlock_t structure.
    112  */
    113 static inline void spinlock_unlock(spinlock_t *lock)
     124 *
     125 */
     126NO_TRACE static inline void spinlock_unlock_nondebug(spinlock_t *lock)
    114127{
    115         ASSERT(atomic_get(&lock->val) != 0);
    116        
    117128        /*
    118129         * Prevent critical section code from bleeding out this way down.
     
    135146        if ((pname)++ > (value)) { \
    136147                (pname) = 0; \
    137                 printf("Deadlock probe %s: exceeded threshold %u\n", \
     148                printf("Deadlock probe %s: exceeded threshold %u\n" \
    138149                    "cpu%u: function=%s, line=%u\n", \
    139150                    #pname, (value), CPU->id, __func__, __LINE__); \
    140151        }
    141152
    142 #else
     153#else /* CONFIG_DEBUG_SPINLOCK */
    143154
    144155#define DEADLOCK_PROBE_INIT(pname)
    145156#define DEADLOCK_PROBE(pname, value)
    146157
    147 #endif
     158#endif /* CONFIG_DEBUG_SPINLOCK */
    148159
    149160#else /* CONFIG_SMP */
     
    159170#define SPINLOCK_INITIALIZE_NAME(name, desc_name)
    160171#define SPINLOCK_STATIC_INITIALIZE_NAME(name, desc_name)
     172
     173#define ASSERT_SPINLOCK(expr, lock)  ASSERT(expr)
    161174
    162175#define spinlock_initialize(lock, name)
     
    165178#define spinlock_trylock(lock)  (preemption_disable(), 1)
    166179#define spinlock_unlock(lock)   preemption_enable()
     180#define spinlock_locked(lock)   1
     181#define spinlock_unlocked(lock) 1
    167182
    168183#define DEADLOCK_PROBE_INIT(pname)
    169184#define DEADLOCK_PROBE(pname, value)
    170185
     186#endif /* CONFIG_SMP */
     187
     188typedef struct {
     189        SPINLOCK_DECLARE(lock);  /**< Spinlock */
     190        bool guard;              /**< Flag whether ipl is valid */
     191        ipl_t ipl;               /**< Original interrupt level */
     192} irq_spinlock_t;
     193
     194#define IRQ_SPINLOCK_DECLARE(lock_name)  irq_spinlock_t lock_name
     195#define IRQ_SPINLOCK_EXTERN(lock_name)   extern irq_spinlock_t lock_name
     196
     197#ifdef CONFIG_SMP
     198
     199#define ASSERT_IRQ_SPINLOCK(expr, irq_lock) \
     200        ASSERT_SPINLOCK(expr, &((irq_lock)->lock))
     201
     202/*
     203 * IRQ_SPINLOCK_INITIALIZE and IRQ_SPINLOCK_STATIC_INITIALIZE are to be used
     204 * for statically allocated interrupts-disabled spinlocks. They declare (either
     205 * as global or static symbol) and initialize the lock.
     206 */
     207#ifdef CONFIG_DEBUG_SPINLOCK
     208
     209#define IRQ_SPINLOCK_INITIALIZE_NAME(lock_name, desc_name) \
     210        irq_spinlock_t lock_name = { \
     211                .lock = { \
     212                        .name = desc_name, \
     213                        .val = { 0 } \
     214                }, \
     215                .guard = false, \
     216                .ipl = 0 \
     217        }
     218
     219#define IRQ_SPINLOCK_STATIC_INITIALIZE_NAME(lock_name, desc_name) \
     220        static irq_spinlock_t lock_name = { \
     221                .lock = { \
     222                        .name = desc_name, \
     223                        .val = { 0 } \
     224                }, \
     225                .guard = false, \
     226                .ipl = 0 \
     227        }
     228
     229#else /* CONFIG_DEBUG_SPINLOCK */
     230
     231#define IRQ_SPINLOCK_INITIALIZE_NAME(lock_name, desc_name) \
     232        irq_spinlock_t lock_name = { \
     233                .lock = { \
     234                        .val = { 0 } \
     235                }, \
     236                .guard = false, \
     237                .ipl = 0 \
     238        }
     239
     240#define IRQ_SPINLOCK_STATIC_INITIALIZE_NAME(lock_name, desc_name) \
     241        static irq_spinlock_t lock_name = { \
     242                .lock = { \
     243                        .val = { 0 } \
     244                }, \
     245                .guard = false, \
     246                .ipl = 0 \
     247        }
     248
     249#endif /* CONFIG_DEBUG_SPINLOCK */
     250
     251#else /* CONFIG_SMP */
     252
     253/*
     254 * Since the spinlocks are void on UP systems, we also need
     255 * to have a special variant of interrupts-disabled spinlock
     256 * macros which take this into account.
     257 */
     258
     259#define ASSERT_IRQ_SPINLOCK(expr, irq_lock) \
     260        ASSERT_SPINLOCK(expr, NULL)
     261
     262#define IRQ_SPINLOCK_INITIALIZE_NAME(lock_name, desc_name) \
     263        irq_spinlock_t lock_name = { \
     264                .guard = false, \
     265                .ipl = 0 \
     266        }
     267
     268#define IRQ_SPINLOCK_STATIC_INITIALIZE_NAME(lock_name, desc_name) \
     269        static irq_spinlock_t lock_name = { \
     270                .guard = false, \
     271                .ipl = 0 \
     272        }
     273
     274#endif /* CONFIG_SMP */
     275
     276#define IRQ_SPINLOCK_INITIALIZE(lock_name) \
     277        IRQ_SPINLOCK_INITIALIZE_NAME(lock_name, #lock_name)
     278
     279#define IRQ_SPINLOCK_STATIC_INITIALIZE(lock_name) \
     280        IRQ_SPINLOCK_STATIC_INITIALIZE_NAME(lock_name, #lock_name)
     281
     282extern void irq_spinlock_initialize(irq_spinlock_t *, const char *);
     283extern void irq_spinlock_lock(irq_spinlock_t *, bool);
     284extern void irq_spinlock_unlock(irq_spinlock_t *, bool);
     285extern int irq_spinlock_trylock(irq_spinlock_t *);
     286extern void irq_spinlock_pass(irq_spinlock_t *, irq_spinlock_t *);
     287extern void irq_spinlock_exchange(irq_spinlock_t *, irq_spinlock_t *);
     288extern bool irq_spinlock_locked(irq_spinlock_t *);
     289
    171290#endif
    172291
    173 #endif
    174 
    175292/** @}
    176293 */
Note: See TracChangeset for help on using the changeset viewer.