Changeset ba25c4b in mainline


Ignore:
Timestamp:
2023-02-09T15:31:39Z (15 months ago)
Author:
Jiří Zárevúcky <zarevucky.jiri@…>
Branches:
master, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
83789ea2
Parents:
78acbc72
git-author:
Jiří Zárevúcky <zarevucky.jiri@…> (2023-02-09 15:28:13)
git-committer:
Jiří Zárevúcky <zarevucky.jiri@…> (2023-02-09 15:31:39)
Message:

Synchronize timeout_unregister() with handler execution

This ensures that when timeout_unregister() returns,
timeout handler either didn't run at all, or it ran to
completion and is no longer executing.

This will be handy a few patches later.

Location:
kernel/generic
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/include/time/timeout.h

    r78acbc72 rba25c4b  
    5353        /** On which processor is this timeout registered. */
    5454        cpu_t *cpu;
     55        /** Used to synchronize with the handler callback. */
     56        atomic_bool finished;
    5557} timeout_t;
    5658
  • kernel/generic/src/time/clock.c

    r78acbc72 rba25c4b  
    168168                timeout_handler_t handler = timeout->handler;
    169169                void *arg = timeout->arg;
     170                atomic_bool *finished = &timeout->finished;
    170171
    171172                irq_spinlock_unlock(&CPU->timeoutlock, false);
    172173
    173174                handler(arg);
     175
     176                /* Signal that the handler is finished. */
     177                atomic_store_explicit(finished, true, memory_order_release);
    174178
    175179                irq_spinlock_lock(&CPU->timeoutlock, false);
  • kernel/generic/src/time/timeout.c

    r78acbc72 rba25c4b  
    9090        assert(!link_in_use(&timeout->link));
    9191
    92         timeout->cpu = CPU;
    93         timeout->deadline = CPU->current_clock_tick + us2ticks(time);
    94         timeout->handler = handler;
    95         timeout->arg = arg;
     92        *timeout = (timeout_t) {
     93                .cpu = CPU,
     94                .deadline = CPU->current_clock_tick + us2ticks(time),
     95                .handler = handler,
     96                .arg = arg,
     97                .finished = ATOMIC_VAR_INIT(false),
     98        };
    9699
    97100        /* Insert timeout into the active timeouts list according to timeout->deadline. */
     
    135138
    136139        irq_spinlock_unlock(&timeout->cpu->timeoutlock, true);
     140
     141        if (!success) {
     142                /* Timeout was fired, we need to wait for the callback to finish. */
     143                while (!atomic_load_explicit(&timeout->finished, memory_order_acquire))
     144                        cpu_spin_hint();
     145        }
     146
    137147        return success;
    138148}
Note: See TracChangeset for help on using the changeset viewer.