Skip to content

cpu/native: use async read for stdio_read() #19002

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Mar 13, 2025

Conversation

benpicco
Copy link
Contributor

@benpicco benpicco commented Dec 1, 2022

Contribution description

The real_read() function will block the thread but won't preempt it.
That means all other threads on the same (or higher) priority level are blocked as RIOT still considers the thread that called stdio_read() as running.

Use async_read/isrpipe to properly block the thread when reading from stdin.

Testing procedure

Run a 2nd thread with the same priority as the main thread:

--- a/tests/shell/main.c
+++ b/tests/shell/main.c
@@ -132,10 +132,28 @@ static int _xfa_test2(int argc, char **argv)
 SHELL_COMMAND(xfa_test2, "xfa test command 2", _xfa_test2);
 SHELL_COMMAND(xfa_test1, "xfa test command 1", _xfa_test1);
 
+#include "thread.h"
+#include "ztimer.h"
+
+static char _stack[1024];
+
+static void *_func(void *arg)
+{
+    while (1) {
+        ztimer_sleep(ZTIMER_MSEC, 1000);
+        puts(arg);
+    }
+
+    return NULL;
+}
+
 int main(void)
 {
     printf("test_shell.\n");
 
+    thread_create(_stack, sizeof(_stack), THREAD_PRIORITY_MAIN, THREAD_CREATE_STACKTEST,
+                  _func, "Hello shell", "periodic");
+
     /* define own shell commands */
     shell_run_once(shell_commands, line_buf, sizeof(line_buf));

On master the periodic "Hello shell" message is never printed.

Issues/PRs references

fixes #16834

@github-actions github-actions bot added Area: cpu Area: CPU/MCU ports Platform: native Platform: This PR/issue effects the native platform labels Dec 1, 2022
@benpicco benpicco requested review from miri64 and kaspar030 December 1, 2022 16:35
@benpicco benpicco added the Type: bug The issue reports a bug / The PR fixes a bug (including spelling errors) label Dec 1, 2022
@benpicco benpicco requested a review from kfessel December 1, 2022 17:04
@benpicco benpicco added the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Dec 2, 2022
@riot-ci
Copy link

riot-ci commented Dec 2, 2022

Murdock results

✔️ PASSED

3ce2264 tests/pkg/lua_loader: disable test on native32

Success Failures Total Runtime
10268 0 10269 13m:14s

Artifacts

@github-actions github-actions bot added Area: Kconfig Area: Kconfig integration Area: tests Area: tests and testing framework labels Dec 2, 2022
@benpicco benpicco requested a review from maribu December 2, 2022 15:22
@benpicco benpicco force-pushed the cpu/native-read_preempt branch from 04cbcef to 9046e8a Compare December 2, 2022 15:31
@benpicco
Copy link
Contributor Author

benpicco commented Dec 2, 2022

@leandrolanzieri do you have an idea how to solve the Kconfig issue?

@benpicco benpicco force-pushed the cpu/native-read_preempt branch from 9046e8a to bfdf538 Compare December 2, 2022 16:26
@github-actions github-actions bot added Area: sys Area: System and removed Area: Kconfig Area: Kconfig integration labels Dec 2, 2022
@benpicco benpicco force-pushed the cpu/native-read_preempt branch from bfdf538 to 42e8122 Compare December 2, 2022 16:34
@github-actions github-actions bot added the Area: examples Area: Example Applications label Dec 2, 2022
Copy link
Contributor

@gschorcht gschorcht left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good and works as expected.

@gschorcht
Copy link
Contributor

Please squash.

@benpicco benpicco force-pushed the cpu/native-read_preempt branch from ebac29d to ad755ef Compare December 20, 2022 19:07
@benpicco
Copy link
Contributor Author

CI will still fail as some tests that use float will now preempt, which triggers #495

@github-actions github-actions bot removed the Area: USB Area: Universal Serial Bus label Feb 9, 2024
@benpicco benpicco force-pushed the cpu/native-read_preempt branch from 17f8f9c to c65dd56 Compare February 9, 2024 18:14
@github-actions github-actions bot added the Area: network Area: Networking label Feb 10, 2024
@benpicco benpicco force-pushed the cpu/native-read_preempt branch from 41ce809 to bc3e7d5 Compare March 12, 2025 23:22
@github-actions github-actions bot removed the Area: pkg Area: External package ports label Mar 12, 2025
The real_read() function will block the thread but won't preempt it.
That means all other thereads on the same (or higher) priority level
are blocked as RIOT still consideres the thread that called stdio_read()
as running.

Use async_read/isrpipe to properly block the thread when reading from
stdin.
It's no longer working on native, but native behaves more like a
real board now.
@benpicco benpicco force-pushed the cpu/native-read_preempt branch from bc3e7d5 to 67ce013 Compare March 12, 2025 23:26
@benpicco benpicco enabled auto-merge March 12, 2025 23:31
@benpicco benpicco force-pushed the cpu/native-read_preempt branch from 67ce013 to 15add22 Compare March 12, 2025 23:47
@benpicco benpicco force-pushed the cpu/native-read_preempt branch from 15add22 to c5eb4ab Compare March 12, 2025 23:50
@benpicco benpicco added this pull request to the merge queue Mar 13, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Mar 13, 2025
@benpicco benpicco force-pushed the cpu/native-read_preempt branch from 125b255 to 3ce2264 Compare March 13, 2025 08:58
@benpicco benpicco added this pull request to the merge queue Mar 13, 2025
Merged via the queue into RIOT-OS:master with commit 5bcddc0 Mar 13, 2025
25 checks passed
@benpicco benpicco deleted the cpu/native-read_preempt branch March 13, 2025 11:37
@mguetschow mguetschow added this to the Release 2025.04 milestone Apr 8, 2025
benpicco added a commit to benpicco/RIOT that referenced this pull request Apr 14, 2025
Now that RIOT-OS#19002 has been merged, the test is also working on `native`.
@mguetschow
Copy link
Contributor

This seems to break when more than STDIO_RX_BUFSIZE characters are input at once on the shell, with

static void _async_read_wrapper(int fd, void *arg) {
uint8_t buf[STDIO_RX_BUFSIZE];
int res = real_read(fd, &buf, sizeof(buf));
if (res > 0) {
isrpipe_write(arg, buf, res);
}
native_async_read_continue(fd);
}

not checking the return value of isrpipe_write. This seems to produce undeterministically garbaged output for shell_readline. This is especially confusing to the user of the shell who configured the shell size to a larger value than the the default 64B.

Not sure what it actually should do with the return value, however :/

Any ideas how to fix that?

@mguetschow
Copy link
Contributor

Oh, interesting:

RIOT/sys/include/shell.h

Lines 102 to 118 in e6a570a

/**
* @brief Default shell buffer size (maximum line length shell can handle)
*
* @warning When terminals that buffer input and send the full command line in
* one go are used on stdin implementations with fast bursts of data,
* it may be necessary to increase the @ref STDIO_RX_BUFSIZE to make
* practical use of this buffer, especially because the current mechanism of
* passing stdin (`isrpipe_t stdin_isrpipe`) does not support backpressure
* and overflows silently. As a consequence, commands through such terminals
* appear to be truncated at @ref STDIO_RX_BUFSIZE bytes (defaulting to 64)
* unless the command is sent in parts (on many terminals, by pressing Ctrl-D
* half way through the command).
*
* For example, this affects systems with direct USB stdio (@ref
* usbus_cdc_acm_stdio) with the default terminal `pyterm`.
*/
#define SHELL_DEFAULT_BUFSIZE (128)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: build system Area: Build system Area: cpu Area: CPU/MCU ports Area: examples Area: Example Applications Area: network Area: Networking Area: sys Area: System Area: tests Area: tests and testing framework CI: no fast fail don't abort PR build after first error CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Platform: native Platform: This PR/issue effects the native platform Type: bug The issue reports a bug / The PR fixes a bug (including spelling errors)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

native getchar is blocking RIOT
5 participants