Changeset f43d8ce in mainline


Ignore:
Timestamp:
2023-02-02T21:58:36Z (22 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

Location:
kernel
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/mips32/src/mips32.c

    r95658c9 rf43d8ce  
    4141#include <str.h>
    4242#include <mem.h>
     43#include <preemption.h>
    4344#include <userspace.h>
    4445#include <stdbool.h>
  • kernel/arch/ppc32/src/mm/frame.c

    r95658c9 rf43d8ce  
    3333 */
    3434
     35#include <arch/asm.h>
    3536#include <arch/boot/boot.h>
    3637#include <arch/mm/frame.h>
  • kernel/generic/include/mm/tlb.h

    r95658c9 rf43d8ce  
    3636#define KERN_TLB_H_
    3737
     38#include <arch/asm.h>
    3839#include <arch/mm/asid.h>
    3940#include <typedefs.h>
  • 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) \
  • kernel/generic/src/synch/irq_spinlock.c

    r95658c9 rf43d8ce  
    3636 */
    3737
     38#include <arch/asm.h>
    3839#include <synch/spinlock.h>
    3940
  • kernel/generic/src/synch/spinlock.c

    r95658c9 rf43d8ce  
    11/*
    22 * Copyright (c) 2001-2004 Jakub Jermar
     3 * Copyright (c) 2023 Jiří Zárevúcky
    34 * All rights reserved.
    45 *
     
    4748#include <cpu.h>
    4849
    49 #ifdef CONFIG_SMP
    50 
    5150/** Initialize spinlock
    5251 *
     
    5655void spinlock_initialize(spinlock_t *lock, const char *name)
    5756{
     57#ifdef CONFIG_SMP
    5858        atomic_flag_clear_explicit(&lock->flag, memory_order_relaxed);
    5959#ifdef CONFIG_DEBUG_SPINLOCK
    6060        lock->name = name;
    6161#endif
     62#endif
    6263}
    6364
    64 #ifdef CONFIG_DEBUG_SPINLOCK
    65 
    6665/** Lock spinlock
    67  *
    68  * Lock spinlock.
    69  * This version has limitted ability to report
    70  * possible occurence of deadlock.
    7166 *
    7267 * @param lock Pointer to spinlock_t structure.
    7368 *
    7469 */
    75 void spinlock_lock_debug(spinlock_t *lock)
     70void spinlock_lock(spinlock_t *lock)
    7671{
     72        preemption_disable();
     73
     74#ifdef CONFIG_SMP
     75        bool deadlock_reported = false;
    7776        size_t i = 0;
    78         bool deadlock_reported = false;
    7977
    80         preemption_disable();
    8178        while (atomic_flag_test_and_set_explicit(&lock->flag, memory_order_acquire)) {
     79#ifdef CONFIG_DEBUG_SPINLOCK
    8280                /*
    8381                 * We need to be careful about particular locks
     
    111109                        deadlock_reported = true;
    112110                }
     111#endif
    113112        }
     113
     114        /* Avoid compiler warning with debug disabled. */
     115        (void) i;
    114116
    115117        if (deadlock_reported)
    116118                printf("cpu%u: not deadlocked\n", CPU->id);
     119
     120#endif
    117121}
    118122
    119123/** Unlock spinlock
    120124 *
    121  * Unlock spinlock.
    122  *
    123125 * @param sl Pointer to spinlock_t structure.
    124126 */
    125 void spinlock_unlock_debug(spinlock_t *lock)
     127void spinlock_unlock(spinlock_t *lock)
    126128{
     129#ifdef CONFIG_SMP
     130#ifdef CONFIG_DEBUG_SPINLOCK
    127131        ASSERT_SPINLOCK(spinlock_locked(lock), lock);
     132#endif
    128133
    129134        atomic_flag_clear_explicit(&lock->flag, memory_order_release);
     135#endif
     136
    130137        preemption_enable();
    131138}
    132139
    133 #endif
    134 
    135 /** Lock spinlock conditionally
    136  *
     140/**
    137141 * Lock spinlock conditionally. If the spinlock is not available
    138142 * at the moment, signal failure.
     
    140144 * @param lock Pointer to spinlock_t structure.
    141145 *
    142  * @return Zero on failure, non-zero otherwise.
     146 * @return true on success.
    143147 *
    144148 */
     
    146150{
    147151        preemption_disable();
     152
     153#ifdef CONFIG_SMP
    148154        bool ret = !atomic_flag_test_and_set_explicit(&lock->flag, memory_order_acquire);
    149155
     
    152158
    153159        return ret;
     160#else
     161        return true;
     162#endif
    154163}
    155164
     
    161170bool spinlock_locked(spinlock_t *lock)
    162171{
     172#ifdef CONFIG_SMP
    163173        // NOTE: Atomic flag doesn't support simple atomic read (by design),
    164174        //       so instead we test_and_set and then clear if necessary.
     
    170180                atomic_flag_clear_explicit(&lock->flag, memory_order_relaxed);
    171181        return ret;
     182#else
     183        return true;
     184#endif
    172185}
    173 
    174 #endif
    175186
    176187/** @}
  • kernel/generic/src/synch/waitq.c

    r95658c9 rf43d8ce  
    4848#include <synch/waitq.h>
    4949#include <synch/spinlock.h>
     50#include <preemption.h>
    5051#include <proc/thread.h>
    5152#include <proc/scheduler.h>
  • kernel/generic/src/time/clock.c

    r95658c9 rf43d8ce  
    5959#include <ddi/ddi.h>
    6060#include <arch/cycle.h>
     61#include <preemption.h>
    6162
    6263/* Pointer to variable with uptime */
Note: See TracChangeset for help on using the changeset viewer.