-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
tests/thread_float: improve and add script #16901
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
Testing for Absence of Interactions between Floating Point Calculations and Context Switches | ||
============================================================================================ | ||
|
||
This tests launches three threads, t1, t2 and t3 that will perform a long and costly series of | ||
floating point calculations with different input data, while a software timer triggers context | ||
switches. The threads t1 and t3 will print the results. All threads will do this in an endless | ||
loop. | ||
|
||
This allows for testing the following: | ||
|
||
1. When using the pseudo module `printf_float`, floating point numbers can be correctly printed | ||
2. `THREAD_STACKSIZE_MAIN` is large enough to print floats without stack overflows. | ||
3. Context switches while the (soft) FPU is busy does not result in precision loss. | ||
- This could happen if the FPU state is not properly saved / restored on context switch. This | ||
could be needed if the FPU internally uses a higher resolution that `float` / `double` | ||
(e.g. the x86 FPU uses 80 bits internally, instead of 64 bits for double) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
#!/usr/bin/env python3 | ||
|
||
# Copyright (C) 2021 Otto-von-Guericke-Universität Magdeburg | ||
# | ||
# This file is subject to the terms and conditions of the GNU Lesser | ||
# General Public License v2.1. See the file LICENSE in the top level | ||
# directory for more details. | ||
|
||
# @author Marian Buschsieweke <marian.buschsieweke@ovgu.de> | ||
|
||
import sys | ||
from testrunner import run | ||
|
||
MIN_PRINTS = 5 | ||
|
||
|
||
def assertAlmostEqual(first, second, delta=0.05): | ||
assert first + delta > second | ||
assert first - delta < second | ||
|
||
|
||
def same_computation_as_in_c_prog(thread_num): | ||
f = 1.0 * thread_num | ||
for _ in range(10000): | ||
f = f + 1.0 / f | ||
return f | ||
|
||
|
||
def testfunc(child): | ||
child.expect_exact("THREADS CREATED") | ||
child.expect_exact("THREAD t1 start") | ||
child.expect_exact("THREAD t2 start") | ||
child.expect_exact("THREAD t3 start") | ||
|
||
child.expect(r"t(\d): (\d{3}\.\d+)\r\n") | ||
first_thread = int(child.match.group(1)) | ||
# Note: intentionally keeping the float output as string to also test that printf("%f", ...) | ||
# prints the exact same char sequence for the same float value each time | ||
first_result = child.match.group(2) | ||
|
||
# wait for second thread to print, but wait at most 50 messages | ||
second_thread = None | ||
for _ in range(50): | ||
child.expect(r"t(\d): (\d{3}\.\d+)\r\n") | ||
if int(child.match.group(1)) != first_thread: | ||
second_thread = int(child.match.group(1)) | ||
second_result = child.match.group(2) | ||
break | ||
|
||
assert second_thread is not None, "both threads t1 and t3 should print" | ||
assert first_thread in [1, 3], "only thread t1 and t3 should print" | ||
assert second_thread in [1, 3], "only thread t1 and t3 should print" | ||
assertAlmostEqual(float(first_result), same_computation_as_in_c_prog(first_thread)) | ||
assertAlmostEqual(float(second_result), same_computation_as_in_c_prog(second_thread)) | ||
|
||
count_first_thread = 0 | ||
count_second_thread = 0 | ||
|
||
# wait for both threads to print at least MIN_PRINTS times, but wait at most 100 messages | ||
for _ in range(100): | ||
child.expect(r"t(\d): (\d{3}\.\d+)\r\n") | ||
thread = int(child.match.group(1)) | ||
assert thread in [1, 3], "only thread t1 and t3 should print" | ||
result = child.match.group(2) | ||
|
||
if thread == first_thread: | ||
assert result == first_result, "same calculation but different result" | ||
count_first_thread += 1 | ||
else: | ||
assert result == second_result, "same calculation but different result" | ||
count_second_thread += 1 | ||
|
||
if (count_first_thread >= MIN_PRINTS) and (count_second_thread >= MIN_PRINTS): | ||
break | ||
|
||
msg = f"Either t1 or t3 printed less than {MIN_PRINTS} times within 100 messages" | ||
assert (count_first_thread >= MIN_PRINTS) and (count_second_thread >= MIN_PRINTS), msg | ||
|
||
|
||
if __name__ == "__main__": | ||
sys.exit(run(testfunc)) |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a useful function that could be used elsewhere I think. Maybe add it in testrunner (any opinion for a better place?) and import it from there ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See #16901 (comment). Maybe then it is better to implement this test as a
PexpectTestCase
instead.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the function is two lines, it might be easier for the occasional Python reader to just look through the code instead of having to consult the documentation.