00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00035 #include <sys/time.h>
00036 #include <time.h>
00037 #include <bool.h>
00038 #include <arch/barrier.h>
00039 #include <macros.h>
00040 #include <errno.h>
00041 #include <sysinfo.h>
00042 #include <as.h>
00043 #include <ddi.h>
00044 #include <libc.h>
00045
00047 struct {
00048 volatile sysarg_t seconds1;
00049 volatile sysarg_t useconds;
00050 volatile sysarg_t seconds2;
00051 } *ktime = NULL;
00052
00059 void tv_add(struct timeval *tv, suseconds_t usecs)
00060 {
00061 tv->tv_sec += usecs / 1000000;
00062 tv->tv_usec += usecs % 1000000;
00063
00064 if (tv->tv_usec > 1000000) {
00065 tv->tv_sec++;
00066 tv->tv_usec -= 1000000;
00067 }
00068 }
00069
00079 suseconds_t tv_sub(struct timeval *tv1, struct timeval *tv2)
00080 {
00081 return (tv1->tv_usec - tv2->tv_usec) +
00082 ((tv1->tv_sec - tv2->tv_sec) * 1000000);
00083 }
00084
00094 int tv_gt(struct timeval *tv1, struct timeval *tv2)
00095 {
00096 if (tv1->tv_sec > tv2->tv_sec)
00097 return true;
00098
00099 if ((tv1->tv_sec == tv2->tv_sec) && (tv1->tv_usec > tv2->tv_usec))
00100 return true;
00101
00102 return false;
00103 }
00104
00114 int tv_gteq(struct timeval *tv1, struct timeval *tv2)
00115 {
00116 if (tv1->tv_sec > tv2->tv_sec)
00117 return true;
00118
00119 if ((tv1->tv_sec == tv2->tv_sec) && (tv1->tv_usec >= tv2->tv_usec))
00120 return true;
00121
00122 return false;
00123 }
00124
00139 int gettimeofday(struct timeval *tv, struct timezone *tz)
00140 {
00141 if (ktime == NULL) {
00142 uintptr_t faddr;
00143 int rc = sysinfo_get_value("clock.faddr", &faddr);
00144 if (rc != EOK) {
00145 errno = rc;
00146 return -1;
00147 }
00148
00149 void *addr = as_get_mappable_page(PAGE_SIZE);
00150 if (addr == NULL) {
00151 errno = ENOMEM;
00152 return -1;
00153 }
00154
00155 rc = physmem_map((void *) faddr, addr, 1,
00156 AS_AREA_READ | AS_AREA_CACHEABLE);
00157 if (rc != EOK) {
00158 as_area_destroy(addr);
00159 errno = rc;
00160 return -1;
00161 }
00162
00163 ktime = addr;
00164 }
00165
00166 if (tz) {
00167 tz->tz_minuteswest = 0;
00168 tz->tz_dsttime = DST_NONE;
00169 }
00170
00171 sysarg_t s2 = ktime->seconds2;
00172
00173 read_barrier();
00174 tv->tv_usec = ktime->useconds;
00175
00176 read_barrier();
00177 sysarg_t s1 = ktime->seconds1;
00178
00179 if (s1 != s2) {
00180 tv->tv_sec = max(s1, s2);
00181 tv->tv_usec = 0;
00182 } else
00183 tv->tv_sec = s1;
00184
00185 return 0;
00186 }
00187
00188 time_t time(time_t *tloc)
00189 {
00190 struct timeval tv;
00191 if (gettimeofday(&tv, NULL))
00192 return (time_t) -1;
00193
00194 if (tloc)
00195 *tloc = tv.tv_sec;
00196
00197 return tv.tv_sec;
00198 }
00199
00203 int usleep(useconds_t usec)
00204 {
00205 (void) __SYSCALL1(SYS_THREAD_USLEEP, usec);
00206 return 0;
00207 }
00208
00209 void udelay(useconds_t time)
00210 {
00211 (void) __SYSCALL1(SYS_THREAD_UDELAY, (sysarg_t) time);
00212 }
00213
00214
00218 unsigned int sleep(unsigned int sec)
00219 {
00220
00221
00222
00223
00224
00225 while (sec > 0) {
00226 unsigned int period = (sec > 1000) ? 1000 : sec;
00227
00228 usleep(period * 1000000);
00229 sec -= period;
00230 }
00231
00232 return 0;
00233 }
00234