Ignore:
Timestamp:
2023-02-02T21:58:36Z (15 months ago)
Author:
Jiří Zárevúcky <zarevucky.jiri@…>
Branches:
master, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
2b264c4
Parents:
95658c9
git-author:
Jiří Zárevúcky <zarevucky.jiri@…> (2023-01-19 22:40:04)
git-committer:
Jiří Zárevúcky <zarevucky.jiri@…> (2023-02-02 21:58:36)
Message:

Make spinlock_lock/unlock into proper functions in all configurations

File:
1 edited

Legend:

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

    r95658c9 rf43d8ce  
    11/*
    22 * Copyright (c) 2001-2004 Jakub Jermar
     3 * Copyright (c) 2023 Jiří Zárevúcky
    34 * All rights reserved.
    45 *
     
    3637#define KERN_SPINLOCK_H_
    3738
    38 #include <assert.h>
    3939#include <stdatomic.h>
    4040#include <stdbool.h>
    41 #include <preemption.h>
    42 #include <arch/asm.h>
    4341
    44 #ifdef CONFIG_SMP
     42#include <arch/types.h>
     43#include <assert.h>
    4544
    46 typedef struct spinlock {
    47         atomic_flag flag;
     45#define DEADLOCK_THRESHOLD  100000000
    4846
    49 #ifdef CONFIG_DEBUG_SPINLOCK
    50         const char *name;
    51 #endif /* CONFIG_DEBUG_SPINLOCK */
    52 } spinlock_t;
    53 
    54 /*
    55  * SPINLOCK_DECLARE is to be used for dynamically allocated spinlocks,
    56  * where the lock gets initialized in run time.
    57  */
    58 #define SPINLOCK_DECLARE(lock_name)  spinlock_t lock_name
    59 #define SPINLOCK_EXTERN(lock_name)   extern spinlock_t lock_name
    60 
    61 /*
    62  * SPINLOCK_INITIALIZE and SPINLOCK_STATIC_INITIALIZE are to be used
    63  * for statically allocated spinlocks. They declare (either as global
    64  * or static) symbol and initialize the lock.
    65  */
    66 #ifdef CONFIG_DEBUG_SPINLOCK
    67 
    68 #define SPINLOCK_INITIALIZE_NAME(lock_name, desc_name) \
    69         spinlock_t lock_name = { \
    70                 .name = desc_name, \
    71                 .flag = ATOMIC_FLAG_INIT \
    72         }
    73 
    74 #define SPINLOCK_STATIC_INITIALIZE_NAME(lock_name, desc_name) \
    75         static spinlock_t lock_name = { \
    76                 .name = desc_name, \
    77                 .flag = ATOMIC_FLAG_INIT \
    78         }
    79 
    80 #define ASSERT_SPINLOCK(expr, lock) \
    81         assert_verbose(expr, (lock)->name)
    82 
    83 #define spinlock_lock(lock)    spinlock_lock_debug((lock))
    84 #define spinlock_unlock(lock)  spinlock_unlock_debug((lock))
    85 
    86 #else /* CONFIG_DEBUG_SPINLOCK */
    87 
    88 #define SPINLOCK_INITIALIZE_NAME(lock_name, desc_name) \
    89         spinlock_t lock_name = { \
    90                 .flag = ATOMIC_FLAG_INIT \
    91         }
    92 
    93 #define SPINLOCK_STATIC_INITIALIZE_NAME(lock_name, desc_name) \
    94         static spinlock_t lock_name = { \
    95                 .flag = ATOMIC_FLAG_INIT \
    96         }
    97 
    98 #define ASSERT_SPINLOCK(expr, lock) \
    99         assert(expr)
    100 
    101 /** Acquire spinlock
    102  *
    103  * @param lock  Pointer to spinlock_t structure.
    104  */
    105 _NO_TRACE static inline void spinlock_lock(spinlock_t *lock)
    106 {
    107         preemption_disable();
    108         while (atomic_flag_test_and_set_explicit(&lock->flag,
    109             memory_order_acquire))
    110                 ;
    111 }
    112 
    113 /** Release spinlock
    114  *
    115  * @param lock  Pointer to spinlock_t structure.
    116  */
    117 _NO_TRACE static inline void spinlock_unlock(spinlock_t *lock)
    118 {
    119         atomic_flag_clear_explicit(&lock->flag, memory_order_release);
    120         preemption_enable();
    121 }
    122 
    123 #endif /* CONFIG_DEBUG_SPINLOCK */
    124 
    125 #define SPINLOCK_INITIALIZE(lock_name) \
    126         SPINLOCK_INITIALIZE_NAME(lock_name, #lock_name)
    127 
    128 #define SPINLOCK_STATIC_INITIALIZE(lock_name) \
    129         SPINLOCK_STATIC_INITIALIZE_NAME(lock_name, #lock_name)
    130 
    131 extern void spinlock_initialize(spinlock_t *, const char *);
    132 extern bool spinlock_trylock(spinlock_t *);
    133 extern void spinlock_lock_debug(spinlock_t *);
    134 extern void spinlock_unlock_debug(spinlock_t *);
    135 extern bool spinlock_locked(spinlock_t *);
    136 
    137 #ifdef CONFIG_DEBUG_SPINLOCK
     47#if defined(CONFIG_SMP) && defined(CONFIG_DEBUG_SPINLOCK)
    13848
    13949#include <log.h>
    140 
    141 #define DEADLOCK_THRESHOLD  100000000
    14250
    14351#define DEADLOCK_PROBE_INIT(pname)  size_t pname = 0
     
    15967#endif /* CONFIG_DEBUG_SPINLOCK */
    16068
    161 #else /* CONFIG_SMP */
     69typedef struct spinlock {
     70#ifdef CONFIG_SMP
     71        atomic_flag flag;
    16272
    163 /* On UP systems, spinlocks are effectively left out. */
     73#ifdef CONFIG_DEBUG_SPINLOCK
     74        const char *name;
     75#endif /* CONFIG_DEBUG_SPINLOCK */
     76#endif
     77} spinlock_t;
    16478
    165 /* Allow the use of spinlock_t as an incomplete type. */
    166 typedef struct spinlock spinlock_t;
     79/*
     80 * SPINLOCK_DECLARE is to be used for dynamically allocated spinlocks,
     81 * where the lock gets initialized in run time.
     82 */
     83#define SPINLOCK_DECLARE(lock_name)  spinlock_t lock_name
     84#define SPINLOCK_EXTERN(lock_name)   extern spinlock_t lock_name
    16785
    168 #define SPINLOCK_DECLARE(name)
    169 #define SPINLOCK_EXTERN(name)
     86#ifdef CONFIG_SMP
     87#ifdef CONFIG_DEBUG_SPINLOCK
     88#define SPINLOCK_INITIALIZER(desc_name) { .name = (desc_name), .flag = ATOMIC_FLAG_INIT }
     89#else
     90#define SPINLOCK_INITIALIZER(desc_name) { .flag = ATOMIC_FLAG_INIT }
     91#endif
     92#else
     93#define SPINLOCK_INITIALIZER(desc_name) {}
     94#endif
    17095
    171 #define SPINLOCK_INITIALIZE(name)
    172 #define SPINLOCK_STATIC_INITIALIZE(name)
     96/*
     97 * SPINLOCK_INITIALIZE and SPINLOCK_STATIC_INITIALIZE are to be used
     98 * for statically allocated spinlocks. They declare (either as global
     99 * or static) symbol and initialize the lock.
     100 */
     101#define SPINLOCK_INITIALIZE_NAME(lock_name, desc_name) \
     102        spinlock_t lock_name = SPINLOCK_INITIALIZER(desc_name)
    173103
    174 #define SPINLOCK_INITIALIZE_NAME(name, desc_name)
    175 #define SPINLOCK_STATIC_INITIALIZE_NAME(name, desc_name)
     104#define SPINLOCK_STATIC_INITIALIZE_NAME(lock_name, desc_name) \
     105        static spinlock_t lock_name = SPINLOCK_INITIALIZER(desc_name)
    176106
    177 #define ASSERT_SPINLOCK(expr, lock)  assert(expr)
     107#if defined(CONFIG_SMP) && defined(CONFIG_DEBUG_SPINLOCK)
     108#define ASSERT_SPINLOCK(expr, lock) assert_verbose(expr, (lock)->name)
     109#else /* CONFIG_DEBUG_SPINLOCK */
     110#define ASSERT_SPINLOCK(expr, lock) assert(expr)
     111#endif /* CONFIG_DEBUG_SPINLOCK */
    178112
    179 #define spinlock_initialize(lock, name)
     113#define SPINLOCK_INITIALIZE(lock_name) \
     114        SPINLOCK_INITIALIZE_NAME(lock_name, #lock_name)
    180115
    181 #define spinlock_lock(lock)     preemption_disable()
    182 #define spinlock_trylock(lock)  ({ preemption_disable(); 1; })
    183 #define spinlock_unlock(lock)   preemption_enable()
    184 #define spinlock_locked(lock)   1
    185 #define spinlock_unlocked(lock) 1
     116#define SPINLOCK_STATIC_INITIALIZE(lock_name) \
     117        SPINLOCK_STATIC_INITIALIZE_NAME(lock_name, #lock_name)
    186118
    187 #define DEADLOCK_PROBE_INIT(pname)
    188 #define DEADLOCK_PROBE(pname, value)
    189 
    190 #endif /* CONFIG_SMP */
     119extern void spinlock_initialize(spinlock_t *, const char *);
     120extern bool spinlock_trylock(spinlock_t *);
     121extern void spinlock_lock(spinlock_t *);
     122extern void spinlock_unlock(spinlock_t *);
     123extern bool spinlock_locked(spinlock_t *);
    191124
    192125typedef struct {
    193         SPINLOCK_DECLARE(lock);  /**< Spinlock */
     126        spinlock_t lock;         /**< Spinlock */
    194127        bool guard;              /**< Flag whether ipl is valid */
    195128        ipl_t ipl;               /**< Original interrupt level */
     
    199132#define IRQ_SPINLOCK_EXTERN(lock_name)   extern irq_spinlock_t lock_name
    200133
    201 #ifdef CONFIG_SMP
    202 
    203134#define ASSERT_IRQ_SPINLOCK(expr, irq_lock) \
    204135        ASSERT_SPINLOCK(expr, &((irq_lock)->lock))
     136
     137#define IRQ_SPINLOCK_INITIALIZER(desc_name) \
     138        { \
     139                .lock = SPINLOCK_INITIALIZER(desc_name), \
     140                .guard = false, \
     141                .ipl = 0, \
     142        }
    205143
    206144/*
     
    209147 * as global or static symbol) and initialize the lock.
    210148 */
    211 #ifdef CONFIG_DEBUG_SPINLOCK
    212 
    213149#define IRQ_SPINLOCK_INITIALIZE_NAME(lock_name, desc_name) \
    214         irq_spinlock_t lock_name = { \
    215                 .lock = { \
    216                         .name = desc_name, \
    217                         .flag = ATOMIC_FLAG_INIT \
    218                 }, \
    219                 .guard = false, \
    220                 .ipl = 0 \
    221         }
     150        irq_spinlock_t lock_name = IRQ_SPINLOCK_INITIALIZER(desc_name)
    222151
    223152#define IRQ_SPINLOCK_STATIC_INITIALIZE_NAME(lock_name, desc_name) \
    224         static irq_spinlock_t lock_name = { \
    225                 .lock = { \
    226                         .name = desc_name, \
    227                         .flag = ATOMIC_FLAG_INIT \
    228                 }, \
    229                 .guard = false, \
    230                 .ipl = 0 \
    231         }
    232 
    233 #else /* CONFIG_DEBUG_SPINLOCK */
    234 
    235 #define IRQ_SPINLOCK_INITIALIZE_NAME(lock_name, desc_name) \
    236         irq_spinlock_t lock_name = { \
    237                 .lock = { \
    238                         .flag = ATOMIC_FLAG_INIT \
    239                 }, \
    240                 .guard = false, \
    241                 .ipl = 0 \
    242         }
    243 
    244 #define IRQ_SPINLOCK_STATIC_INITIALIZE_NAME(lock_name, desc_name) \
    245         static irq_spinlock_t lock_name = { \
    246                 .lock = { \
    247                         .flag = ATOMIC_FLAG_INIT \
    248                 }, \
    249                 .guard = false, \
    250                 .ipl = 0 \
    251         }
    252 
    253 #endif /* CONFIG_DEBUG_SPINLOCK */
    254 
    255 #else /* CONFIG_SMP */
    256 
    257 /*
    258  * Since the spinlocks are void on UP systems, we also need
    259  * to have a special variant of interrupts-disabled spinlock
    260  * macros which take this into account.
    261  */
    262 
    263 #define ASSERT_IRQ_SPINLOCK(expr, irq_lock) \
    264         ASSERT_SPINLOCK(expr, NULL)
    265 
    266 #define IRQ_SPINLOCK_INITIALIZE_NAME(lock_name, desc_name) \
    267         irq_spinlock_t lock_name = { \
    268                 .guard = false, \
    269                 .ipl = 0 \
    270         }
    271 
    272 #define IRQ_SPINLOCK_STATIC_INITIALIZE_NAME(lock_name, desc_name) \
    273         static irq_spinlock_t lock_name = { \
    274                 .guard = false, \
    275                 .ipl = 0 \
    276         }
    277 
    278 #endif /* CONFIG_SMP */
     153        static irq_spinlock_t lock_name = IRQ_SPINLOCK_INITIALIZER(desc_name)
    279154
    280155#define IRQ_SPINLOCK_INITIALIZE(lock_name) \
Note: See TracChangeset for help on using the changeset viewer.