-
Notifications
You must be signed in to change notification settings - Fork 6.8k
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
posix: sched: Implement sched_getparam() and sched_getscheduler() #67028
Conversation
70ac9c5
to
64a15b4
Compare
64a15b4
to
8bd3471
Compare
ef03798
to
8218bea
Compare
6495257
to
2fbb113
Compare
lib/posix/posix_internal.h
Outdated
* must be already initialized whereas valid PID should | ||
* have positive value. | ||
*/ | ||
static inline pthread_t z_get_tid(pid_t pid) |
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.
Personally, I would welcome proper support for separate Process IDs and processes done the right way at the kernel level, but it's probably not a good idea to try and implement a PID structure outside of the kernel.
Currently, we can only assume there is at most 1 process ID (maybe 2 in a sense) and that Zephyr runs in a single-process environment.
Of course, if you have plans to add that functionality to the kernel, it would be quite important to submit that as an RFC first. That would be very interesting.
https://github.com/zephyrproject-rtos/zephyr/issues/new/choose
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.
Personally, I would welcome proper support for separate Process IDs and processes done the right way at the kernel level, but it's probably not a good idea to try and implement a PID structure outside of the kernel.
I agree, that's why I'm trying to have a single wrapper function here at POSIX API level which can be later adjusted to whatever decision (or not ?) will be at the Zephyr kernel in regard of Process object and its PID going in the opposite way from POSIX standard's history perspective.
There is a bunch of POSIX APIs with pid_t
parameters and in case of sched_*
they need to be related to a thread, so we can assume for now that PID value maps 1:1 to the 'main' thread's id.
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.
will be at the Zephyr kernel in regard of Process object and its PID going in the opposite way from POSIX standard's history perspective.
Can you please clarify?
There is a bunch of POSIX APIs with pid_t parameters and in case of sched_* they need to be related to a thread, so we can assume for now that PID value maps 1:1 to the 'main' thread's id.
I'm not sure if they need to be related to a thread or should even be related to a single thread. sched_getparam()
, and sched_getscheduler()
operate on processes (groups of threads) according to
https://pubs.opengroup.org/onlinepubs/9699919799/functions/sched_getparam.html
https://pubs.opengroup.org/onlinepubs/9699919799/functions/sched_getscheduler.html
I get the impression that your reference in this PR is the Linux implementation of these calls.
https://linux.die.net/man/2/sched_getscheduler
Is that correct? If so, then this PR makes significantly more sense
The scheduling policy and parameters are in fact per-thread attributes on Linux. The value returned from a call to gettid(2) can be passed in the argument pid. Specifying pid as 0 will operate on the attribute for the calling thread, and passing the value returned from a call to getpid(2) will operate on the attribute for the main thread of the thread group.
Of course, the following is directly from the same page...
(If you are using the POSIX threads API, then use pthread_setschedparam(3), pthread_getschedparam(3), and pthread_setschedprio(3), instead of the sched_*(2) system calls.)
So I believe it's really only appropriate in Linux to use sched_getparam()
and sched_getscheduler()
to query (and analogously, sched_setparam()
and sched_setscheduler()
to modify) the scheduling parameters of individual threads.
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.
will be at the Zephyr kernel in regard of Process object and its PID going in the opposite way from POSIX standard's history perspective.
Can you please clarify?
well, I just mean that threads were accepted into POSIX after processes, as an extension, and now for Zephyr it is a kind of opposite task to implement processes having threads already.
I get the impression that your reference in this PR is the Linux implementation of these calls.
https://linux.die.net/man/2/sched_getscheduler
Is that correct? If so, then this PR makes significantly more sense
GNU libc, Linux NTPL, and the APUE book
I had no intention to suggest any solution for Zephyr process design in this tiny PR )), rather a proposal to discuss it and possibly do something meaningful with these sched_get* functions instead of simply return 'not-yet-implemented'.
lib/posix/sched.c
Outdated
struct sched_param dummy_param = {0}; | ||
pthread_t tid = 0; | ||
int t_policy = -1; | ||
int ret = -1; | ||
|
||
if (param == NULL) { | ||
param = &dummy_param; | ||
} | ||
|
||
tid = (pid == 0) ? pthread_self() : z_get_tid(pid); | ||
|
||
ret = pthread_getschedparam(tid, &t_policy, param); | ||
errno = ret; | ||
|
||
return ((ret) ? -1 : 0); |
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.
It might be more in line with the POSIX specification to simply return -1
and set errno to ENOSYS
here, since Zephyr does not (yet) support processes or process scheduling.
https://pubs.opengroup.org/onlinepubs/9699919799/functions/sched_getparam.html
struct sched_param dummy_param = {0}; | |
pthread_t tid = 0; | |
int t_policy = -1; | |
int ret = -1; | |
if (param == NULL) { | |
param = &dummy_param; | |
} | |
tid = (pid == 0) ? pthread_self() : z_get_tid(pid); | |
ret = pthread_getschedparam(tid, &t_policy, param); | |
errno = ret; | |
return ((ret) ? -1 : 0); | |
ARG_UNUSED(pid); | |
ARG_UNUSED(param); | |
errno = ENOSYS; | |
return -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.
It might be more in line with the POSIX specification to simply return
-1
and set errno toENOSYS
here, since Zephyr does not (yet) support processes or process scheduling.
what do you think if we deal only with pid==0
for pthread_self()
and errno EINVAL
otherwise ?
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.
It might be more in line with the POSIX specification to simply return
-1
and set errno toENOSYS
here, since Zephyr does not (yet) support processes or process scheduling.what do you think if we deal only with
pid==0
forpthread_self()
and errnoEINVAL
otherwise ?
There is still a chance for a great deal of inconsistency, even from the perspective of just querying the policy / priority.
For example, Thread A and Thread B are both threads that belong to pid zero (i.e. are part of the same process), but when one looks at them, they see that the individual thread-level scheduling policy and priority are different. So inherently, we are conflating process scheduling and thread scheduling.
The situation can even get a bit more worrisome when one considers that some threads might be running in Kernel mode, and others in user mode.
I think in order to do what Linux does (and I'm not saying it's wrong - that would be kind of nice), there would need to be support from the kernel for essentially threads being equivalent to lightweight processes (which is what Linux does), and for the kernel to support processes as well (and for the main thread of a given process to be equivalent to its PID).
It's a fantastically interesting area for potential improvement, but I would not want to jump ahead of the kernel / architecture on it.
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.
ok, removed.
The situation can even get a bit more worrisome when one considers that some threads might be running in Kernel mode, and others in user mode.
yeah, its another design question on what to do with kernel/user threads at the posix subsys level.
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.
Quite happy for the contribution. Some changes requested to better reflect the fact that Zephyr currently does not support processes or scheduling of processes, but otherwise, looks OK.
Documentation changes should also be in a separate commit.
Thanks!
do you mean to put 'yes' here - https://github.com/zephyrproject-rtos/zephyr/blob/main/doc/services/portability/posix/option_groups/index.rst?plain=1#L449-L450 |
#define sched_getparam(...) zap_sched_getparam(__VA_ARGS__) | ||
#define sched_getscheduler(...) zap_sched_getscheduler(__VA_ARGS__) |
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 don't know if this is necessary as part of this PR. I would maybe suggest making it in a separate PR.
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 thought to do it same way how other APIs were introduced back then (6 years ago!) keeping related changes together in the same PR
@aescolar, what do you think ?
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.
It is not necessary but quite harmless.
Background: This POSIX API renames were used at the time when building the POSIX API together with the host libC was allowed (the POSIX API function names were renamed with this trick to avoid them colliding with the host libC). That combination is not supported or permitted anymore, so there is no need to add more (or keep the majority of these).
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.
This POSIX API renames were used at the time when building the POSIX API together with the host libC was allowed (the POSIX API function names were renamed with this trick to avoid them colliding with the host libC). That combination is not supported or permitted anymore, so there is no need to add more (or keep the majority of these).
is a bulk cleanup already planned for posix_cheats.h
? or should it be done gradually for API groups like sched_*
?
in scope of this PR it looks confusing to have only some of these APIs 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.
It is in my low priority TODO. So it should happen eventually, probably when I need to change something around there.
Yep - that's about it. I made some code comments to hopefully clarify. |
Add `CONFIG_POSIX_PRIORITY_SCHEDULING` Kconfig option to select APIs from PSE53 `_POSIX_PRIORITY_SCHEDULING` option group. Signed-off-by: Dmitrii Golovanov <dmitrii.golovanov@intel.com>
Initial implementation of `sched_getparam()` and `sched_getscheduler()` POSIX APIs as a part of PSE53 `_POSIX_PRIORITY_SCHEDULING` option group. Both functions are actually placeholders and just return `ENOSYS` since Zephyr does not yet support processes or process scheduling. Signed-off-by: Dmitrii Golovanov <dmitrii.golovanov@intel.com>
9d34ae2
to
f3f0be3
Compare
Implement
sched_getparam()
andsched_getscheduler()
POSIX APIsas a part of PSE53
_POSIX_PRIORITY_SCHEDULING
option group.Add
CONFIG_POSIX_SCHED
Kconfig option for APIs in the group.Add
pid_t
typedef for some configurations where it is missed and its value derived frompthread_t
.Resolves #66959
Resolves #66960