1c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman/* 2c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman * Copyright (C) 2012 The Android Open Source Project 3c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman * 4c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman * Licensed under the Apache License, Version 2.0 (the "License"); 5c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman * you may not use this file except in compliance with the License. 6c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman * You may obtain a copy of the License at 7c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman * 8c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman * http://www.apache.org/licenses/LICENSE-2.0 9c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman * 10c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman * Unless required by applicable law or agreed to in writing, software 11c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman * distributed under the License is distributed on an "AS IS" BASIS, 12c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman * See the License for the specific language governing permissions and 14c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman * limitations under the License. 15c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman */ 16c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman 1779489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman#define LOG_TAG "common_time" 1879489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman#include <utils/Log.h> 1979489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman 20c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman#include "utils.h" 21c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman 22c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossmannamespace android { 23c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman 24c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossmanvoid Timeout::setTimeout(int msec) { 25c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman if (msec < 0) { 26c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman mSystemEndTime = 0; 27c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman return; 28c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman } 29c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman 30c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman mSystemEndTime = systemTime() + (static_cast<nsecs_t>(msec) * 1000000); 31c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman} 32c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman 33c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossmanint Timeout::msecTillTimeout(nsecs_t nowTime) { 34c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman if (!mSystemEndTime) { 35c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman return -1; 36c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman } 37c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman 38c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman if (mSystemEndTime < nowTime) { 39c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman return 0; 40c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman } 41c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman 42c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman nsecs_t delta = mSystemEndTime - nowTime; 43c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman delta += 999999; 44c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman delta /= 1000000; 45c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman if (delta > 0x7FFFFFFF) { 46c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman return 0x7FFFFFFF; 47c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman } 48c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman 49c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman return static_cast<int>(delta); 50c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman} 51c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman 5279489c4c65d3c8e628991995b4a18f2a81802ee6John GrossmanLogRing::LogRing(const char* header, size_t entries) 5379489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman : mSize(entries) 5479489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman , mWr(0) 5579489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman , mIsFull(false) 5679489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman , mHeader(header) { 5779489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman mRingBuffer = new Entry[mSize]; 5879489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman if (NULL == mRingBuffer) 59f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat ALOGE("Failed to allocate log ring with %zu entries.", mSize); 6079489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman} 6179489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman 6279489c4c65d3c8e628991995b4a18f2a81802ee6John GrossmanLogRing::~LogRing() { 6379489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman if (NULL != mRingBuffer) 6479489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman delete[] mRingBuffer; 6579489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman} 6679489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman 6779489c4c65d3c8e628991995b4a18f2a81802ee6John Grossmanvoid LogRing::log(int prio, const char* tag, const char* fmt, ...) { 6879489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman va_list argp; 6979489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman va_start(argp, fmt); 7079489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman internalLog(prio, tag, fmt, argp); 7179489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman va_end(argp); 7279489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman} 7379489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman 7479489c4c65d3c8e628991995b4a18f2a81802ee6John Grossmanvoid LogRing::log(const char* fmt, ...) { 7579489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman va_list argp; 7679489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman va_start(argp, fmt); 7779489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman internalLog(0, NULL, fmt, argp); 7879489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman va_end(argp); 7979489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman} 8079489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman 8179489c4c65d3c8e628991995b4a18f2a81802ee6John Grossmanvoid LogRing::internalLog(int prio, 8279489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman const char* tag, 8379489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman const char* fmt, 8479489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman va_list argp) { 8579489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman if (NULL != mRingBuffer) { 8679489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman Mutex::Autolock lock(&mLock); 8779489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman String8 s(String8::formatV(fmt, argp)); 8879489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman Entry* last = NULL; 8979489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman 9079489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman if (mIsFull || mWr) 9179489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman last = &(mRingBuffer[(mWr + mSize - 1) % mSize]); 9279489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman 9379489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman 9479489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman if ((NULL != last) && !last->s.compare(s)) { 9579489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman gettimeofday(&(last->last_ts), NULL); 9679489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman ++last->count; 9779489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman } else { 9879489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman gettimeofday(&mRingBuffer[mWr].first_ts, NULL); 9979489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman mRingBuffer[mWr].last_ts = mRingBuffer[mWr].first_ts; 10079489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman mRingBuffer[mWr].count = 1; 10179489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman mRingBuffer[mWr].s.setTo(s); 10279489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman 10379489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman mWr = (mWr + 1) % mSize; 10479489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman if (!mWr) 10579489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman mIsFull = true; 10679489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman } 10779489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman } 10879489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman 10979489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman if (NULL != tag) 11079489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman LOG_PRI_VA(prio, tag, fmt, argp); 11179489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman} 11279489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman 11379489c4c65d3c8e628991995b4a18f2a81802ee6John Grossmanvoid LogRing::dumpLog(int fd) { 11479489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman if (NULL == mRingBuffer) 11579489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman return; 11679489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman 11779489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman Mutex::Autolock lock(&mLock); 11879489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman 11979489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman if (!mWr && !mIsFull) 12079489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman return; 12179489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman 12279489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman char buf[1024]; 12379489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman int res; 12479489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman size_t start = mIsFull ? mWr : 0; 12579489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman size_t count = mIsFull ? mSize : mWr; 12679489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman static const char* kTimeFmt = "%a %b %d %Y %H:%M:%S"; 12779489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman 12879489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman res = snprintf(buf, sizeof(buf), "\n%s\n", mHeader); 12979489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman if (res > 0) 13079489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman write(fd, buf, res); 13179489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman 13279489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman for (size_t i = 0; i < count; ++i) { 13379489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman struct tm t; 13479489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman char timebuf[64]; 13579489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman char repbuf[96]; 13679489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman size_t ndx = (start + i) % mSize; 13779489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman 13879489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman if (1 != mRingBuffer[ndx].count) { 13979489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman localtime_r(&mRingBuffer[ndx].last_ts.tv_sec, &t); 14079489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman strftime(timebuf, sizeof(timebuf), kTimeFmt, &t); 14179489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman snprintf(repbuf, sizeof(repbuf), 14279489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman " (repeated %d times, last was %s.%03ld)", 14379489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman mRingBuffer[ndx].count, 14479489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman timebuf, 14579489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman mRingBuffer[ndx].last_ts.tv_usec / 1000); 14679489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman repbuf[sizeof(repbuf) - 1] = 0; 14779489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman } else { 14879489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman repbuf[0] = 0; 14979489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman } 15079489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman 15179489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman localtime_r(&mRingBuffer[ndx].first_ts.tv_sec, &t); 15279489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman strftime(timebuf, sizeof(timebuf), kTimeFmt, &t); 153f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat res = snprintf(buf, sizeof(buf), "[%2zu] %s.%03ld :: %s%s\n", 15479489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman i, timebuf, 15579489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman mRingBuffer[ndx].first_ts.tv_usec / 1000, 15679489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman mRingBuffer[ndx].s.string(), 15779489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman repbuf); 15879489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman 15979489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman if (res > 0) 16079489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman write(fd, buf, res); 16179489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman } 16279489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman} 16379489c4c65d3c8e628991995b4a18f2a81802ee6John Grossman 164c7f57c6f9289d0e3aaecc0bca4ae7b6eed1c93d7John Grossman} // namespace android 165