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