1/*
2 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
4 *  Use of this source code is governed by a BSD-style license
5 *  that can be found in the LICENSE file in the root of the source
6 *  tree. An additional intellectual property rights grant can be found
7 *  in the file PATENTS.  All contributing project authors may
8 *  be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "trace_posix.h"
12
13#include <cassert>
14#include <stdarg.h>
15#include <stdio.h>
16#include <string.h>
17#include <sys/time.h>
18#include <time.h>
19#ifdef WEBRTC_ANDROID
20    #include <pthread.h>
21#else
22    #include <iostream>
23#endif
24
25#if defined(_DEBUG)
26    #define BUILDMODE "d"
27#elif defined(DEBUG)
28    #define BUILDMODE "d"
29#elif defined(NDEBUG)
30    #define BUILDMODE "r"
31#else
32    #define BUILDMODE "?"
33#endif
34#define BUILDTIME __TIME__
35#define BUILDDATE __DATE__
36// example: "Oct 10 2002 12:05:30 r"
37#define BUILDINFO BUILDDATE " " BUILDTIME " " BUILDMODE
38
39namespace webrtc {
40TracePosix::TracePosix()
41{
42    struct timeval systemTimeHighRes;
43    gettimeofday(&systemTimeHighRes, 0);
44    _prevAPITickCount = _prevTickCount = systemTimeHighRes.tv_sec;
45}
46
47TracePosix::~TracePosix()
48{
49    StopThread();
50}
51
52WebRtc_Word32 TracePosix::AddTime(char* traceMessage,
53                                  const TraceLevel level) const
54{
55    struct timeval systemTimeHighRes;
56    if (gettimeofday(&systemTimeHighRes, 0) == -1)
57    {
58        return -1;
59    }
60    struct tm buffer;
61    const struct tm* systemTime =
62        localtime_r(&systemTimeHighRes.tv_sec, &buffer);
63
64    const WebRtc_UWord32 ms_time = systemTimeHighRes.tv_usec / 1000;
65    WebRtc_UWord32 prevTickCount = 0;
66    if (level == kTraceApiCall)
67    {
68        prevTickCount = _prevTickCount;
69        _prevTickCount = ms_time;
70    } else {
71        prevTickCount = _prevAPITickCount;
72        _prevAPITickCount = ms_time;
73    }
74    WebRtc_UWord32 dwDeltaTime = ms_time - prevTickCount;
75    if (prevTickCount == 0)
76    {
77        dwDeltaTime = 0;
78    }
79    if (dwDeltaTime > 0x0fffffff)
80    {
81        // Either wraparound or data race.
82        dwDeltaTime = 0;
83    }
84    if(dwDeltaTime > 99999)
85    {
86        dwDeltaTime = 99999;
87    }
88
89    sprintf(traceMessage, "(%2u:%2u:%2u:%3u |%5lu) ", systemTime->tm_hour,
90            systemTime->tm_min, systemTime->tm_sec, ms_time,
91            static_cast<unsigned long>(dwDeltaTime));
92    // Messages are 22 characters.
93    return 22;
94}
95
96WebRtc_Word32 TracePosix::AddBuildInfo(char* traceMessage) const
97{
98    sprintf(traceMessage, "Build info: %s", BUILDINFO);
99    // Include NULL termination (hence + 1).
100    return strlen(traceMessage) + 1;
101}
102
103WebRtc_Word32 TracePosix::AddDateTimeInfo(char* traceMessage) const
104{
105    time_t t;
106    time(&t);
107    char buffer[26];  // man ctime says buffer should have room for >=26 bytes.
108    sprintf(traceMessage, "Local Date: %s", ctime_r(&t, buffer));
109    WebRtc_Word32 len = static_cast<WebRtc_Word32>(strlen(traceMessage));
110
111    if ('\n' == traceMessage[len - 1])
112    {
113        traceMessage[len - 1] = '\0';
114        --len;
115    }
116
117    // Messages is 12 characters.
118    return len + 1;
119}
120} // namespace webrtc
121