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;
...
@@ -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
...
...
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