Source code formating unification
[platform/framework/web/wrt.git] / src / profiling / profiling_util.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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  * @file
18  * @author      Lukasz Wrzosek (l.wrzosek@samsung.com)
19  * @version     1.0
20  * @brief       This is implementation file for profiling function.
21  */
22
23 #include "profiling_util.h"
24
25 #include <vector>
26 #include <cstdio>
27 #include <cstdlib>
28
29 #include <sys/time.h>
30 #include <signal.h>
31
32 #include <dpl/foreach.h>
33 #include <dpl/log/log.h>
34 #include <dpl/mutex.h>
35
36 namespace {
37 const int PROFILING_OUTPUT_DESCRIPTOR = 3;
38
39 unsigned long long toULong(const struct timeval& value)
40 {
41     unsigned long long ret = static_cast<unsigned long long>(value.tv_sec) *
42         1000000ULL;
43     ret += static_cast<unsigned long long>(value.tv_usec);
44     return ret;
45 }
46
47 struct PacketResult
48 {
49     unsigned long long time;
50     const char* name;
51     const char* prefix;
52     const char* description;
53     PacketResult() :
54         time(0),
55         name(0),
56         prefix(0),
57         description(0)
58     {}
59     PacketResult(unsigned long long t,
60                  const char* n,
61                  const char* p,
62                  const char* d) :
63         time(t),
64         name(n),
65         prefix(p),
66         description(d)
67     {}
68
69     void Print(FILE *filePtr)
70     {
71         if (!prefix) {
72             prefix = "";
73         }
74         if (!description) {
75             description = "";
76         }
77         fprintf(filePtr, "%s#%s#%llu#[%s]\n", prefix, name, time, description);
78     }
79 };
80
81 std::vector<PacketResult> results;
82
83 void dumpStatistic()
84 {
85     FILE* fp = NULL;
86     int newfd = dup(PROFILING_OUTPUT_DESCRIPTOR);
87     if (-1 != newfd) {
88         fp = fdopen(newfd, "w");
89     }
90     if (!fp) {
91         if (-1 != newfd) {
92             close(newfd);
93         }
94         fp = stdout; //fallback
95     }
96     fprintf(fp, "###PROFILING###START###\n");
97     FOREACH(result, results)
98     {
99         result->Print(fp);
100     }
101     fprintf(fp, "###PROFILING###STOP###\n");
102     fflush(fp);
103     if (stdout != fp) {
104         fclose(fp); // newfd is also closed
105     }
106 }
107
108 void sigUsrHandler(int /*num*/)
109 {
110     dumpStatistic();
111 }
112
113 int initialize();
114
115 const int i = initialize();
116 DPL::Mutex* m_mutex = NULL;
117
118 int initialize()
119 {
120     (void)i;
121     m_mutex = new DPL::Mutex;
122     results.reserve(64 * 1024);
123     signal(SIGUSR1, &sigUsrHandler);
124     signal(SIGUSR2, &sigUsrHandler);
125     LogDebug("Initialized profiling");
126     AddProfilingMeasurment("Profiling_Started");
127     return 1;
128 }
129
130 std::string GetFormattedTime()
131 {
132     timeval tv;
133     tm localNowTime;
134
135     gettimeofday(&tv, NULL);
136     localtime_r(&tv.tv_sec, &localNowTime);
137
138     char format[64];
139     snprintf(format,
140              sizeof(format),
141              "%02i:%02i:%02i.%03i",
142              localNowTime.tm_hour,
143              localNowTime.tm_min,
144              localNowTime.tm_sec,
145              static_cast<int>(tv.tv_usec / 1000));
146     return format;
147 }
148 } // namespace anonymous
149
150 void AddStdoutProfilingMeasurment(const char* name, bool start)
151 {
152     std::ostringstream output;
153     output << "[" << GetFormattedTime() << "] [](): " << name << " ";
154     output << (start ? "profiling##start" : "profiling##stop");
155     fprintf(stdout, "%s\n", output.str().c_str());
156 }
157
158 extern "C"
159 void AddProfilingMeasurment(const char* name,
160                             const char* prefix,
161                             const char* description)
162 {
163     DPL::Mutex::ScopedLock lock(m_mutex);
164     struct timeval value;
165     gettimeofday(&value, NULL);
166     results.push_back(
167         PacketResult(toULong(value), name, prefix, description));
168 }