Commit 812a9a26 by lucapegolotti

Fix style of linearizability_tester.h

parent cc1e3c42
...@@ -81,22 +81,22 @@ using std::make_unique; ...@@ -81,22 +81,22 @@ using std::make_unique;
/// Linearizability tester /// Linearizability tester
namespace lt namespace lt
{ {
/************* Core data structures && algorithms *************/ /************* Core data structures && algorithms *************/
template<class S> template<class S>
class Entry; class Entry;
/// Doubly-linked list of log entries /// Doubly-linked list of log entries
/// S - sequential data type /// S - sequential data type
template<class S> template<class S>
using EntryPtr = Entry<S>*; using EntryPtr = Entry<S>*;
/// Bounded stack of call entries that have been linearized /// Bounded stack of call entries that have been linearized
/// S - sequential data type /// S - sequential data type
template<class S> template<class S>
class Stack class Stack
{ {
private: private:
typedef std::tuple<EntryPtr<S>, S> Pair; typedef std::tuple<EntryPtr<S>, S> Pair;
typedef std::vector<Pair> Pairs; typedef std::vector<Pair> Pairs;
...@@ -164,27 +164,27 @@ namespace lt ...@@ -164,27 +164,27 @@ namespace lt
assert(pos < m_top); assert(pos < m_top);
return std::get<0>(m_vector[pos]); return std::get<0>(m_vector[pos]);
} }
}; };
enum class Option : unsigned char enum class Option : unsigned char
{ {
NEVER_CACHE, NEVER_CACHE,
LRU_CACHE, LRU_CACHE,
ALWAYS_CACHE, ALWAYS_CACHE,
}; };
template<class S> class Entry; template<class S> class Entry;
template<class S> class Log; template<class S> class Log;
template<class S> class ConcurrentLog; template<class S> class ConcurrentLog;
template<class S> class Slicer; template<class S> class Slicer;
template<class S, Option> class LinearizabilityTester; template<class S, Option> class LinearizabilityTester;
/// A kind of "functor" in C++ terminology /// A kind of "functor" in C++ terminology
/// S - sequential data type /// S - sequential data type
template<class S> template<class S>
class Op class Op
{ {
private: private:
friend class Entry<S>; friend class Entry<S>;
...@@ -250,11 +250,11 @@ namespace lt ...@@ -250,11 +250,11 @@ namespace lt
return op.print(os); return op.print(os);
} }
#endif #endif
}; };
/// Fixed-size set of bits with persistence features /// Fixed-size set of bits with persistence features
class Bitset class Bitset
{ {
public: public:
typedef std::size_t Pos; typedef std::size_t Pos;
...@@ -385,36 +385,36 @@ namespace lt ...@@ -385,36 +385,36 @@ namespace lt
return m_number_of_set_bits != other.m_number_of_set_bits || return m_number_of_set_bits != other.m_number_of_set_bits ||
m_blocks != other.m_blocks; m_blocks != other.m_blocks;
} }
}; };
/// Constant-time, O(1), hash function /// Constant-time, O(1), hash function
struct BitsetHash struct BitsetHash
{ {
std::size_t operator()(const Bitset& bitset) const noexcept std::size_t operator()(const Bitset& bitset) const noexcept
{ {
return bitset.m_hash; return bitset.m_hash;
} }
}; };
/// States of abstract data types /// States of abstract data types
namespace state namespace state
{ {
template<class T> template<class T>
struct Hash struct Hash
{ {
std::size_t operator()(const T&) const noexcept; std::size_t operator()(const T&) const noexcept;
}; };
} }
template<class S> template<class S>
using OpPtr = std::unique_ptr<Op<S>>; using OpPtr = std::unique_ptr<Op<S>>;
/// Call/ret log entry /// Call/ret log entry
/// S - sequential data type /// S - sequential data type
template<class S> template<class S>
class Entry class Entry
{ {
private: private:
friend class Log<S>; friend class Log<S>;
friend class Slicer<S>; friend class Slicer<S>;
...@@ -630,13 +630,13 @@ namespace lt ...@@ -630,13 +630,13 @@ namespace lt
{ {
return m_is_call; return m_is_call;
} }
}; };
#ifdef _LT_DEBUG_ #ifdef _LT_DEBUG_
/// S - sequential data type /// S - sequential data type
template<class S> template<class S>
std::ostream& operator<<(std::ostream& os, EntryPtr<S> entry_ptr) std::ostream& operator<<(std::ostream& os, EntryPtr<S> entry_ptr)
{ {
if (entry_ptr == nullptr) if (entry_ptr == nullptr)
return os << "entry id: none, thread id: none [nullptr]"; return os << "entry id: none, thread id: none [nullptr]";
...@@ -646,12 +646,12 @@ namespace lt ...@@ -646,12 +646,12 @@ namespace lt
", thread id: " << entry.thread_id() << ", thread id: " << entry.thread_id() <<
", " << (entry.is_call() ? "call: " : "return: ") << ", " << (entry.is_call() ? "call: " : "return: ") <<
entry.op(); entry.op();
} }
#endif #endif
template<class S> template<class S>
void Stack<S>::push(EntryPtr<S> ptr, S&& s) void Stack<S>::push(EntryPtr<S> ptr, S&& s)
{ {
assert(!is_full()); assert(!is_full());
assert(ptr != nullptr); assert(ptr != nullptr);
assert(ptr->is_call()); assert(ptr->is_call());
...@@ -659,14 +659,14 @@ namespace lt ...@@ -659,14 +659,14 @@ namespace lt
// no overflow // no overflow
m_vector[m_top++] = std::make_pair(ptr, std::move(s)); m_vector[m_top++] = std::make_pair(ptr, std::move(s));
assert(0U != m_top); assert(0U != m_top);
} }
/// Input to linearizabilty testers /// Input to linearizabilty testers
/// S - sequential data type /// S - sequential data type
template<class S> template<class S>
class LogInfo class LogInfo
{ {
private: private:
friend class Slicer<S>; friend class Slicer<S>;
...@@ -706,13 +706,13 @@ namespace lt ...@@ -706,13 +706,13 @@ namespace lt
{ {
return m_log_head_ptr == nullptr && m_number_of_entries == 0U; return m_log_head_ptr == nullptr && m_number_of_entries == 0U;
} }
}; };
#ifdef _LT_DEBUG_ #ifdef _LT_DEBUG_
/// S - sequential data type /// S - sequential data type
template<class S> template<class S>
std::ostream& operator<<(std::ostream& os, const LogInfo<S>& log_info) std::ostream& operator<<(std::ostream& os, const LogInfo<S>& log_info)
{ {
EntryPtr<S> entry_ptr{ log_info.log_head_ptr() }; EntryPtr<S> entry_ptr{ log_info.log_head_ptr() };
os << "log info, number of entries: " << log_info.number_of_entries() << std::endl; os << "log info, number of entries: " << log_info.number_of_entries() << std::endl;
...@@ -720,17 +720,17 @@ namespace lt ...@@ -720,17 +720,17 @@ namespace lt
os << entry_ptr << std::endl; os << entry_ptr << std::endl;
return os; return os;
} }
#endif #endif
/// Bounded history log /// Bounded history log
/// If you need thread-safety, use ConcurrentLog<S> instead. /// If you need thread-safety, use ConcurrentLog<S> instead.
/// ///
/// S - sequential data type /// S - sequential data type
template<class S> template<class S>
class Log class Log
{ {
private: private:
// fixed-size vector // fixed-size vector
typedef std::vector<Entry<S>> Entries; typedef std::vector<Entry<S>> Entries;
...@@ -848,14 +848,14 @@ namespace lt ...@@ -848,14 +848,14 @@ namespace lt
{ {
return{ log_head_ptr(), number_of_entries() }; return{ log_head_ptr(), number_of_entries() };
} }
}; };
/// Output of linearizability tester /// Output of linearizability tester
/// S - sequential data type /// S - sequential data type
template<class S> template<class S>
class Result class Result
{ {
private: private:
friend class LinearizabilityTester<S, Option::NEVER_CACHE>; friend class LinearizabilityTester<S, Option::NEVER_CACHE>;
friend class LinearizabilityTester<S, Option::LRU_CACHE>; friend class LinearizabilityTester<S, Option::LRU_CACHE>;
...@@ -953,12 +953,12 @@ namespace lt ...@@ -953,12 +953,12 @@ namespace lt
} }
} }
#endif #endif
}; };
#ifdef _LT_TIMEOUT_ #ifdef _LT_TIMEOUT_
template <typename Clock = std::chrono::steady_clock> template <typename Clock = std::chrono::steady_clock>
struct Timeout struct Timeout
{ {
const typename Clock::time_point start_time; const typename Clock::time_point start_time;
const typename Clock::duration max_duration; const typename Clock::duration max_duration;
...@@ -974,13 +974,13 @@ namespace lt ...@@ -974,13 +974,13 @@ namespace lt
{ {
return max_duration < (Clock::now() - start_time); return max_duration < (Clock::now() - start_time);
} }
}; };
#endif #endif
/// Least-recently used cache eviction /// Least-recently used cache eviction
template<class Key, class Hash = std::hash<Key>> template<class Key, class Hash = std::hash<Key>>
class LruCache class LruCache
{ {
private: private:
typedef std::list<Key> List; typedef std::list<Key> List;
typedef typename List::iterator ListIterator; typedef typename List::iterator ListIterator;
...@@ -1023,10 +1023,10 @@ namespace lt ...@@ -1023,10 +1023,10 @@ namespace lt
return pair.second; return pair.second;
} }
}; };
namespace cache namespace cache
{ {
// regardless of caching, we need to keep track of the current state of type S // regardless of caching, we need to keep track of the current state of type S
template<class S> template<class S>
using State = std::pair<Bitset, S>; using State = std::pair<Bitset, S>;
...@@ -1097,12 +1097,12 @@ namespace lt ...@@ -1097,12 +1097,12 @@ namespace lt
return std::get<1>(cache.emplace(bs, s)); return std::get<1>(cache.emplace(bs, s));
} }
}; };
} }
/// S - sequential data type /// S - sequential data type
template<class S, Option option = Option::ALWAYS_CACHE> template<class S, Option option = Option::ALWAYS_CACHE>
class LinearizabilityTester class LinearizabilityTester
{ {
private: private:
typedef cache::Switch<S, option> Cache; typedef cache::Switch<S, option> Cache;
...@@ -1329,12 +1329,12 @@ namespace lt ...@@ -1329,12 +1329,12 @@ namespace lt
internal_check(result, disregard_cutoff_entry_id); internal_check(result, disregard_cutoff_entry_id);
#endif #endif
} }
}; };
template<class S, class Duration> template<class S, class Duration>
void compositional_check(Log<S>& log, Result<S> &result, void compositional_check(Log<S>& log, Result<S> &result,
unsigned number_of_partitions, Duration max_duration) unsigned number_of_partitions, Duration max_duration)
{ {
Slicer<S> slicer{ log.info(), number_of_partitions }; Slicer<S> slicer{ log.info(), number_of_partitions };
for (unsigned partition = 0; partition < slicer.number_of_partitions; ++partition) for (unsigned partition = 0; partition < slicer.number_of_partitions; ++partition)
{ {
...@@ -1343,11 +1343,11 @@ namespace lt ...@@ -1343,11 +1343,11 @@ namespace lt
if (!(result.is_timeout() || result.is_linearizable())) if (!(result.is_timeout() || result.is_linearizable()))
break; break;
} }
} }
/// RAII class to ensure a thread becomes unjoinable on all paths /// RAII class to ensure a thread becomes unjoinable on all paths
class Thread class Thread
{ {
private: private:
std::thread m_thread; std::thread m_thread;
...@@ -1387,26 +1387,26 @@ namespace lt ...@@ -1387,26 +1387,26 @@ namespace lt
m_thread = std::move(thread.m_thread); m_thread = std::move(thread.m_thread);
return *this; return *this;
} }
}; };
/// Partition history into sub-histories /// Partition history into sub-histories
/// A slicer partitions the history into independent sub-histories. /// A slicer partitions the history into independent sub-histories.
/// Our partitioning scheme hinges on Theorem 3.6.1 in "The Art of /// Our partitioning scheme hinges on Theorem 3.6.1 in "The Art of
/// Multiprocessor Programming" (Revised Ed.) by Herlihy && Shavit. /// Multiprocessor Programming" (Revised Ed.) by Herlihy && Shavit.
/// ///
/// Typically only associative concurrent abstract data types (ADTs) /// Typically only associative concurrent abstract data types (ADTs)
/// such as sets && hash tables are suitable for this partitioning /// such as sets && hash tables are suitable for this partitioning
/// scheme. && !all operations on such ADTs are always supported. /// scheme. && !all operations on such ADTs are always supported.
/// For example, the partitioning scheme is incompatible with 0-arg /// For example, the partitioning scheme is incompatible with 0-arg
/// operations such as "empty?" on sets. But it is very effective if /// operations such as "empty?" on sets. But it is very effective if
/// we want to only check linearizability of say "insert", "remove" /// we want to only check linearizability of say "insert", "remove"
/// && "contains". /// && "contains".
/// ///
/// S - sequential data type /// S - sequential data type
template<class S> template<class S>
class Slicer class Slicer
{ {
private: private:
typedef std::vector<LogInfo<S>> Sublogs; typedef std::vector<LogInfo<S>> Sublogs;
...@@ -1493,12 +1493,12 @@ namespace lt ...@@ -1493,12 +1493,12 @@ namespace lt
return s_empty_log; return s_empty_log;
} }
}; };
/// S - sequential data type /// S - sequential data type
template<class S> template<class S>
class ConcurrentLog class ConcurrentLog
{ {
private: private:
typedef std::vector<Entry<S>> Entries; typedef std::vector<Entry<S>> Entries;
typedef typename Entries::size_type Size; typedef typename Entries::size_type Size;
...@@ -1601,12 +1601,12 @@ namespace lt ...@@ -1601,12 +1601,12 @@ namespace lt
{ {
return{ log_head_ptr(), number_of_entries() }; return{ log_head_ptr(), number_of_entries() };
} }
}; };
/************* Models for sequential abstract data types *************/ /************* Models for sequential abstract data types *************/
class FlexibleBitset class FlexibleBitset
{ {
public: public:
typedef Bitset::Pos Pos; typedef Bitset::Pos Pos;
...@@ -1669,15 +1669,15 @@ namespace lt ...@@ -1669,15 +1669,15 @@ namespace lt
{ {
return m_bitset.m_hash; return m_bitset.m_hash;
} }
}; };
namespace state namespace state
{ {
namespace internal namespace internal
{ {
template<class S, class Ret> template<class S, class Ret>
struct RetOp : public Op<S> struct RetOp : public Op<S>
{ {
typedef RetOp<S, Ret> Base; typedef RetOp<S, Ret> Base;
const Ret ret; const Ret ret;
...@@ -1694,11 +1694,11 @@ namespace lt ...@@ -1694,11 +1694,11 @@ namespace lt
return os << "ret: " << ret; return os << "ret: " << ret;
} }
#endif #endif
}; };
template<class S, const char* const op_name> template<class S, const char* const op_name>
struct ZeroArgOp : public Op<S> struct ZeroArgOp : public Op<S>
{ {
typedef ZeroArgOp<S, op_name> Base; typedef ZeroArgOp<S, op_name> Base;
ZeroArgOp() ZeroArgOp()
...@@ -1710,11 +1710,11 @@ namespace lt ...@@ -1710,11 +1710,11 @@ namespace lt
return os << op_name << "()"; return os << op_name << "()";
} }
#endif #endif
}; };
template<class S, class Value, const char* const op_name> template<class S, class Value, const char* const op_name>
struct ArgOp : public Op<S> struct ArgOp : public Op<S>
{ {
typedef ArgOp<S, Value, op_name> Base; typedef ArgOp<S, Value, op_name> Base;
const Value value; const Value value;
...@@ -1731,12 +1731,12 @@ namespace lt ...@@ -1731,12 +1731,12 @@ namespace lt
return os << op_name << "(" << std::to_string(value) << ")"; return os << op_name << "(" << std::to_string(value) << ")";
} }
#endif #endif
}; };
} }
/// Byte read-write register with CAS /// Byte read-write register with CAS
class Atomic class Atomic
{ {
public: public:
typedef signed char Value; typedef signed char Value;
...@@ -1978,20 +1978,20 @@ namespace lt ...@@ -1978,20 +1978,20 @@ namespace lt
{ {
return m_value != atomic.m_value; return m_value != atomic.m_value;
} }
}; };
constexpr char Atomic::s_read_op_name[]; constexpr char Atomic::s_read_op_name[];
constexpr char Atomic::s_write_op_name[]; constexpr char Atomic::s_write_op_name[];
template<> template<>
struct Hash<Atomic> struct Hash<Atomic>
{ {
std::size_t operator()(const Atomic& atomic) const noexcept std::size_t operator()(const Atomic& atomic) const noexcept
{ {
return atomic.get() * 193U; return atomic.get() * 193U;
} }
}; };
} }
} }
#endif #endif
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment