-
-
Notifications
You must be signed in to change notification settings - Fork 8.2k
windows/thread: Add support for win32 micropython _thread. #7796
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
base: master
Are you sure you want to change the base?
Conversation
Looks good. The thread tests don't run in CI though, would be best to add that. thread_exc2 fails here for all msvc builds:
and thread_thread_stacksize1.py hangs forever for Debug/x64 but does print
For ease of maintainance it's tempting to incorporate this into unix/mpthreadport though since the main difference is pthread vs win32 and the rest of the code is non-trivial, have you considered that? |
That's curious, the unit test results above were from a local msvc build on my laptop, I wonder why there's a difference. I guess I could possibly turn what I've done into a custom wrapper/shim to work with the unix driver, not sure how much value is in that now though. I didn't previously think it was worth it, there really are a fair few differences - the signalling method for thread gc needed a new architecture, the entry needed a wrapper and the waiting for events is a common function vs different functions for each type of object. I had previously tried using a win32-pthreads |
Ah, In terms of ci - yeah it turns out the micropython/tests/run-tests.py Line 806 in 2a7b6d6
|
Yeah i wouldn't go for win32-pthreads especially if you have something which works already. |
2a7b6d6
to
2c121c3
Compare
ports/windows/Makefile
Outdated
@@ -49,6 +50,9 @@ ifeq ($(MICROPY_USE_READLINE),1) | |||
CFLAGS_MOD += -DMICROPY_USE_READLINE=1 | |||
SRC_C += shared/readline/readline.c | |||
endif | |||
# ifeq ($(MICROPY_PY_THREAD),1) |
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.
I'd think MicroPython's policy is to not check in dead code?
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.
Whoops yeah, thanks for that. I initially expected to need MICROPY_PY_THREAD
to be defined in makefile snippet like other ports, ended up not turning out that way as it doesn't need extra linker argurments.
I did push this branch along with the other windows ones I'm working on in a rush before the meetup so didn't do a personal git review properly... sorry for the extra noise :-/
ports/windows/mpthreadport.c
Outdated
// This value seems to be about right for both 32-bit and 64-bit builds. | ||
#define THREAD_STACK_OVERFLOW_MARGIN (8192) | ||
|
||
// this structure forms a linked list, one node per active thread |
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.
Minor nitpick; perhaps this should be enforced by the formatting as well, but it looks a bit off to have half of the comments like // This is a comment.
and the others // this is a comment
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 good point really, I guess it's possibly asking too much to parse for grammer in the auto format checker, but things like this all contribute to the consistency of quality in a project.
2c121c3
to
903daa4
Compare
FWIW my main use case for threads on unix/windows is to enable easy mocking of Timers and similar for running unit tests, a loop in a Thread behaves quite similar to an interrupt in embedded code,m especially if you enforce a gc lock in the mocked function. |
3f3d8fb
to
bed2436
Compare
I assume you're aware that most likely all sleep/wait implementations on windows by default use a 16mSec (or close to that) resolution? Just mentioning because it's a common source of problems in tests which deal with timing. |
I didn't realise that, do you know if that applies to the SleepEx command I've used here? My mock timers are generally less about testing specific exact timing (it's always hard to compare embedded to unix for timing) but more about being able to run the same code on embedded as on desktop and have background tasks run regularly that can interrupt the main application at any point (unlike background async tasks). |
Yes, see https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-sleepex#remarks
Yeah as long as there's nothing which explicitly relies on wait/sleep being accurate (there shouldn't be ideally) it is usually ok, but still, especially with smaller timeouts, things sometimes don't go well. But in any cas: if tests pass there's not much to worry about. |
@andrewleech can you please rebase this on latest master? And also enable thread tests in |
bed2436
to
363a561
Compare
1a9f29c
to
08544d1
Compare
08544d1
to
9f0a4ed
Compare
ports/windows/mpthreadport.c
Outdated
|
||
void mp_thread_mutex_init(mp_thread_mutex_t *mutex) { | ||
// The win32 Mutex is re-entrant, unlike the posix equivalent. | ||
// To avoid this a sepaphore with size of 1 is used. |
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.
spelling: "semaphore"
ports/windows/sleep.c
Outdated
// mingw and the likes provide their own usleep() which we need to | ||
// replace with one that can be interrupted by APC function if needed | ||
// (used in mp_thread_gc) | ||
#undef usleep |
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.
Is this the right way to do things? If usleep
is #define'd to something then that define will be active in all other compilation units. So only the code in this file will pick up this custom usleep
implementation.
Why not just keep it as usleep_impl()
?
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.
Yeah that was a bit strange / wrong. usleep_impl()
was only being used in the single usleep()
wrapper function below on msvc, it was ignored elsewhere. I thought I needed it to be the usleep used everywhere - but this wouldn't have actually been working as you suggest.
Turns out we don't need to provide usleep in any particular global sense, it was only being used in unix/mpconfigport.h to provide mp_hal_delay_us()
so I think it's better to directly provide mp_hal_delay_us()
here for win32 only.
9f0a4ed
to
9d55587
Compare
9d55587
to
6f7d6c5
Compare
This change has broken some tests on AppVeyor:
|
This is an automated heads-up that we've just merged a Pull Request See #13763 A search suggests this PR might apply the STATIC macro to some C code. If it Although this is an automated message, feel free to @-reply to me directly if |
This PR adds support for thread to the windows port with both mingw and msvc compilers.
Passes the test suite: