#define __deal2__logstream_h
#include <deal.II/base/config.h>
-#include <deal.II/base/smartpointer.h>
#include <deal.II/base/exceptions.h>
+#include <deal.II/base/smartpointer.h>
#include <deal.II/base/std_cxx1x/shared_ptr.h>
+#include <deal.II/base/thread_local_storage.h>
#include <string>
#include <stack>
};
#endif
+
DEAL_II_NAMESPACE_OPEN
/**
*
* Before entering a new phase of your program, e.g. a new loop,
* a new prefix can be set via <tt>LogStream::Prefix p("loopname");</tt>.
- * The destructor of the prefix will pop the prefix text from the stack.
+ * The destructor of the prefix will pop the prefix text from the stack.
*
* Writes via the <tt><<</tt> operator,
* <tt> deallog << "This is a log notice";</tt> will be buffered thread
* the variable is destroyed.
*/
Prefix(const std::string &text,
- LogStream &stream);
+ LogStream &stream);
/**
* Remove the prefix associated with this variable.
* function will return the correct internal ostringstream buffer for
* operater<<.
*/
- std::ostringstream &get_stream();
-
- /**
- * Type of the stream map
- */
- typedef std::map<unsigned int, std_cxx1x::shared_ptr<std::ostringstream> > stream_map_type;
+ std::ostringstream &get_stream()
+ {
+ outstreams.get().setf(std::ios::showpoint | std::ios::left);
+ return outstreams.get();
+ }
/**
- * We generate a stringstream for every process that sends log messages.
+ * We use tbb's thread local storage facility to generate a stringstream
+ * for every thread that sends log messages.
*/
- stream_map_type outstreams;
+ Threads::ThreadLocalStorage<std::ostringstream> outstreams;
};
#if defined(HAVE_UNISTD_H) && defined(HAVE_TIMES)
reference_time_val = 1./sysconf(_SC_CLK_TCK) * times(&reference_tms);
#endif
+
}
// if there was anything left in the stream that is current to this
// thread, make sure we flush it before it gets lost
{
- const unsigned int id = Threads::this_thread_id();
- if ((outstreams.find(id) != outstreams.end())
- &&
- (*outstreams[id] != 0)
- &&
- (outstreams[id]->str().length() > 0))
+ if (get_stream().str().length() > 0)
{
// except the situation is not quite that simple. if this object is
// the 'deallog' object, then it is destroyed upon exit of the
if (old_cerr)
std::cerr.rdbuf(old_cerr);
-
- // on some systems, destroying the outstreams objects of deallog triggers
- // some sort of memory corruption, in particular when we also link with
- // Trilinos; since this happens at the very end of the program, we take
- // the liberty to simply not do it by putting that object into a
- // deliberate memory leak and instead destroying an empty object
-#ifdef DEAL_II_WITH_TRILINOS
- if (this == &deallog)
- {
- stream_map_type *dummy = new stream_map_type();
- dummy->swap (outstreams);
- delete dummy;
- }
-#endif
}
}
-std::ostringstream &
-LogStream::get_stream()
-{
-//TODO: use a ThreadLocalStorage object here
- Threads::Mutex::ScopedLock lock(log_lock);
- const unsigned int id = Threads::this_thread_id();
-
- // if necessary allocate a stream object
- if (outstreams.find (id) == outstreams.end())
- {
- outstreams[id].reset (new std::ostringstream());
- outstreams[id]->setf(std::ios::showpoint | std::ios::left);
- }
- return *outstreams[id];
-}
-
-
void
LogStream::attach(std::ostream &o)
{