Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
las3_pub
/
predictable_parallel_patterns
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
37f7753a
authored
6 years ago
by
FritzFlorian
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix memory order in single write, multiple read lock.
parent
0548562e
master
…
v0.2.0
v0.1
V0.1.1
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
20 additions
and
10 deletions
+20
-10
lib/pls/include/pls/internal/base/system_details.h
+3
-1
lib/pls/include/pls/internal/scheduling/abstract_task.h
+2
-2
lib/pls/src/internal/base/swmr_spin_lock.cpp
+13
-5
lib/pls/src/internal/scheduling/abstract_task.cpp
+2
-2
No files found.
lib/pls/include/pls/internal/base/system_details.h
View file @
37f7753a
...
@@ -3,6 +3,9 @@
...
@@ -3,6 +3,9 @@
#define PLS_SYSTEM_DETAILS_H
#define PLS_SYSTEM_DETAILS_H
#include <cstdint>
#include <cstdint>
#if (COMPILER == MVCC)
#include <emmintrin.h>
#endif
namespace
pls
{
namespace
pls
{
namespace
internal
{
namespace
internal
{
...
@@ -36,7 +39,6 @@ constexpr std::uintptr_t CACHE_LINE_SIZE = 64;
...
@@ -36,7 +39,6 @@ constexpr std::uintptr_t CACHE_LINE_SIZE = 64;
* Choose the implementation appropriate for your compiler-cpu combination.
* Choose the implementation appropriate for your compiler-cpu combination.
*/
*/
#if (COMPILER == MVCC)
#if (COMPILER == MVCC)
#include <emmintrin.h>
inline
void
relax_cpu
()
{
inline
void
relax_cpu
()
{
_mm_pause
();
_mm_pause
();
}
}
...
...
This diff is collapsed.
Click to expand it.
lib/pls/include/pls/internal/scheduling/abstract_task.h
View file @
37f7753a
...
@@ -16,7 +16,7 @@ class abstract_task {
...
@@ -16,7 +16,7 @@ class abstract_task {
private
:
private
:
unsigned
int
depth_
;
unsigned
int
depth_
;
abstract_task
::
id
unique_id_
;
abstract_task
::
id
unique_id_
;
abstract_task
*
child_task_
;
abstract_task
*
volatile
child_task_
;
public
:
public
:
abstract_task
(
const
unsigned
int
depth
,
const
abstract_task
::
id
&
unique_id
)
:
abstract_task
(
const
unsigned
int
depth
,
const
abstract_task
::
id
&
unique_id
)
:
...
@@ -26,7 +26,7 @@ class abstract_task {
...
@@ -26,7 +26,7 @@ class abstract_task {
virtual
void
execute
()
=
0
;
virtual
void
execute
()
=
0
;
void
set_child
(
abstract_task
*
child_task
)
{
child_task_
=
child_task
;
}
void
set_child
(
abstract_task
*
child_task
)
{
child_task_
=
child_task
;
}
abstract_task
*
child
()
{
return
child_task_
;
}
abstract_task
*
child
()
const
{
return
child_task_
;
}
void
set_depth
(
unsigned
int
depth
)
{
depth_
=
depth
;
}
void
set_depth
(
unsigned
int
depth
)
{
depth_
=
depth
;
}
unsigned
int
depth
()
const
{
return
depth_
;
}
unsigned
int
depth
()
const
{
return
depth_
;
}
...
...
This diff is collapsed.
Click to expand it.
lib/pls/src/internal/base/swmr_spin_lock.cpp
View file @
37f7753a
...
@@ -11,7 +11,7 @@ bool swmr_spin_lock::reader_try_lock() {
...
@@ -11,7 +11,7 @@ bool swmr_spin_lock::reader_try_lock() {
return
false
;
return
false
;
}
}
// We think we can enter the region
// We think we can enter the region
readers_
++
;
readers_
.
fetch_add
(
1
,
std
::
memory_order_acquire
)
;
if
(
write_request_
.
load
()
==
1
)
{
if
(
write_request_
.
load
()
==
1
)
{
// Whoops, the writer acquires the lock, so we back off again
// Whoops, the writer acquires the lock, so we back off again
readers_
--
;
readers_
--
;
...
@@ -23,21 +23,29 @@ bool swmr_spin_lock::reader_try_lock() {
...
@@ -23,21 +23,29 @@ bool swmr_spin_lock::reader_try_lock() {
void
swmr_spin_lock
::
reader_unlock
()
{
void
swmr_spin_lock
::
reader_unlock
()
{
PROFILE_LOCK
(
"Release Read Lock"
)
PROFILE_LOCK
(
"Release Read Lock"
)
readers_
--
;
readers_
.
fetch_add
(
-
1
,
std
::
memory_order_release
)
;
}
}
void
swmr_spin_lock
::
writer_lock
()
{
void
swmr_spin_lock
::
writer_lock
()
{
PROFILE_LOCK
(
"Acquire Write Lock"
)
PROFILE_LOCK
(
"Acquire Write Lock"
)
// Tell the readers that we would like to write
// Tell the readers that we would like to write
write_request_
=
1
;
int
expected
;
while
(
true
)
{
expected
=
0
;
if
(
write_request_
.
compare_exchange_weak
(
expected
,
1
,
std
::
memory_order_acquire
))
{
break
;
}
system_details
::
relax_cpu
();
// Spin until WE set the write lock flag
}
// Wait for all of them to exit the critical section
// Wait for all of them to exit the critical section
while
(
readers_
.
load
(
std
::
memory_order_relaxed
)
>
0
)
while
(
readers_
.
load
()
>
0
)
system_details
::
relax_cpu
();
// Spin, not expensive as relaxed load
system_details
::
relax_cpu
();
// Spin, not expensive as relaxed load
}
}
void
swmr_spin_lock
::
writer_unlock
()
{
void
swmr_spin_lock
::
writer_unlock
()
{
PROFILE_LOCK
(
"Release Write Lock"
)
PROFILE_LOCK
(
"Release Write Lock"
)
write_request_
=
0
;
write_request_
.
store
(
0
,
std
::
memory_order_release
)
;
}
}
}
}
...
...
This diff is collapsed.
Click to expand it.
lib/pls/src/internal/scheduling/abstract_task.cpp
View file @
37f7753a
...
@@ -31,7 +31,7 @@ bool abstract_task::steal_work() {
...
@@ -31,7 +31,7 @@ bool abstract_task::steal_work() {
PROFILE_STEALING
(
"Go to our level"
)
PROFILE_STEALING
(
"Go to our level"
)
abstract_task
*
current_task
=
target_state
->
root_task_
;
abstract_task
*
current_task
=
target_state
->
root_task_
;
while
(
current_task
!=
nullptr
&&
current_task
->
depth
()
<
depth
())
{
while
(
current_task
!=
nullptr
&&
current_task
->
depth
()
<
depth
())
{
current_task
=
current_task
->
child
_task_
;
current_task
=
current_task
->
child
()
;
}
}
PROFILE_END_BLOCK
PROFILE_END_BLOCK
...
@@ -48,7 +48,7 @@ bool abstract_task::steal_work() {
...
@@ -48,7 +48,7 @@ bool abstract_task::steal_work() {
}
}
// No success, we need to steal work from a deeper level using 'top level task stealing'
// No success, we need to steal work from a deeper level using 'top level task stealing'
current_task
=
current_task
->
child
_task_
;
current_task
=
current_task
->
child
()
;
}
}
}
}
PROFILE_END_BLOCK
;
PROFILE_END_BLOCK
;
...
...
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