Changeset 2c577e0b in mainline
- Timestamp:
- 2011-01-29T11:29:35Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 64d2b10
- Parents:
- 9c81703
- Location:
- uspace/lib/c
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/ipc/ns.c
r9c81703 r2c577e0b 79 79 } 80 80 81 void *service_realtime_share_in(void) 82 { 83 void *rtime = as_get_mappable_page(PAGE_SIZE); 84 if (rtime == NULL) 85 return NULL; 86 87 int res = async_share_in_start_1_0(PHONE_NS, rtime, PAGE_SIZE, 88 SERVICE_MEM_REALTIME); 89 if (res != EOK) { 90 as_area_destroy((void *) rtime); 91 return NULL; 92 } 93 94 return rtime; 95 } 96 81 97 /** @} 82 98 */ -
uspace/lib/c/generic/time.c
r9c81703 r2c577e0b 35 35 #include <sys/time.h> 36 36 #include <unistd.h> 37 #include < ipc/ipc.h>38 #include < stdio.h>37 #include <bool.h> 38 #include <ipc/ns.h> 39 39 #include <arch/barrier.h> 40 #include <unistd.h> 41 #include <atomic.h> 42 #include <sysinfo.h> 43 #include <ipc/services.h> 40 #include <macros.h> 44 41 #include <libc.h> 45 46 #include <sysinfo.h>47 #include <as.h>48 #include <ddi.h>49 50 42 #include <time.h> 51 43 52 /* Pointers to publicvariables with time */44 /** Pointer to kernel shared variables with time */ 53 45 struct { 54 46 volatile sysarg_t seconds1; … … 59 51 /** Add microseconds to given timeval. 60 52 * 61 * @param tv Destination timeval. 62 * @param usecs Number of microseconds to add. 53 * @param tv Destination timeval. 54 * @param usecs Number of microseconds to add. 55 * 63 56 */ 64 57 void tv_add(struct timeval *tv, suseconds_t usecs) … … 66 59 tv->tv_sec += usecs / 1000000; 67 60 tv->tv_usec += usecs % 1000000; 61 68 62 if (tv->tv_usec > 1000000) { 69 63 tv->tv_sec++; … … 74 68 /** Subtract two timevals. 75 69 * 76 * @param tv1 First timeval. 77 * @param tv2 Second timeval. 78 * 79 * @return Return difference between tv1 and tv2 (tv1 - tv2) in 80 * microseconds. 70 * @param tv1 First timeval. 71 * @param tv2 Second timeval. 72 * 73 * @return Difference between tv1 and tv2 (tv1 - tv2) in 74 * microseconds. 75 * 81 76 */ 82 77 suseconds_t tv_sub(struct timeval *tv1, struct timeval *tv2) 83 78 { 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; 79 return (tv1->tv_usec - tv2->tv_usec) + 80 ((tv1->tv_sec - tv2->tv_sec) * 1000000); 90 81 } 91 82 92 83 /** Decide if one timeval is greater than the other. 93 84 * 94 * @param t1 First timeval. 95 * @param t2 Second timeval. 96 * 97 * @return Return true tv1 is greater than tv2. Otherwise return 98 * false. 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 * 99 91 */ 100 92 int tv_gt(struct timeval *tv1, struct timeval *tv2) 101 93 { 102 94 if (tv1->tv_sec > tv2->tv_sec) 103 return 1; 104 if (tv1->tv_sec == tv2->tv_sec && tv1->tv_usec > tv2->tv_usec) 105 return 1; 106 return 0; 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; 107 101 } 108 102 109 103 /** Decide if one timeval is greater than or equal to the other. 110 104 * 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. 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 * 116 111 */ 117 112 int tv_gteq(struct timeval *tv1, struct timeval *tv2) 118 113 { 119 114 if (tv1->tv_sec > tv2->tv_sec) 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. 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 * 135 136 */ 136 137 int gettimeofday(struct timeval *tv, struct timezone *tz) 137 138 { 138 void *mapping;139 sysarg_t s1, s2;140 int rights;141 int res;142 143 139 if (!ktime) { 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 } 140 ktime = service_realtime_share_in(); 141 if (!ktime) 142 return -1; 143 } 144 160 145 if (tz) { 161 146 tz->tz_minuteswest = 0; 162 147 tz->tz_dsttime = DST_NONE; 163 148 } 164 165 s2 = ktime->seconds2; 149 150 sysarg_t s2 = ktime->seconds2; 151 166 152 read_barrier(); 167 153 tv->tv_usec = ktime->useconds; 154 168 155 read_barrier(); 169 s1 = ktime->seconds1; 156 sysarg_t s1 = ktime->seconds1; 157 170 158 if (s1 != s2) { 159 tv->tv_sec = max(s1, s2); 171 160 tv->tv_usec = 0; 172 tv->tv_sec = s1 > s2 ? s1 : s2;173 161 } else 174 162 tv->tv_sec = s1; 175 163 176 164 return 0; 177 165 } … … 180 168 { 181 169 struct timeval tv; 182 183 170 if (gettimeofday(&tv, NULL)) 184 171 return (time_t) -1; 172 185 173 if (tloc) 186 174 *tloc = tv.tv_sec; 175 187 176 return tv.tv_sec; 188 177 } 189 178 190 /** Wait unconditionally for specified number of microseconds */ 179 /** Wait unconditionally for specified number of microseconds 180 * 181 */ 191 182 int usleep(useconds_t usec) 192 183 { … … 195 186 } 196 187 197 /** Wait unconditionally for specified number of seconds */ 188 /** Wait unconditionally for specified number of seconds 189 * 190 */ 198 191 unsigned int sleep(unsigned int sec) 199 192 { 200 /* Sleep in 1000 second steps to support 201 full argument range */ 193 /* 194 * Sleep in 1000 second steps to support 195 * full argument range 196 */ 197 202 198 while (sec > 0) { 203 199 unsigned int period = (sec > 1000) ? 1000 : sec; 204 200 205 201 usleep(period * 1000000); 206 202 sec -= period; 207 203 } 204 208 205 return 0; 209 206 } -
uspace/lib/c/include/ipc/ns.h
r9c81703 r2c577e0b 37 37 38 38 #include <sys/types.h> 39 #include <ipc/ ipc.h>39 #include <ipc/common.h> 40 40 41 41 typedef enum { … … 51 51 52 52 extern wchar_t *service_klog_share_in(size_t *); 53 extern void *service_realtime_share_in(void); 53 54 54 55 #endif -
uspace/lib/c/include/ipc/services.h
r9c81703 r2c577e0b 66 66 } services_t; 67 67 68 /* Memory area to be received from NS */ 69 #define SERVICE_MEM_REALTIME 1 70 #define SERVICE_MEM_KLOG 2 68 /* Memory areas to be received from NS */ 69 typedef enum { 70 SERVICE_MEM_REALTIME = 1, 71 SERVICE_MEM_KLOG = 2 72 } mem_services_t; 71 73 72 74 #endif
Note:
See TracChangeset
for help on using the changeset viewer.