Permalink
Browse files

Merge branch 'master' into v1.

This marks the release of TPIE version 1.0.

The following improvements have been merged in since 1.0rc2:

* Time estimation warning has been moved to debug log. (8a9138e)
* Priority queue memory usage slightly improved. (fa1e12e)
* Move backtrace printed by fractional_subindicator to debug log. (f016d26)
* Fix memory management crashes in debug mode. (91b940b)
* Get rid of CMake option TPIE_THREADSAFE_MEMORY_MANAGEMNT. (21eb5b8)
* Various documentation cleanup; code comments have been added/clarified.
* Some compiler warnings have been addressed.
  • Loading branch information...
2 parents 4b251dd + fd5806a commit e2b2b65727e6ed9a98179ac8b2156892b03385bb @Mortal Mortal committed Dec 14, 2012
View
@@ -91,7 +91,6 @@ add_subdirectory(doc)
option(COMPILE_TEST "Compile test programs" ON)
option(TPL_LOGGING "Enable tpie logging." ON)
-option(TPIE_THREADSAFE_MEMORY_MANAGEMNT "Thread safe memory managment" ON)
option(TPIE_DEPRECATED_WARNINGS "Enable warnings for deprecated classes, methods and typedefs" OFF)
option(TPIE_PARALLEL_SORT "Enable parallel quick sort implementation" ON)
@@ -63,7 +63,7 @@ class disjointsets_memory_test: public memory_test {
virtual size_type claimed_size() {return static_cast<size_type>(disjoint_sets<int>::memory_usage(123456));}
};
-bool stress_test(size_t n) {
+bool stress_test(int n) {
test_timer t("disjoint_sets");
for (int _ = 0; _ < 5; ++_) {
t.start();
@@ -87,5 +87,5 @@ int main(int argc, char **argv) {
return tpie::tests(argc, argv)
.test(basic_test, "basic")
.test(disjointsets_memory_test(), "memory")
- .test(stress_test, "stress", "n", 1024);
+ .test(stress_test, "stress", "n", static_cast<int>(1024));
}
View
@@ -20,7 +20,11 @@
#include "common.h"
#include <tpie/memory.h>
#include <vector>
-
+#include <tpie/internal_queue.h>
+#include <tpie/internal_vector.h>
+#include <boost/random.hpp>
+#include <tpie/job.h>
+#include <tpie/cpu_timer.h>
struct mtest {
size_t & r;
@@ -132,7 +136,88 @@ bool basic_test() {
return true;
}
+struct tpie_alloc {
+ template <typename T>
+ static T * alloc() { return tpie::tpie_new<T>(); }
+ template <typename T>
+ static void dealloc(T * t) { tpie::tpie_delete(t); }
+};
+
+struct std_alloc {
+ template <typename T>
+ static T * alloc() { return new T; }
+ template <typename T>
+ static void dealloc(T * t) { delete t; }
+};
+
+struct c_alloc {
+ template <typename T>
+ static T * alloc() { return (T *) malloc(sizeof(T)); }
+ template <typename T>
+ static void dealloc(T * t) { free(t); }
+};
+
+template <typename Alloc>
+class memory_user : public tpie::job {
+ typedef int test_t;
+ size_t times;
+ tpie::internal_queue<test_t *> pointers;
+ boost::rand48 rnd;
+ boost::uniform_01<double> urnd;
+
+public:
+ memory_user(size_t times, size_t capacity) : times(times), pointers(capacity) {}
+
+ virtual void operator()() /*override*/ {
+ for (size_t i = 0; i < times; ++i) {
+ if (pointers.empty() ||
+ (!pointers.full() && urnd(rnd) <= (cos(static_cast<double>(i) * 60.0 / static_cast<double>(pointers.size())) + 1.0)/2.0)) {
+
+ pointers.push(Alloc::template alloc<test_t>());
+ } else {
+ Alloc::dealloc(pointers.front());
+ pointers.pop();
+ }
+ }
+ while (!pointers.empty()) {
+ Alloc::dealloc(pointers.front());
+ pointers.pop();
+ }
+ }
+};
+
+template <typename Alloc>
+bool parallel_test(const size_t nJobs, const size_t times, const size_t capacity) {
+ tpie::cpu_timer t;
+ t.start();
+ tpie::internal_vector<memory_user<Alloc> *> workers(nJobs);
+ for (size_t i = 0; i < nJobs; ++i) {
+ workers[i] = tpie::tpie_new<memory_user<Alloc> >(times, capacity);
+ workers[i]->enqueue();
+ }
+ for (size_t i = 0; i < nJobs; ++i) {
+ workers[i]->join();
+ tpie::tpie_delete(workers[i]);
+ }
+ t.stop();
+ tpie::log_info() << t << std::endl;
+ return true;
+}
+
int main(int argc, char ** argv) {
return tpie::tests(argc, argv, 128)
- .test(basic_test, "basic");
+ .test(basic_test, "basic")
+ .test(parallel_test<tpie_alloc>, "parallel",
+ "n", static_cast<size_t>(8),
+ "times", static_cast<size_t>(500000),
+ "capacity", static_cast<size_t>(50000))
+ .test(parallel_test<std_alloc>, "parallel_stdnew",
+ "n", static_cast<size_t>(8),
+ "times", static_cast<size_t>(500000),
+ "capacity", static_cast<size_t>(50000))
+ .test(parallel_test<c_alloc>, "parallel_malloc",
+ "n", static_cast<size_t>(8),
+ "times", static_cast<size_t>(500000),
+ "capacity", static_cast<size_t>(50000))
+ ;
}
View
@@ -20,7 +20,6 @@
#endif
#cmakedefine TPL_LOGGING 1
-#cmakedefine TPIE_THREADSAFE_MEMORY_MANAGEMNT 1
#cmakedefine TPIE_NDEBUG
@@ -188,9 +188,7 @@ class time_estimator_database {
if (l == e.end()) {
--l;
if (l->first == 0) {
-#ifdef TPIE_NDEBUG
- log_warning() << "In time estimation first was 0, this should not happen!" << std::endl;
-#endif
+ log_debug() << "In time estimation, first was 0." << std::endl;
confidence=0.0;
return -1;
}
@@ -30,6 +30,7 @@
#include <tpie/file_accessor/win32.h>
namespace tpie {
namespace file_accessor {
+typedef win32 raw_file_accessor;
typedef stream_accessor<win32> file_accessor;
}
}
@@ -39,13 +40,15 @@ typedef stream_accessor<win32> file_accessor;
#include <tpie/file_accessor/posix.h>
namespace tpie {
namespace file_accessor {
+typedef posix raw_file_accessor;
typedef stream_accessor<posix> file_accessor;
}
}
#endif // WIN32
namespace tpie {
+typedef file_accessor::raw_file_accessor default_raw_file_accessor;
typedef file_accessor::file_accessor default_file_accessor;
} // namespace tpie
@@ -51,6 +51,7 @@ class posix {
inline void seek_i(stream_size_type offset);
inline void close_i();
inline void truncate_i(stream_size_type bytes);
+ inline bool is_open() const;
///////////////////////////////////////////////////////////////////////////
/// \brief Check the global errno variable and throw an exception that
@@ -101,6 +101,10 @@ void posix::open_rw_new(const std::string & path) {
::posix_fadvise(m_fd, 0, 0, m_advice);
}
+bool posix::is_open() const {
+ return m_fd != 0;
+}
+
void posix::close_i() {
if (m_fd != 0) {
::close(m_fd);
@@ -57,6 +57,7 @@ class win32 {
inline void seek_i(stream_size_type offset);
inline void close_i();
inline void truncate_i(stream_size_type bytes);
+ inline bool is_open() const;
inline void set_cache_hint(cache_hint cacheHint);
};
@@ -99,6 +99,10 @@ void win32::open_rw_new(const std::string & path) {
if (m_fd == INVALID_HANDLE_VALUE) throw_getlasterror();
}
+bool win32::is_open() const {
+ return m_fd != INVALID_HANDLE_VALUE;
+}
+
void win32::close_i() {
if (m_fd != INVALID_HANDLE_VALUE) {
CloseHandle(m_fd);
View
@@ -49,16 +49,20 @@ class file_base: public file_base_crtp<file_base> {
/// This is the type of our block buffers. We have one per file::stream
/// distributed over two linked lists.
///////////////////////////////////////////////////////////////////////////
-#pragma warning( push )
-#pragma warning( disable : 4200 )
+#ifdef WIN32
+#pragma warning( push )
+#pragma warning( disable : 4200 )
+#endif
struct block_t : public boost::intrusive::list_base_hook<> {
memory_size_type size;
memory_size_type usage;
stream_size_type number;
bool dirty;
char data[0];
};
-#pragma warning( pop )
+#ifdef WIN32
+#pragma warning( pop )
+#endif
inline void update_size(stream_size_type size) {
m_size = std::max(m_size, size);
@@ -245,8 +245,10 @@ fractional_subindicator::~fractional_subindicator() {
} else {
s << "A fractional_subindicator was assigned a non-zero fraction but never initialized." << std::endl;
}
- tpie::backtrace(s, 5);
TP_LOG_FATAL(s.str());
+ s.str("");
+ tpie::backtrace(s, 5);
+ TP_LOG_DEBUG(s.str());
TP_LOG_FLUSH_LOG;
}
#endif
@@ -267,8 +269,10 @@ void fractional_progress::init(stream_size_type range) {
std::stringstream s;
s << "init() was called on a fractional_progress for which init had already been called. Subindicators were:" << std::endl;
s << sub_indicators_ss();
- tpie::backtrace(s, 5);
TP_LOG_FATAL(s.str());
+ s.str("");
+ tpie::backtrace(s, 5);
+ TP_LOG_DEBUG(s.str());
TP_LOG_FLUSH_LOG;
}
m_init_called=true;
@@ -286,8 +290,10 @@ void fractional_progress::done() {
s << "done() was called on fractional_progress, but init has not been called. Subindicators were:" << std::endl;
}
s << sub_indicators_ss();
- tpie::backtrace(s, 5);
TP_LOG_FATAL(s.str());
+ s.str("");
+ tpie::backtrace(s, 5);
+ TP_LOG_DEBUG(s.str());
TP_LOG_FLUSH_LOG;
}
m_done_called=true;
@@ -299,10 +305,12 @@ fractional_progress::~fractional_progress() {
#ifndef TPIE_NDEBUG
if (m_init_called && !m_done_called && !std::uncaught_exception()) {
std::stringstream s;
- s << "A fractional_progress was destructed without done being called. Subindicators were:" << std::endl;
+ s << "A fractional_progress was destructed without done being called." << std::endl;
+ TP_LOG_FATAL(s.str());
+ s.str("Subindicators were:\n");
s << sub_indicators_ss();
tpie::backtrace(s, 5);
- TP_LOG_FATAL(s.str());
+ TP_LOG_DEBUG(s.str());
TP_LOG_FLUSH_LOG;
}
#endif
View
@@ -1,6 +1,6 @@
// -*- mode: c++; tab-width: 4; indent-tabs-mode: t; c-file-style: "stroustrup"; -*-
// vi:set ts=4 sts=4 sw=4 noet :
-// Copyright 2010, The TPIE development team
+// Copyright 2010, 2012, The TPIE development team
//
// This file is part of TPIE.
//
@@ -28,33 +28,42 @@
#include <tpie/internal_stack_vector_base.h>
namespace tpie {
-/////////////////////////////////////////////////////////
-/// \brief A generic internal stack
+///////////////////////////////////////////////////////////////////////////////
+/// \brief A generic internal stack.
///
-/// \tparam T The type of items storred on the stack
-/////////////////////////////////////////////////////////
+/// \tparam T The type of items stored in the structure.
+///////////////////////////////////////////////////////////////////////////////
template <typename T>
class internal_stack: public internal_stack_vector_base<T,internal_stack<T> > {
public:
typedef internal_stack_vector_base<T,internal_stack<T> > parent_t;
+
+ ///////////////////////////////////////////////////////////////////////////
+ /// \brief Construct structure with given capacity.
+ /// \copydetails tpie::internal_stack_vector_base::internal_stack_vector_base
+ ///////////////////////////////////////////////////////////////////////////
internal_stack(size_t size=0): parent_t(size){}
+
using parent_t::m_elements;
using parent_t::m_size;
- /////////////////////////////////////////////////////////
- /// \brief Return the top most element on the stack
- /////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////////////
+ /// \brief Return the topmost element on the stack.
+ ///////////////////////////////////////////////////////////////////////////
inline T & top() {return m_elements[m_size-1];}
- /////////////////////////////////////////////////////////
- /// \brief Add an element to the top of the stack
+ ///////////////////////////////////////////////////////////////////////////
+ /// \brief Add an element to the top of the stack.
+ /// If size() is equal to the capacity (set in the constructor or in
+ /// resize()), effects are undefined. resize() is not called implicitly.
///
- /// \param val The element to add
- /////////////////////////////////////////////////////////
+ /// \param val The element to add.
+ ///////////////////////////////////////////////////////////////////////////
inline void push(const T & val){m_elements[m_size++] = val;}
- /////////////////////////////////////////////////////////
- /// \brief Remove the top most element from the stack
- /////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////////
+ /// \brief Remove the topmost element from the stack.
+ ///////////////////////////////////////////////////////////////////////////
inline void pop(){--m_size;}
};
Oops, something went wrong.

0 comments on commit e2b2b65

Please sign in to comment.