Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/time.c

    r2c577e0b r63f8966  
    3535#include <sys/time.h>
    3636#include <unistd.h>
    37 #include <bool.h>
    38 #include <ipc/ns.h>
     37#include <ipc/ipc.h>
     38#include <stdio.h>
    3939#include <arch/barrier.h>
    40 #include <macros.h>
     40#include <unistd.h>
     41#include <atomic.h>
     42#include <sysinfo.h>
     43#include <ipc/services.h>
    4144#include <libc.h>
     45
     46#include <sysinfo.h>
     47#include <as.h>
     48#include <ddi.h>
     49
    4250#include <time.h>
    4351
    44 /** Pointer to kernel shared variables with time */
     52/* Pointers to public variables with time */
    4553struct {
    4654        volatile sysarg_t seconds1;
     
    5159/** Add microseconds to given timeval.
    5260 *
    53  * @param tv    Destination timeval.
    54  * @param usecs Number of microseconds to add.
    55  *
     61 * @param tv            Destination timeval.
     62 * @param usecs         Number of microseconds to add.
    5663 */
    5764void tv_add(struct timeval *tv, suseconds_t usecs)
     
    5966        tv->tv_sec += usecs / 1000000;
    6067        tv->tv_usec += usecs % 1000000;
    61        
    6268        if (tv->tv_usec > 1000000) {
    6369                tv->tv_sec++;
     
    6874/** Subtract two timevals.
    6975 *
    70  * @param tv1 First timeval.
    71  * @param tv2 Second timeval.
    72  *
    73  * @return Difference between tv1 and tv2 (tv1 - tv2) in
    74  *         microseconds.
    75  *
     76 * @param tv1           First timeval.
     77 * @param tv2           Second timeval.
     78 *
     79 * @return              Return difference between tv1 and tv2 (tv1 - tv2) in
     80 *                      microseconds.
    7681 */
    7782suseconds_t tv_sub(struct timeval *tv1, struct timeval *tv2)
    7883{
    79         return (tv1->tv_usec - tv2->tv_usec) +
    80             ((tv1->tv_sec - tv2->tv_sec) * 1000000);
     84        suseconds_t result;
     85
     86        result = tv1->tv_usec - tv2->tv_usec;
     87        result += (tv1->tv_sec - tv2->tv_sec) * 1000000;
     88
     89        return result;
    8190}
    8291
    8392/** Decide if one timeval is greater than the other.
    8493 *
    85  * @param t1 First timeval.
    86  * @param t2 Second timeval.
    87  *
    88  * @return True if tv1 is greater than tv2.
    89  * @return False otherwise.
    90  *
     94 * @param t1            First timeval.
     95 * @param t2            Second timeval.
     96 *
     97 * @return              Return true tv1 is greater than tv2. Otherwise return
     98 *                      false.
    9199 */
    92100int tv_gt(struct timeval *tv1, struct timeval *tv2)
    93101{
    94102        if (tv1->tv_sec > tv2->tv_sec)
    95                 return true;
    96        
    97         if ((tv1->tv_sec == tv2->tv_sec) && (tv1->tv_usec > tv2->tv_usec))
    98                 return true;
    99        
    100         return false;
     103                return 1;
     104        if (tv1->tv_sec == tv2->tv_sec && tv1->tv_usec > tv2->tv_usec)
     105                return 1;
     106        return 0;
    101107}
    102108
    103109/** Decide if one timeval is greater than or equal to the other.
    104110 *
    105  * @param tv1 First timeval.
    106  * @param tv2 Second timeval.
    107  *
    108  * @return True if tv1 is greater than or equal to tv2.
    109  * @return False otherwise.
    110  *
     111 * @param tv1           First timeval.
     112 * @param tv2           Second timeval.
     113 *
     114 * @return              Return true if tv1 is greater than or equal to tv2.
     115 *                      Otherwise return false.
    111116 */
    112117int tv_gteq(struct timeval *tv1, struct timeval *tv2)
    113118{
    114119        if (tv1->tv_sec > tv2->tv_sec)
    115                 return true;
    116        
    117         if ((tv1->tv_sec == tv2->tv_sec) && (tv1->tv_usec >= tv2->tv_usec))
    118                 return true;
    119        
    120         return false;
    121 }
    122 
    123 /** Get time of day
    124  *
    125  * The time variables are memory mapped (read-only) from kernel which
    126  * updates them periodically.
    127  *
    128  * As it is impossible to read 2 values atomically, we use a trick:
    129  * First we read the seconds, then we read the microseconds, then we
    130  * read the seconds again. If a second elapsed in the meantime, set
    131  * the microseconds to zero.
    132  *
    133  * This assures that the values returned by two subsequent calls
    134  * to gettimeofday() are monotonous.
    135  *
     120                return 1;
     121        if (tv1->tv_sec == tv2->tv_sec && tv1->tv_usec >= tv2->tv_usec)
     122                return 1;
     123        return 0;
     124}
     125
     126
     127/** POSIX gettimeofday
     128 *
     129 * The time variables are memory mapped(RO) from kernel, which updates
     130 * them periodically. As it is impossible to read 2 values atomically, we
     131 * use a trick: First read a seconds, then read microseconds, then
     132 * read seconds again. If a second elapsed in the meantime, set it to zero.
     133 * This provides assurance, that at least the
     134 * sequence of subsequent gettimeofday calls is ordered.
    136135 */
    137136int gettimeofday(struct timeval *tv, struct timezone *tz)
    138137{
     138        void *mapping;
     139        sysarg_t s1, s2;
     140        int rights;
     141        int res;
     142
    139143        if (!ktime) {
    140                 ktime = service_realtime_share_in();
    141                 if (!ktime)
    142                         return -1;
    143         }
    144        
     144                mapping = as_get_mappable_page(PAGE_SIZE);
     145                /* Get the mapping of kernel clock */
     146                res = ipc_share_in_start_1_1(PHONE_NS, mapping, PAGE_SIZE,
     147                    SERVICE_MEM_REALTIME, &rights);
     148                if (res) {
     149                        printf("Failed to initialize timeofday memarea\n");
     150                        _exit(1);
     151                }
     152                if (!(rights & AS_AREA_READ)) {
     153                        printf("Received bad rights on time area: %X\n",
     154                            rights);
     155                        as_area_destroy(mapping);
     156                        _exit(1);
     157                }
     158                ktime = mapping;
     159        }
    145160        if (tz) {
    146161                tz->tz_minuteswest = 0;
    147162                tz->tz_dsttime = DST_NONE;
    148163        }
    149        
    150         sysarg_t s2 = ktime->seconds2;
    151        
     164
     165        s2 = ktime->seconds2;
    152166        read_barrier();
    153167        tv->tv_usec = ktime->useconds;
    154        
    155168        read_barrier();
    156         sysarg_t s1 = ktime->seconds1;
    157        
     169        s1 = ktime->seconds1;
    158170        if (s1 != s2) {
    159                 tv->tv_sec = max(s1, s2);
    160171                tv->tv_usec = 0;
     172                tv->tv_sec = s1 > s2 ? s1 : s2;
    161173        } else
    162174                tv->tv_sec = s1;
    163        
     175
    164176        return 0;
    165177}
     
    168180{
    169181        struct timeval tv;
     182
    170183        if (gettimeofday(&tv, NULL))
    171184                return (time_t) -1;
    172        
    173185        if (tloc)
    174186                *tloc = tv.tv_sec;
    175        
    176187        return tv.tv_sec;
    177188}
    178189
    179 /** Wait unconditionally for specified number of microseconds
    180  *
    181  */
     190/** Wait unconditionally for specified number of microseconds */
    182191int usleep(useconds_t usec)
    183192{
     
    186195}
    187196
    188 /** Wait unconditionally for specified number of seconds
    189  *
    190  */
     197/** Wait unconditionally for specified number of seconds */
    191198unsigned int sleep(unsigned int sec)
    192199{
    193         /*
    194          * Sleep in 1000 second steps to support
    195          * full argument range
    196          */
    197        
     200        /* Sleep in 1000 second steps to support
     201           full argument range */
    198202        while (sec > 0) {
    199203                unsigned int period = (sec > 1000) ? 1000 : sec;
    200                
     204       
    201205                usleep(period * 1000000);
    202206                sec -= period;
    203207        }
    204        
    205208        return 0;
    206209}
Note: See TracChangeset for help on using the changeset viewer.