1
//---------------------------------------------------------------------------
2
// $Id: log.cc 18724 2009-04-23 23:06:37Z bangerth $
5
// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009 by the deal.II authors
7
// This file is subject to QPL and may not be distributed
8
// without copyright and license information. Please refer
9
// to the file deal.II/doc/license.html for the text and
10
// further information on this license.
12
//---------------------------------------------------------------------------
15
#include <base/logstream.h>
16
#include <base/job_identifier.h>
17
#include <base/memory_consumption.h>
18
#include <base/thread_management.h>
20
// include sys/resource.h for rusage(). Mac OS X needs sys/time.h then
21
// as well (strange), so include that, too.
23
#include <sys/resource.h>
24
#include <sys/types.h>
32
// on SunOS 4.x, getrusage is stated in the man pages and exists, but
33
// is not declared in resource.h. declare it ourselves
34
#ifdef NO_HAVE_GETRUSAGE
36
int getrusage(int who, struct rusage* ru);
40
// When modifying the prefix list, we need to lock it just in case
41
// another thread tries to do the same.
42
DEAL_II_NAMESPACE_OPEN
46
Threads::ThreadMutex log_lock;
47
Threads::ThreadMutex write_lock;
54
LogStream::LogStream()
56
std_out(&std::cerr), file(0),
57
std_depth(10000), file_depth(10000),
58
print_utime(false), diff_utime(false),
59
last_time (0.), double_threshold(0.), old_cerr(0)
61
prefixes.push("DEAL:");
62
std_out->setf(std::ios::showpoint | std::ios::left);
66
LogStream::~LogStream()
69
std::cerr.rdbuf(old_cerr);
71
// on some systems, destroying the
72
// outstreams objects of deallog
73
// triggers some sort of memory
74
// corruption, in particular when
75
// we also link with Trilinos;
76
// since this happens at the very
77
// end of the program, we take the
78
// liberty to simply not do it by
79
// putting that object into a
80
// deliberate memory leak and
81
// instead destroying an empty
83
#ifdef DEAL_II_USE_TRILINOS
85
(new stream_map_type())->swap (outstreams);
91
LogStream::operator<< (std::ostream& (*p) (std::ostream&))
93
// do the work that is common to
94
// the operator<< functions
97
// next check whether this is the
98
// <tt>endl</tt> manipulator, and if so
100
std::ostream & (* const p_endl) (std::ostream&) = &std::endl;
103
Threads::ThreadMutex::ScopedLock lock(write_lock);
105
std::ostringstream& stream = get_stream();
106
if (prefixes.size() <= std_depth)
107
*std_out << stream.str();
109
if (file && (prefixes.size() <= file_depth))
110
*file << stream.str() << std::flush;
112
// Start a new string
120
LogStream::get_stream()
122
Threads::ThreadMutex::ScopedLock lock(log_lock);
123
unsigned int id = Threads::this_thread_id();
125
std_cxx1x::shared_ptr<std::ostringstream>& sptr = outstreams[id];
128
sptr = std_cxx1x::shared_ptr<std::ostringstream> (new std::ostringstream());
129
sptr->setf(std::ios::showpoint | std::ios::left);
137
LogStream::attach(std::ostream& o)
139
Threads::ThreadMutex::ScopedLock lock(log_lock);
141
o.setf(std::ios::showpoint | std::ios::left);
146
void LogStream::detach ()
148
Threads::ThreadMutex::ScopedLock lock(log_lock);
153
void LogStream::log_cerr ()
155
Threads::ThreadMutex::ScopedLock lock(log_lock);
158
old_cerr = std::cerr.rdbuf(file->rdbuf());
160
std::cerr.rdbuf(old_cerr);
167
LogStream::get_console()
174
LogStream::get_file_stream()
176
Assert(file, ExcNoFileStreamGiven());
182
LogStream::has_file() const
189
LogStream::get_prefix() const
191
return prefixes.top();
196
LogStream::push (const std::string& text)
198
Threads::ThreadMutex::ScopedLock lock(log_lock);
199
std::string pre=prefixes.top();
201
pre += std::string(":");
206
void LogStream::pop ()
208
Threads::ThreadMutex::ScopedLock lock(log_lock);
209
if (prefixes.size() > 1)
215
LogStream::depth_console (const unsigned n)
217
Threads::ThreadMutex::ScopedLock lock(log_lock);
218
const unsigned int h = std_depth;
225
LogStream::depth_file (const unsigned n)
227
Threads::ThreadMutex::ScopedLock lock(log_lock);
228
const unsigned int h = file_depth;
235
LogStream::threshold_double (const double t)
237
Threads::ThreadMutex::ScopedLock lock(log_lock);
238
double_threshold = t;
243
LogStream::log_execution_time (const bool flag)
245
Threads::ThreadMutex::ScopedLock lock(log_lock);
246
const bool h = print_utime;
253
LogStream::log_time_differences (const bool flag)
255
Threads::ThreadMutex::ScopedLock lock(log_lock);
256
const bool h = diff_utime;
263
LogStream::log_thread_id (const bool flag)
265
Threads::ThreadMutex::ScopedLock lock(log_lock);
266
const bool h = print_thread_id;
267
print_thread_id = flag;
273
LogStream::print_line_head()
279
getrusage(RUSAGE_SELF, &usage);
280
utime = usage.ru_utime.tv_sec + 1.e-6 * usage.ru_utime.tv_usec;
283
double diff = utime - last_time;
290
* The following lines were used for debugging a memory leak.
291
* They work on Linux, not on Solaris, since the /proc filesystem
292
* on Solaris is quite cryptic. For other systems, we don't know.
294
* Unfortunately, the information in /proc/pid/stat is updated slowly,
295
* therefore, the information is quite unreliable.
297
* Furthermore, the constructor of ifstream caused another memory leak.
299
* Still, this code might be useful sometimes, so I kept it here.
300
* When we have more information about the kernel, this should be
301
* incorporated properly. Suggestions are welcome!
304
#ifdef DEALII_MEMORY_DEBUG
305
static const pid_t id = getpid();
307
std::ostringstream statname;
308
statname << "/proc/" << id << "/stat";
312
ifstream stat(statname.str());
314
stat >> dummy >> dummy >> dummy >> dummy >> dummy >> dummy >>
315
dummy >> dummy >> dummy >> dummy >> dummy >>
316
dummy >> dummy >> dummy >> dummy >> dummy >> dummy >>
317
dummy >> dummy >> dummy >> dummy >> dummy >> size;
320
const std::string& head = get_prefix();
321
const unsigned int thread = Threads::this_thread_id();
323
if (prefixes.size() <= std_depth)
327
int p = std_out->width(5);
328
*std_out << utime << ':';
329
#ifdef DEALII_MEMORY_DEBUG
330
*std_out << size << ':';
335
*std_out << '[' << thread << ']';
337
*std_out << head << ':';
340
if (file && (prefixes.size() <= file_depth))
344
int p = file->width(6);
345
*file << utime << ':';
346
#ifdef DEALII_MEMORY_DEBUG
347
*file << size << ':';
352
*file << '[' << thread << ']';
354
*file << head << ':';
360
LogStream::memory_consumption () const
362
unsigned int mem = sizeof(*this);
363
// to determine size of stack
364
// elements, we have to copy the
365
// stack since we can't access
366
// elements from further below
367
std::stack<std::string> tmp;
368
while (tmp.size() > 0)
370
mem += MemoryConsumption::memory_consumption (tmp.top());
377
DEAL_II_NAMESPACE_CLOSE