Changeset e1d61fe in rtems


Ignore:
Timestamp:
Jun 9, 2015, 11:49:56 AM (4 years ago)
Author:
kib <kib@…>
Branches:
4.11, master
Children:
fecc911
Parents:
7e1a9ac
git-author:
kib <kib@…> (06/09/15 11:49:56)
git-committer:
Sebastian Huber <sebastian.huber@…> (06/09/15 12:56:02)
Message:

timecounter: Synchronize with FreeBSD

When updating/accessing the timehands, barriers are needed to ensure
that:

  • th_generation update is visible after the parameters update is visible;
  • the read of parameters is not reordered before initial read of th_generation.

On UP kernels, compiler barriers are enough. For SMP machines, CPU
barriers must be used too, as was confirmed by submitter by testing on
the Freescale T4240 platform with 24 PowerPC processors.

Submitted by: Sebastian Huber <sebastian.huber@…>
MFC after: 1 week

File:
1 edited

Legend:

Unmodified
Added
Removed
  • cpukit/score/src/kern_tc.c

    r7e1a9ac re1d61fe  
    3737#endif /* __rtems__ */
    3838#include <sys/cdefs.h>
    39 __FBSDID("$FreeBSD r282424 2015-05-04T17:59:39Z$");
     39__FBSDID("$FreeBSD r284178 2015-06-09T11:49:56Z$");
    4040
    4141#include "opt_compat.h"
     
    6060#ifndef __rtems__
    6161#include <sys/vdso.h>
     62#include <machine/atomic.h>
    6263#endif /* __rtems__ */
    6364#ifdef __rtems__
     
    117118        struct timespec         th_nanotime;
    118119        /* Fields not to be copied in tc_windup start with th_generation. */
    119         volatile uint32_t       th_generation;
     120#ifndef __rtems__
     121        u_int                   th_generation;
     122#else /* __rtems__ */
     123        Atomic_Ulong            th_generation;
     124#endif /* __rtems__ */
    120125        struct timehands        *th_next;
    121126};
     
    249254}
    250255
     256static u_int
     257tc_getgen(struct timehands *th)
     258{
     259
     260#ifndef __rtems__
     261#ifdef SMP
     262        return (atomic_load_acq_int(&th->th_generation));
     263#else
     264        u_int gen;
     265
     266        gen = th->th_generation;
     267        __compiler_membar();
     268        return (gen);
     269#endif
     270#else /* __rtems__ */
     271        return (_Atomic_Load_ulong(&th->th_generation, ATOMIC_ORDER_ACQUIRE));
     272#endif /* __rtems__ */
     273}
     274
     275static void
     276tc_setgen(struct timehands *th, u_int newgen)
     277{
     278
     279#ifndef __rtems__
     280#ifdef SMP
     281        atomic_store_rel_int(&th->th_generation, newgen);
     282#else
     283        __compiler_membar();
     284        th->th_generation = newgen;
     285#endif
     286#else /* __rtems__ */
     287        _Atomic_Store_ulong(&th->th_generation, newgen, ATOMIC_ORDER_RELEASE);
     288#endif /* __rtems__ */
     289}
     290
    251291/*
    252292 * Functions for reading the time.  We have to loop until we are sure that
     
    264304        do {
    265305                th = timehands;
    266                 gen = th->th_generation;
     306                gen = tc_getgen(th);
    267307                *bt = th->th_offset;
    268308                bintime_addx(bt, th->th_scale * tc_delta(th));
    269         } while (gen == 0 || gen != th->th_generation);
     309        } while (gen == 0 || gen != tc_getgen(th));
    270310}
    271311
     
    322362        do {
    323363                th = timehands;
    324                 gen = th->th_generation;
     364                gen = tc_getgen(th);
    325365                *bt = th->th_offset;
    326         } while (gen == 0 || gen != th->th_generation);
     366        } while (gen == 0 || gen != tc_getgen(th));
    327367}
    328368
     
    335375        do {
    336376                th = timehands;
    337                 gen = th->th_generation;
     377                gen = tc_getgen(th);
    338378                bintime2timespec(&th->th_offset, tsp);
    339         } while (gen == 0 || gen != th->th_generation);
     379        } while (gen == 0 || gen != tc_getgen(th));
    340380}
    341381
     
    348388        do {
    349389                th = timehands;
    350                 gen = th->th_generation;
     390                gen = tc_getgen(th);
    351391                bintime2timeval(&th->th_offset, tvp);
    352         } while (gen == 0 || gen != th->th_generation);
     392        } while (gen == 0 || gen != tc_getgen(th));
    353393}
    354394
     
    361401        do {
    362402                th = timehands;
    363                 gen = th->th_generation;
     403                gen = tc_getgen(th);
    364404                *bt = th->th_offset;
    365         } while (gen == 0 || gen != th->th_generation);
     405        } while (gen == 0 || gen != tc_getgen(th));
    366406        bintime_add(bt, &boottimebin);
    367407}
     
    375415        do {
    376416                th = timehands;
    377                 gen = th->th_generation;
     417                gen = tc_getgen(th);
    378418                *tsp = th->th_nanotime;
    379         } while (gen == 0 || gen != th->th_generation);
     419        } while (gen == 0 || gen != tc_getgen(th));
    380420}
    381421
     
    388428        do {
    389429                th = timehands;
    390                 gen = th->th_generation;
     430                gen = tc_getgen(th);
    391431                *tvp = th->th_microtime;
    392         } while (gen == 0 || gen != th->th_generation);
     432        } while (gen == 0 || gen != tc_getgen(th));
    393433}
    394434#else /* !FFCLOCK */
     
    401441        do {
    402442                th = timehands;
    403                 gen = th->th_generation;
     443                gen = tc_getgen(th);
    404444                *bt = th->th_offset;
    405445                bintime_addx(bt, th->th_scale * tc_delta(th));
    406         } while (gen == 0 || gen != th->th_generation);
     446        } while (gen == 0 || gen != tc_getgen(th));
    407447}
    408448
     
    459499        do {
    460500                th = timehands;
    461                 gen = th->th_generation;
     501                gen = tc_getgen(th);
    462502                *bt = th->th_offset;
    463         } while (gen == 0 || gen != th->th_generation);
     503        } while (gen == 0 || gen != tc_getgen(th));
    464504}
    465505
     
    472512        do {
    473513                th = timehands;
    474                 gen = th->th_generation;
     514                gen = tc_getgen(th);
    475515                bintime2timespec(&th->th_offset, tsp);
    476         } while (gen == 0 || gen != th->th_generation);
     516        } while (gen == 0 || gen != tc_getgen(th));
    477517}
    478518
     
    485525        do {
    486526                th = timehands;
    487                 gen = th->th_generation;
     527                gen = tc_getgen(th);
    488528                bintime2timeval(&th->th_offset, tvp);
    489         } while (gen == 0 || gen != th->th_generation);
     529        } while (gen == 0 || gen != tc_getgen(th));
    490530}
    491531
     
    498538        do {
    499539                th = timehands;
    500                 gen = th->th_generation;
     540                gen = tc_getgen(th);
    501541                *bt = th->th_offset;
    502         } while (gen == 0 || gen != th->th_generation);
     542        } while (gen == 0 || gen != tc_getgen(th));
    503543        bintime_add(bt, &boottimebin);
    504544}
     
    512552        do {
    513553                th = timehands;
    514                 gen = th->th_generation;
     554                gen = tc_getgen(th);
    515555                *tsp = th->th_nanotime;
    516         } while (gen == 0 || gen != th->th_generation);
     556        } while (gen == 0 || gen != tc_getgen(th));
    517557}
    518558
     
    525565        do {
    526566                th = timehands;
    527                 gen = th->th_generation;
     567                gen = tc_getgen(th);
    528568                *tvp = th->th_microtime;
    529         } while (gen == 0 || gen != th->th_generation);
     569        } while (gen == 0 || gen != tc_getgen(th));
    530570}
    531571#endif /* FFCLOCK */
     
    940980        do {
    941981                th = timehands;
    942                 gen = th->th_generation;
     982                gen = tc_getgen(th);
    943983                ffth = fftimehands;
    944984                delta = tc_delta(th);
    945985                *ffcount = ffth->tick_ffcount;
    946         } while (gen == 0 || gen != th->th_generation);
     986        } while (gen == 0 || gen != tc_getgen(th));
    947987
    948988        *ffcount += delta;
     
    10491089        do {
    10501090                th = timehands;
    1051                 gen = th->th_generation;
     1091                gen = tc_getgen(th);
    10521092                *tsp = th->th_nanotime;
    1053         } while (gen == 0 || gen != th->th_generation);
     1093        } while (gen == 0 || gen != tc_getgen(th));
    10541094}
    10551095#endif /* __rtems__ */
     
    10931133        do {
    10941134                th = timehands;
    1095                 gen = th->th_generation;
     1135                gen = tc_getgen(th);
    10961136                fbi->th_scale = th->th_scale;
    10971137                fbi->tick_time = th->th_offset;
     
    11071147                if (!fast)
    11081148                        delta = tc_delta(th);
    1109         } while (gen == 0 || gen != th->th_generation);
     1149        } while (gen == 0 || gen != tc_getgen(th));
    11101150
    11111151        clock_snap->delta = delta;
     
    13551395        th = tho->th_next;
    13561396        ogen = th->th_generation;
    1357         th->th_generation = 0;
     1397        tc_setgen(th, 0);
    13581398        bcopy(tho, th, offsetof(struct timehands, th_generation));
    13591399
     
    14761516        if (++ogen == 0)
    14771517                ogen = 1;
    1478         th->th_generation = ogen;
     1518        tc_setgen(th, ogen);
    14791519
    14801520        /* Go live with the new struct timehands. */
     
    17581798        KASSERT(pps != NULL, ("NULL pps pointer in pps_capture"));
    17591799        th = timehands;
    1760         pps->capgen = th->th_generation;
     1800        pps->capgen = tc_getgen(th);
    17611801        pps->capth = th;
    17621802#ifdef FFCLOCK
     
    17641804#endif
    17651805        pps->capcount = th->th_counter->tc_get_timecount(th->th_counter);
    1766         if (pps->capgen != th->th_generation)
     1806        if (pps->capgen != tc_getgen(th))
    17671807                pps->capgen = 0;
    17681808}
     
    17841824        KASSERT(pps != NULL, ("NULL pps pointer in pps_event"));
    17851825        /* If the timecounter was wound up underneath us, bail out. */
    1786         if (pps->capgen == 0 || pps->capgen != pps->capth->th_generation)
     1826        if (pps->capgen == 0 || pps->capgen != tc_getgen(pps->capth))
    17871827                return;
    17881828
     
    18341874
    18351875        /* If the timecounter was wound up underneath us, bail out. */
    1836         if (pps->capgen != pps->capth->th_generation)
     1876        if (pps->capgen != tc_getgen(pps->capth))
    18371877                return;
    18381878
Note: See TracChangeset for help on using the changeset viewer.