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
b9bb90a4
authored
Apr 15, 2019
by
FritzFlorian
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add ttas_spinlock.
parent
14cc1155
Pipeline
#1153
passed with stages
in 3 minutes 29 seconds
Changes
7
Pipelines
1
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
131 additions
and
33 deletions
+131
-33
app/invoke_parallel/main.cpp
+1
-1
lib/pls/CMakeLists.txt
+5
-2
lib/pls/include/pls/internal/base/spin_lock.h
+4
-22
lib/pls/include/pls/internal/base/tas_spin_lock.h
+39
-0
lib/pls/include/pls/internal/base/ttas_spin_lock.h
+39
-0
lib/pls/src/internal/base/tas_spin_lock.cpp
+9
-8
lib/pls/src/internal/base/ttas_spin_lock.cpp
+34
-0
No files found.
app/invoke_parallel/main.cpp
View file @
b9bb90a4
...
...
@@ -34,7 +34,7 @@ long fib(long n) {
int
main
()
{
PROFILE_ENABLE
pls
::
scheduler
scheduler
{
&
my_scheduler_memory
,
2
};
pls
::
scheduler
scheduler
{
&
my_scheduler_memory
,
8
};
long
result
;
scheduler
.
perform_work
([
&
]
{
...
...
lib/pls/CMakeLists.txt
View file @
b9bb90a4
...
...
@@ -5,7 +5,9 @@ add_library(pls STATIC
include/pls/algorithms/invoke_parallel.h
include/pls/algorithms/invoke_parallel_impl.h
include/pls/internal/base/spin_lock.h src/internal/base/spin_lock.cpp
include/pls/internal/base/spin_lock.h
include/pls/internal/base/tas_spin_lock.h src/internal/base/tas_spin_lock.cpp
include/pls/internal/base/ttas_spin_lock.h src/internal/base/ttas_spin_lock.cpp
include/pls/internal/base/thread.h src/internal/base/thread.cpp
include/pls/internal/base/thread_impl.h
include/pls/internal/base/barrier.h src/internal/base/barrier.cpp
...
...
@@ -20,6 +22,7 @@ add_library(pls STATIC
include/pls/internal/helpers/prohibit_new.h
include/pls/internal/helpers/profiler.h
include/pls/internal/helpers/mini_benchmark.h
include/pls/internal/helpers/unique_id.h
include/pls/internal/scheduling/root_task.h src/internal/scheduling/root_task.cpp
include/pls/internal/scheduling/thread_state.h src/internal/scheduling/thread_state.cpp
...
...
@@ -29,7 +32,7 @@ add_library(pls STATIC
include/pls/internal/scheduling/run_on_n_threads_task.h src/internal/scheduling/run_on_n_threads_task.cpp
include/pls/internal/scheduling/fork_join_task.h src/internal/scheduling/fork_join_task.cpp
include/pls/internal/scheduling/scheduler_memory.h src/internal/scheduling/scheduler_memory.cpp
include/pls/internal/helpers/unique_id.h
)
)
# Add everything in `./include` to be in the include path of this project
target_include_directories
(
pls
...
...
lib/pls/include/pls/internal/base/spin_lock.h
View file @
b9bb90a4
...
...
@@ -2,32 +2,14 @@
#ifndef PLS_SPINLOCK_H
#define PLS_SPINLOCK_H
#include <atomic>
#include <iostream>
#include "pls/internal/base/thread.h"
#include "tas_spin_lock.h"
#include "ttas_spin_lock.h"
namespace
pls
{
namespace
internal
{
namespace
base
{
/**
* A simple set and test_and_set based spin lock implementation.
*
* PORTABILITY:
* Current implementation is based on C++ 11 atomic_flag.
*/
class
spin_lock
{
std
::
atomic_flag
flag_
;
unsigned
int
yield_at_tries_
;
public
:
spin_lock
()
:
flag_
{
ATOMIC_FLAG_INIT
},
yield_at_tries_
{
1024
}
{};
spin_lock
(
const
spin_lock
&
other
)
:
flag_
{
ATOMIC_FLAG_INIT
},
yield_at_tries_
{
other
.
yield_at_tries_
}
{}
void
lock
();
void
unlock
();
};
// Default Spin-Lock implementation for this project.
using
spin_lock
=
tas_spin_lock
;
}
}
}
...
...
lib/pls/include/pls/internal/base/tas_spin_lock.h
0 → 100644
View file @
b9bb90a4
#ifndef PLS_TAS_SPIN_LOCK_H
#define PLS_TAS_SPIN_LOCK_H
#include "tas_spin_lock.h"
#include <atomic>
#include <iostream>
#include "pls/internal/base/thread.h"
namespace
pls
{
namespace
internal
{
namespace
base
{
/**
* A simple set and test_and_set based spin lock implementation.
*
* PORTABILITY:
* Current implementation is based on C++ 11 atomic_flag.
*/
class
tas_spin_lock
{
std
::
atomic_flag
flag_
;
unsigned
int
yield_at_tries_
;
public
:
tas_spin_lock
()
:
flag_
{
ATOMIC_FLAG_INIT
},
yield_at_tries_
{
1024
}
{};
tas_spin_lock
(
const
tas_spin_lock
&
other
)
:
flag_
{
ATOMIC_FLAG_INIT
},
yield_at_tries_
{
other
.
yield_at_tries_
}
{}
void
lock
();
bool
try_lock
();
void
unlock
();
};
}
}
}
#endif //PLS_TAS_SPIN_LOCK_H
lib/pls/include/pls/internal/base/ttas_spin_lock.h
0 → 100644
View file @
b9bb90a4
#ifndef PLS_TTAS_SPIN_LOCK_H
#define PLS_TTAS_SPIN_LOCK_H
#include "tas_spin_lock.h"
#include <atomic>
#include <iostream>
#include "pls/internal/base/thread.h"
namespace
pls
{
namespace
internal
{
namespace
base
{
/**
* A simple set and test_and_set based spin lock implementation.
*
* PORTABILITY:
* Current implementation is based on C++ 11 atomic_flag.
*/
class
ttas_spin_lock
{
std
::
atomic
<
int
>
flag_
;
unsigned
int
yield_at_tries_
;
public
:
ttas_spin_lock
()
:
flag_
{
0
},
yield_at_tries_
{
1024
}
{};
ttas_spin_lock
(
const
ttas_spin_lock
&
other
)
:
flag_
{
0
},
yield_at_tries_
{
other
.
yield_at_tries_
}
{}
void
lock
();
bool
try_lock
();
void
unlock
();
};
}
}
}
#endif //PLS_TTAS_SPIN_LOCK_H
lib/pls/src/internal/base/spin_lock.cpp
→
lib/pls/src/internal/base/
tas_
spin_lock.cpp
View file @
b9bb90a4
#include "pls/internal/helpers/profiler.h"
#include "pls/internal/base/spin_lock.h"
#include "pls/internal/base/
tas_
spin_lock.h"
namespace
pls
{
namespace
internal
{
namespace
base
{
// TODO: Research/Measure how the memory fences/orders influence this.
// For now we simply try to be safe by forcing this lock to
// also act as a strict memory fence.
void
spin_lock
::
lock
()
{
void
tas_spin_lock
::
lock
()
{
PROFILE_LOCK
(
"Acquire Lock"
)
int
tries
=
0
;
while
(
flag_
.
test_and_set
(
std
::
memory_order_
seq_cst
))
{
while
(
flag_
.
test_and_set
(
std
::
memory_order_
acquire
))
{
tries
++
;
if
(
tries
%
yield_at_tries_
==
0
)
{
this_thread
::
yield
();
...
...
@@ -18,8 +15,12 @@ namespace pls {
}
}
void
spin_lock
::
unlock
()
{
flag_
.
clear
(
std
::
memory_order_seq_cst
);
bool
tas_spin_lock
::
try_lock
()
{
return
flag_
.
test_and_set
(
std
::
memory_order_acquire
)
==
0
;
}
void
tas_spin_lock
::
unlock
()
{
flag_
.
clear
(
std
::
memory_order_release
);
}
}
}
...
...
lib/pls/src/internal/base/ttas_spin_lock.cpp
0 → 100644
View file @
b9bb90a4
#include "pls/internal/helpers/profiler.h"
#include "pls/internal/base/ttas_spin_lock.h"
namespace
pls
{
namespace
internal
{
namespace
base
{
void
ttas_spin_lock
::
lock
()
{
PROFILE_LOCK
(
"Acquire Lock"
)
int
tries
=
0
;
int
expected
=
0
;
do
{
while
(
flag_
.
load
(
std
::
memory_order_relaxed
)
==
1
)
{
tries
++
;
if
(
tries
%
yield_at_tries_
==
0
)
{
this_thread
::
yield
();
}
}
expected
=
0
;
}
while
(
!
flag_
.
compare_exchange_weak
(
expected
,
1
,
std
::
memory_order_acquire
));
}
bool
ttas_spin_lock
::
try_lock
()
{
int
expected
=
0
;
return
flag_
.
load
(
std
::
memory_order_relaxed
)
==
0
&&
flag_
.
compare_exchange_weak
(
expected
,
1
,
std
::
memory_order_acquire
);
}
void
ttas_spin_lock
::
unlock
()
{
flag_
.
store
(
0
,
std
::
memory_order_release
);
}
}
}
}
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