Skip to content

Commit

Permalink
Merge branch 'feature/adds_pthread_funcs' into 'master'
Browse files Browse the repository at this point in the history
feat(pthread): Adds set/get sched param funcs

Closes IDFGH-13997 and IDFGH-6976

See merge request espressif/esp-idf!34787
  • Loading branch information
Konstantin Kondrashov committed Nov 13, 2024
2 parents 582c990 + 3318e0a commit d37e1cc
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 1 deletion.
14 changes: 13 additions & 1 deletion components/newlib/platform_include/pthread.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2018-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2018-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand All @@ -20,6 +20,18 @@ int pthread_condattr_getclock(const pthread_condattr_t * attr, clockid_t * clock

int pthread_condattr_setclock(pthread_condattr_t *attr, clockid_t clock_id);

/* Dynamic Thread Scheduling Parameters Access */
int pthread_getschedparam(pthread_t thread, int *policy, struct sched_param *param);

int pthread_setschedparam(pthread_t thread, int policy, const struct sched_param *param);

/* Set Scheduling Priority of a Thread */
int pthread_setschedprio(pthread_t thread, int prio);

int sched_get_priority_min(int policy);

int sched_get_priority_max(int policy);

#ifdef __cplusplus
}
#endif
Expand Down
75 changes: 75 additions & 0 deletions components/pthread/pthread.c
Original file line number Diff line number Diff line change
Expand Up @@ -916,6 +916,81 @@ int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)
return EINVAL;
}

int pthread_getschedparam(pthread_t thread, int *policy, struct sched_param *param)
{
int ret;
if (!policy || !param) {
return EINVAL;
}

_lock_acquire(&s_threads_lock);
TaskHandle_t handle = pthread_find_handle(thread);
if (!handle) {
ret = ESRCH;
} else {
*policy = SCHED_OTHER;
param->sched_priority = uxTaskPriorityGet(handle);
ret = 0;
}
_lock_release(&s_threads_lock);

return ret;
}

static int set_prio(pthread_t thread, int policy, int prio)
{
int ret;
if (prio < sched_get_priority_min(policy) || sched_get_priority_max(policy) < prio) {
return EINVAL;
}

_lock_acquire(&s_threads_lock);
TaskHandle_t handle = pthread_find_handle(thread);
if (!handle) {
ret = ESRCH;
} else {
vTaskPrioritySet(handle, prio);
ret = 0;
}
_lock_release(&s_threads_lock);

return ret;
}

int pthread_setschedparam(pthread_t thread, int policy, const struct sched_param *param)
{
// the policy does not change anything for the FreeRTOS kernel, ignore it.
int ret;
if (!param) {
return EINVAL;
}

ret = set_prio(thread, policy, param->sched_priority);

return ret;
}

int pthread_setschedprio(pthread_t thread, int prio)
{
// the policy does not change anything for the FreeRTOS kernel, ignore it.
int policy = SCHED_OTHER;
return set_prio(thread, policy, prio);
}

int sched_get_priority_min(int policy)
{
// the policy does not change anything for the FreeRTOS kernel, ignore it.
(void) policy;
return tskIDLE_PRIORITY;
}

int sched_get_priority_max(int policy)
{
// the policy does not change anything for the FreeRTOS kernel, ignore it.
(void) policy;
return configMAX_PRIORITIES - 1;
}

/* Hook function to force linking this file */
void pthread_include_pthread_impl(void)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -298,3 +298,46 @@ TEST_CASE("pthread mutex trylock timedlock", "[pthread]")
pthread_mutex_destroy(&mutex);
}
}

static volatile bool finish_test;

static void *test_thread(void * arg)
{
while (!finish_test) {
vTaskDelay(1);
}
printf("Thread 0x%"PRIx32" exiting\n", pthread_self());
return NULL;
}

TEST_CASE("pthread set and get sched param", "[pthread]")
{
finish_test = false;
pthread_t thread;
TEST_ASSERT_EQUAL_INT(0, pthread_create(&thread, NULL, test_thread, NULL));

int policy;
struct sched_param param;
TEST_ASSERT_EQUAL_INT(0, pthread_getschedparam(thread, &policy, &param));
int orig_prio = param.sched_priority;
printf("Origin Priority: %d\n", param.sched_priority);
printf("Policy: %d (2=SCHED_RR)\n", policy);

param.sched_priority += 1;
TEST_ASSERT_EQUAL_INT(0, pthread_setschedparam(thread, policy, &param));
param.sched_priority += 1;
TEST_ASSERT_EQUAL_INT(0, pthread_setschedprio(thread, param.sched_priority));

TEST_ASSERT_EQUAL_INT(0, pthread_getschedparam(thread, &policy, &param));
printf("Priority: %d + 2 = %d\n", orig_prio, param.sched_priority);
TEST_ASSERT_EQUAL_INT(orig_prio + 2, param.sched_priority);

// return priority back
TEST_ASSERT_EQUAL_INT(0, pthread_setschedprio(thread, orig_prio));
TEST_ASSERT_EQUAL_INT(0, pthread_getschedparam(thread, &policy, &param));
TEST_ASSERT_EQUAL_INT(orig_prio, param.sched_priority);
printf("Return Priority back to %d, current is %d\n", orig_prio, param.sched_priority);
// Wait for the thread to finish 100ms sleep
finish_test = true;
TEST_ASSERT_EQUAL_INT(0, pthread_join(thread, NULL));
}

0 comments on commit d37e1cc

Please sign in to comment.