2 * Copyright (C) 2012 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #define LOG_TAG "common_time"
18 #include <utils/Log.h>
24 void Timeout::setTimeout(int msec) {
30 mSystemEndTime = systemTime() + (static_cast<nsecs_t>(msec) * 1000000);
33 int Timeout::msecTillTimeout(nsecs_t nowTime) {
34 if (!mSystemEndTime) {
38 if (mSystemEndTime < nowTime) {
42 nsecs_t delta = mSystemEndTime - nowTime;
45 if (delta > 0x7FFFFFFF) {
49 return static_cast<int>(delta);
52 LogRing::LogRing(const char* header, size_t entries)
57 mRingBuffer = new Entry[mSize];
58 if (NULL == mRingBuffer)
59 ALOGE("Failed to allocate log ring with %u entries.", mSize);
63 if (NULL != mRingBuffer)
67 void LogRing::log(int prio, const char* tag, const char* fmt, ...) {
70 internalLog(prio, tag, fmt, argp);
74 void LogRing::log(const char* fmt, ...) {
77 internalLog(0, NULL, fmt, argp);
81 void LogRing::internalLog(int prio,
85 if (NULL != mRingBuffer) {
86 Mutex::Autolock lock(&mLock);
87 String8 s(String8::formatV(fmt, argp));
91 last = &(mRingBuffer[(mWr + mSize - 1) % mSize]);
94 if ((NULL != last) && !last->s.compare(s)) {
95 gettimeofday(&(last->last_ts), NULL);
98 gettimeofday(&mRingBuffer[mWr].first_ts, NULL);
99 mRingBuffer[mWr].last_ts = mRingBuffer[mWr].first_ts;
100 mRingBuffer[mWr].count = 1;
101 mRingBuffer[mWr].s.setTo(s);
103 mWr = (mWr + 1) % mSize;
110 LOG_PRI_VA(prio, tag, fmt, argp);
113 void LogRing::dumpLog(int fd) {
114 if (NULL == mRingBuffer)
117 Mutex::Autolock lock(&mLock);
119 if (!mWr && !mIsFull)
124 size_t start = mIsFull ? mWr : 0;
125 size_t count = mIsFull ? mSize : mWr;
126 static const char* kTimeFmt = "%a %b %d %Y %H:%M:%S";
128 res = snprintf(buf, sizeof(buf), "\n%s\n", mHeader);
132 for (size_t i = 0; i < count; ++i) {
136 size_t ndx = (start + i) % mSize;
138 if (1 != mRingBuffer[ndx].count) {
139 localtime_r(&mRingBuffer[ndx].last_ts.tv_sec, &t);
140 strftime(timebuf, sizeof(timebuf), kTimeFmt, &t);
141 snprintf(repbuf, sizeof(repbuf),
142 " (repeated %d times, last was %s.%03ld)",
143 mRingBuffer[ndx].count,
145 mRingBuffer[ndx].last_ts.tv_usec / 1000);
146 repbuf[sizeof(repbuf) - 1] = 0;
151 localtime_r(&mRingBuffer[ndx].first_ts.tv_sec, &t);
152 strftime(timebuf, sizeof(timebuf), kTimeFmt, &t);
153 res = snprintf(buf, sizeof(buf), "[%2d] %s.%03ld :: %s%s\n",
155 mRingBuffer[ndx].first_ts.tv_usec / 1000,
156 mRingBuffer[ndx].s.string(),
164 } // namespace android