Skip to content
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

Merged
merged 2 commits into from
Jan 15, 2024

Conversation

golowanow
Copy link
Member

@golowanow golowanow commented Dec 27, 2023

Implement sched_getparam() and sched_getscheduler() POSIX APIs
as 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 from pthread_t.

Resolves #66959
Resolves #66960

@golowanow golowanow force-pushed the posix_66959 branch 2 times, most recently from 70ac9c5 to 64a15b4 Compare December 27, 2023 19:51
@golowanow golowanow changed the title posix: sched: Implements sched_getparam() posix: sched: Implement sched_getparam() and sched_getscheduler() Dec 27, 2023
@golowanow golowanow marked this pull request as ready for review December 27, 2023 22:33
@zephyrbot zephyrbot added area: native port Host native arch port (native_sim) area: POSIX POSIX API Library labels Dec 27, 2023
@golowanow golowanow requested a review from ycsin December 27, 2023 22:34
lib/posix/sched.c Outdated Show resolved Hide resolved
lib/posix/sched.c Outdated Show resolved Hide resolved
@golowanow golowanow force-pushed the posix_66959 branch 2 times, most recently from ef03798 to 8218bea Compare January 1, 2024 10:54
@golowanow golowanow requested a review from cfriedt January 1, 2024 11:02
@golowanow golowanow force-pushed the posix_66959 branch 2 times, most recently from 6495257 to 2fbb113 Compare January 1, 2024 14:32
* must be already initialized whereas valid PID should
* have positive value.
*/
static inline pthread_t z_get_tid(pid_t pid)
Copy link
Member

@cfriedt cfriedt Jan 3, 2024

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

Copy link
Member Author

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.

Copy link
Member

@cfriedt cfriedt Jan 3, 2024

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.

Copy link
Member Author

@golowanow golowanow Jan 3, 2024

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'.

Comment on lines 54 to 68
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);
Copy link
Member

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

Suggested change
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;

Copy link
Member Author

@golowanow golowanow Jan 3, 2024

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.

what do you think if we deal only with pid==0 for pthread_self() and errno EINVAL otherwise ?

Copy link
Member

@cfriedt cfriedt Jan 3, 2024

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.

what do you think if we deal only with pid==0 for pthread_self() and errno EINVAL 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.

Copy link
Member Author

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.

lib/posix/sched.c Outdated Show resolved Hide resolved
Copy link
Member

@cfriedt cfriedt left a 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!

@golowanow
Copy link
Member Author

golowanow commented Jan 3, 2024

Documentation changes should also be in a separate commit.

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
or what is in commit with CONFIG_POSIX_SHED ?
is the former fair with ENOSYS functions, and the latter better to keep in the same commit ?

@golowanow golowanow requested a review from cfriedt January 3, 2024 20:14
Comment on lines +154 to +155
#define sched_getparam(...) zap_sched_getparam(__VA_ARGS__)
#define sched_getscheduler(...) zap_sched_getscheduler(__VA_ARGS__)
Copy link
Member

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.

Copy link
Member Author

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 ?

Copy link
Member

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).

Copy link
Member Author

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.

Copy link
Member

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.

lib/posix/Kconfig.sched Outdated Show resolved Hide resolved
@cfriedt
Copy link
Member

cfriedt commented Jan 8, 2024

Documentation changes should also be in a separate commit.

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 or what is in commit with CONFIG_POSIX_SHED ? is the former fair with ENOSYS functions, and the latter better to keep in the same commit ?

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>
@carlescufi carlescufi merged commit 68d1a52 into zephyrproject-rtos:main Jan 15, 2024
38 checks passed
@golowanow golowanow deleted the posix_66959 branch January 15, 2024 09:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: native port Host native arch port (native_sim) area: POSIX POSIX API Library
Projects
None yet
Development

Successfully merging this pull request may close these issues.

posix: implement sched_getscheduler() posix: implement sched_getparam()
6 participants