Changeset 205f1add in mainline for uspace/lib/c/generic


Ignore:
Timestamp:
2018-08-23T21:14:56Z (7 years ago)
Author:
Jakub Jermar <jakub@…>
Children:
f33c989e
Parents:
e2625b1a
git-author:
Jakub Jermar <jakub@…> (2018-08-21 21:58:52)
git-committer:
Jakub Jermar <jakub@…> (2018-08-23 21:14:56)
Message:

Get rid of sys/time.h

This commit moves the POSIX-like time functionality from libc's
sys/time.h to libposix and introduces C99-like or HelenOS-specific
interfaces to libc.

Specifically, use of sys/time.h, struct timeval, suseconds_t and
gettimeofday is replaced by time.h (C99), struct timespec (C99),
usec_t (HelenOS) and getuptime / getrealtime (HelenOS).

Location:
uspace/lib/c/generic
Files:
15 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/async/client.c

    re2625b1a r205f1add  
    110110#include <assert.h>
    111111#include <errno.h>
    112 #include <sys/time.h>
     112#include <time.h>
    113113#include <barrier.h>
    114114#include <stdbool.h>
     
    342342 *
    343343 */
    344 errno_t async_wait_timeout(aid_t amsgid, errno_t *retval, suseconds_t timeout)
     344errno_t async_wait_timeout(aid_t amsgid, errno_t *retval, usec_t timeout)
    345345{
    346346        if (amsgid == 0) {
     
    359359                timeout = 0;
    360360
    361         struct timeval expires;
     361        struct timespec expires;
    362362        getuptime(&expires);
    363         tv_add_diff(&expires, timeout);
     363        ts_add_diff(&expires, USEC2NSEC(timeout));
    364364
    365365        errno_t rc = fibril_wait_timeout(&msg->received, &expires);
  • uspace/lib/c/generic/async/ports.c

    re2625b1a r205f1add  
    4141#include <assert.h>
    4242#include <errno.h>
    43 #include <sys/time.h>
     43#include <time.h>
    4444#include <barrier.h>
    4545#include <stdbool.h>
  • uspace/lib/c/generic/async/server.c

    re2625b1a r205f1add  
    110110#include <assert.h>
    111111#include <errno.h>
    112 #include <sys/time.h>
     112#include <time.h>
    113113#include <stdbool.h>
    114114#include <stdlib.h>
     
    916916 *
    917917 */
    918 bool async_get_call_timeout(ipc_call_t *call, suseconds_t usecs)
     918bool async_get_call_timeout(ipc_call_t *call, usec_t usecs)
    919919{
    920920        assert(call);
    921921        assert(fibril_connection);
    922922
    923         struct timeval tv;
    924         struct timeval *expires = NULL;
     923        struct timespec ts;
     924        struct timespec *expires = NULL;
    925925        if (usecs) {
    926                 getuptime(&tv);
    927                 tv_add_diff(&tv, usecs);
    928                 expires = &tv;
     926                getuptime(&ts);
     927                ts_add_diff(&ts, USEC2NSEC(usecs));
     928                expires = &ts;
    929929        }
    930930
  • uspace/lib/c/generic/io/console.c

    re2625b1a r205f1add  
    223223
    224224bool console_get_event_timeout(console_ctrl_t *ctrl, cons_event_t *event,
    225     suseconds_t *timeout)
    226 {
    227         struct timeval t0;
    228         gettimeofday(&t0, NULL);
     225    usec_t *timeout)
     226{
     227        struct timespec t0;
     228        getuptime(&t0);
    229229
    230230        if (ctrl->input_aid == 0) {
     
    257257
    258258        /* Update timeout */
    259         struct timeval t1;
    260         gettimeofday(&t1, NULL);
    261         *timeout -= tv_sub_diff(&t1, &t0);
     259        struct timespec t1;
     260        getuptime(&t1);
     261        *timeout -= NSEC2USEC(ts_sub_diff(&t1, &t0));
    262262
    263263        return true;
  • uspace/lib/c/generic/private/async.h

    re2625b1a r205f1add  
    4040#include <fibril.h>
    4141#include <fibril_synch.h>
    42 #include <sys/time.h>
     42#include <time.h>
    4343#include <stdbool.h>
    4444
  • uspace/lib/c/generic/private/fibril.h

    re2625b1a r205f1add  
    8181
    8282extern void fibril_wait_for(fibril_event_t *);
    83 extern errno_t fibril_wait_timeout(fibril_event_t *, const struct timeval *);
     83extern errno_t fibril_wait_timeout(fibril_event_t *, const struct timespec *);
    8484extern void fibril_notify(fibril_event_t *);
    8585
    86 extern errno_t fibril_ipc_wait(ipc_call_t *, const struct timeval *);
     86extern errno_t fibril_ipc_wait(ipc_call_t *, const struct timespec *);
    8787extern void fibril_ipc_poke(void);
    8888
  • uspace/lib/c/generic/private/futex.h

    re2625b1a r205f1add  
    102102 *
    103103 */
    104 static inline errno_t futex_down_composable(futex_t *futex, const struct timeval *expires)
     104static inline errno_t futex_down_composable(futex_t *futex,
     105    const struct timespec *expires)
    105106{
    106107        // TODO: Add tests for this.
     
    109110                return EOK;
    110111
    111         suseconds_t timeout;
     112        usec_t timeout;
    112113
    113114        if (!expires) {
     
    119120                        timeout = 1;
    120121                } else {
    121                         struct timeval tv;
     122                        struct timespec tv;
    122123                        getuptime(&tv);
    123                         timeout = tv_gteq(&tv, expires) ? 1 :
    124                             tv_sub_diff(expires, &tv);
     124                        timeout = ts_gteq(&tv, expires) ? 1 :
     125                            NSEC2USEC(ts_sub_diff(expires, &tv));
    125126                }
    126127
     
    148149}
    149150
    150 static inline errno_t futex_down_timeout(futex_t *futex, const struct timeval *expires)
    151 {
    152         if (expires && expires->tv_sec == 0 && expires->tv_usec == 0) {
     151static inline errno_t futex_down_timeout(futex_t *futex,
     152    const struct timespec *expires)
     153{
     154        if (expires && expires->tv_sec == 0 && expires->tv_nsec == 0) {
    153155                /* Nonblocking down. */
    154156
     
    209211         * trydown.
    210212         */
    211         struct timeval tv = { .tv_sec = 0, .tv_usec = 0 };
     213        struct timespec tv = { .tv_sec = 0, .tv_nsec = 0 };
    212214        return futex_down_timeout(futex, &tv) == EOK;
    213215}
  • uspace/lib/c/generic/private/thread.h

    re2625b1a r205f1add  
    4949extern void thread_detach(thread_id_t);
    5050extern thread_id_t thread_get_id(void);
    51 extern int thread_usleep(useconds_t);
    52 extern unsigned int thread_sleep(unsigned int);
     51extern void thread_usleep(usec_t);
     52extern void thread_sleep(sec_t);
    5353
    5454#endif
  • uspace/lib/c/generic/rndgen.c

    re2625b1a r205f1add  
    5252{
    5353        rndgen_t *rndgen;
    54         struct timeval tv;
     54        struct timespec ts;
    5555
    5656        rndgen = calloc(1, sizeof(rndgen_t));
     
    5959
    6060        /* XXX This is a rather poor way of generating random numbers */
    61         gettimeofday(&tv, NULL);
    62         rndgen->seed = tv.tv_sec ^ tv.tv_usec;
     61        getuptime(&ts);
     62        rndgen->seed = ts.tv_sec ^ ts.tv_nsec;
    6363
    6464        *rrndgen = rndgen;
  • uspace/lib/c/generic/stdlib.c

    re2625b1a r205f1add  
    3737#include <fibril_synch.h>
    3838#include <stdlib.h>
     39#include <errno.h>
    3940#include "private/libc.h"
    4041#include "private/scanf.h"
  • uspace/lib/c/generic/thread/fibril.c

    re2625b1a r205f1add  
    6060typedef struct {
    6161        link_t link;
    62         struct timeval expires;
     62        struct timespec expires;
    6363        fibril_event_t *event;
    6464} _timeout_t;
     
    142142}
    143143
    144 static inline errno_t _ready_down(const struct timeval *expires)
     144static inline errno_t _ready_down(const struct timespec *expires)
    145145{
    146146        if (multithreaded)
     
    253253}
    254254
    255 static errno_t _ipc_wait(ipc_call_t *call, const struct timeval *expires)
     255static errno_t _ipc_wait(ipc_call_t *call, const struct timespec *expires)
    256256{
    257257        if (!expires)
     
    261261                return ipc_wait(call, SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NON_BLOCKING);
    262262
    263         struct timeval now;
     263        struct timespec now;
    264264        getuptime(&now);
    265265
    266         if (tv_gteq(&now, expires))
     266        if (ts_gteq(&now, expires))
    267267                return ipc_wait(call, SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NON_BLOCKING);
    268268
    269         return ipc_wait(call, tv_sub_diff(expires, &now), SYNCH_FLAGS_NONE);
     269        return ipc_wait(call, NSEC2USEC(ts_sub_diff(expires, &now)),
     270            SYNCH_FLAGS_NONE);
    270271}
    271272
     
    275276 * wait after new ready fibrils are added.
    276277 */
    277 static fibril_t *_ready_list_pop(const struct timeval *expires, bool locked)
     278static fibril_t *_ready_list_pop(const struct timespec *expires, bool locked)
    278279{
    279280        if (locked) {
     
    370371static fibril_t *_ready_list_pop_nonblocking(bool locked)
    371372{
    372         struct timeval tv = { .tv_sec = 0, .tv_usec = 0 };
     373        struct timespec tv = { .tv_sec = 0, .tv_nsec = 0 };
    373374        return _ready_list_pop(&tv, locked);
    374375}
     
    393394
    394395/* Blocks the current fibril until an IPC call arrives. */
    395 static errno_t _wait_ipc(ipc_call_t *call, const struct timeval *expires)
     396static errno_t _wait_ipc(ipc_call_t *call, const struct timespec *expires)
    396397{
    397398        futex_assert_is_not_locked(&fibril_futex);
     
    430431
    431432/** Fire all timeouts that expired. */
    432 static struct timeval *_handle_expired_timeouts(struct timeval *next_timeout)
    433 {
    434         struct timeval tv;
    435         getuptime(&tv);
     433static struct timespec *_handle_expired_timeouts(struct timespec *next_timeout)
     434{
     435        struct timespec ts;
     436        getuptime(&ts);
    436437
    437438        futex_lock(&fibril_futex);
     
    441442                _timeout_t *to = list_get_instance(cur, _timeout_t, link);
    442443
    443                 if (tv_gt(&to->expires, &tv)) {
     444                if (ts_gt(&to->expires, &ts)) {
    444445                        *next_timeout = to->expires;
    445446                        futex_unlock(&fibril_futex);
     
    535536        (void) arg;
    536537
    537         struct timeval next_timeout;
     538        struct timespec next_timeout;
    538539        while (true) {
    539                 struct timeval *to = _handle_expired_timeouts(&next_timeout);
     540                struct timespec *to = _handle_expired_timeouts(&next_timeout);
    540541                fibril_t *f = _ready_list_pop(to, false);
    541542                if (f) {
     
    615616                _timeout_t *cur = list_get_instance(tmp, _timeout_t, link);
    616617
    617                 if (tv_gteq(&cur->expires, &timeout->expires))
     618                if (ts_gteq(&cur->expires, &timeout->expires))
    618619                        break;
    619620
     
    634635 * @return ETIMEOUT if timed out. EOK otherwise.
    635636 */
    636 errno_t fibril_wait_timeout(fibril_event_t *event, const struct timeval *expires)
     637errno_t fibril_wait_timeout(fibril_event_t *event,
     638    const struct timespec *expires)
    637639{
    638640        assert(fibril_self()->rmutex_locks == 0);
     
    889891}
    890892
    891 void fibril_usleep(suseconds_t timeout)
    892 {
    893         struct timeval expires;
     893void fibril_usleep(usec_t timeout)
     894{
     895        struct timespec expires;
    894896        getuptime(&expires);
    895         tv_add_diff(&expires, timeout);
     897        ts_add_diff(&expires, USEC2NSEC(timeout));
    896898
    897899        fibril_event_t event = FIBRIL_EVENT_INIT;
     
    899901}
    900902
    901 void fibril_sleep(unsigned int sec)
    902 {
    903         struct timeval expires;
     903void fibril_sleep(sec_t sec)
     904{
     905        struct timespec expires;
    904906        getuptime(&expires);
    905907        expires.tv_sec += sec;
     
    916918}
    917919
    918 errno_t fibril_ipc_wait(ipc_call_t *call, const struct timeval *expires)
     920errno_t fibril_ipc_wait(ipc_call_t *call, const struct timespec *expires)
    919921{
    920922        return _wait_ipc(call, expires);
  • uspace/lib/c/generic/thread/fibril_synch.c

    re2625b1a r205f1add  
    3737#include <async.h>
    3838#include <adt/list.h>
    39 #include <sys/time.h>
     39#include <time.h>
    4040#include <errno.h>
    4141#include <assert.h>
     
    390390errno_t
    391391fibril_condvar_wait_timeout(fibril_condvar_t *fcv, fibril_mutex_t *fm,
    392     suseconds_t timeout)
     392    usec_t timeout)
    393393{
    394394        assert(fibril_mutex_is_locked(fm));
     
    400400        wdata.mutex = fm;
    401401
    402         struct timeval tv;
    403         struct timeval *expires = NULL;
     402        struct timespec ts;
     403        struct timespec *expires = NULL;
    404404        if (timeout) {
    405                 getuptime(&tv);
    406                 tv_add_diff(&tv, timeout);
    407                 expires = &tv;
     405                getuptime(&ts);
     406                ts_add_diff(&ts, USEC2NSEC(timeout));
     407                expires = &ts;
    408408        }
    409409
     
    557557 * @param arg           Argument for @a fun
    558558 */
    559 void fibril_timer_set(fibril_timer_t *timer, suseconds_t delay,
     559void fibril_timer_set(fibril_timer_t *timer, usec_t delay,
    560560    fibril_timer_fun_t fun, void *arg)
    561561{
     
    575575 * @param arg           Argument for @a fun
    576576 */
    577 void fibril_timer_set_locked(fibril_timer_t *timer, suseconds_t delay,
     577void fibril_timer_set_locked(fibril_timer_t *timer, usec_t delay,
    578578    fibril_timer_fun_t fun, void *arg)
    579579{
     
    728728}
    729729
    730 errno_t fibril_semaphore_down_timeout(fibril_semaphore_t *sem, suseconds_t timeout)
     730errno_t fibril_semaphore_down_timeout(fibril_semaphore_t *sem, usec_t timeout)
    731731{
    732732        if (timeout < 0)
     
    751751        futex_unlock(&fibril_synch_futex);
    752752
    753         struct timeval tv;
    754         struct timeval *expires = NULL;
     753        struct timespec ts;
     754        struct timespec *expires = NULL;
    755755        if (timeout) {
    756                 getuptime(&tv);
    757                 tv_add_diff(&tv, timeout);
    758                 expires = &tv;
     756                getuptime(&ts);
     757                ts_add_diff(&ts, USEC2NSEC(timeout));
     758                expires = &ts;
    759759        }
    760760
  • uspace/lib/c/generic/thread/mpsc.c

    re2625b1a r205f1add  
    146146 * there is no message left in the queue.
    147147 */
    148 errno_t mpsc_receive(mpsc_t *q, void *b, const struct timeval *expires)
     148errno_t mpsc_receive(mpsc_t *q, void *b, const struct timespec *expires)
    149149{
    150150        mpsc_node_t *n;
  • uspace/lib/c/generic/thread/thread.c

    re2625b1a r205f1add  
    176176 *
    177177 */
    178 int thread_usleep(useconds_t usec)
     178void thread_usleep(usec_t usec)
    179179{
    180180        (void) __SYSCALL1(SYS_THREAD_USLEEP, usec);
    181         return 0;
    182181}
    183182
     
    185184 *
    186185 */
    187 unsigned int thread_sleep(unsigned int sec)
     186void thread_sleep(sec_t sec)
    188187{
    189188        /*
    190          * Sleep in 1000 second steps to support
    191          * full argument range
     189         * Sleep in 1000 second steps to support full argument range
    192190         */
    193 
    194191        while (sec > 0) {
    195192                unsigned int period = (sec > 1000) ? 1000 : sec;
    196193
    197                 thread_usleep(period * 1000000);
     194                thread_usleep(SEC2USEC(period));
    198195                sec -= period;
    199196        }
    200 
    201         return 0;
    202197}
    203198
  • uspace/lib/c/generic/time.c

    re2625b1a r205f1add  
    3535 */
    3636
    37 #include <sys/time.h>
    3837#include <time.h>
    3938#include <stdbool.h>
     
    5756#define MINS_PER_HOUR  60
    5857#define SECS_PER_MIN   60
    59 #define USECS_PER_SEC  1000000
     58#define NSECS_PER_SEC  1000000000ll
    6059#define MINS_PER_DAY   (MINS_PER_HOUR * HOURS_PER_DAY)
    6160#define SECS_PER_HOUR  (SECS_PER_MIN * MINS_PER_HOUR)
     
    252251 *
    253252 * @param tm Broken-down time to normalize.
    254  * @param tv Timeval to add.
     253 * @param ts Timespec to add.
    255254 *
    256255 * @return 0 on success, -1 on overflow
    257256 *
    258257 */
    259 static int normalize_tm_tv(struct tm *tm, const struct timeval *tv)
     258static int normalize_tm_ts(struct tm *tm, const struct timespec *ts)
    260259{
    261260        // TODO: DST correction
    262261
    263262        /* Set initial values. */
    264         time_t usec = tm->tm_usec + tv->tv_usec;
    265         time_t sec = tm->tm_sec + tv->tv_sec;
     263        time_t nsec = tm->tm_nsec + ts->tv_nsec;
     264        time_t sec = tm->tm_sec + ts->tv_sec;
    266265        time_t min = tm->tm_min;
    267266        time_t hour = tm->tm_hour;
     
    271270
    272271        /* Adjust time. */
    273         sec += floor_div(usec, USECS_PER_SEC);
    274         usec = floor_mod(usec, USECS_PER_SEC);
     272        sec += floor_div(nsec, NSECS_PER_SEC);
     273        nsec = floor_mod(nsec, NSECS_PER_SEC);
    275274        min += floor_div(sec, SECS_PER_MIN);
    276275        sec = floor_mod(sec, SECS_PER_MIN);
     
    321320
    322321        /* And put the values back to the struct. */
    323         tm->tm_usec = (int) usec;
     322        tm->tm_nsec = (int) nsec;
    324323        tm->tm_sec = (int) sec;
    325324        tm->tm_min = (int) min;
     
    340339static int normalize_tm_time(struct tm *tm, time_t time)
    341340{
    342         struct timeval tv = {
     341        struct timespec ts = {
    343342                .tv_sec = time,
    344                 .tv_usec = 0
     343                .tv_nsec = 0
    345344        };
    346345
    347         return normalize_tm_tv(tm, &tv);
     346        return normalize_tm_ts(tm, &ts);
    348347}
    349348
     
    456455}
    457456
    458 static void tv_normalize(struct timeval *tv)
    459 {
    460         while (tv->tv_usec > USECS_PER_SEC) {
    461                 tv->tv_sec++;
    462                 tv->tv_usec -= USECS_PER_SEC;
    463         }
    464         while (tv->tv_usec < 0) {
    465                 tv->tv_sec--;
    466                 tv->tv_usec += USECS_PER_SEC;
    467         }
    468 }
    469 
    470 /** Add microseconds to given timeval.
    471  *
    472  * @param tv    Destination timeval.
    473  * @param usecs Number of microseconds to add.
    474  *
    475  */
    476 void tv_add_diff(struct timeval *tv, suseconds_t usecs)
    477 {
    478         tv->tv_sec += usecs / USECS_PER_SEC;
    479         tv->tv_usec += usecs % USECS_PER_SEC;
    480         tv_normalize(tv);
    481 }
    482 
    483 /** Add two timevals.
    484  *
    485  * @param tv1 First timeval.
    486  * @param tv2 Second timeval.
    487  */
    488 void tv_add(struct timeval *tv1, const struct timeval *tv2)
    489 {
    490         tv1->tv_sec += tv2->tv_sec;
    491         tv1->tv_usec += tv2->tv_usec;
    492         tv_normalize(tv1);
    493 }
    494 
    495 /** Subtract two timevals.
    496  *
    497  * @param tv1 First timeval.
    498  * @param tv2 Second timeval.
    499  *
    500  * @return Difference between tv1 and tv2 (tv1 - tv2) in
    501  *         microseconds.
    502  *
    503  */
    504 suseconds_t tv_sub_diff(const struct timeval *tv1, const struct timeval *tv2)
    505 {
    506         return (tv1->tv_usec - tv2->tv_usec) +
    507             ((tv1->tv_sec - tv2->tv_sec) * USECS_PER_SEC);
    508 }
    509 
    510 /** Subtract two timevals.
    511  *
    512  * @param tv1 First timeval.
    513  * @param tv2 Second timeval.
    514  *
    515  */
    516 void tv_sub(struct timeval *tv1, const struct timeval *tv2)
    517 {
    518         tv1->tv_sec -= tv2->tv_sec;
    519         tv1->tv_usec -= tv2->tv_usec;
    520         tv_normalize(tv1);
    521 }
    522 
    523 /** Decide if one timeval is greater than the other.
    524  *
    525  * @param t1 First timeval.
    526  * @param t2 Second timeval.
    527  *
    528  * @return True if tv1 is greater than tv2.
    529  * @return False otherwise.
    530  *
    531  */
    532 int tv_gt(const struct timeval *tv1, const struct timeval *tv2)
    533 {
    534         if (tv1->tv_sec > tv2->tv_sec)
     457static void ts_normalize(struct timespec *ts)
     458{
     459        while (ts->tv_nsec >= NSECS_PER_SEC) {
     460                ts->tv_sec++;
     461                ts->tv_nsec -= NSECS_PER_SEC;
     462        }
     463        while (ts->tv_nsec < 0) {
     464                ts->tv_sec--;
     465                ts->tv_nsec += NSECS_PER_SEC;
     466        }
     467}
     468
     469/** Add nanoseconds to given timespec.
     470 *
     471 * @param ts     Destination timespec.
     472 * @param nsecs  Number of nanoseconds to add.
     473 *
     474 */
     475void ts_add_diff(struct timespec *ts, nsec_t nsecs)
     476{
     477        ts->tv_sec += nsecs / NSECS_PER_SEC;
     478        ts->tv_nsec += nsecs % NSECS_PER_SEC;
     479        ts_normalize(ts);
     480}
     481
     482/** Add two timespecs.
     483 *
     484 * @param ts1  First timespec.
     485 * @param ts2  Second timespec.
     486 */
     487void ts_add(struct timespec *ts1, const struct timespec *ts2)
     488{
     489        ts1->tv_sec += ts2->tv_sec;
     490        ts1->tv_nsec += ts2->tv_nsec;
     491        ts_normalize(ts1);
     492}
     493
     494/** Subtract two timespecs.
     495 *
     496 * @param ts1  First timespec.
     497 * @param ts2  Second timespec.
     498 *
     499 * @return  Difference between ts1 and ts2 (ts1 - ts2) in nanoseconds.
     500 *
     501 */
     502nsec_t ts_sub_diff(const struct timespec *ts1, const struct timespec *ts2)
     503{
     504        return (nsec_t) (ts1->tv_nsec - ts2->tv_nsec) +
     505            SEC2NSEC((ts1->tv_sec - ts2->tv_sec));
     506}
     507
     508/** Subtract two timespecs.
     509 *
     510 * @param ts1  First timespec.
     511 * @param ts2  Second timespec.
     512 *
     513 */
     514void ts_sub(struct timespec *ts1, const struct timespec *ts2)
     515{
     516        ts1->tv_sec -= ts2->tv_sec;
     517        ts1->tv_nsec -= ts2->tv_nsec;
     518        ts_normalize(ts1);
     519}
     520
     521/** Decide if one timespec is greater than the other.
     522 *
     523 * @param ts1  First timespec.
     524 * @param ts2  Second timespec.
     525 *
     526 * @return  True if ts1 is greater than ts2.
     527 * @return  False otherwise.
     528 *
     529 */
     530bool ts_gt(const struct timespec *ts1, const struct timespec *ts2)
     531{
     532        if (ts1->tv_sec > ts2->tv_sec)
    535533                return true;
    536534
    537         if ((tv1->tv_sec == tv2->tv_sec) && (tv1->tv_usec > tv2->tv_usec))
     535        if ((ts1->tv_sec == ts2->tv_sec) && (ts1->tv_nsec > ts2->tv_nsec))
    538536                return true;
    539537
     
    541539}
    542540
    543 /** Decide if one timeval is greater than or equal to the other.
    544  *
    545  * @param tv1 First timeval.
    546  * @param tv2 Second timeval.
    547  *
    548  * @return True if tv1 is greater than or equal to tv2.
    549  * @return False otherwise.
    550  *
    551  */
    552 int tv_gteq(const struct timeval *tv1, const struct timeval *tv2)
    553 {
    554         if (tv1->tv_sec > tv2->tv_sec)
     541/** Decide if one timespec is greater than or equal to the other.
     542 *
     543 * @param ts1  First timespec.
     544 * @param ts2  Second timespec.
     545 *
     546 * @return  True if ts1 is greater than or equal to ts2.
     547 * @return  False otherwise.
     548 *
     549 */
     550bool ts_gteq(const struct timespec *ts1, const struct timespec *ts2)
     551{
     552        if (ts1->tv_sec > ts2->tv_sec)
    555553                return true;
    556554
    557         if ((tv1->tv_sec == tv2->tv_sec) && (tv1->tv_usec >= tv2->tv_usec))
     555        if ((ts1->tv_sec == ts2->tv_sec) && (ts1->tv_nsec >= ts2->tv_nsec))
    558556                return true;
    559557
     
    561559}
    562560
    563 /** Get time of day.
    564  *
    565  * The time variables are memory mapped (read-only) from kernel which
    566  * updates them periodically.
    567  *
    568  * As it is impossible to read 2 values atomically, we use a trick:
    569  * First we read the seconds, then we read the microseconds, then we
    570  * read the seconds again. If a second elapsed in the meantime, set
    571  * the microseconds to zero.
    572  *
    573  * This assures that the values returned by two subsequent calls
    574  * to gettimeofday() are monotonous.
    575  *
    576  */
    577 void gettimeofday(struct timeval *tv, struct timezone *tz)
    578 {
    579         if (tz) {
    580                 tz->tz_minuteswest = 0;
    581                 tz->tz_dsttime = DST_NONE;
    582         }
    583 
     561/** Get real time from a RTC service.
     562 *
     563 * @param[out] ts  Timespec to hold time read from the RTC service (if
     564 *                 available). If no such service exists, the returned time
     565 *                 corresponds to system uptime.
     566 */
     567void getrealtime(struct timespec *ts)
     568{
    584569        if (clock_conn == NULL) {
    585570                category_id_t cat_id;
     
    620605                goto fallback;
    621606
    622         tv->tv_usec = time.tm_usec;
    623         tv->tv_sec = mktime(&time);
     607        ts->tv_nsec = time.tm_nsec;
     608        ts->tv_sec = mktime(&time);
    624609
    625610        return;
    626611
    627612fallback:
    628         getuptime(tv);
    629 }
    630 
    631 void getuptime(struct timeval *tv)
     613        getuptime(ts);
     614}
     615
     616/** Get system uptime.
     617 *
     618 * @param[out] ts  Timespec to hold time current uptime.
     619 *
     620 * The time variables are memory mapped (read-only) from kernel which
     621 * updates them periodically.
     622 *
     623 * As it is impossible to read 2 values atomically, we use a trick:
     624 * First we read the seconds, then we read the microseconds, then we
     625 * read the seconds again. If a second elapsed in the meantime, set
     626 * the microseconds to zero.
     627 *
     628 * This assures that the values returned by two subsequent calls
     629 * to getuptime() are monotonous.
     630 *
     631 */
     632void getuptime(struct timespec *ts)
    632633{
    633634        if (ktime == NULL) {
     
    654655
    655656        read_barrier();
    656         tv->tv_usec = ktime->useconds;
     657        ts->tv_nsec = USEC2NSEC(ktime->useconds);
    657658
    658659        read_barrier();
     
    660661
    661662        if (s1 != s2) {
    662                 tv->tv_sec = max(s1, s2);
    663                 tv->tv_usec = 0;
     663                ts->tv_sec = max(s1, s2);
     664                ts->tv_nsec = 0;
    664665        } else
    665                 tv->tv_sec = s1;
     666                ts->tv_sec = s1;
    666667
    667668        return;
    668669
    669670fallback:
    670         tv->tv_sec = 0;
    671         tv->tv_usec = 0;
     671        ts->tv_sec = 0;
     672        ts->tv_nsec = 0;
    672673}
    673674
    674675time_t time(time_t *tloc)
    675676{
    676         struct timeval tv;
    677         gettimeofday(&tv, NULL);
     677        struct timespec ts;
     678        getrealtime(&ts);
    678679
    679680        if (tloc)
    680                 *tloc = tv.tv_sec;
    681 
    682         return tv.tv_sec;
    683 }
    684 
    685 void udelay(useconds_t time)
     681                *tloc = ts.tv_sec;
     682
     683        return ts.tv_sec;
     684}
     685
     686void udelay(usec_t time)
    686687{
    687688        (void) __SYSCALL1(SYS_THREAD_UDELAY, (sysarg_t) time);
     
    884885                        break;
    885886                case 's':
    886                         APPEND("%ld", secs_since_epoch(tm));
     887                        APPEND("%lld", secs_since_epoch(tm));
    887888                        break;
    888889                case 'S':
     
    961962
    962963        /* Set result to epoch. */
    963         result->tm_usec = 0;
     964        result->tm_nsec = 0;
    964965        result->tm_sec = 0;
    965966        result->tm_min = 0;
     
    10381039 *
    10391040 */
    1040 errno_t time_tv2tm(const struct timeval *tv, struct tm *restrict result)
     1041errno_t time_ts2tm(const struct timespec *ts, struct tm *restrict result)
    10411042{
    10421043        // TODO: Deal with timezones.
     
    10441045
    10451046        /* Set result to epoch. */
    1046         result->tm_usec = 0;
     1047        result->tm_nsec = 0;
    10471048        result->tm_sec = 0;
    10481049        result->tm_min = 0;
     
    10521053        result->tm_year = 70; /* 1970 */
    10531054
    1054         if (normalize_tm_tv(result, tv) == -1)
     1055        if (normalize_tm_ts(result, ts) == -1)
    10551056                return EOVERFLOW;
    10561057
     
    10701071errno_t time_local2tm(const time_t time, struct tm *restrict result)
    10711072{
    1072         struct timeval tv = {
     1073        struct timespec ts = {
    10731074                .tv_sec = time,
    1074                 .tv_usec = 0
     1075                .tv_nsec = 0
    10751076        };
    10761077
    1077         return time_tv2tm(&tv, result);
     1078        return time_ts2tm(&ts, result);
    10781079}
    10791080
Note: See TracChangeset for help on using the changeset viewer.