linux-bk/include/linux/spinlock.h
<<
>>
Prefs
   1#ifndef __LINUX_SPINLOCK_H
   2#define __LINUX_SPINLOCK_H
   3
   4#include <linux/config.h>
   5#include <linux/preempt.h>
   6#include <linux/linkage.h>
   7#include <linux/compiler.h>
   8#include <linux/thread_info.h>
   9#include <linux/kernel.h>
  10
  11#include <asm/system.h>
  12
  13/*
  14 * These are the generic versions of the spinlocks and read-write
  15 * locks..
  16 */
  17#define spin_lock_irqsave(lock, flags)          do { local_irq_save(flags);       spin_lock(lock); } while (0)
  18#define spin_lock_irq(lock)                     do { local_irq_disable();         spin_lock(lock); } while (0)
  19#define spin_lock_bh(lock)                      do { local_bh_disable();          spin_lock(lock); } while (0)
  20
  21#define read_lock_irqsave(lock, flags)          do { local_irq_save(flags);       read_lock(lock); } while (0)
  22#define read_lock_irq(lock)                     do { local_irq_disable();         read_lock(lock); } while (0)
  23#define read_lock_bh(lock)                      do { local_bh_disable();          read_lock(lock); } while (0)
  24
  25#define write_lock_irqsave(lock, flags)         do { local_irq_save(flags);      write_lock(lock); } while (0)
  26#define write_lock_irq(lock)                    do { local_irq_disable();        write_lock(lock); } while (0)
  27#define write_lock_bh(lock)                     do { local_bh_disable();         write_lock(lock); } while (0)
  28
  29#define spin_unlock_irqrestore(lock, flags)     do { _raw_spin_unlock(lock);  local_irq_restore(flags); preempt_enable(); } while (0)
  30#define _raw_spin_unlock_irqrestore(lock, flags) do { _raw_spin_unlock(lock);  local_irq_restore(flags); } while (0)
  31#define spin_unlock_irq(lock)                   do { _raw_spin_unlock(lock);  local_irq_enable(); preempt_enable();       } while (0)
  32#define spin_unlock_bh(lock)                    do { spin_unlock(lock); local_bh_enable(); } while (0)
  33
  34#define read_unlock_irqrestore(lock, flags)     do { _raw_read_unlock(lock);  local_irq_restore(flags); preempt_enable(); } while (0)
  35#define read_unlock_irq(lock)                   do { _raw_read_unlock(lock);  local_irq_enable(); preempt_enable(); } while (0)
  36#define read_unlock_bh(lock)                    do { read_unlock(lock);  local_bh_enable();        } while (0)
  37
  38#define write_unlock_irqrestore(lock, flags)    do { _raw_write_unlock(lock); local_irq_restore(flags); preempt_enable(); } while (0)
  39#define write_unlock_irq(lock)                  do { _raw_write_unlock(lock); local_irq_enable(); preempt_enable();       } while (0)
  40#define write_unlock_bh(lock)                   do { write_unlock(lock); local_bh_enable();        } while (0)
  41#define spin_trylock_bh(lock)                   ({ int __r; local_bh_disable();\
  42                                                __r = spin_trylock(lock);      \
  43                                                if (!__r) local_bh_enable();   \
  44                                                __r; })
  45
  46/* Must define these before including other files, inline functions need them */
  47
  48#include <linux/stringify.h>
  49
  50#define LOCK_SECTION_NAME                       \
  51        ".text.lock." __stringify(KBUILD_BASENAME)
  52
  53#define LOCK_SECTION_START(extra)               \
  54        ".subsection 1\n\t"                     \
  55        extra                                   \
  56        ".ifndef " LOCK_SECTION_NAME "\n\t"     \
  57        LOCK_SECTION_NAME ":\n\t"               \
  58        ".endif\n\t"
  59
  60#define LOCK_SECTION_END                        \
  61        ".previous\n\t"
  62
  63#ifdef CONFIG_SMP
  64#include <asm/spinlock.h>
  65
  66#elif !defined(spin_lock_init) /* !SMP and spin_lock_init not previously
  67                                  defined (e.g. by including asm/spinlock.h */
  68
  69#ifndef CONFIG_PREEMPT
  70# define atomic_dec_and_lock(atomic,lock) atomic_dec_and_test(atomic)
  71# define ATOMIC_DEC_AND_LOCK
  72#endif
  73
  74/*
  75 * Your basic spinlocks, allowing only a single CPU anywhere
  76 *
  77 * Most gcc versions have a nasty bug with empty initializers.
  78 */
  79#if (__GNUC__ > 2)
  80  typedef struct { } spinlock_t;
  81# define SPIN_LOCK_UNLOCKED (spinlock_t) { }
  82#else
  83  typedef struct { int gcc_is_buggy; } spinlock_t;
  84# define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 }
  85#endif
  86
  87#define spin_lock_init(lock)    do { (void)(lock); } while(0)
  88#define _raw_spin_lock(lock)    (void)(lock) /* Not "unused variable". */
  89#define spin_is_locked(lock)    ((void)(lock), 0)
  90#define _raw_spin_trylock(lock) ((void)(lock), 1)
  91#define spin_unlock_wait(lock)  do { (void)(lock); } while(0)
  92#define _raw_spin_unlock(lock)  do { (void)(lock); } while(0)
  93
  94/*
  95 * Read-write spinlocks, allowing multiple readers
  96 * but only one writer.
  97 *
  98 * NOTE! it is quite common to have readers in interrupts
  99 * but no interrupt writers. For those circumstances we
 100 * can "mix" irq-safe locks - any writer needs to get a
 101 * irq-safe write-lock, but readers can get non-irqsafe
 102 * read-locks.
 103 *
 104 * Most gcc versions have a nasty bug with empty initializers.
 105 */
 106#if (__GNUC__ > 2)
 107  typedef struct { } rwlock_t;
 108  #define RW_LOCK_UNLOCKED (rwlock_t) { }
 109#else
 110  typedef struct { int gcc_is_buggy; } rwlock_t;
 111  #define RW_LOCK_UNLOCKED (rwlock_t) { 0 }
 112#endif
 113
 114#define rwlock_init(lock)       do { } while(0)
 115#define _raw_read_lock(lock)    (void)(lock) /* Not "unused variable". */
 116#define _raw_read_unlock(lock)  do { } while(0)
 117#define _raw_write_lock(lock)   (void)(lock) /* Not "unused variable". */
 118#define _raw_write_unlock(lock) do { } while(0)
 119
 120#endif /* !SMP */
 121
 122#ifdef CONFIG_PREEMPT
 123
 124#define spin_lock(lock) \
 125do { \
 126        preempt_disable(); \
 127        _raw_spin_lock(lock); \
 128} while(0)
 129
 130#define spin_trylock(lock)      ({preempt_disable(); _raw_spin_trylock(lock) ? \
 131                                1 : ({preempt_enable(); 0;});})
 132#define spin_unlock(lock) \
 133do { \
 134        _raw_spin_unlock(lock); \
 135        preempt_enable(); \
 136} while (0)
 137
 138#define read_lock(lock)         ({preempt_disable(); _raw_read_lock(lock);})
 139#define read_unlock(lock)       ({_raw_read_unlock(lock); preempt_enable();})
 140#define write_lock(lock)        ({preempt_disable(); _raw_write_lock(lock);})
 141#define write_unlock(lock)      ({_raw_write_unlock(lock); preempt_enable();})
 142#define write_trylock(lock)     ({preempt_disable();_raw_write_trylock(lock) ? \
 143                                1 : ({preempt_enable(); 0;});})
 144
 145#else
 146
 147#define spin_lock(lock)                 _raw_spin_lock(lock)
 148#define spin_trylock(lock)              _raw_spin_trylock(lock)
 149#define spin_unlock(lock)               _raw_spin_unlock(lock)
 150
 151#define read_lock(lock)                 _raw_read_lock(lock)
 152#define read_unlock(lock)               _raw_read_unlock(lock)
 153#define write_lock(lock)                _raw_write_lock(lock)
 154#define write_unlock(lock)              _raw_write_unlock(lock)
 155#define write_trylock(lock)             _raw_write_trylock(lock)
 156#endif
 157
 158/* "lock on reference count zero" */
 159#ifndef ATOMIC_DEC_AND_LOCK
 160#include <asm/atomic.h>
 161extern int atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock);
 162#endif
 163
 164#endif /* __LINUX_SPINLOCK_H */
 165
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.