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
Jan 13, 2020
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
Hide 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
)
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 */
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
...
...
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
;
}
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
)
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
;
}
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