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
540fb8ed
authored
5 years ago
by
FritzFlorian
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Extend context switch example for arm32.
parent
5490e966
Pipeline
#1376
failed with stages
in 34 seconds
Changes
6
Pipelines
1
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
119 additions
and
72 deletions
+119
-72
app/context_switch/CMakeLists.txt
+13
-0
app/context_switch/custom_stack_callback_arm32.s
+15
-0
app/context_switch/custom_stack_callback_x86_64.s
+1
-1
app/context_switch/main.cpp
+89
-0
app/playground/CMakeLists.txt
+1
-1
app/playground/main.cpp
+0
-70
No files found.
app/context_switch/CMakeLists.txt
0 → 100644
View file @
540fb8ed
if
(
CMAKE_SYSTEM_PROCESSOR STREQUAL
"x86_64"
AND CMAKE_SYSTEM_NAME STREQUAL
"Linux"
)
SET
(
SWITCH_ASSEMBLY
"custom_stack_callback_x86_64.s"
)
elseif
(
CMAKE_SYSTEM_PROCESSOR STREQUAL
"arm"
AND CMAKE_SYSTEM_NAME STREQUAL
"Linux"
)
SET
(
SWITCH_ASSEMBLY
"custom_stack_callback_arm32.s"
)
else
()
MESSAGE
(
FATAL_ERROR
"Platform (
${
CMAKE_SYSTEM_PROCESSOR
}
on
${
CMAKE_SYSTEM_NAME
}
) not supported! Please see Readme for instructions to port."
)
endif
()
add_executable
(
playground main.cpp
${
SWITCH_ASSEMBLY
}
)
# Example for adding the library to your app (as a cmake project dependency)
target_link_libraries
(
playground
)
This diff is collapsed.
Click to expand it.
app/context_switch/custom_stack_callback_arm32.s
0 → 100644
View file @
540fb8ed
.arm
.text
.global custom_stack_callback
.type custom_stack_callback, %function
.align 4
custom_stack_callback:
/* r0 new stack adress (passed as parameter) */
/* r4 temporary for restoring old stack (callee saved, so we get the correct value in case of a return) */
push {r4, lr} /* store the callee saved register as required and the return address */
mov r4, sp /* store current stack pointer */
mov sp, r0 /* update stack pointer to new user level stack */
bl callback /* enter next tasks (will not return if continuation is stolen) */
mov sp, r4 /* restore to the old stack pointer */
pop {r4, pc} /* restore the callee saved register as required and returns */
This diff is collapsed.
Click to expand it.
app/
playground/custom_stack_callback
.s
→
app/
context_switch/custom_stack_callback_x86_64
.s
View file @
540fb8ed
.file "custom_stack_callback.s"
.file "custom_stack_callback
_x86_64
.s"
.text
.global custom_stack_callback
.type custom_stack_callback, @function
...
...
This diff is collapsed.
Click to expand it.
app/context_switch/main.cpp
0 → 100644
View file @
540fb8ed
#include <cstdio>
#include <csetjmp>
#include <cstring>
#include <chrono>
using
namespace
std
;
// Settings for stack and benchmark
const
unsigned
int
NUM_RUNS
=
100000
;
const
unsigned
int
STACK_SIZE
=
512
*
1
;
const
unsigned
char
MAGIC_NUMBER
=
(
unsigned
char
)
0xAB
;
// Memory for custom stack and continuation semantics
unsigned
char
custom_stack
[
STACK_SIZE
]
=
{
0
};
jmp_buf
buffer
;
// Example callback function and declaration of our assembly stack switching routine
extern
"C"
{
void
custom_stack_callback
(
void
*
);
void
__attribute__
((
noinline
))
callback
()
{
static
volatile
int
tmp
;
tmp
=
0
;
// Force at least a single memory write
}
}
long
__attribute__
((
noinline
))
measure_function_call
()
{
auto
start_time
=
chrono
::
steady_clock
::
now
();
for
(
unsigned
int
i
=
0
;
i
<
NUM_RUNS
;
i
++
)
{
callback
();
}
auto
end_time
=
chrono
::
steady_clock
::
now
();
return
chrono
::
duration_cast
<
chrono
::
nanoseconds
>
(
end_time
-
start_time
).
count
();
}
long
__attribute__
((
noinline
))
measure_stack_switch
()
{
auto
start_time
=
chrono
::
steady_clock
::
now
();
for
(
unsigned
int
i
=
0
;
i
<
NUM_RUNS
;
i
++
)
{
custom_stack_callback
(
&
custom_stack
[
STACK_SIZE
-
16
]);
}
auto
end_time
=
chrono
::
steady_clock
::
now
();
return
chrono
::
duration_cast
<
chrono
::
nanoseconds
>
(
end_time
-
start_time
).
count
();
}
long
__attribute__
((
noinline
))
measure_continuation
()
{
auto
start_time
=
chrono
::
steady_clock
::
now
();
for
(
unsigned
int
i
=
0
;
i
<
NUM_RUNS
;
i
++
)
{
if
(
setjmp
(
buffer
)
==
0
)
{
custom_stack_callback
(
&
custom_stack
[
STACK_SIZE
-
16
]);
}
}
auto
end_time
=
chrono
::
steady_clock
::
now
();
return
chrono
::
duration_cast
<
chrono
::
nanoseconds
>
(
end_time
-
start_time
).
count
();
}
long
__attribute__
((
noinline
))
measure_continuation_and_jump
()
{
auto
start_time
=
chrono
::
steady_clock
::
now
();
for
(
unsigned
int
i
=
0
;
i
<
NUM_RUNS
;
i
++
)
{
if
(
setjmp
(
buffer
)
==
0
)
{
custom_stack_callback
(
&
custom_stack
[
STACK_SIZE
-
16
]);
longjmp
(
buffer
,
1
);
}
}
auto
end_time
=
chrono
::
steady_clock
::
now
();
return
chrono
::
duration_cast
<
chrono
::
nanoseconds
>
(
end_time
-
start_time
).
count
();
}
int
main
()
{
memset
(
custom_stack
,
MAGIC_NUMBER
,
STACK_SIZE
);
auto
time_cont_jump
=
measure_continuation_and_jump
();
auto
time_cont
=
measure_continuation
();
auto
time_stack
=
measure_stack_switch
();
auto
time_func
=
measure_function_call
();
for
(
unsigned
int
i
=
0
;
i
<
STACK_SIZE
;
i
++
)
{
if
(
custom_stack
[
i
]
!=
MAGIC_NUMBER
)
{
printf
(
"Used stack size about %u bytes.
\n\n\n
"
,
(
STACK_SIZE
-
i
));
break
;
}
}
printf
(
"Function Call : %10ld, %5.5f
\n
"
,
time_func
,
((
float
)
time_func
/
NUM_RUNS
));
printf
(
"Stack Switching : %10ld, %5.5f
\n
"
,
time_stack
,
((
float
)
time_stack
/
NUM_RUNS
));
printf
(
"Full Continuation: %10ld, %5.5f
\n
"
,
time_cont
,
((
float
)
time_cont
/
NUM_RUNS
));
printf
(
"Jump Continuation: %10ld, %5.5f
\n
"
,
time_cont_jump
,
((
float
)
time_cont_jump
/
NUM_RUNS
));
return
0
;
}
This diff is collapsed.
Click to expand it.
app/playground/CMakeLists.txt
View file @
540fb8ed
add_executable
(
playground main.cpp
custom_stack_callback.s
)
add_executable
(
playground main.cpp
)
# Example for adding the library to your app (as a cmake project dependency)
target_link_libraries
(
playground
)
This diff is collapsed.
Click to expand it.
app/playground/main.cpp
View file @
540fb8ed
#include <cstdio>
#include <csetjmp>
#include <cstring>
#include <chrono>
using
namespace
std
;
// Settings for stack and benchmark
const
unsigned
int
NUM_RUNS
=
100000
;
const
unsigned
int
STACK_SIZE
=
512
*
1
;
const
unsigned
char
MAGIC_NUMBER
=
(
unsigned
char
)
0xAB
;
// Memory for custom stack and continuation semantics
unsigned
char
custom_stack
[
STACK_SIZE
]
=
{
0
};
jmp_buf
buffer
;
// Example callback function and declaration of our assembly stack switching routine
extern
"C"
{
void
custom_stack_callback
(
void
*
);
void
__attribute__
((
noinline
))
callback
()
{
static
volatile
int
tmp
;
tmp
=
0
;
// Force at least a single memory write
}
}
long
__attribute__
((
noinline
))
measure_function_call
()
{
auto
start_time
=
chrono
::
steady_clock
::
now
();
for
(
unsigned
int
i
=
0
;
i
<
NUM_RUNS
;
i
++
)
{
callback
();
}
auto
end_time
=
chrono
::
steady_clock
::
now
();
return
chrono
::
duration_cast
<
chrono
::
nanoseconds
>
(
end_time
-
start_time
).
count
();
}
long
__attribute__
((
noinline
))
measure_stack_switch
()
{
auto
start_time
=
chrono
::
steady_clock
::
now
();
for
(
unsigned
int
i
=
0
;
i
<
NUM_RUNS
;
i
++
)
{
custom_stack_callback
(
&
custom_stack
[
STACK_SIZE
-
16
]);
}
auto
end_time
=
chrono
::
steady_clock
::
now
();
return
chrono
::
duration_cast
<
chrono
::
nanoseconds
>
(
end_time
-
start_time
).
count
();
}
long
__attribute__
((
noinline
))
measure_continuation
()
{
auto
start_time
=
chrono
::
steady_clock
::
now
();
for
(
unsigned
int
i
=
0
;
i
<
NUM_RUNS
;
i
++
)
{
if
(
setjmp
(
buffer
)
==
0
)
{
custom_stack_callback
(
&
custom_stack
[
STACK_SIZE
-
16
]);
}
}
auto
end_time
=
chrono
::
steady_clock
::
now
();
return
chrono
::
duration_cast
<
chrono
::
nanoseconds
>
(
end_time
-
start_time
).
count
();
}
int
main
()
{
memset
(
custom_stack
,
MAGIC_NUMBER
,
STACK_SIZE
);
auto
time_cont
=
measure_continuation
();
auto
time_stack
=
measure_stack_switch
();
auto
time_func
=
measure_function_call
();
for
(
unsigned
int
i
=
0
;
i
<
STACK_SIZE
;
i
++
)
{
if
(
custom_stack
[
i
]
!=
MAGIC_NUMBER
)
{
printf
(
"Used stack size about %u bytes.
\n\n\n
"
,
(
STACK_SIZE
-
i
));
break
;
}
}
printf
(
"Function Call : %10ld, %5.5f
\n
"
,
time_func
,
((
float
)
time_func
/
NUM_RUNS
));
printf
(
"Stack Switching : %10ld, %5.5f
\n
"
,
time_stack
,
((
float
)
time_stack
/
NUM_RUNS
));
printf
(
"Full Continuation: %10ld, %5.5f
\n
"
,
time_cont
,
((
float
)
time_cont
/
NUM_RUNS
));
return
0
;
}
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