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
d3b64a85
authored
5 years ago
by
FritzFlorian
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
WIP: Initialization of continuation chains.
parent
740ae661
Pipeline
#1333
failed with stages
in 25 seconds
Changes
3
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
73 additions
and
10 deletions
+73
-10
lib/pls/include/pls/internal/data_structures/delayed_initialization_wrapper.h
+9
-1
lib/pls/include/pls/internal/scheduling/cont_manager.h
+38
-5
lib/pls/include/pls/internal/scheduling/continuation.h
+26
-4
No files found.
lib/pls/include/pls/internal/data_structures/delayed_initialization_wrapper.h
View file @
d3b64a85
...
@@ -35,11 +35,19 @@ class delayed_initialization_wrapper {
...
@@ -35,11 +35,19 @@ class delayed_initialization_wrapper {
template
<
typename
...
ARGS
>
template
<
typename
...
ARGS
>
void
initialize
(
ARGS
&&
...
args
)
{
void
initialize
(
ARGS
&&
...
args
)
{
PLS_ASSERT
(
initialized_
,
"Can only initialize delayed wrapper object once!"
)
PLS_ASSERT
(
!
initialized_
,
"Can only initialize delayed wrapper object once!"
)
new
(
memory_
)
T
(
std
::
forward
<
ARGS
>
(
args
)...);
new
(
memory_
)
T
(
std
::
forward
<
ARGS
>
(
args
)...);
initialized_
=
true
;
initialized_
=
true
;
}
}
void
destroy
()
{
PLS_ASSERT
(
initialized_
,
"Can only destroy initialized objects!"
)
memory_
->~
T
();
initialized_
=
false
;
}
T
&
object
()
{
T
&
object
()
{
PLS_ASSERT
(
initialized_
,
"Can not use an uninitialized delayed wrapper object!"
)
PLS_ASSERT
(
initialized_
,
"Can not use an uninitialized delayed wrapper object!"
)
return
*
reinterpret_cast
<
T
*>
(
memory_
);
return
*
reinterpret_cast
<
T
*>
(
memory_
);
...
...
This diff is collapsed.
Click to expand it.
lib/pls/include/pls/internal/scheduling/cont_manager.h
View file @
d3b64a85
...
@@ -3,6 +3,8 @@
...
@@ -3,6 +3,8 @@
#define PLS_CONT_MANAGER_H_
#define PLS_CONT_MANAGER_H_
#include <memory>
#include <memory>
#include <tuple>
#include <array>
#include "pls/internal/data_structures/aligned_stack.h"
#include "pls/internal/data_structures/aligned_stack.h"
#include "pls/internal/scheduling/continuation.h"
#include "pls/internal/scheduling/continuation.h"
...
@@ -13,14 +15,45 @@ namespace scheduling {
...
@@ -13,14 +15,45 @@ namespace scheduling {
class
cont_manager
{
class
cont_manager
{
public
:
public
:
explicit
cont_manager
(
size_t
num_conts
,
size_t
max_cont_size
,
data_structures
::
aligned_stack
&
cont_storage
)
template
<
size_t
NUM_CONTS
,
size_t
MAX_CONT_SIZE
>
:
num_conts_
{
num_conts
},
max_cont_size_
{
max_cont_size
},
cont_storage_
{
cont_storage
}
{
explicit
cont_manager
(
data_structures
::
aligned_stack
&
cont_storage
)
{
//TODO: Init linked list like structure
// First node is currently active and our local start
start_node_
=
active_node_
=
init_cont_node
<
MAX_CONT_SIZE
>
(
cont_storage
,
nullptr
,
nullptr
);
// Build up chain after it
continuation_node
*
current_node
=
start_node_
;
for
(
size_t
i
=
1
;
i
<
NUM_CONTS
;
i
++
)
{
continuation_node
*
next_node
=
init_cont_node
<
MAX_CONT_SIZE
>
(
cont_storage
,
start_node_
,
current_node
);
current_node
->
set_prev
(
next_node
);
}
};
};
continuation_node
*
fast_path_get_next
()
{
active_node_
=
active_node_
->
get_next
();
return
active_node_
;
}
void
fast_path_return
()
{
active_node_
=
active_node_
->
get_prev
();
}
private
:
template
<
size_t
MAX_CONT_SIZE
>
static
continuation_node
*
init_cont_node
(
data_structures
::
aligned_stack
&
cont_storage
,
continuation_node
*
cont_chain_start
,
continuation_node
*
prev
)
{
// Represents one cont node and its corresponding memory buffer (as one continuous block of memory).
using
cont_node_memory_pair
=
std
::
tuple
<
continuation_node
,
std
::
array
<
char
,
MAX_CONT_SIZE
-
sizeof
(
continuation_node
)
>>
;
char
*
tuple_memory
=
cont_storage
.
push_bytes
<
cont_node_memory_pair
>
();
char
*
cont_node_address
=
tuple_memory
;
char
*
cont_node_memory_address
=
tuple_memory
+
sizeof
(
continuation_node
);
return
new
(
cont_node_address
)
continuation_node
(
cont_node_memory_address
,
cont_chain_start
,
prev
);
}
private
:
private
:
con
st
size_t
num_conts_
,
max_cont_siz
e_
;
con
tinuation_node
*
start_nod
e_
;
data_structures
::
aligned_stack
&
cont_storag
e_
;
continuation_node
*
active_nod
e_
;
};
};
template
<
size_t
NUM_CONTS
,
size_t
MAX_CONT_SIZE
>
template
<
size_t
NUM_CONTS
,
size_t
MAX_CONT_SIZE
>
...
...
This diff is collapsed.
Click to expand it.
lib/pls/include/pls/internal/scheduling/continuation.h
View file @
d3b64a85
...
@@ -20,10 +20,27 @@ class base_continuation {
...
@@ -20,10 +20,27 @@ class base_continuation {
class
continuation_node
{
class
continuation_node
{
public
:
public
:
continuation_node
(
char
*
continuation_memory
,
continuation_node
*
cont_chain_start
,
continuation_node
*
prev
)
:
continuation_memory_
{
continuation_memory
},
continuation_
{
nullptr
},
cont_chain_start_
{
cont_chain_start
},
prev_
{
prev
},
next_
{
nullptr
},
offered_chain_
{
nullptr
}
{}
void
set_cont_chain_start
(
continuation_node
*
cont_chain_start
)
{
cont_chain_start_
=
cont_chain_start
;
}
continuation_node
*
get_cont_chain_start
()
{
return
cont_chain_start_
;
}
void
set_next
(
continuation_node
*
next
)
{
next_
=
next
;
}
continuation_node
*
get_next
()
{
return
next_
;
}
void
set_prev
(
continuation_node
*
prev
)
{
prev_
=
prev
;
}
continuation_node
*
get_prev
()
{
return
prev_
;
}
base_continuation
*
continuation
()
{
return
continuation_
;
}
private
:
private
:
// Pointer to memory region reserved for the companion continuation.
// Pointer to memory region reserved for the companion continuation.
// Must be a buffer big enough to hold any continuation encountered in the program.
// Must be a buffer big enough to hold any continuation encountered in the program.
char
*
continuation_memory_
;
base_continuation
*
continuation_
;
base_continuation
*
continuation_
;
// Linked list property of continuations (continuation chains as memory management).
// Linked list property of continuations (continuation chains as memory management).
...
@@ -47,6 +64,10 @@ class continuation : public base_continuation {
...
@@ -47,6 +64,10 @@ class continuation : public base_continuation {
// E.g. handle passing the result to the parent continuation
// E.g. handle passing the result to the parent continuation
function_
.
object
()(
result_1_
.
object
(),
result_2_
.
object
());
function_
.
object
()(
result_1_
.
object
(),
result_2_
.
object
());
}
}
// Warning: De-constructor only called once the continuation is actually needed.
// This should be a non issue, as all memory in the continuation is uninitialized
// until the first use anyways to save runtime.
~
continuation
()
override
=
default
;
~
continuation
()
override
=
default
;
template
<
typename
R1ARG
>
template
<
typename
R1ARG
>
...
@@ -76,14 +97,15 @@ class continuation : public base_continuation {
...
@@ -76,14 +97,15 @@ class continuation : public base_continuation {
template
<
typename
T
>
template
<
typename
T
>
using
delayed_init
=
data_structures
::
delayed_initialization_wrapper
<
T
>
;
using
delayed_init
=
data_structures
::
delayed_initialization_wrapper
<
T
>
;
delayed_init
<
R1
>
result_1_
;
delayed_init
<
R2
>
result_2_
;
delayed_init
<
F
>
function_
;
// Also uninitialized at first, only take the atomic write on the slow path.
// Also uninitialized at first, only take the atomic write on the slow path.
// The stealer will init it to 2 while stealing, the 'stolen' sync will then make sure
// The stealer will init it to 2 while stealing, the 'stolen' sync will then make sure
// everyone sees the value in correct order.
// everyone sees the value in correct order.
std
::
atomic
<
unsigned
short
>
results_missing_
{};
std
::
atomic
<
unsigned
short
>
results_missing_
{};
// All fields/actual values stay uninitialized (save time on the fast path if we don not need them).
delayed_init
<
R1
>
result_1_
;
delayed_init
<
R2
>
result_2_
;
delayed_init
<
F
>
function_
;
};
};
}
}
...
...
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