Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
Actor Framework
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
cpp-libs
Actor Framework
Commits
a21f0ac6
Commit
a21f0ac6
authored
Apr 11, 2011
by
neverlord
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
benchmarking
parent
1c1b11a6
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
207 additions
and
0 deletions
+207
-0
queue_performances/intrusive_sutter_list.hpp
queue_performances/intrusive_sutter_list.hpp
+107
-0
queue_performances/lockfree_list.hpp
queue_performances/lockfree_list.hpp
+100
-0
No files found.
queue_performances/intrusive_sutter_list.hpp
0 → 100644
View file @
a21f0ac6
#ifndef INTRUSIVE_SUTTER_LIST_HPP
#define INTRUSIVE_SUTTER_LIST_HPP
#include <atomic>
#include <boost/thread.hpp>
#include "defines.hpp"
// This implementation is a single-consumer version
// of an example implementation of Herb Sutter:
// http://drdobbs.com/cpp/211601363.
// T is any type
template
<
typename
T
>
class
intrusive_sutter_list
{
public:
struct
node
{
node
(
T
val
=
T
())
:
value
(
val
),
next
(
0
)
{
}
T
value
;
std
::
atomic
<
node
*>
next
;
char
pad
[
CACHE_LINE_SIZE
-
sizeof
(
T
)
-
sizeof
(
std
::
atomic
<
node
*>
)];
};
private:
// one consumer at a time
node
*
m_first
;
char
m_pad1
[
CACHE_LINE_SIZE
-
sizeof
(
node
*
)];
// for one producers at a time
node
*
m_last
;
char
m_pad2
[
CACHE_LINE_SIZE
-
sizeof
(
node
*
)];
// shared among producers
std
::
atomic
<
bool
>
m_producer_lock
;
public:
intrusive_sutter_list
()
{
m_first
=
m_last
=
new
node
;
m_producer_lock
=
false
;
}
~
intrusive_sutter_list
()
{
while
(
m_first
)
{
node
*
tmp
=
m_first
;
m_first
=
tmp
->
next
;
delete
tmp
;
}
}
// takes ownership of what
void
push
(
node
*
tmp
)
{
// acquire exclusivity
while
(
m_producer_lock
.
exchange
(
true
))
{
boost
::
this_thread
::
yield
();
}
// publish & swing last forward
m_last
->
next
=
tmp
;
m_last
=
tmp
;
// release exclusivity
m_producer_lock
=
false
;
}
// returns nullptr on failure
bool
try_pop
(
T
&
result
)
{
// no critical section; only one consumer allowed
node
*
first
=
m_first
;
node
*
next
=
m_first
->
next
;
if
(
next
)
{
// queue is not empty
result
=
next
->
value
;
// take it out of the node
// swing first forward
m_first
=
next
;
// delete old dummy
delete
first
;
// done
return
true
;
}
return
false
;
}
// polls the queue until an element was dequeued
T
pop
()
{
T
result
;
while
(
!
try_pop
(
result
))
{
boost
::
this_thread
::
yield
();
}
return
result
;
}
};
#endif // INTRUSIVE_SUTTER_LIST_HPP
queue_performances/lockfree_list.hpp
0 → 100644
View file @
a21f0ac6
#ifndef LOCKFREE_LIST_HPP
#define LOCKFREE_LIST_HPP
#include <atomic>
#include <boost/thread.hpp>
#include "defines.hpp"
// This implementation is a single-consumer version
// of an example implementation of Herb Sutter:
// http://drdobbs.com/cpp/211601363.
// T is any type
template
<
typename
T
>
class
lockfree_list
{
public:
struct
node
{
node
(
T
val
=
T
())
:
value
(
val
),
next
(
0
)
{
}
T
value
;
std
::
atomic
<
node
*>
next
;
char
pad
[
CACHE_LINE_SIZE
-
sizeof
(
T
)
-
sizeof
(
std
::
atomic
<
node
*>
)];
};
private:
// one consumer at a time
node
*
m_first
;
char
m_pad1
[
CACHE_LINE_SIZE
-
sizeof
(
node
*
)];
// shared among producers
std
::
atomic
<
node
*>
m_last
;
public:
lockfree_list
()
{
m_first
=
m_last
=
new
node
;
}
~
lockfree_list
()
{
while
(
m_first
)
{
node
*
tmp
=
m_first
;
m_first
=
tmp
->
next
;
delete
tmp
;
}
}
// takes ownership of what
void
push
(
node
*
tmp
)
{
// m_last becomes our predecessor
node
*
predecessor
=
m_last
.
load
();
// swing last forward
while
(
!
m_last
.
compare_exchange_weak
(
predecessor
,
tmp
))
{
}
// link pieces together
predecessor
->
next
=
tmp
;
}
// returns nullptr on failure
bool
try_pop
(
T
&
result
)
{
// no critical section; only one consumer allowed
node
*
first
=
m_first
;
node
*
next
=
m_first
->
next
;
if
(
next
)
{
// queue is not empty
result
=
next
->
value
;
// take it out
next
->
value
=
0
;
// of the node
// swing first forward
m_first
=
next
;
// delete old dummy
delete
first
;
// done
return
true
;
}
// queue was empty
return
false
;
}
// polls the queue until an element was dequeued
T
pop
()
{
T
result
;
while
(
!
try_pop
(
result
))
{
boost
::
this_thread
::
yield
();
}
return
result
;
}
};
#endif // LOCKFREE_LIST_HPP
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