Changeset b076dfb 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:
64e9cf4
Parents:
2b264c4
git-author:
Jiří Zárevúcky <zarevucky.jiri@…> (2023-01-20 19:05:09)
git-committer:
Jiří Zárevúcky <zarevucky.jiri@…> (2023-02-02 21:58:36)
Message:

Implement more elaborate debug checking for spinlocks

Location:
kernel/generic
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/include/arch.h

    r2b264c4 rb076dfb  
    7575typedef struct {
    7676        size_t preemption;      /**< Preemption disabled counter and flag. */
     77        size_t mutex_locks;
    7778        struct thread *thread;  /**< Current thread. */
    7879        struct task *task;      /**< Current task. */
  • kernel/generic/include/synch/spinlock.h

    r2b264c4 rb076dfb  
    124124
    125125typedef struct {
    126         spinlock_t lock;         /**< Spinlock */
    127         bool guard;              /**< Flag whether ipl is valid */
    128         ipl_t ipl;               /**< Original interrupt level */
     126        spinlock_t lock;              /**< Spinlock */
     127        bool guard;                   /**< Flag whether ipl is valid */
     128        ipl_t ipl;                    /**< Original interrupt level */
     129#ifdef CONFIG_DEBUG_SPINLOCK
     130        _Atomic(struct cpu *) owner;  /**< Which cpu currently owns this lock */
     131#endif
    129132} irq_spinlock_t;
    130133
  • kernel/generic/src/synch/irq_spinlock.c

    r2b264c4 rb076dfb  
    11/*
    22 * Copyright (c) 2001-2004 Jakub Jermar
     3 * Copyright (c) 2023 Jiří Zárevúcky
    34 * All rights reserved.
    45 *
     
    3940#include <synch/spinlock.h>
    4041
     42#include <cpu.h>
     43
     44#ifdef CONFIG_DEBUG_SPINLOCK
     45
     46#define CPU_OWNER ((CPU == NULL) ? (cpu_t *) UINTPTR_MAX : CPU)
     47
     48static inline bool owned_by_me(irq_spinlock_t *lock)
     49{
     50        return atomic_load_explicit(&lock->owner, memory_order_relaxed) == CPU_OWNER;
     51}
     52
     53static inline bool not_owned_by_me(irq_spinlock_t *lock)
     54{
     55        return !owned_by_me(lock);
     56}
     57
     58static inline void claim(irq_spinlock_t *lock)
     59{
     60        cpu_t *cpu = CPU_OWNER;
     61        atomic_store_explicit(&lock->owner, cpu, memory_order_relaxed);
     62        CURRENT->mutex_locks++;
     63}
     64
     65static inline void unclaim(irq_spinlock_t *lock)
     66{
     67        CURRENT->mutex_locks--;
     68        atomic_store_explicit(&lock->owner, NULL, memory_order_relaxed);
     69}
     70
     71#else
     72
     73static inline bool owned_by_me(irq_spinlock_t *lock)
     74{
     75        return true;
     76}
     77
     78static inline bool not_owned_by_me(irq_spinlock_t *lock)
     79{
     80        return true;
     81}
     82
     83static inline void claim(irq_spinlock_t *lock)
     84{
     85}
     86
     87static inline void unclaim(irq_spinlock_t *lock)
     88{
     89}
     90
     91#endif
     92
    4193/** Initialize interrupts-disabled spinlock
    4294 *
     
    4799void irq_spinlock_initialize(irq_spinlock_t *lock, const char *name)
    48100{
    49         spinlock_initialize(&(lock->lock), name);
    50         lock->guard = false;
    51         lock->ipl = 0;
     101        *lock = (irq_spinlock_t) IRQ_SPINLOCK_INITIALIZER(name);
    52102}
    53103
     
    63113void irq_spinlock_lock(irq_spinlock_t *lock, bool irq_dis)
    64114{
     115        ASSERT_IRQ_SPINLOCK(not_owned_by_me(lock), lock);
     116
    65117        if (irq_dis) {
    66118                ipl_t ipl = interrupts_disable();
     
    75127                ASSERT_IRQ_SPINLOCK(!lock->guard, lock);
    76128        }
     129
     130        claim(lock);
    77131}
    78132
     
    89143{
    90144        ASSERT_IRQ_SPINLOCK(interrupts_disabled(), lock);
     145        ASSERT_IRQ_SPINLOCK(owned_by_me(lock), lock);
     146
     147        unclaim(lock);
    91148
    92149        if (irq_res) {
     
    119176        ASSERT_IRQ_SPINLOCK(interrupts_disabled(), lock);
    120177        bool ret = spinlock_trylock(&(lock->lock));
     178        if (ret)
     179                claim(lock);
    121180
    122181        ASSERT_IRQ_SPINLOCK((!ret) || (!lock->guard), lock);
     
    138197{
    139198        ASSERT_IRQ_SPINLOCK(interrupts_disabled(), unlock);
     199        ASSERT_IRQ_SPINLOCK(owned_by_me(unlock), unlock);
     200        ASSERT_IRQ_SPINLOCK(not_owned_by_me(lock), lock);
    140201
    141202        /* Pass guard from unlock to lock */
     
    144205        unlock->guard = false;
    145206
     207        unclaim(unlock);
     208
    146209        spinlock_unlock(&(unlock->lock));
    147210        spinlock_lock(&(lock->lock));
     211
     212        claim(lock);
    148213
    149214        ASSERT_IRQ_SPINLOCK(!lock->guard, lock);
     
    169234{
    170235        ASSERT_IRQ_SPINLOCK(interrupts_disabled(), unlock);
     236        ASSERT_IRQ_SPINLOCK(owned_by_me(unlock), unlock);
     237        ASSERT_IRQ_SPINLOCK(not_owned_by_me(lock), lock);
    171238
    172239        spinlock_lock(&(lock->lock));
     
    180247        }
    181248
     249        claim(lock);
     250        unclaim(unlock);
     251
    182252        spinlock_unlock(&(unlock->lock));
    183253}
     
    188258 * @return              True if the IRQ spinlock is locked, false otherwise.
    189259 */
    190 bool irq_spinlock_locked(irq_spinlock_t *ilock)
    191 {
    192         return spinlock_locked(&ilock->lock);
     260bool irq_spinlock_locked(irq_spinlock_t *lock)
     261{
     262        return owned_by_me(lock) && spinlock_locked(&lock->lock);
    193263}
    194264
Note: See TracChangeset for help on using the changeset viewer.