Skip to content

Commit 8bd3471

Browse files
committed
posix: sched: Implement get APIs for scheduling parameters
Implement `sched_getparam()` and `sched_getscheduler()` POSIX APIs as a part of PSE53 `_POSIX_PRIORITY_SCHEDULING` option group. Signed-off-by: Dmitrii Golovanov <[email protected]>
1 parent e4b89e1 commit 8bd3471

File tree

6 files changed

+150
-6
lines changed

6 files changed

+150
-6
lines changed

arch/posix/include/posix_cheats.h

+2
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@ extern "C" int _posix_zephyr_main(void);
151151
#define sched_yield(...) zap_sched_yield(__VA_ARGS__)
152152
#define sched_get_priority_min(...) zap_sched_get_priority_min(__VA_ARGS__)
153153
#define sched_get_priority_max(...) zap_sched_get_priority_max(__VA_ARGS__)
154+
#define sched_getparam(...) zap_sched_getparam(__VA_ARGS__)
155+
#define sched_getscheduler(...) zap_sched_getscheduler(__VA_ARGS__)
154156

155157
/* Sleep */
156158
#define sleep(...) zap_sleep(__VA_ARGS__)

doc/services/portability/posix/option_groups/index.rst

+2-2
Original file line numberDiff line numberDiff line change
@@ -446,8 +446,8 @@ _POSIX_PRIORITY_SCHEDULING
446446

447447
sched_get_priority_max(),yes
448448
sched_get_priority_min(),yes
449-
sched_getparam(),
450-
sched_getscheduler(),
449+
sched_getparam(),yes
450+
sched_getscheduler(),yes
451451
sched_rr_get_interval(),
452452
sched_setparam(),
453453
sched_setscheduler(),

include/zephyr/posix/sched.h

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018 Intel Corporation
2+
* Copyright (c) 2018-2023 Intel Corporation
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -8,6 +8,8 @@
88

99
#include <zephyr/kernel.h>
1010

11+
#include "posix_types.h"
12+
1113
#ifdef __cplusplus
1214
extern "C" {
1315
#endif
@@ -46,6 +48,9 @@ static inline int sched_yield(void)
4648
int sched_get_priority_min(int policy);
4749
int sched_get_priority_max(int policy);
4850

51+
int sched_getparam(pid_t pid, struct sched_param *param);
52+
int sched_getscheduler(pid_t pid);
53+
4954
#ifdef __cplusplus
5055
}
5156
#endif

lib/posix/sched.c

+56-1
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
/*
2-
* Copyright (c) 2018 Intel Corporation
2+
* Copyright (c) 2018-2023 Intel Corporation
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

77
#include "pthread_sched.h"
88

99
#include <zephyr/kernel.h>
10+
#include <zephyr/posix/pthread.h>
1011
#include <zephyr/posix/sched.h>
1112

1213
/**
@@ -41,3 +42,57 @@ int sched_get_priority_max(int policy)
4142
errno = EINVAL;
4243
return -1;
4344
}
45+
46+
/**
47+
* @brief Get scheduling parameters
48+
*
49+
* See IEEE 1003.1
50+
*/
51+
int sched_getparam(pid_t pid, struct sched_param *param)
52+
{
53+
/* TODO: Ensure the Zephyr POSIX process id (PID) value is assigned
54+
* with its first thread's id (TID).
55+
*/
56+
struct sched_param dummy_param = {0};
57+
pthread_t tid = (pthread_t)pid;
58+
int t_policy = -1;
59+
int ret = -1;
60+
61+
if (param == NULL) {
62+
param = &dummy_param;
63+
}
64+
65+
if (tid == 0) {
66+
tid = pthread_self();
67+
}
68+
69+
ret = pthread_getschedparam(tid, &t_policy, param);
70+
errno = ret;
71+
72+
return ((ret) ? -1 : 0);
73+
}
74+
75+
/**
76+
* @brief Get scheduling policy
77+
*
78+
* See IEEE 1003.1
79+
*/
80+
int sched_getscheduler(pid_t pid)
81+
{
82+
/* TODO: Ensure the Zephyr POSIX process id (PID) value is assigned
83+
* with its first thread's id (TID).
84+
*/
85+
struct sched_param dummy_param = {0};
86+
pthread_t tid = (pthread_t)pid;
87+
int t_policy = -1;
88+
int ret = -1;
89+
90+
if (tid == 0) {
91+
tid = pthread_self();
92+
}
93+
94+
ret = pthread_getschedparam(tid, &t_policy, &dummy_param);
95+
errno = ret;
96+
97+
return (ret == 0) ? t_policy : -1;
98+
}

tests/posix/common/src/pthread.c

+82
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
K_THREAD_STACK_ARRAY_DEFINE(stack_e, N_THR_E, STACKS);
3030
K_THREAD_STACK_ARRAY_DEFINE(stack_t, N_THR_T, STACKS);
31+
K_THREAD_STACK_ARRAY_DEFINE(stack_s, 1, STACKS);
3132
K_THREAD_STACK_ARRAY_DEFINE(stack_1, 1, 32);
3233

3334
void *thread_top_exec(void *p1);
@@ -647,6 +648,87 @@ ZTEST(posix_apis, test_pthread_descriptor_leak)
647648
}
648649
}
649650

651+
static void *create_thread_sched(void *p1)
652+
{
653+
struct sched_param param = { .sched_priority = -1 };
654+
int err = 0;
655+
int rc = 0;
656+
657+
/* Get scheduling params of the current process. */
658+
rc = sched_getparam(0, &param);
659+
err = errno;
660+
zassert_ok(rc, "unable to get scheduling parameters: rc=%d, errno=%d",
661+
rc, err);
662+
663+
rc = sched_getscheduler(0);
664+
err = errno;
665+
zassert_not_equal(rc, -1, "unable to get scheduling policy: errno=%d",
666+
err);
667+
zassert_equal(rc, SCHED_RR, "unexpected scheduling policy: %d", rc);
668+
669+
if (p1) {
670+
zassert_equal(param.sched_priority,
671+
((struct sched_param *)p1)->sched_priority,
672+
"unexpected sched_priority=%d expects=%d",
673+
param.sched_priority,
674+
((struct sched_param *)p1)->sched_priority);
675+
}
676+
677+
return NULL;
678+
}
679+
680+
ZTEST(posix_apis, test_sched_getparam)
681+
{
682+
struct sched_param param = { .sched_priority = -1 };
683+
int err = 0;
684+
int rc = 0;
685+
686+
/* TODO: Assuming non-existent PID is -1 */
687+
rc = sched_getparam(-1, &param);
688+
err = errno;
689+
zassert_true((rc == -1 && err == ESRCH),
690+
"failed parameter check: rc=%d, errno=%d", rc, err);
691+
692+
rc = sched_getscheduler(-1);
693+
err = errno;
694+
zassert_true((rc == -1 && err == ESRCH),
695+
"failed parameter check: rc=%d, errno=%d", rc, err);
696+
697+
/* .. and it is safe to call with NULL as praram. */
698+
rc = sched_getparam(-1, NULL);
699+
err = errno;
700+
zassert_true((rc == -1 && err == ESRCH),
701+
"failed parameter check: rc=%d, errno=%d", rc, err);
702+
703+
/* Try with the current PID as ztest execution thread - it fails. */
704+
rc = sched_getparam(0, &param);
705+
err = errno;
706+
zassert_true((rc == -1 && err == ESRCH),
707+
"Unexpected result : rc=%d, errno=%d", rc, err);
708+
709+
rc = sched_getscheduler(0);
710+
err = errno;
711+
zassert_true((rc == -1 && err == ESRCH),
712+
"Unexpected result : rc=%d, errno=%d", rc, err);
713+
714+
/* Check with a test thread. */
715+
pthread_t pthread1;
716+
pthread_attr_t attr1 = (pthread_attr_t){0};
717+
718+
param.sched_priority = sched_get_priority_min(SCHED_RR);
719+
err = errno;
720+
zassert_not_equal(-1, param.sched_priority,
721+
"sched_get_priority_min(SCHED_RR) failed: errno=%d", err);
722+
zassert_ok(pthread_attr_init(&attr1));
723+
zassert_ok(pthread_attr_setschedparam(&attr1, &param),
724+
"pthread_attr_setschedparam() failed");
725+
zassert_ok(pthread_attr_setstack(&attr1, &stack_s[0][0], STACKS));
726+
zassert_ok(pthread_create(&pthread1, &attr1, create_thread_sched, (void *)&param),
727+
"unable to create a test thread");
728+
k_msleep(100);
729+
zassert_ok(pthread_join(pthread1, NULL), "unable to join the test thread");
730+
}
731+
650732
ZTEST(posix_apis, test_sched_policy)
651733
{
652734
/*

tests/posix/headers/src/sched_h.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ ZTEST(posix_headers, test_sched_h)
3030
zassert_not_null(sched_get_priority_max);
3131
zassert_not_null(sched_get_priority_min);
3232

33-
/* zassert_not_null(sched_getparam); */ /* not implemented */
34-
/* zassert_not_null(sched_getscheduler); */ /* not implemented */
33+
zassert_not_null(sched_getparam);
34+
zassert_not_null(sched_getscheduler);
3535

3636
/* zassert_not_null(sched_rr_get_interval); */ /* not implemented */
3737

0 commit comments

Comments
 (0)