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