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
9 years ago
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
...
...
This diff is collapsed.
Click to expand it.
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