Changeset e04b72d6 in mainline for kernel/generic/src/time/clock.c


Ignore:
Timestamp:
2023-01-08T21:19:21Z (16 months ago)
Author:
GitHub <noreply@…>
Branches:
master, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
d8503fd
Parents:
5b19d80 (diff), eda43238 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
git-author:
Jakub Jermář <jakub@…> (2023-01-08 21:19:21)
git-committer:
GitHub <noreply@…> (2023-01-08 21:19:21)
Message:

Merge pull request #222 from le-jzr/timeout

Simplify timeout implementation in kernel

File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/time/clock.c

    r5b19d80 re04b72d6  
    11/*
    22 * Copyright (c) 2001-2004 Jakub Jermar
     3 * Copyright (c) 2022 Jiří Zárevúcky
    34 * All rights reserved.
    45 *
     
    6566static parea_t clock_parea;
    6667
    67 /** Fragment of second
    68  *
    69  * For updating  seconds correctly.
    70  *
    71  */
    72 static sysarg_t secfrag = 0;
    73 
    7468/** Initialize realtime clock counter
    7569 *
     
    109103 *
    110104 * Update it only on first processor
    111  * TODO: Do we really need so many write barriers?
    112  *
    113  */
    114 static void clock_update_counters(void)
     105 */
     106static void clock_update_counters(uint64_t current_tick)
    115107{
    116108        if (CPU->id == 0) {
    117                 secfrag += 1000000 / HZ;
    118                 if (secfrag >= 1000000) {
    119                         secfrag -= 1000000;
    120                         uptime->seconds1++;
    121                         write_barrier();
    122                         uptime->useconds = secfrag;
    123                         write_barrier();
    124                         uptime->seconds2 = uptime->seconds1;
    125                 } else
    126                         uptime->useconds += 1000000 / HZ;
     109                uint64_t usec = (1000000 / HZ) * current_tick;
     110
     111                sysarg_t secs = usec / 1000000;
     112                sysarg_t usecs = usec % 1000000;
     113
     114                uptime->seconds1 = secs;
     115                write_barrier();
     116                uptime->useconds = usecs;
     117                write_barrier();
     118                uptime->seconds2 = secs;
    127119        }
    128120}
     
    147139{
    148140        size_t missed_clock_ticks = CPU->missed_clock_ticks;
     141        CPU->missed_clock_ticks = 0;
     142
     143        CPU->current_clock_tick += missed_clock_ticks + 1;
     144        uint64_t current_clock_tick = CPU->current_clock_tick;
     145        clock_update_counters(current_clock_tick);
    149146
    150147        /* Account CPU usage */
     
    156153         *
    157154         */
    158         size_t i;
    159         for (i = 0; i <= missed_clock_ticks; i++) {
    160                 /* Update counters and accounting */
    161                 clock_update_counters();
    162                 cpu_update_accounting();
     155
     156        irq_spinlock_lock(&CPU->timeoutlock, false);
     157
     158        link_t *cur;
     159        while ((cur = list_first(&CPU->timeout_active_list)) != NULL) {
     160                timeout_t *timeout = list_get_instance(cur, timeout_t, link);
     161
     162                if (current_clock_tick <= timeout->deadline) {
     163                        break;
     164                }
     165
     166                list_remove(cur);
     167                timeout_handler_t handler = timeout->handler;
     168                void *arg = timeout->arg;
     169
     170                irq_spinlock_unlock(&CPU->timeoutlock, false);
     171
     172                handler(arg);
    163173
    164174                irq_spinlock_lock(&CPU->timeoutlock, false);
    165 
    166                 link_t *cur;
    167                 while ((cur = list_first(&CPU->timeout_active_list)) != NULL) {
    168                         timeout_t *timeout = list_get_instance(cur, timeout_t,
    169                             link);
    170 
    171                         irq_spinlock_lock(&timeout->lock, false);
    172                         if (timeout->ticks-- != 0) {
    173                                 irq_spinlock_unlock(&timeout->lock, false);
    174                                 break;
    175                         }
    176 
    177                         list_remove(cur);
    178                         timeout_handler_t handler = timeout->handler;
    179                         void *arg = timeout->arg;
    180                         timeout_reinitialize(timeout);
    181 
    182                         irq_spinlock_unlock(&timeout->lock, false);
    183                         irq_spinlock_unlock(&CPU->timeoutlock, false);
    184 
    185                         handler(arg);
    186 
    187                         irq_spinlock_lock(&CPU->timeoutlock, false);
    188                 }
    189 
    190                 irq_spinlock_unlock(&CPU->timeoutlock, false);
    191175        }
    192         CPU->missed_clock_ticks = 0;
     176
     177        irq_spinlock_unlock(&CPU->timeoutlock, false);
    193178
    194179        /*
Note: See TracChangeset for help on using the changeset viewer.