Changeset bd41ac52 in mainline for uspace/lib/c/generic
- Timestamp:
- 2018-08-25T22:21:25Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- cca80a2
- Parents:
- e2625b1a
- Location:
- uspace/lib/c/generic
- Files:
-
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/async/client.c
re2625b1a rbd41ac52 110 110 #include <assert.h> 111 111 #include <errno.h> 112 #include < sys/time.h>112 #include <time.h> 113 113 #include <barrier.h> 114 114 #include <stdbool.h> … … 342 342 * 343 343 */ 344 errno_t async_wait_timeout(aid_t amsgid, errno_t *retval, suseconds_t timeout)344 errno_t async_wait_timeout(aid_t amsgid, errno_t *retval, usec_t timeout) 345 345 { 346 346 if (amsgid == 0) { … … 359 359 timeout = 0; 360 360 361 struct time valexpires;361 struct timespec expires; 362 362 getuptime(&expires); 363 t v_add_diff(&expires, timeout);363 ts_add_diff(&expires, USEC2NSEC(timeout)); 364 364 365 365 errno_t rc = fibril_wait_timeout(&msg->received, &expires); -
uspace/lib/c/generic/async/ports.c
re2625b1a rbd41ac52 41 41 #include <assert.h> 42 42 #include <errno.h> 43 #include < sys/time.h>43 #include <time.h> 44 44 #include <barrier.h> 45 45 #include <stdbool.h> -
uspace/lib/c/generic/async/server.c
re2625b1a rbd41ac52 110 110 #include <assert.h> 111 111 #include <errno.h> 112 #include < sys/time.h>112 #include <time.h> 113 113 #include <stdbool.h> 114 114 #include <stdlib.h> … … 916 916 * 917 917 */ 918 bool async_get_call_timeout(ipc_call_t *call, suseconds_t usecs)918 bool async_get_call_timeout(ipc_call_t *call, usec_t usecs) 919 919 { 920 920 assert(call); 921 921 assert(fibril_connection); 922 922 923 struct time val tv;924 struct time val*expires = NULL;923 struct timespec ts; 924 struct timespec *expires = NULL; 925 925 if (usecs) { 926 getuptime(&t v);927 t v_add_diff(&tv, usecs);928 expires = &t v;926 getuptime(&ts); 927 ts_add_diff(&ts, USEC2NSEC(usecs)); 928 expires = &ts; 929 929 } 930 930 -
uspace/lib/c/generic/io/console.c
re2625b1a rbd41ac52 223 223 224 224 bool console_get_event_timeout(console_ctrl_t *ctrl, cons_event_t *event, 225 suseconds_t *timeout)226 { 227 struct time valt0;228 get timeofday(&t0, NULL);225 usec_t *timeout) 226 { 227 struct timespec t0; 228 getuptime(&t0); 229 229 230 230 if (ctrl->input_aid == 0) { … … 257 257 258 258 /* Update timeout */ 259 struct time valt1;260 get timeofday(&t1, NULL);261 *timeout -= tv_sub_diff(&t1, &t0);259 struct timespec t1; 260 getuptime(&t1); 261 *timeout -= NSEC2USEC(ts_sub_diff(&t1, &t0)); 262 262 263 263 return true; -
uspace/lib/c/generic/private/async.h
re2625b1a rbd41ac52 40 40 #include <fibril.h> 41 41 #include <fibril_synch.h> 42 #include < sys/time.h>42 #include <time.h> 43 43 #include <stdbool.h> 44 44 -
uspace/lib/c/generic/private/fibril.h
re2625b1a rbd41ac52 81 81 82 82 extern void fibril_wait_for(fibril_event_t *); 83 extern errno_t fibril_wait_timeout(fibril_event_t *, const struct time val*);83 extern errno_t fibril_wait_timeout(fibril_event_t *, const struct timespec *); 84 84 extern void fibril_notify(fibril_event_t *); 85 85 86 extern errno_t fibril_ipc_wait(ipc_call_t *, const struct time val*);86 extern errno_t fibril_ipc_wait(ipc_call_t *, const struct timespec *); 87 87 extern void fibril_ipc_poke(void); 88 88 -
uspace/lib/c/generic/private/futex.h
re2625b1a rbd41ac52 102 102 * 103 103 */ 104 static inline errno_t futex_down_composable(futex_t *futex, const struct timeval *expires) 104 static inline errno_t futex_down_composable(futex_t *futex, 105 const struct timespec *expires) 105 106 { 106 107 // TODO: Add tests for this. … … 109 110 return EOK; 110 111 111 suseconds_t timeout;112 usec_t timeout; 112 113 113 114 if (!expires) { … … 119 120 timeout = 1; 120 121 } else { 121 struct time valtv;122 struct timespec tv; 122 123 getuptime(&tv); 123 timeout = t v_gteq(&tv, expires) ? 1 :124 tv_sub_diff(expires, &tv);124 timeout = ts_gteq(&tv, expires) ? 1 : 125 NSEC2USEC(ts_sub_diff(expires, &tv)); 125 126 } 126 127 … … 148 149 } 149 150 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) { 151 static 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) { 153 155 /* Nonblocking down. */ 154 156 … … 209 211 * trydown. 210 212 */ 211 struct time val tv = { .tv_sec = 0, .tv_usec = 0 };213 struct timespec tv = { .tv_sec = 0, .tv_nsec = 0 }; 212 214 return futex_down_timeout(futex, &tv) == EOK; 213 215 } -
uspace/lib/c/generic/private/thread.h
re2625b1a rbd41ac52 49 49 extern void thread_detach(thread_id_t); 50 50 extern thread_id_t thread_get_id(void); 51 extern int thread_usleep(useconds_t);52 extern unsigned int thread_sleep(unsigned int);51 extern void thread_usleep(usec_t); 52 extern void thread_sleep(sec_t); 53 53 54 54 #endif -
uspace/lib/c/generic/rndgen.c
re2625b1a rbd41ac52 52 52 { 53 53 rndgen_t *rndgen; 54 struct time val tv;54 struct timespec ts; 55 55 56 56 rndgen = calloc(1, sizeof(rndgen_t)); … … 59 59 60 60 /* XXX This is a rather poor way of generating random numbers */ 61 get timeofday(&tv, NULL);62 rndgen->seed = t v.tv_sec ^ tv.tv_usec;61 getuptime(&ts); 62 rndgen->seed = ts.tv_sec ^ ts.tv_nsec; 63 63 64 64 *rrndgen = rndgen; -
uspace/lib/c/generic/stdlib.c
re2625b1a rbd41ac52 37 37 #include <fibril_synch.h> 38 38 #include <stdlib.h> 39 #include <errno.h> 39 40 #include "private/libc.h" 40 41 #include "private/scanf.h" -
uspace/lib/c/generic/thread/fibril.c
re2625b1a rbd41ac52 60 60 typedef struct { 61 61 link_t link; 62 struct time valexpires;62 struct timespec expires; 63 63 fibril_event_t *event; 64 64 } _timeout_t; … … 142 142 } 143 143 144 static inline errno_t _ready_down(const struct time val*expires)144 static inline errno_t _ready_down(const struct timespec *expires) 145 145 { 146 146 if (multithreaded) … … 253 253 } 254 254 255 static errno_t _ipc_wait(ipc_call_t *call, const struct time val*expires)255 static errno_t _ipc_wait(ipc_call_t *call, const struct timespec *expires) 256 256 { 257 257 if (!expires) … … 261 261 return ipc_wait(call, SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NON_BLOCKING); 262 262 263 struct time valnow;263 struct timespec now; 264 264 getuptime(&now); 265 265 266 if (t v_gteq(&now, expires))266 if (ts_gteq(&now, expires)) 267 267 return ipc_wait(call, SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NON_BLOCKING); 268 268 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); 270 271 } 271 272 … … 275 276 * wait after new ready fibrils are added. 276 277 */ 277 static fibril_t *_ready_list_pop(const struct time val*expires, bool locked)278 static fibril_t *_ready_list_pop(const struct timespec *expires, bool locked) 278 279 { 279 280 if (locked) { … … 370 371 static fibril_t *_ready_list_pop_nonblocking(bool locked) 371 372 { 372 struct time val tv = { .tv_sec = 0, .tv_usec = 0 };373 struct timespec tv = { .tv_sec = 0, .tv_nsec = 0 }; 373 374 return _ready_list_pop(&tv, locked); 374 375 } … … 393 394 394 395 /* Blocks the current fibril until an IPC call arrives. */ 395 static errno_t _wait_ipc(ipc_call_t *call, const struct time val*expires)396 static errno_t _wait_ipc(ipc_call_t *call, const struct timespec *expires) 396 397 { 397 398 futex_assert_is_not_locked(&fibril_futex); … … 430 431 431 432 /** Fire all timeouts that expired. */ 432 static struct time val *_handle_expired_timeouts(struct timeval*next_timeout)433 { 434 struct time val tv;435 getuptime(&t v);433 static struct timespec *_handle_expired_timeouts(struct timespec *next_timeout) 434 { 435 struct timespec ts; 436 getuptime(&ts); 436 437 437 438 futex_lock(&fibril_futex); … … 441 442 _timeout_t *to = list_get_instance(cur, _timeout_t, link); 442 443 443 if (t v_gt(&to->expires, &tv)) {444 if (ts_gt(&to->expires, &ts)) { 444 445 *next_timeout = to->expires; 445 446 futex_unlock(&fibril_futex); … … 535 536 (void) arg; 536 537 537 struct time valnext_timeout;538 struct timespec next_timeout; 538 539 while (true) { 539 struct time val*to = _handle_expired_timeouts(&next_timeout);540 struct timespec *to = _handle_expired_timeouts(&next_timeout); 540 541 fibril_t *f = _ready_list_pop(to, false); 541 542 if (f) { … … 615 616 _timeout_t *cur = list_get_instance(tmp, _timeout_t, link); 616 617 617 if (t v_gteq(&cur->expires, &timeout->expires))618 if (ts_gteq(&cur->expires, &timeout->expires)) 618 619 break; 619 620 … … 634 635 * @return ETIMEOUT if timed out. EOK otherwise. 635 636 */ 636 errno_t fibril_wait_timeout(fibril_event_t *event, const struct timeval *expires) 637 errno_t fibril_wait_timeout(fibril_event_t *event, 638 const struct timespec *expires) 637 639 { 638 640 assert(fibril_self()->rmutex_locks == 0); … … 889 891 } 890 892 891 void fibril_usleep( suseconds_t timeout)892 { 893 struct time valexpires;893 void fibril_usleep(usec_t timeout) 894 { 895 struct timespec expires; 894 896 getuptime(&expires); 895 t v_add_diff(&expires, timeout);897 ts_add_diff(&expires, USEC2NSEC(timeout)); 896 898 897 899 fibril_event_t event = FIBRIL_EVENT_INIT; … … 899 901 } 900 902 901 void fibril_sleep( unsigned int sec)902 { 903 struct time valexpires;903 void fibril_sleep(sec_t sec) 904 { 905 struct timespec expires; 904 906 getuptime(&expires); 905 907 expires.tv_sec += sec; … … 916 918 } 917 919 918 errno_t fibril_ipc_wait(ipc_call_t *call, const struct time val*expires)920 errno_t fibril_ipc_wait(ipc_call_t *call, const struct timespec *expires) 919 921 { 920 922 return _wait_ipc(call, expires); -
uspace/lib/c/generic/thread/fibril_synch.c
re2625b1a rbd41ac52 37 37 #include <async.h> 38 38 #include <adt/list.h> 39 #include < sys/time.h>39 #include <time.h> 40 40 #include <errno.h> 41 41 #include <assert.h> … … 390 390 errno_t 391 391 fibril_condvar_wait_timeout(fibril_condvar_t *fcv, fibril_mutex_t *fm, 392 suseconds_t timeout)392 usec_t timeout) 393 393 { 394 394 assert(fibril_mutex_is_locked(fm)); … … 400 400 wdata.mutex = fm; 401 401 402 struct time val tv;403 struct time val*expires = NULL;402 struct timespec ts; 403 struct timespec *expires = NULL; 404 404 if (timeout) { 405 getuptime(&t v);406 t v_add_diff(&tv, timeout);407 expires = &t v;405 getuptime(&ts); 406 ts_add_diff(&ts, USEC2NSEC(timeout)); 407 expires = &ts; 408 408 } 409 409 … … 557 557 * @param arg Argument for @a fun 558 558 */ 559 void fibril_timer_set(fibril_timer_t *timer, suseconds_t delay,559 void fibril_timer_set(fibril_timer_t *timer, usec_t delay, 560 560 fibril_timer_fun_t fun, void *arg) 561 561 { … … 575 575 * @param arg Argument for @a fun 576 576 */ 577 void fibril_timer_set_locked(fibril_timer_t *timer, suseconds_t delay,577 void fibril_timer_set_locked(fibril_timer_t *timer, usec_t delay, 578 578 fibril_timer_fun_t fun, void *arg) 579 579 { … … 728 728 } 729 729 730 errno_t fibril_semaphore_down_timeout(fibril_semaphore_t *sem, suseconds_t timeout)730 errno_t fibril_semaphore_down_timeout(fibril_semaphore_t *sem, usec_t timeout) 731 731 { 732 732 if (timeout < 0) … … 751 751 futex_unlock(&fibril_synch_futex); 752 752 753 struct time val tv;754 struct time val*expires = NULL;753 struct timespec ts; 754 struct timespec *expires = NULL; 755 755 if (timeout) { 756 getuptime(&t v);757 t v_add_diff(&tv, timeout);758 expires = &t v;756 getuptime(&ts); 757 ts_add_diff(&ts, USEC2NSEC(timeout)); 758 expires = &ts; 759 759 } 760 760 -
uspace/lib/c/generic/thread/mpsc.c
re2625b1a rbd41ac52 146 146 * there is no message left in the queue. 147 147 */ 148 errno_t mpsc_receive(mpsc_t *q, void *b, const struct time val*expires)148 errno_t mpsc_receive(mpsc_t *q, void *b, const struct timespec *expires) 149 149 { 150 150 mpsc_node_t *n; -
uspace/lib/c/generic/thread/thread.c
re2625b1a rbd41ac52 176 176 * 177 177 */ 178 int thread_usleep(useconds_t usec)178 void thread_usleep(usec_t usec) 179 179 { 180 180 (void) __SYSCALL1(SYS_THREAD_USLEEP, usec); 181 return 0;182 181 } 183 182 … … 185 184 * 186 185 */ 187 unsigned int thread_sleep(unsigned int sec)186 void thread_sleep(sec_t sec) 188 187 { 189 188 /* 190 * Sleep in 1000 second steps to support 191 * full argument range 189 * Sleep in 1000 second steps to support full argument range 192 190 */ 193 194 191 while (sec > 0) { 195 192 unsigned int period = (sec > 1000) ? 1000 : sec; 196 193 197 thread_usleep( period * 1000000);194 thread_usleep(SEC2USEC(period)); 198 195 sec -= period; 199 196 } 200 201 return 0;202 197 } 203 198 -
uspace/lib/c/generic/time.c
re2625b1a rbd41ac52 35 35 */ 36 36 37 #include <sys/time.h>38 37 #include <time.h> 39 38 #include <stdbool.h> … … 51 50 #include <loc.h> 52 51 #include <device/clock_dev.h> 52 #include <stats.h> 53 53 54 54 #define ASCTIME_BUF_LEN 26 … … 57 57 #define MINS_PER_HOUR 60 58 58 #define SECS_PER_MIN 60 59 #define USECS_PER_SEC 100000059 #define NSECS_PER_SEC 1000000000ll 60 60 #define MINS_PER_DAY (MINS_PER_HOUR * HOURS_PER_DAY) 61 61 #define SECS_PER_HOUR (SECS_PER_MIN * MINS_PER_HOUR) … … 71 71 static async_sess_t *clock_conn = NULL; 72 72 73 /** 74 * Get CPU time used since the process invocation. 75 * 76 * @return Consumed microseconds by this process or -1 if not available. 77 */ 78 clock_t clock(void) 79 { 80 static_assert(CLOCKS_PER_SEC == 1000000); 81 82 size_t count; 83 stats_cpu_t *cpu_stats = stats_get_cpus(&count); 84 if (!cpu_stats) 85 return (clock_t) -1; 86 if (!cpu_stats->frequency_mhz) { 87 free(cpu_stats); 88 return (clock_t) -1; 89 } 90 91 clock_t total_usecs = -1; 92 if (cpu_stats) { 93 stats_task_t *task_stats = stats_get_task(task_get_id()); 94 if (task_stats) { 95 total_usecs = (clock_t) (task_stats->kcycles + 96 task_stats->ucycles) / cpu_stats->frequency_mhz; 97 free(task_stats); 98 } 99 free(cpu_stats); 100 } 101 102 return total_usecs; 103 } 104 73 105 /** Check whether the year is a leap year. 74 106 * … … 252 284 * 253 285 * @param tm Broken-down time to normalize. 254 * @param t v Timevalto add.286 * @param ts Timespec to add. 255 287 * 256 288 * @return 0 on success, -1 on overflow 257 289 * 258 290 */ 259 static int normalize_tm_t v(struct tm *tm, const struct timeval *tv)291 static int normalize_tm_ts(struct tm *tm, const struct timespec *ts) 260 292 { 261 293 // TODO: DST correction 262 294 263 295 /* Set initial values. */ 264 time_t usec = tm->tm_usec + tv->tv_usec;265 time_t sec = tm->tm_sec + t v->tv_sec;296 time_t nsec = tm->tm_nsec + ts->tv_nsec; 297 time_t sec = tm->tm_sec + ts->tv_sec; 266 298 time_t min = tm->tm_min; 267 299 time_t hour = tm->tm_hour; … … 271 303 272 304 /* Adjust time. */ 273 sec += floor_div( usec, USECS_PER_SEC);274 usec = floor_mod(usec, USECS_PER_SEC);305 sec += floor_div(nsec, NSECS_PER_SEC); 306 nsec = floor_mod(nsec, NSECS_PER_SEC); 275 307 min += floor_div(sec, SECS_PER_MIN); 276 308 sec = floor_mod(sec, SECS_PER_MIN); … … 321 353 322 354 /* And put the values back to the struct. */ 323 tm->tm_ usec = (int) usec;355 tm->tm_nsec = (int) nsec; 324 356 tm->tm_sec = (int) sec; 325 357 tm->tm_min = (int) min; … … 340 372 static int normalize_tm_time(struct tm *tm, time_t time) 341 373 { 342 struct time val tv= {374 struct timespec ts = { 343 375 .tv_sec = time, 344 .tv_ usec = 0376 .tv_nsec = 0 345 377 }; 346 378 347 return normalize_tm_t v(tm, &tv);379 return normalize_tm_ts(tm, &ts); 348 380 } 349 381 … … 456 488 } 457 489 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) 490 static void ts_normalize(struct timespec *ts) 491 { 492 while (ts->tv_nsec >= NSECS_PER_SEC) { 493 ts->tv_sec++; 494 ts->tv_nsec -= NSECS_PER_SEC; 495 } 496 while (ts->tv_nsec < 0) { 497 ts->tv_sec--; 498 ts->tv_nsec += NSECS_PER_SEC; 499 } 500 } 501 502 /** Add nanoseconds to given timespec. 503 * 504 * @param ts Destination timespec. 505 * @param nsecs Number of nanoseconds to add. 506 * 507 */ 508 void ts_add_diff(struct timespec *ts, nsec_t nsecs) 509 { 510 ts->tv_sec += nsecs / NSECS_PER_SEC; 511 ts->tv_nsec += nsecs % NSECS_PER_SEC; 512 ts_normalize(ts); 513 } 514 515 /** Add two timespecs. 516 * 517 * @param ts1 First timespec. 518 * @param ts2 Second timespec. 519 */ 520 void ts_add(struct timespec *ts1, const struct timespec *ts2) 521 { 522 ts1->tv_sec += ts2->tv_sec; 523 ts1->tv_nsec += ts2->tv_nsec; 524 ts_normalize(ts1); 525 } 526 527 /** Subtract two timespecs. 528 * 529 * @param ts1 First timespec. 530 * @param ts2 Second timespec. 531 * 532 * @return Difference between ts1 and ts2 (ts1 - ts2) in nanoseconds. 533 * 534 */ 535 nsec_t ts_sub_diff(const struct timespec *ts1, const struct timespec *ts2) 536 { 537 return (nsec_t) (ts1->tv_nsec - ts2->tv_nsec) + 538 SEC2NSEC((ts1->tv_sec - ts2->tv_sec)); 539 } 540 541 /** Subtract two timespecs. 542 * 543 * @param ts1 First timespec. 544 * @param ts2 Second timespec. 545 * 546 */ 547 void ts_sub(struct timespec *ts1, const struct timespec *ts2) 548 { 549 ts1->tv_sec -= ts2->tv_sec; 550 ts1->tv_nsec -= ts2->tv_nsec; 551 ts_normalize(ts1); 552 } 553 554 /** Decide if one timespec is greater than the other. 555 * 556 * @param ts1 First timespec. 557 * @param ts2 Second timespec. 558 * 559 * @return True if ts1 is greater than ts2. 560 * @return False otherwise. 561 * 562 */ 563 bool ts_gt(const struct timespec *ts1, const struct timespec *ts2) 564 { 565 if (ts1->tv_sec > ts2->tv_sec) 535 566 return true; 536 567 537 if ((t v1->tv_sec == tv2->tv_sec) && (tv1->tv_usec > tv2->tv_usec))568 if ((ts1->tv_sec == ts2->tv_sec) && (ts1->tv_nsec > ts2->tv_nsec)) 538 569 return true; 539 570 … … 541 572 } 542 573 543 /** Decide if one time valis greater than or equal to the other.544 * 545 * @param t v1 First timeval.546 * @param t v2 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 (t v1->tv_sec > tv2->tv_sec)574 /** Decide if one timespec is greater than or equal to the other. 575 * 576 * @param ts1 First timespec. 577 * @param ts2 Second timespec. 578 * 579 * @return True if ts1 is greater than or equal to ts2. 580 * @return False otherwise. 581 * 582 */ 583 bool ts_gteq(const struct timespec *ts1, const struct timespec *ts2) 584 { 585 if (ts1->tv_sec > ts2->tv_sec) 555 586 return true; 556 587 557 if ((t v1->tv_sec == tv2->tv_sec) && (tv1->tv_usec >= tv2->tv_usec))588 if ((ts1->tv_sec == ts2->tv_sec) && (ts1->tv_nsec >= ts2->tv_nsec)) 558 589 return true; 559 590 … … 561 592 } 562 593 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 594 /** Get real time from a RTC service. 595 * 596 * @param[out] ts Timespec to hold time read from the RTC service (if 597 * available). If no such service exists, the returned time 598 * corresponds to system uptime. 599 */ 600 void getrealtime(struct timespec *ts) 601 { 584 602 if (clock_conn == NULL) { 585 603 category_id_t cat_id; … … 620 638 goto fallback; 621 639 622 t v->tv_usec = time.tm_usec;623 t v->tv_sec = mktime(&time);640 ts->tv_nsec = time.tm_nsec; 641 ts->tv_sec = mktime(&time); 624 642 625 643 return; 626 644 627 645 fallback: 628 getuptime(tv); 629 } 630 631 void getuptime(struct timeval *tv) 646 getuptime(ts); 647 } 648 649 /** Get system uptime. 650 * 651 * @param[out] ts Timespec to hold time current uptime. 652 * 653 * The time variables are memory mapped (read-only) from kernel which 654 * updates them periodically. 655 * 656 * As it is impossible to read 2 values atomically, we use a trick: 657 * First we read the seconds, then we read the microseconds, then we 658 * read the seconds again. If a second elapsed in the meantime, set 659 * the microseconds to zero. 660 * 661 * This assures that the values returned by two subsequent calls 662 * to getuptime() are monotonous. 663 * 664 */ 665 void getuptime(struct timespec *ts) 632 666 { 633 667 if (ktime == NULL) { … … 654 688 655 689 read_barrier(); 656 t v->tv_usec = ktime->useconds;690 ts->tv_nsec = USEC2NSEC(ktime->useconds); 657 691 658 692 read_barrier(); … … 660 694 661 695 if (s1 != s2) { 662 t v->tv_sec = max(s1, s2);663 t v->tv_usec = 0;696 ts->tv_sec = max(s1, s2); 697 ts->tv_nsec = 0; 664 698 } else 665 t v->tv_sec = s1;699 ts->tv_sec = s1; 666 700 667 701 return; 668 702 669 703 fallback: 670 t v->tv_sec = 0;671 t v->tv_usec = 0;704 ts->tv_sec = 0; 705 ts->tv_nsec = 0; 672 706 } 673 707 674 708 time_t time(time_t *tloc) 675 709 { 676 struct time val tv;677 get timeofday(&tv, NULL);710 struct timespec ts; 711 getrealtime(&ts); 678 712 679 713 if (tloc) 680 *tloc = t v.tv_sec;681 682 return t v.tv_sec;683 } 684 685 void udelay( useconds_t time)714 *tloc = ts.tv_sec; 715 716 return ts.tv_sec; 717 } 718 719 void udelay(sysarg_t time) 686 720 { 687 721 (void) __SYSCALL1(SYS_THREAD_UDELAY, (sysarg_t) time); … … 884 918 break; 885 919 case 's': 886 APPEND("%l d", secs_since_epoch(tm));920 APPEND("%lld", secs_since_epoch(tm)); 887 921 break; 888 922 case 'S': … … 961 995 962 996 /* Set result to epoch. */ 963 result->tm_ usec = 0;997 result->tm_nsec = 0; 964 998 result->tm_sec = 0; 965 999 result->tm_min = 0; … … 1038 1072 * 1039 1073 */ 1040 errno_t time_t v2tm(const struct timeval *tv, struct tm *restrict result)1074 errno_t time_ts2tm(const struct timespec *ts, struct tm *restrict result) 1041 1075 { 1042 1076 // TODO: Deal with timezones. … … 1044 1078 1045 1079 /* Set result to epoch. */ 1046 result->tm_ usec = 0;1080 result->tm_nsec = 0; 1047 1081 result->tm_sec = 0; 1048 1082 result->tm_min = 0; … … 1052 1086 result->tm_year = 70; /* 1970 */ 1053 1087 1054 if (normalize_tm_t v(result, tv) == -1)1088 if (normalize_tm_ts(result, ts) == -1) 1055 1089 return EOVERFLOW; 1056 1090 … … 1070 1104 errno_t time_local2tm(const time_t time, struct tm *restrict result) 1071 1105 { 1072 struct time val tv= {1106 struct timespec ts = { 1073 1107 .tv_sec = time, 1074 .tv_ usec = 01108 .tv_nsec = 0 1075 1109 }; 1076 1110 1077 return time_t v2tm(&tv, result);1111 return time_ts2tm(&ts, result); 1078 1112 } 1079 1113
Note:
See TracChangeset
for help on using the changeset viewer.