testUtil.c revision 87dd9e92610d5e7552f5cdb6ab2578035e2210f5
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 * 16 */ 17 18#include <testUtil.h> 19 20#include <assert.h> 21#include <math.h> 22#include <stdarg.h> 23#include <stdint.h> 24#include <stdio.h> 25#include <stdlib.h> 26#include <time.h> 27#include <sys/time.h> 28#include <cutils/log.h> 29 30#define ALEN(a) (sizeof(a) / sizeof(a [0])) // Array length 31typedef unsigned int bool_t; 32#define true (0 == 0) 33#define false (!true) 34 35#define MAXSTR 200 36static const char *logCatTag; 37 38// struct timeval to double 39double 40tv2double(const struct timeval *val) 41{ 42 const unsigned int uSecsPerSec = 1000000; 43 double rv; 44 45 rv = val->tv_sec; 46 rv += (double) val->tv_usec / uSecsPerSec; 47 48 return rv; 49} 50 51// double to struct timespec 52struct timespec 53double2ts(double amt) 54{ 55 const unsigned int nSecsPerSec = 1000000000; 56 struct timespec rv; 57 58 rv.tv_sec = floor(amt); 59 rv.tv_nsec = (amt - rv.tv_sec) * nSecsPerSec; 60 // TODO: Handle cases where amt is negative 61 while ((unsigned) rv.tv_nsec >= nSecsPerSec) { 62 rv.tv_nsec -= nSecsPerSec; 63 rv.tv_sec++; 64 } 65 66 return rv; 67} 68 69// Delta (difference) between two struct timeval. 70// It is expected that the time given by the structure pointed to by 71// second, is later than the time pointed to by first. 72struct timeval 73tvDelta(const struct timeval *first, 74 const struct timeval *second) 75{ 76 const unsigned int uSecsPerSec = 1000000; 77 struct timeval rv; 78 79 assert(first != NULL); 80 assert(second != NULL); 81 assert(first->tv_usec >= 0 && first->tv_usec < uSecsPerSec); 82 assert(second->tv_usec >= 0 && second->tv_usec < uSecsPerSec); 83 rv.tv_sec = second->tv_sec - first->tv_sec; 84 if (second->tv_usec >= first->tv_usec) { 85 rv.tv_usec = second->tv_usec - first->tv_usec; 86 } else { 87 rv.tv_usec = (second->tv_usec + uSecsPerSec) - first->tv_usec; 88 rv.tv_sec--; 89 } 90 91 return rv; 92} 93 94void 95testPrint(FILE *stream, const char *fmt, ...) 96{ 97 char line[MAXSTR]; 98 va_list args; 99 100 va_start(args, fmt); 101 vsnprintf(line, sizeof(line), fmt, args); 102 if (stream == stderr) { 103 LOG(LOG_ERROR, logCatTag, "%s", line); 104 } else { 105 LOG(LOG_INFO, logCatTag, "%s", line); 106 } 107 vfprintf(stream, fmt, args); 108 fputc('\n', stream); 109} 110 111// Set tag used while logging to the logcat error interface 112void 113testSetLogCatTag(const char *tag) 114{ 115 logCatTag = tag; 116} 117 118// Obtain pointer to current log to logcat error interface tag 119const char * 120testGetLogCatTag(void) 121{ 122 return logCatTag; 123} 124 125/* 126 * Random Boolean 127 * 128 * Pseudo randomly returns 0 (false) or 1 (true). 129 * 130 * Precondition: srand48() called to set the seed of 131 * the pseudo random number generator. 132 */ 133int 134testRandBool(void) 135{ 136 /* Use the most significant bit from lrand48(), because the 137 * less significant bits are less random across different seeds 138 * (e.g. srand48(x) and srand48(x + n * 4) cause lrand48() to 139 * return the same sequence of least significant bits.) 140 */ 141 return (lrand48() & (1U << 30)) ? 0 : 1; 142} 143 144// Delays for the number of seconds specified by amt or a greater amount. 145// The amt variable is of type float and thus non-integer amounts 146// of time can be specified. This function automatically handles cases 147// where nanosleep(2) returns early due to reception of a signal. 148void 149delay(float amt) 150{ 151 struct timeval start, current, delta; 152 struct timespec remaining; 153 154 // Get the time at which we started 155 gettimeofday(&start, NULL); 156 157 do { 158 // Get current time 159 gettimeofday(¤t, NULL); 160 161 // How much time is left 162 delta = tvDelta(&start, ¤t); 163 if (tv2double(&delta) > amt) { break; } 164 165 // Request to sleep for the remaining time 166 remaining = double2ts(amt - tv2double(&delta)); 167 (void) nanosleep(&remaining, NULL); 168 } while (true); 169} 170