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
Apr 18, 2019
by
FritzFlorian
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix memory order in single write, multiple read lock.
parent
0548562e
Hide 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 @@
#define PLS_SYSTEM_DETAILS_H
#include <cstdint>
#if (COMPILER == MVCC)
#include <emmintrin.h>
#endif
namespace
pls
{
namespace
internal
{
...
...
@@ -36,7 +39,6 @@ constexpr std::uintptr_t CACHE_LINE_SIZE = 64;
* Choose the implementation appropriate for your compiler-cpu combination.
*/
#if (COMPILER == MVCC)
#include <emmintrin.h>
inline
void
relax_cpu
()
{
_mm_pause
();
}
...
...
lib/pls/include/pls/internal/scheduling/abstract_task.h
View file @
37f7753a
...
...
@@ -16,7 +16,7 @@ class abstract_task {
private
:
unsigned
int
depth_
;
abstract_task
::
id
unique_id_
;
abstract_task
*
child_task_
;
abstract_task
*
volatile
child_task_
;
public
:
abstract_task
(
const
unsigned
int
depth
,
const
abstract_task
::
id
&
unique_id
)
:
...
...
@@ -26,7 +26,7 @@ class abstract_task {
virtual
void
execute
()
=
0
;
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
;
}
unsigned
int
depth
()
const
{
return
depth_
;
}
...
...
lib/pls/src/internal/base/swmr_spin_lock.cpp
View file @
37f7753a
...
...
@@ -11,7 +11,7 @@ bool swmr_spin_lock::reader_try_lock() {
return
false
;
}
// We think we can enter the region
readers_
++
;
readers_
.
fetch_add
(
1
,
std
::
memory_order_acquire
)
;
if
(
write_request_
.
load
()
==
1
)
{
// Whoops, the writer acquires the lock, so we back off again
readers_
--
;
...
...
@@ -23,21 +23,29 @@ bool swmr_spin_lock::reader_try_lock() {
void
swmr_spin_lock
::
reader_unlock
()
{
PROFILE_LOCK
(
"Release Read Lock"
)
readers_
--
;
readers_
.
fetch_add
(
-
1
,
std
::
memory_order_release
)
;
}
void
swmr_spin_lock
::
writer_lock
()
{
PROFILE_LOCK
(
"Acquire Write Lock"
)
// 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
while
(
readers_
.
load
(
std
::
memory_order_relaxed
)
>
0
)
while
(
readers_
.
load
()
>
0
)
system_details
::
relax_cpu
();
// Spin, not expensive as relaxed load
}
void
swmr_spin_lock
::
writer_unlock
()
{
PROFILE_LOCK
(
"Release Write Lock"
)
write_request_
=
0
;
write_request_
.
store
(
0
,
std
::
memory_order_release
)
;
}
}
...
...
lib/pls/src/internal/scheduling/abstract_task.cpp
View file @
37f7753a
...
...
@@ -31,7 +31,7 @@ bool abstract_task::steal_work() {
PROFILE_STEALING
(
"Go to our level"
)
abstract_task
*
current_task
=
target_state
->
root_task_
;
while
(
current_task
!=
nullptr
&&
current_task
->
depth
()
<
depth
())
{
current_task
=
current_task
->
child
_task_
;
current_task
=
current_task
->
child
()
;
}
PROFILE_END_BLOCK
...
...
@@ -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'
current_task
=
current_task
->
child
_task_
;
current_task
=
current_task
->
child
()
;
}
}
PROFILE_END_BLOCK
;
...
...
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