Skip to content

Commit

Permalink
Merge branch 'master' into v1.
Browse files Browse the repository at this point in the history
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
Mortal committed Dec 14, 2012
2 parents 4b251dd + fd5806a commit e2b2b65
Show file tree
Hide file tree
Showing 21 changed files with 441 additions and 176 deletions.
1 change: 0 additions & 1 deletion CMakeLists.txt
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ add_subdirectory(doc)


option(COMPILE_TEST "Compile test programs" ON) option(COMPILE_TEST "Compile test programs" ON)
option(TPL_LOGGING "Enable tpie logging." 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_DEPRECATED_WARNINGS "Enable warnings for deprecated classes, methods and typedefs" OFF)
option(TPIE_PARALLEL_SORT "Enable parallel quick sort implementation" ON) option(TPIE_PARALLEL_SORT "Enable parallel quick sort implementation" ON)


Expand Down
4 changes: 2 additions & 2 deletions test/unit/test_disjoint_set.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -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));} 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"); test_timer t("disjoint_sets");
for (int _ = 0; _ < 5; ++_) { for (int _ = 0; _ < 5; ++_) {
t.start(); t.start();
Expand All @@ -87,5 +87,5 @@ int main(int argc, char **argv) {
return tpie::tests(argc, argv) return tpie::tests(argc, argv)
.test(basic_test, "basic") .test(basic_test, "basic")
.test(disjointsets_memory_test(), "memory") .test(disjointsets_memory_test(), "memory")
.test(stress_test, "stress", "n", 1024); .test(stress_test, "stress", "n", static_cast<int>(1024));
} }
89 changes: 87 additions & 2 deletions test/unit/test_memory.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@
#include "common.h" #include "common.h"
#include <tpie/memory.h> #include <tpie/memory.h>
#include <vector> #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 { struct mtest {
size_t & r; size_t & r;
Expand Down Expand Up @@ -132,7 +136,88 @@ bool basic_test() {
return true; 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) { int main(int argc, char ** argv) {
return tpie::tests(argc, argv, 128) 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))
;
} }
1 change: 0 additions & 1 deletion tpie/config.h.cmake
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
#endif #endif


#cmakedefine TPL_LOGGING 1 #cmakedefine TPL_LOGGING 1
#cmakedefine TPIE_THREADSAFE_MEMORY_MANAGEMNT 1


#cmakedefine TPIE_NDEBUG #cmakedefine TPIE_NDEBUG


Expand Down
4 changes: 1 addition & 3 deletions tpie/execution_time_predictor.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -188,9 +188,7 @@ class time_estimator_database {
if (l == e.end()) { if (l == e.end()) {
--l; --l;
if (l->first == 0) { if (l->first == 0) {
#ifdef TPIE_NDEBUG log_debug() << "In time estimation, first was 0." << std::endl;
log_warning() << "In time estimation first was 0, this should not happen!" << std::endl;
#endif
confidence=0.0; confidence=0.0;
return -1; return -1;
} }
Expand Down
3 changes: 3 additions & 0 deletions tpie/file_accessor/file_accessor.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <tpie/file_accessor/win32.h> #include <tpie/file_accessor/win32.h>
namespace tpie { namespace tpie {
namespace file_accessor { namespace file_accessor {
typedef win32 raw_file_accessor;
typedef stream_accessor<win32> file_accessor; typedef stream_accessor<win32> file_accessor;
} }
} }
Expand All @@ -39,13 +40,15 @@ typedef stream_accessor<win32> file_accessor;
#include <tpie/file_accessor/posix.h> #include <tpie/file_accessor/posix.h>
namespace tpie { namespace tpie {
namespace file_accessor { namespace file_accessor {
typedef posix raw_file_accessor;
typedef stream_accessor<posix> file_accessor; typedef stream_accessor<posix> file_accessor;
} }
} }


#endif // WIN32 #endif // WIN32


namespace tpie { namespace tpie {
typedef file_accessor::raw_file_accessor default_raw_file_accessor;
typedef file_accessor::file_accessor default_file_accessor; typedef file_accessor::file_accessor default_file_accessor;
} // namespace tpie } // namespace tpie


Expand Down
1 change: 1 addition & 0 deletions tpie/file_accessor/posix.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class posix {
inline void seek_i(stream_size_type offset); inline void seek_i(stream_size_type offset);
inline void close_i(); inline void close_i();
inline void truncate_i(stream_size_type bytes); inline void truncate_i(stream_size_type bytes);
inline bool is_open() const;


/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
/// \brief Check the global errno variable and throw an exception that /// \brief Check the global errno variable and throw an exception that
Expand Down
4 changes: 4 additions & 0 deletions tpie/file_accessor/posix.inl
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ void posix::open_rw_new(const std::string & path) {
::posix_fadvise(m_fd, 0, 0, m_advice); ::posix_fadvise(m_fd, 0, 0, m_advice);
} }


bool posix::is_open() const {
return m_fd != 0;
}

void posix::close_i() { void posix::close_i() {
if (m_fd != 0) { if (m_fd != 0) {
::close(m_fd); ::close(m_fd);
Expand Down
1 change: 1 addition & 0 deletions tpie/file_accessor/win32.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ class win32 {
inline void seek_i(stream_size_type offset); inline void seek_i(stream_size_type offset);
inline void close_i(); inline void close_i();
inline void truncate_i(stream_size_type bytes); inline void truncate_i(stream_size_type bytes);
inline bool is_open() const;


inline void set_cache_hint(cache_hint cacheHint); inline void set_cache_hint(cache_hint cacheHint);
}; };
Expand Down
4 changes: 4 additions & 0 deletions tpie/file_accessor/win32.inl
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ void win32::open_rw_new(const std::string & path) {
if (m_fd == INVALID_HANDLE_VALUE) throw_getlasterror(); if (m_fd == INVALID_HANDLE_VALUE) throw_getlasterror();
} }


bool win32::is_open() const {
return m_fd != INVALID_HANDLE_VALUE;
}

void win32::close_i() { void win32::close_i() {
if (m_fd != INVALID_HANDLE_VALUE) { if (m_fd != INVALID_HANDLE_VALUE) {
CloseHandle(m_fd); CloseHandle(m_fd);
Expand Down
10 changes: 7 additions & 3 deletions tpie/file_base.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -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 /// This is the type of our block buffers. We have one per file::stream
/// distributed over two linked lists. /// distributed over two linked lists.
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
#pragma warning( push ) #ifdef WIN32
#pragma warning( disable : 4200 ) #pragma warning( push )
#pragma warning( disable : 4200 )
#endif
struct block_t : public boost::intrusive::list_base_hook<> { struct block_t : public boost::intrusive::list_base_hook<> {
memory_size_type size; memory_size_type size;
memory_size_type usage; memory_size_type usage;
stream_size_type number; stream_size_type number;
bool dirty; bool dirty;
char data[0]; char data[0];
}; };
#pragma warning( pop ) #ifdef WIN32
#pragma warning( pop )
#endif


inline void update_size(stream_size_type size) { inline void update_size(stream_size_type size) {
m_size = std::max(m_size, size); m_size = std::max(m_size, size);
Expand Down
18 changes: 13 additions & 5 deletions tpie/fractional_progress.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -245,8 +245,10 @@ fractional_subindicator::~fractional_subindicator() {
} else { } else {
s << "A fractional_subindicator was assigned a non-zero fraction but never initialized." << std::endl; s << "A fractional_subindicator was assigned a non-zero fraction but never initialized." << std::endl;
} }
tpie::backtrace(s, 5);
TP_LOG_FATAL(s.str()); TP_LOG_FATAL(s.str());
s.str("");
tpie::backtrace(s, 5);
TP_LOG_DEBUG(s.str());
TP_LOG_FLUSH_LOG; TP_LOG_FLUSH_LOG;
} }
#endif #endif
Expand All @@ -267,8 +269,10 @@ void fractional_progress::init(stream_size_type range) {
std::stringstream s; std::stringstream s;
s << "init() was called on a fractional_progress for which init had already been called. Subindicators were:" << std::endl; s << "init() was called on a fractional_progress for which init had already been called. Subindicators were:" << std::endl;
s << sub_indicators_ss(); s << sub_indicators_ss();
tpie::backtrace(s, 5);
TP_LOG_FATAL(s.str()); TP_LOG_FATAL(s.str());
s.str("");
tpie::backtrace(s, 5);
TP_LOG_DEBUG(s.str());
TP_LOG_FLUSH_LOG; TP_LOG_FLUSH_LOG;
} }
m_init_called=true; m_init_called=true;
Expand All @@ -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 << "done() was called on fractional_progress, but init has not been called. Subindicators were:" << std::endl;
} }
s << sub_indicators_ss(); s << sub_indicators_ss();
tpie::backtrace(s, 5);
TP_LOG_FATAL(s.str()); TP_LOG_FATAL(s.str());
s.str("");
tpie::backtrace(s, 5);
TP_LOG_DEBUG(s.str());
TP_LOG_FLUSH_LOG; TP_LOG_FLUSH_LOG;
} }
m_done_called=true; m_done_called=true;
Expand All @@ -299,10 +305,12 @@ fractional_progress::~fractional_progress() {
#ifndef TPIE_NDEBUG #ifndef TPIE_NDEBUG
if (m_init_called && !m_done_called && !std::uncaught_exception()) { if (m_init_called && !m_done_called && !std::uncaught_exception()) {
std::stringstream s; 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(); s << sub_indicators_ss();
tpie::backtrace(s, 5); tpie::backtrace(s, 5);
TP_LOG_FATAL(s.str()); TP_LOG_DEBUG(s.str());
TP_LOG_FLUSH_LOG; TP_LOG_FLUSH_LOG;
} }
#endif #endif
Expand Down
39 changes: 24 additions & 15 deletions tpie/internal_stack.h
Original file line number Original file line Diff line number Diff line change
@@ -1,6 +1,6 @@
// -*- mode: c++; tab-width: 4; indent-tabs-mode: t; c-file-style: "stroustrup"; -*- // -*- mode: c++; tab-width: 4; indent-tabs-mode: t; c-file-style: "stroustrup"; -*-
// vi:set ts=4 sts=4 sw=4 noet : // 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. // This file is part of TPIE.
// //
Expand Down Expand Up @@ -28,33 +28,42 @@
#include <tpie/internal_stack_vector_base.h> #include <tpie/internal_stack_vector_base.h>
namespace tpie { 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> template <typename T>
class internal_stack: public internal_stack_vector_base<T,internal_stack<T> > { class internal_stack: public internal_stack_vector_base<T,internal_stack<T> > {
public: public:
typedef internal_stack_vector_base<T,internal_stack<T> > parent_t; 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){} internal_stack(size_t size=0): parent_t(size){}

using parent_t::m_elements; using parent_t::m_elements;
using parent_t::m_size; 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];} 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;} 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;} inline void pop(){--m_size;}


}; };
Expand Down
Loading

0 comments on commit e2b2b65

Please sign in to comment.