testUtil.c revision d2447fd2505466a8c30cdca247325f79ba95be34
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2010 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <testUtil.h>
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <assert.h>
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <math.h>
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdarg.h>
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdint.h>
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdio.h>
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdlib.h>
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <time.h>
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/time.h>
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <cutils/log.h>
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
30b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn#define ALEN(a) (sizeof(a) / sizeof(a [0]))  // Array length
31b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborntypedef unsigned int bool_t;
32b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn#define true (0 == 0)
33b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn#define false (!true)
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define MAXSTR 200
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const char *logCatTag;
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const unsigned int uSecsPerSec = 1000000;
39static const unsigned int nSecsPerSec = 1000000000;
40
41// struct timespec to double
42double ts2double(const struct timespec *val)
43{
44    double rv;
45
46    rv = val->tv_sec;
47    rv += (double) val->tv_nsec / nSecsPerSec;
48
49    return rv;
50}
51
52// struct timeval to double
53double tv2double(const struct timeval *val)
54{
55    double rv;
56
57    rv = val->tv_sec;
58    rv += (double) val->tv_usec / uSecsPerSec;
59
60    return rv;
61}
62
63// double to struct timespec
64struct timespec double2ts(double amt)
65{
66    struct timespec rv;
67
68    rv.tv_sec = floor(amt);
69    rv.tv_nsec = (amt - rv.tv_sec) * nSecsPerSec;
70    // TODO: Handle cases where amt is negative
71    while ((unsigned) rv.tv_nsec >= nSecsPerSec) {
72        rv.tv_nsec -= nSecsPerSec;
73        rv.tv_sec++;
74    }
75
76    return rv;
77}
78
79// double to struct timeval
80struct timeval double2tv(double amt)
81{
82    struct timeval rv;
83
84    rv.tv_sec = floor(amt);
85    rv.tv_usec = (amt - rv.tv_sec) * uSecsPerSec;
86    // TODO: Handle cases where amt is negative
87    while ((unsigned) rv.tv_usec >= uSecsPerSec) {
88        rv.tv_usec -= uSecsPerSec;
89        rv.tv_sec++;
90    }
91
92    return rv;
93}
94
95// Delta (difference) between two struct timespec.
96// It is expected that the time given by the structure pointed to by
97// second, is later than the time pointed to by first.
98struct timespec tsDelta(const struct timespec *first,
99                        const struct timespec *second)
100{
101    struct timespec rv;
102
103    assert(first != NULL);
104    assert(second != NULL);
105    assert(first->tv_nsec >= 0 && first->tv_nsec < nSecsPerSec);
106    assert(second->tv_nsec >= 0 && second->tv_nsec < nSecsPerSec);
107    rv.tv_sec = second->tv_sec - first->tv_sec;
108    if (second->tv_nsec >= first->tv_nsec) {
109        rv.tv_nsec = second->tv_nsec - first->tv_nsec;
110    } else {
111        rv.tv_nsec = (second->tv_nsec + nSecsPerSec) - first->tv_nsec;
112        rv.tv_sec--;
113    }
114
115    return rv;
116}
117
118// Delta (difference) between two struct timeval.
119// It is expected that the time given by the structure pointed to by
120// second, is later than the time pointed to by first.
121struct timeval tvDelta(const struct timeval *first,
122                       const struct timeval *second)
123{
124    struct timeval rv;
125
126    assert(first != NULL);
127    assert(second != NULL);
128    assert(first->tv_usec >= 0 && first->tv_usec < uSecsPerSec);
129    assert(second->tv_usec >= 0 && second->tv_usec < uSecsPerSec);
130    rv.tv_sec = second->tv_sec - first->tv_sec;
131    if (second->tv_usec >= first->tv_usec) {
132        rv.tv_usec = second->tv_usec - first->tv_usec;
133    } else {
134        rv.tv_usec = (second->tv_usec + uSecsPerSec) - first->tv_usec;
135        rv.tv_sec--;
136    }
137
138    return rv;
139}
140
141void testPrint(FILE *stream, const char *fmt, ...)
142{
143    char line[MAXSTR];
144    va_list args;
145
146    va_start(args, fmt);
147    vsnprintf(line, sizeof(line), fmt, args);
148    if (stream == stderr) {
149        LOG(LOG_ERROR, logCatTag, "%s", line);
150    } else {
151        LOG(LOG_INFO, logCatTag, "%s", line);
152    }
153    vfprintf(stream, fmt, args);
154    fputc('\n', stream);
155}
156
157// Set tag used while logging to the logcat error interface
158void testSetLogCatTag(const char *tag)
159{
160    logCatTag = tag;
161}
162
163// Obtain pointer to current log to logcat error interface tag
164const char * testGetLogCatTag(void)
165{
166    return logCatTag;
167}
168
169/*
170 * Random Boolean
171 *
172 * Pseudo randomly returns 0 (false) or 1 (true).
173 *
174 * Precondition: srand48() called to set the seed of
175 *   the pseudo random number generator.
176 */
177int testRandBool(void)
178{
179    /* Use the most significant bit from lrand48(), because the
180     * less significant bits are less random across different seeds
181     * (e.g. srand48(x) and srand48(x + n * 4) cause lrand48() to
182     * return the same sequence of least significant bits.)
183     */
184    return (lrand48() & (1U << 30)) ? 0 : 1;
185}
186
187// Delays for the number of seconds specified by amt or a greater amount.
188// The amt variable is of type float and thus non-integer amounts
189// of time can be specified.  This function automatically handles cases
190// where nanosleep(2) returns early due to reception of a signal.
191void delay(float amt)
192{
193    struct timespec   start, current, delta;
194    struct timespec   remaining;
195
196    // Get the time at which we started
197    clock_gettime(CLOCK_MONOTONIC, &start);
198
199    do {
200        // Get current time
201        clock_gettime(CLOCK_MONOTONIC, &current);
202
203        // How much time is left
204        delta = tsDelta(&start, &current);
205        if (ts2double(&delta) > amt) { break; }
206
207        // Request to sleep for the remaining time
208        remaining = double2ts(amt - ts2double(&delta));
209        (void) nanosleep(&remaining, NULL);
210    } while (true);
211}
212