1 /* Copyright (c) 2012 The Chromium OS Authors. All rights reserved. 2 * Use of this source code is governed by a BSD-style license that can be 3 * found in the LICENSE file. 4 */ 5 6 #ifndef CRAS_UTIL_H_ 7 #define CRAS_UTIL_H_ 8 9 #ifdef __cplusplus 10 extern "C" { 11 #endif 12 13 #include <poll.h> 14 #include <time.h> 15 16 #include "cras_types.h" 17 18 #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) 19 20 #define assert_on_compile(e) ((void)sizeof(char[1 - 2 * !(e)])) 21 #define assert_on_compile_is_power_of_2(n) \ 22 assert_on_compile((n) != 0 && (((n) & ((n) - 1)) == 0)) 23 24 /* Enables real time scheduling. */ 25 int cras_set_rt_scheduling(int rt_lim); 26 /* Sets the priority. */ 27 int cras_set_thread_priority(int priority); 28 /* Sets the niceness level of the current thread. */ 29 int cras_set_nice_level(int nice); 30 31 /* Converts a buffer level from one sample rate to another. */ 32 static inline size_t cras_frames_at_rate(size_t orig_rate, size_t orig_frames, 33 size_t act_rate) 34 { 35 return (orig_frames * act_rate + orig_rate - 1) / orig_rate; 36 } 37 38 /* Converts a number of frames to a time in a timespec. */ 39 static inline void cras_frames_to_time(unsigned int frames, 40 unsigned int rate, 41 struct timespec *t) 42 { 43 t->tv_sec = frames / rate; 44 frames = frames % rate; 45 t->tv_nsec = (uint64_t)frames * 1000000000 / rate; 46 } 47 48 /* Converts a number of frames to a time in a timespec. */ 49 static inline void cras_frames_to_time_precise(unsigned int frames, 50 double rate, 51 struct timespec *t) 52 { 53 double seconds = frames / rate; 54 t->tv_sec = (unsigned int)seconds; 55 seconds -= t->tv_sec; 56 t->tv_nsec = (unsigned int)(seconds * 1000000000); 57 } 58 59 /* Converts a timespec duration to a frame count. */ 60 static inline unsigned int cras_time_to_frames(const struct timespec *t, 61 unsigned int rate) 62 { 63 return t->tv_nsec * (uint64_t)rate / 1000000000 + rate * t->tv_sec; 64 } 65 66 /* Converts a number of frames to a duration in ms. */ 67 static inline unsigned int cras_frames_to_ms(unsigned int frames, 68 unsigned int rate) 69 { 70 return 1000 * frames / rate; 71 } 72 73 /* Makes a file descriptor non blocking. */ 74 int cras_make_fd_nonblocking(int fd); 75 76 /* Makes a file descriptor blocking. */ 77 int cras_make_fd_blocking(int fd); 78 79 /* Send data in buf to the socket attach the fds. */ 80 int cras_send_with_fds(int sockfd, const void *buf, size_t len, int *fd, 81 unsigned int num_fds); 82 83 /* Receive data in buf from the socket. If file descriptors are received, put 84 * them in *fd, otherwise set *fd to -1. */ 85 int cras_recv_with_fds(int sockfd, void *buf, size_t len, int *fd, 86 unsigned int *num_fds); 87 88 /* This must be written a million times... */ 89 static inline void subtract_timespecs(const struct timespec *end, 90 const struct timespec *beg, 91 struct timespec *diff) 92 { 93 diff->tv_sec = end->tv_sec - beg->tv_sec; 94 diff->tv_nsec = end->tv_nsec - beg->tv_nsec; 95 96 /* Adjust tv_sec and tv_nsec to the same sign. */ 97 if (diff->tv_sec > 0 && diff->tv_nsec < 0) { 98 diff->tv_sec--; 99 diff->tv_nsec += 1000000000L; 100 } else if (diff->tv_sec < 0 && diff->tv_nsec > 0) { 101 diff->tv_sec++; 102 diff->tv_nsec -= 1000000000L; 103 } 104 } 105 106 static inline void add_timespecs(struct timespec *a, 107 const struct timespec *b) 108 { 109 a->tv_sec += b->tv_sec; 110 a->tv_nsec += b->tv_nsec; 111 112 while (a->tv_nsec >= 1000000000L) { 113 a->tv_sec++; 114 a->tv_nsec -= 1000000000L; 115 } 116 } 117 118 /* Converts a fixed-size cras_timespec to a native timespec */ 119 static inline void cras_timespec_to_timespec(struct timespec *dest, 120 const struct cras_timespec *src) 121 { 122 dest->tv_sec = src->tv_sec; 123 dest->tv_nsec = src->tv_nsec; 124 } 125 126 /* Fills a fixed-size cras_timespec with the current system time */ 127 static inline int cras_clock_gettime(clockid_t clk_id, 128 struct cras_timespec *ctp) 129 { 130 struct timespec tp; 131 int ret = clock_gettime(clk_id, &tp); 132 ctp->tv_sec = tp.tv_sec; 133 ctp->tv_nsec = tp.tv_nsec; 134 return ret; 135 } 136 137 /* Returns true if timeval a is after timeval b */ 138 static inline int timeval_after(const struct timeval *a, 139 const struct timeval *b) 140 { 141 return (a->tv_sec > b->tv_sec) || 142 (a->tv_sec == b->tv_sec && a->tv_usec > b->tv_usec); 143 } 144 145 /* Returns true if timespec a is after timespec b */ 146 static inline int timespec_after(const struct timespec *a, 147 const struct timespec *b) 148 { 149 return (a->tv_sec > b->tv_sec) || 150 (a->tv_sec == b->tv_sec && a->tv_nsec > b->tv_nsec); 151 } 152 153 /* Retruns the equivalent number of milliseconds for a given timespec. 154 * The result is rounded up to the next millisecond. */ 155 static inline unsigned int timespec_to_ms(const struct timespec *ts) 156 { 157 return ts->tv_sec * 1000 + (ts->tv_nsec + 999999) / 1000000; 158 } 159 160 /* Convert milliseconds to timespec. */ 161 static inline void ms_to_timespec(time_t milliseconds, struct timespec *ts) 162 { 163 ts->tv_sec = milliseconds / 1000; 164 ts->tv_nsec = (milliseconds % 1000) * 1000000; 165 } 166 167 /* Returns non-zero if the given timespec is non-zero. */ 168 static inline int timespec_is_nonzero(const struct timespec *ts) { 169 return ts && (ts->tv_sec != 0 || 170 (ts->tv_sec == 0 && ts->tv_nsec != 0)); 171 } 172 173 /* Calculates frames since time beg. */ 174 static inline unsigned int cras_frames_since_time(const struct timespec *beg, 175 unsigned int rate) 176 { 177 struct timespec now, time_since; 178 179 clock_gettime(CLOCK_MONOTONIC_RAW, &now); 180 if (!timespec_after(&now, beg)) 181 return 0; 182 183 subtract_timespecs(&now, beg, &time_since); 184 return cras_time_to_frames(&time_since, rate); 185 } 186 187 /* Poll on the given file descriptors. 188 * 189 * See ppoll(). This implementation changes the value of timeout to the 190 * remaining time, and returns negative error codes on error. 191 * 192 * Args: 193 * fds - Array of pollfd structures. 194 * nfds - Number of pollfd structures. 195 * timeout - Timeout time updated upon return with remaining time. The 196 * timeout value may be updated to become invalid (negative 197 * tv_nsec or negative tv_sec). In that case, -tv_nsec is the 198 * number of nanoseconds by which the polling exceeded the 199 * supplied timeout. The function immediately returns with 200 * -ETIMEOUT if tv_nsec is negative, simplifying loops that 201 * rely on the returned remaining timeout. 202 * sigmask - Signal mask while in the poll. 203 * 204 * Returns: 205 * Positive when file decriptors are ready. 206 * Zero if no file descriptors are ready and timeout is NULL. 207 * -ETIMEDOUT when no file descriptors are ready and a timeout specified. 208 * Other negative error codes specified in the ppoll() man page. 209 */ 210 int cras_poll(struct pollfd *fds, nfds_t nfds, struct timespec *timeout, 211 const sigset_t *sigmask); 212 213 /* Wait for /dev/input/event* files to become accessible. 214 * 215 * Returns: 216 * Zero on success. Otherwise a negative error code. 217 */ 218 int wait_for_dev_input_access(); 219 220 #ifdef __cplusplus 221 } /* extern "C" */ 222 #endif 223 224 #endif /* CRAS_UTIL_H_ */ 225