~ubuntu-branches/ubuntu/wily/clamav/wily-proposed

« back to all changes in this revision

Viewing changes to libclamav/c++/llvm/lib/Support/Timer.cpp

  • Committer: Package Import Robot
  • Author(s): Scott Kitterman, Sebastian Andrzej Siewior, Andreas Cadhalpun, Scott Kitterman, Javier Fernández-Sanguino
  • Date: 2015-01-28 00:25:13 UTC
  • mfrom: (0.48.14 sid)
  • Revision ID: package-import@ubuntu.com-20150128002513-lil2oi74cooy4lzr
Tags: 0.98.6+dfsg-1
[ Sebastian Andrzej Siewior ]
* update "fix-ssize_t-size_t-off_t-printf-modifier", include of misc.h was
  missing but was pulled in via the systemd patch.
* Don't leak return codes from libmspack to clamav API. (Closes: #774686).

[ Andreas Cadhalpun ]
* Add patch to avoid emitting incremental progress messages when not
  outputting to a terminal. (Closes: #767350)
* Update lintian-overrides for unused-file-paragraph-in-dep5-copyright.
* clamav-base.postinst: always chown /var/log/clamav and /var/lib/clamav
  to clamav:clamav, not only on fresh installations. (Closes: #775400)
* Adapt the clamav-daemon and clamav-freshclam logrotate scripts,
  so that they correctly work under systemd.
* Move the PidFile variable from the clamd/freshclam configuration files
  to the init scripts. This makes the init scripts more robust against
  misconfiguration and avoids error messages with systemd. (Closes: #767353)
* debian/copyright: drop files from Files-Excluded only present in github
  tarballs
* Drop Workaround-a-bug-in-libc-on-Hurd.patch, because hurd got fixed.
  (see #752237)
* debian/rules: Remove useless --with-system-tommath --without-included-ltdl
  configure options.

[ Scott Kitterman ]
* Stop stripping llvm when repacking the tarball as the system llvm on some
  releases is too old to use
* New upstream bugfix release
  - Library shared object revisions.
  - Includes a patch from Sebastian Andrzej Siewior making ClamAV pid files
    compatible with systemd.
  - Fix a heap out of bounds condition with crafted Yoda's crypter files.
    This issue was discovered by Felix Groebert of the Google Security Team.
  - Fix a heap out of bounds condition with crafted mew packer files. This
    issue was discovered by Felix Groebert of the Google Security Team.
  - Fix a heap out of bounds condition with crafted upx packer files. This
    issue was discovered by Kevin Szkudlapski of Quarkslab.
  - Fix a heap out of bounds condition with crafted upack packer files. This
    issue was discovered by Sebastian Andrzej Siewior. CVE-2014-9328.
  - Compensate a crash due to incorrect compiler optimization when handling
    crafted petite packer files. This issue was discovered by Sebastian
    Andrzej Siewior.
* Update lintian override for embedded zlib to match new so version

[ Javier Fernández-Sanguino ]
* Updated Spanish Debconf template translation (Closes: #773563)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//===-- Timer.cpp - Interval Timing Support -------------------------------===//
 
2
//
 
3
//                     The LLVM Compiler Infrastructure
 
4
//
 
5
// This file is distributed under the University of Illinois Open Source
 
6
// License. See LICENSE.TXT for details.
 
7
//
 
8
//===----------------------------------------------------------------------===//
 
9
//
 
10
// Interval Timing implementation.
 
11
//
 
12
//===----------------------------------------------------------------------===//
 
13
 
 
14
#include "llvm/Support/Timer.h"
 
15
#include "llvm/Support/CommandLine.h"
 
16
#include "llvm/Support/Debug.h"
 
17
#include "llvm/Support/ManagedStatic.h"
 
18
#include "llvm/Support/raw_ostream.h"
 
19
#include "llvm/Support/Format.h"
 
20
#include "llvm/System/Mutex.h"
 
21
#include "llvm/System/Process.h"
 
22
#include "llvm/ADT/OwningPtr.h"
 
23
#include "llvm/ADT/StringMap.h"
 
24
using namespace llvm;
 
25
 
 
26
// CreateInfoOutputFile - Return a file stream to print our output on.
 
27
namespace llvm { extern raw_ostream *CreateInfoOutputFile(); }
 
28
 
 
29
// getLibSupportInfoOutputFilename - This ugly hack is brought to you courtesy
 
30
// of constructor/destructor ordering being unspecified by C++.  Basically the
 
31
// problem is that a Statistic object gets destroyed, which ends up calling
 
32
// 'GetLibSupportInfoOutputFile()' (below), which calls this function.
 
33
// LibSupportInfoOutputFilename used to be a global variable, but sometimes it
 
34
// would get destroyed before the Statistic, causing havoc to ensue.  We "fix"
 
35
// this by creating the string the first time it is needed and never destroying
 
36
// it.
 
37
static ManagedStatic<std::string> LibSupportInfoOutputFilename;
 
38
static std::string &getLibSupportInfoOutputFilename() {
 
39
  return *LibSupportInfoOutputFilename;
 
40
}
 
41
 
 
42
static ManagedStatic<sys::SmartMutex<true> > TimerLock;
 
43
 
 
44
namespace {
 
45
  static cl::opt<bool>
 
46
  TrackSpace("track-memory", cl::desc("Enable -time-passes memory "
 
47
                                      "tracking (this may be slow)"),
 
48
             cl::Hidden);
 
49
 
 
50
  static cl::opt<std::string, true>
 
51
  InfoOutputFilename("info-output-file", cl::value_desc("filename"),
 
52
                     cl::desc("File to append -stats and -timer output to"),
 
53
                   cl::Hidden, cl::location(getLibSupportInfoOutputFilename()));
 
54
}
 
55
 
 
56
// CreateInfoOutputFile - Return a file stream to print our output on.
 
57
raw_ostream *llvm::CreateInfoOutputFile() {
 
58
  const std::string &OutputFilename = getLibSupportInfoOutputFilename();
 
59
  if (OutputFilename.empty())
 
60
    return new raw_fd_ostream(2, false); // stderr.
 
61
  if (OutputFilename == "-")
 
62
    return new raw_fd_ostream(1, false); // stdout.
 
63
  
 
64
  // Append mode is used because the info output file is opened and closed
 
65
  // each time -stats or -time-passes wants to print output to it. To
 
66
  // compensate for this, the test-suite Makefiles have code to delete the
 
67
  // info output file before running commands which write to it.
 
68
  std::string Error;
 
69
  raw_ostream *Result = new raw_fd_ostream(OutputFilename.c_str(),
 
70
                                           Error, raw_fd_ostream::F_Append);
 
71
  if (Error.empty())
 
72
    return Result;
 
73
  
 
74
  errs() << "Error opening info-output-file '"
 
75
    << OutputFilename << " for appending!\n";
 
76
  delete Result;
 
77
  return new raw_fd_ostream(2, false); // stderr.
 
78
}
 
79
 
 
80
 
 
81
static TimerGroup *DefaultTimerGroup = 0;
 
82
static TimerGroup *getDefaultTimerGroup() {
 
83
  TimerGroup *tmp = DefaultTimerGroup;
 
84
  sys::MemoryFence();
 
85
  if (tmp) return tmp;
 
86
  
 
87
  llvm_acquire_global_lock();
 
88
  tmp = DefaultTimerGroup;
 
89
  if (!tmp) {
 
90
    tmp = new TimerGroup("Miscellaneous Ungrouped Timers");
 
91
    sys::MemoryFence();
 
92
    DefaultTimerGroup = tmp;
 
93
  }
 
94
  llvm_release_global_lock();
 
95
 
 
96
  return tmp;
 
97
}
 
98
 
 
99
//===----------------------------------------------------------------------===//
 
100
// Timer Implementation
 
101
//===----------------------------------------------------------------------===//
 
102
 
 
103
void Timer::init(StringRef N) {
 
104
  assert(TG == 0 && "Timer already initialized");
 
105
  Name.assign(N.begin(), N.end());
 
106
  Started = false;
 
107
  TG = getDefaultTimerGroup();
 
108
  TG->addTimer(*this);
 
109
}
 
110
 
 
111
void Timer::init(StringRef N, TimerGroup &tg) {
 
112
  assert(TG == 0 && "Timer already initialized");
 
113
  Name.assign(N.begin(), N.end());
 
114
  Started = false;
 
115
  TG = &tg;
 
116
  TG->addTimer(*this);
 
117
}
 
118
 
 
119
Timer::~Timer() {
 
120
  if (!TG) return;  // Never initialized, or already cleared.
 
121
  TG->removeTimer(*this);
 
122
}
 
123
 
 
124
static inline size_t getMemUsage() {
 
125
  if (!TrackSpace) return 0;
 
126
  return sys::Process::GetMallocUsage();
 
127
}
 
128
 
 
129
TimeRecord TimeRecord::getCurrentTime(bool Start) {
 
130
  TimeRecord Result;
 
131
  sys::TimeValue now(0,0), user(0,0), sys(0,0);
 
132
  
 
133
  if (Start) {
 
134
    Result.MemUsed = getMemUsage();
 
135
    sys::Process::GetTimeUsage(now, user, sys);
 
136
  } else {
 
137
    sys::Process::GetTimeUsage(now, user, sys);
 
138
    Result.MemUsed = getMemUsage();
 
139
  }
 
140
 
 
141
  Result.WallTime   =  now.seconds() +  now.microseconds() / 1000000.0;
 
142
  Result.UserTime   = user.seconds() + user.microseconds() / 1000000.0;
 
143
  Result.SystemTime =  sys.seconds() +  sys.microseconds() / 1000000.0;
 
144
  return Result;
 
145
}
 
146
 
 
147
static ManagedStatic<std::vector<Timer*> > ActiveTimers;
 
148
 
 
149
void Timer::startTimer() {
 
150
  Started = true;
 
151
  ActiveTimers->push_back(this);
 
152
  Time -= TimeRecord::getCurrentTime(true);
 
153
}
 
154
 
 
155
void Timer::stopTimer() {
 
156
  Time += TimeRecord::getCurrentTime(false);
 
157
 
 
158
  if (ActiveTimers->back() == this) {
 
159
    ActiveTimers->pop_back();
 
160
  } else {
 
161
    std::vector<Timer*>::iterator I =
 
162
      std::find(ActiveTimers->begin(), ActiveTimers->end(), this);
 
163
    assert(I != ActiveTimers->end() && "stop but no startTimer?");
 
164
    ActiveTimers->erase(I);
 
165
  }
 
166
}
 
167
 
 
168
static void printVal(double Val, double Total, raw_ostream &OS) {
 
169
  if (Total < 1e-7)   // Avoid dividing by zero.
 
170
    OS << "        -----     ";
 
171
  else {
 
172
    OS << "  " << format("%7.4f", Val) << " (";
 
173
    OS << format("%5.1f", Val*100/Total) << "%)";
 
174
  }
 
175
}
 
176
 
 
177
void TimeRecord::print(const TimeRecord &Total, raw_ostream &OS) const {
 
178
  if (Total.getUserTime())
 
179
    printVal(getUserTime(), Total.getUserTime(), OS);
 
180
  if (Total.getSystemTime())
 
181
    printVal(getSystemTime(), Total.getSystemTime(), OS);
 
182
  if (Total.getProcessTime())
 
183
    printVal(getProcessTime(), Total.getProcessTime(), OS);
 
184
  printVal(getWallTime(), Total.getWallTime(), OS);
 
185
  
 
186
  OS << "  ";
 
187
  
 
188
  if (Total.getMemUsed())
 
189
    OS << format("%9lld", (long long)getMemUsed()) << "  ";
 
190
}
 
191
 
 
192
 
 
193
//===----------------------------------------------------------------------===//
 
194
//   NamedRegionTimer Implementation
 
195
//===----------------------------------------------------------------------===//
 
196
 
 
197
namespace {
 
198
 
 
199
typedef StringMap<Timer> Name2TimerMap;
 
200
 
 
201
class Name2PairMap {
 
202
  StringMap<std::pair<TimerGroup*, Name2TimerMap> > Map;
 
203
public:
 
204
  ~Name2PairMap() {
 
205
    for (StringMap<std::pair<TimerGroup*, Name2TimerMap> >::iterator
 
206
         I = Map.begin(), E = Map.end(); I != E; ++I)
 
207
      delete I->second.first;
 
208
  }
 
209
  
 
210
  Timer &get(StringRef Name, StringRef GroupName) {
 
211
    sys::SmartScopedLock<true> L(*TimerLock);
 
212
    
 
213
    std::pair<TimerGroup*, Name2TimerMap> &GroupEntry = Map[GroupName];
 
214
    
 
215
    if (!GroupEntry.first)
 
216
      GroupEntry.first = new TimerGroup(GroupName);
 
217
    
 
218
    Timer &T = GroupEntry.second[Name];
 
219
    if (!T.isInitialized())
 
220
      T.init(Name, *GroupEntry.first);
 
221
    return T;
 
222
  }
 
223
};
 
224
 
 
225
}
 
226
 
 
227
static ManagedStatic<Name2TimerMap> NamedTimers;
 
228
static ManagedStatic<Name2PairMap> NamedGroupedTimers;
 
229
 
 
230
static Timer &getNamedRegionTimer(StringRef Name) {
 
231
  sys::SmartScopedLock<true> L(*TimerLock);
 
232
  
 
233
  Timer &T = (*NamedTimers)[Name];
 
234
  if (!T.isInitialized())
 
235
    T.init(Name);
 
236
  return T;
 
237
}
 
238
 
 
239
NamedRegionTimer::NamedRegionTimer(StringRef Name,
 
240
                                   bool Enabled)
 
241
  : TimeRegion(!Enabled ? 0 : &getNamedRegionTimer(Name)) {}
 
242
 
 
243
NamedRegionTimer::NamedRegionTimer(StringRef Name, StringRef GroupName,
 
244
                                   bool Enabled)
 
245
  : TimeRegion(!Enabled ? 0 : &NamedGroupedTimers->get(Name, GroupName)) {}
 
246
 
 
247
//===----------------------------------------------------------------------===//
 
248
//   TimerGroup Implementation
 
249
//===----------------------------------------------------------------------===//
 
250
 
 
251
/// TimerGroupList - This is the global list of TimerGroups, maintained by the
 
252
/// TimerGroup ctor/dtor and is protected by the TimerLock lock.
 
253
static TimerGroup *TimerGroupList = 0;
 
254
 
 
255
TimerGroup::TimerGroup(StringRef name)
 
256
  : Name(name.begin(), name.end()), FirstTimer(0) {
 
257
    
 
258
  // Add the group to TimerGroupList.
 
259
  sys::SmartScopedLock<true> L(*TimerLock);
 
260
  if (TimerGroupList)
 
261
    TimerGroupList->Prev = &Next;
 
262
  Next = TimerGroupList;
 
263
  Prev = &TimerGroupList;
 
264
  TimerGroupList = this;
 
265
}
 
266
 
 
267
TimerGroup::~TimerGroup() {
 
268
  // If the timer group is destroyed before the timers it owns, accumulate and
 
269
  // print the timing data.
 
270
  while (FirstTimer != 0)
 
271
    removeTimer(*FirstTimer);
 
272
  
 
273
  // Remove the group from the TimerGroupList.
 
274
  sys::SmartScopedLock<true> L(*TimerLock);
 
275
  *Prev = Next;
 
276
  if (Next)
 
277
    Next->Prev = Prev;
 
278
}
 
279
 
 
280
 
 
281
void TimerGroup::removeTimer(Timer &T) {
 
282
  sys::SmartScopedLock<true> L(*TimerLock);
 
283
  
 
284
  // If the timer was started, move its data to TimersToPrint.
 
285
  if (T.Started)
 
286
    TimersToPrint.push_back(std::make_pair(T.Time, T.Name));
 
287
 
 
288
  T.TG = 0;
 
289
  
 
290
  // Unlink the timer from our list.
 
291
  *T.Prev = T.Next;
 
292
  if (T.Next)
 
293
    T.Next->Prev = T.Prev;
 
294
  
 
295
  // Print the report when all timers in this group are destroyed if some of
 
296
  // them were started.
 
297
  if (FirstTimer != 0 || TimersToPrint.empty())
 
298
    return;
 
299
  
 
300
  raw_ostream *OutStream = CreateInfoOutputFile();
 
301
  PrintQueuedTimers(*OutStream);
 
302
  delete OutStream;   // Close the file.
 
303
}
 
304
 
 
305
void TimerGroup::addTimer(Timer &T) {
 
306
  sys::SmartScopedLock<true> L(*TimerLock);
 
307
  
 
308
  // Add the timer to our list.
 
309
  if (FirstTimer)
 
310
    FirstTimer->Prev = &T.Next;
 
311
  T.Next = FirstTimer;
 
312
  T.Prev = &FirstTimer;
 
313
  FirstTimer = &T;
 
314
}
 
315
 
 
316
void TimerGroup::PrintQueuedTimers(raw_ostream &OS) {
 
317
  // Sort the timers in descending order by amount of time taken.
 
318
  std::sort(TimersToPrint.begin(), TimersToPrint.end());
 
319
  
 
320
  TimeRecord Total;
 
321
  for (unsigned i = 0, e = TimersToPrint.size(); i != e; ++i)
 
322
    Total += TimersToPrint[i].first;
 
323
  
 
324
  // Print out timing header.
 
325
  OS << "===" << std::string(73, '-') << "===\n";
 
326
  // Figure out how many spaces to indent TimerGroup name.
 
327
  unsigned Padding = (80-Name.length())/2;
 
328
  if (Padding > 80) Padding = 0;         // Don't allow "negative" numbers
 
329
  OS.indent(Padding) << Name << '\n';
 
330
  OS << "===" << std::string(73, '-') << "===\n";
 
331
  
 
332
  // If this is not an collection of ungrouped times, print the total time.
 
333
  // Ungrouped timers don't really make sense to add up.  We still print the
 
334
  // TOTAL line to make the percentages make sense.
 
335
  if (this != DefaultTimerGroup) {
 
336
    OS << "  Total Execution Time: ";
 
337
    OS << format("%5.4f", Total.getProcessTime()) << " seconds (";
 
338
    OS << format("%5.4f", Total.getWallTime()) << " wall clock)\n";
 
339
  }
 
340
  OS << '\n';
 
341
  
 
342
  if (Total.getUserTime())
 
343
    OS << "   ---User Time---";
 
344
  if (Total.getSystemTime())
 
345
    OS << "   --System Time--";
 
346
  if (Total.getProcessTime())
 
347
    OS << "   --User+System--";
 
348
  OS << "   ---Wall Time---";
 
349
  if (Total.getMemUsed())
 
350
    OS << "  ---Mem---";
 
351
  OS << "  --- Name ---\n";
 
352
  
 
353
  // Loop through all of the timing data, printing it out.
 
354
  for (unsigned i = 0, e = TimersToPrint.size(); i != e; ++i) {
 
355
    const std::pair<TimeRecord, std::string> &Entry = TimersToPrint[e-i-1];
 
356
    Entry.first.print(Total, OS);
 
357
    OS << Entry.second << '\n';
 
358
  }
 
359
  
 
360
  Total.print(Total, OS);
 
361
  OS << "Total\n\n";
 
362
  OS.flush();
 
363
  
 
364
  TimersToPrint.clear();
 
365
}
 
366
 
 
367
/// print - Print any started timers in this group and zero them.
 
368
void TimerGroup::print(raw_ostream &OS) {
 
369
  sys::SmartScopedLock<true> L(*TimerLock);
 
370
 
 
371
  // See if any of our timers were started, if so add them to TimersToPrint and
 
372
  // reset them.
 
373
  for (Timer *T = FirstTimer; T; T = T->Next) {
 
374
    if (!T->Started) continue;
 
375
    TimersToPrint.push_back(std::make_pair(T->Time, T->Name));
 
376
    
 
377
    // Clear out the time.
 
378
    T->Started = 0;
 
379
    T->Time = TimeRecord();
 
380
  }
 
381
 
 
382
  // If any timers were started, print the group.
 
383
  if (!TimersToPrint.empty())
 
384
    PrintQueuedTimers(OS);
 
385
}
 
386
 
 
387
/// printAll - This static method prints all timers and clears them all out.
 
388
void TimerGroup::printAll(raw_ostream &OS) {
 
389
  sys::SmartScopedLock<true> L(*TimerLock);
 
390
 
 
391
  for (TimerGroup *TG = TimerGroupList; TG; TG = TG->Next)
 
392
    TG->print(OS);
 
393
}