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


Ignore:
Timestamp:
2010-05-24T18:57:31Z (14 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0095368
Parents:
666f492
Message:

major code revision

  • replace spinlocks taken with interrupts disabled with irq_spinlocks
  • change spacing (not indendation) to be tab-size independent
  • use unsigned integer types where appropriate (especially bit flags)
  • visual separation
  • remove argument names in function prototypes
  • string changes
  • correct some formating directives
  • replace various cryptic single-character variables (t, a, m, c, b, etc.) with proper identifiers (thread, task, timeout, as, itm, itc, etc.)
  • unify some assembler constructs
  • unused page table levels are now optimized out in compile time
  • replace several ints (with boolean semantics) with bools
  • use specifically sized types instead of generic types where appropriate (size_t, uint32_t, btree_key_t)
  • improve comments
  • split asserts with conjuction into multiple independent asserts
File:
1 edited

Legend:

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

    r666f492 rda1bafb  
    3333/**
    3434 * @file
    35  * @brief       High-level clock interrupt handler.
     35 * @brief High-level clock interrupt handler.
    3636 *
    3737 * This file contains the clock() function which is the source
    3838 * of preemption. It is also responsible for executing expired
    3939 * timeouts.
    40  */
    41  
     40 *
     41 */
     42
    4243#include <time/clock.h>
    4344#include <time/timeout.h>
     
    6364static parea_t clock_parea;
    6465
    65 /* Variable holding fragment of second, so that we would update
    66  * seconds correctly
     66/** Fragment of second
     67 *
     68 * For updating  seconds correctly.
     69 *
    6770 */
    6871static unative_t secfrag = 0;
     
    7376 * information about realtime data. We allocate 1 page with these
    7477 * data and update it periodically.
     78 *
    7579 */
    7680void clock_counter_init(void)
    7781{
    78         void *faddr;
    79 
    80         faddr = frame_alloc(ONE_FRAME, FRAME_ATOMIC);
     82        void *faddr = frame_alloc(ONE_FRAME, FRAME_ATOMIC);
    8183        if (!faddr)
    8284                panic("Cannot allocate page for clock.");
     
    8789        uptime->seconds2 = 0;
    8890        uptime->useconds = 0;
    89 
     91       
    9092        clock_parea.pbase = (uintptr_t) faddr;
    9193        clock_parea.frames = 1;
    9294        ddi_parea_register(&clock_parea);
    93 
     95       
    9496        /*
    9597         * Prepare information for the userspace so that it can successfully
    9698         * physmem_map() the clock_parea.
     99         *
    97100         */
    98101        sysinfo_set_item_val("clock.cacheable", NULL, (unative_t) true);
     
    100103}
    101104
    102 
    103105/** Update public counters
    104106 *
    105107 * Update it only on first processor
    106  * TODO: Do we really need so many write barriers?
     108 * TODO: Do we really need so many write barriers?
     109 *
    107110 */
    108111static void clock_update_counters(void)
     
    131134void clock(void)
    132135{
    133         link_t *l;
    134         timeout_t *h;
    135         timeout_handler_t f;
    136         void *arg;
    137136        size_t missed_clock_ticks = CPU->missed_clock_ticks;
    138         unsigned int i;
    139 
     137       
    140138        /* Account lost ticks to CPU usage */
    141         if (CPU->idle) {
     139        if (CPU->idle)
    142140                CPU->idle_ticks += missed_clock_ticks + 1;
    143         } else {
     141        else
    144142                CPU->busy_ticks += missed_clock_ticks + 1;
    145         }
     143       
    146144        CPU->idle = false;
    147 
     145       
    148146        /*
    149147         * To avoid lock ordering problems,
    150148         * run all expired timeouts as you visit them.
     149         *
    151150         */
     151        size_t i;
    152152        for (i = 0; i <= missed_clock_ticks; i++) {
    153153                clock_update_counters();
    154                 spinlock_lock(&CPU->timeoutlock);
    155                 while ((l = CPU->timeout_active_head.next) != &CPU->timeout_active_head) {
    156                         h = list_get_instance(l, timeout_t, link);
    157                         spinlock_lock(&h->lock);
    158                         if (h->ticks-- != 0) {
    159                                 spinlock_unlock(&h->lock);
     154                irq_spinlock_lock(&CPU->timeoutlock, false);
     155               
     156                link_t *cur;
     157                while ((cur = CPU->timeout_active_head.next) != &CPU->timeout_active_head) {
     158                        timeout_t *timeout = list_get_instance(cur, timeout_t, link);
     159                       
     160                        irq_spinlock_lock(&timeout->lock, false);
     161                        if (timeout->ticks-- != 0) {
     162                                irq_spinlock_unlock(&timeout->lock, false);
    160163                                break;
    161164                        }
    162                         list_remove(l);
    163                         f = h->handler;
    164                         arg = h->arg;
    165                         timeout_reinitialize(h);
    166                         spinlock_unlock(&h->lock);     
    167                         spinlock_unlock(&CPU->timeoutlock);
    168 
    169                         f(arg);
    170 
    171                         spinlock_lock(&CPU->timeoutlock);
     165                       
     166                        list_remove(cur);
     167                        timeout_handler_t handler = timeout->handler;
     168                        void *arg = timeout->arg;
     169                        timeout_reinitialize(timeout);
     170                       
     171                        irq_spinlock_unlock(&timeout->lock, false);
     172                        irq_spinlock_unlock(&CPU->timeoutlock, false);
     173                       
     174                        handler(arg);
     175                       
     176                        irq_spinlock_lock(&CPU->timeoutlock, false);
    172177                }
    173                 spinlock_unlock(&CPU->timeoutlock);
     178               
     179                irq_spinlock_unlock(&CPU->timeoutlock, false);
    174180        }
    175181        CPU->missed_clock_ticks = 0;
    176 
     182       
    177183        /*
    178184         * Do CPU usage accounting and find out whether to preempt THREAD.
     185         *
    179186         */
    180 
     187       
    181188        if (THREAD) {
    182189                uint64_t ticks;
    183190               
    184                 spinlock_lock(&CPU->lock);
     191                irq_spinlock_lock(&CPU->lock, false);
    185192                CPU->needs_relink += 1 + missed_clock_ticks;
    186                 spinlock_unlock(&CPU->lock);   
    187        
    188                 spinlock_lock(&THREAD->lock);
     193                irq_spinlock_unlock(&CPU->lock, false);
     194               
     195                irq_spinlock_lock(&THREAD->lock, false);
    189196                if ((ticks = THREAD->ticks)) {
    190197                        if (ticks >= 1 + missed_clock_ticks)
     
    193200                                THREAD->ticks = 0;
    194201                }
    195                 spinlock_unlock(&THREAD->lock);
     202                irq_spinlock_unlock(&THREAD->lock, false);
    196203               
    197204                if ((!ticks) && (!PREEMPTION_DISABLED)) {
    198 #ifdef CONFIG_UDEBUG
    199                         istate_t *istate;
    200 #endif
    201205                        scheduler();
    202206#ifdef CONFIG_UDEBUG
     
    205209                         * before it begins executing userspace code.
    206210                         */
    207                         istate = THREAD->udebug.uspace_state;
    208                         if (istate && istate_from_uspace(istate))
     211                        istate_t *istate = THREAD->udebug.uspace_state;
     212                        if ((istate) && (istate_from_uspace(istate)))
    209213                                udebug_before_thread_runs();
    210214#endif
    211215                }
    212216        }
    213 
    214217}
    215218
Note: See TracChangeset for help on using the changeset viewer.