diff --git a/cpukit/include/rtems/confdefs/scheduler.h b/cpukit/include/rtems/confdefs/scheduler.h index fdad17a4e1..de818939b0 100644 --- a/cpukit/include/rtems/confdefs/scheduler.h +++ b/cpukit/include/rtems/confdefs/scheduler.h @@ -72,6 +72,10 @@ extern "C" { #define CONFIGURE_MAXIMUM_PRIORITY PRIORITY_DEFAULT_MAXIMUM #endif +#if !defined(CONFIGURE_SCHEDULER_EDF) && \ + !defined(CONFIGURE_SCHEDULER_EDF_SMP) && \ + !defined(CONFIGURE_SCHEDULER_CBS) + #if CONFIGURE_MAXIMUM_PRIORITY != 3 \ && CONFIGURE_MAXIMUM_PRIORITY != 7 \ && CONFIGURE_MAXIMUM_PRIORITY != 15 \ @@ -86,6 +90,8 @@ extern "C" { #error "CONFIGURE_SCHEDULER_PRIORITY must be less than or equal to the architecture defined maximum priority" #endif +#endif + #ifdef CONFIGURE_SCHEDULER_PRIORITY #ifndef CONFIGURE_SCHEDULER_NAME #define CONFIGURE_SCHEDULER_NAME rtems_build_name( 'U', 'P', 'D', ' ' ) diff --git a/cpukit/include/rtems/scheduler.h b/cpukit/include/rtems/scheduler.h index 325391605e..b79a25c906 100644 --- a/cpukit/include/rtems/scheduler.h +++ b/cpukit/include/rtems/scheduler.h @@ -171,7 +171,7 @@ { \ &SCHEDULER_CBS_CONTEXT_NAME( name ).Base, \ SCHEDULER_CBS_ENTRY_POINTS, \ - SCHEDULER_CBS_MAXIMUM_PRIORITY, \ + CONFIGURE_MAXIMUM_PRIORITY, \ ( obj_name ) \ SCHEDULER_CONTROL_IS_NON_PREEMPT_MODE_SUPPORTED( true ) \ } @@ -223,7 +223,7 @@ { \ &SCHEDULER_EDF_CONTEXT_NAME( name ).Base, \ SCHEDULER_EDF_ENTRY_POINTS, \ - SCHEDULER_EDF_MAXIMUM_PRIORITY, \ + CONFIGURE_MAXIMUM_PRIORITY, \ ( obj_name ) \ SCHEDULER_CONTROL_IS_NON_PREEMPT_MODE_SUPPORTED( true ) \ } @@ -278,7 +278,7 @@ { \ &SCHEDULER_EDF_SMP_CONTEXT_NAME( name ).Base.Base.Base, \ SCHEDULER_EDF_SMP_ENTRY_POINTS, \ - SCHEDULER_EDF_MAXIMUM_PRIORITY, \ + CONFIGURE_MAXIMUM_PRIORITY, \ ( obj_name ) \ SCHEDULER_CONTROL_IS_NON_PREEMPT_MODE_SUPPORTED( false ) \ } diff --git a/cpukit/include/rtems/score/schedulercbs.h b/cpukit/include/rtems/score/schedulercbs.h index a45a7fe6b8..48ceaec370 100644 --- a/cpukit/include/rtems/score/schedulercbs.h +++ b/cpukit/include/rtems/score/schedulercbs.h @@ -63,8 +63,6 @@ extern "C" { * @{ */ -#define SCHEDULER_CBS_MAXIMUM_PRIORITY SCHEDULER_EDF_MAXIMUM_PRIORITY - /** * Entry points for the Constant Bandwidth Server Scheduler. * diff --git a/cpukit/include/rtems/score/scheduleredf.h b/cpukit/include/rtems/score/scheduleredf.h index 8c50a3ab1e..0a75b1d238 100644 --- a/cpukit/include/rtems/score/scheduleredf.h +++ b/cpukit/include/rtems/score/scheduleredf.h @@ -60,13 +60,6 @@ extern "C" { * @{ */ -/* - * Actually the EDF scheduler supports a maximum priority of - * 0x7fffffffffffffff, but the user API is limited to uint32_t or int for - * thread priorities. Ignore ILP64 targets for now. - */ -#define SCHEDULER_EDF_MAXIMUM_PRIORITY INT_MAX - /** * Entry points for the Earliest Deadline First Scheduler. */ diff --git a/cpukit/score/src/scheduleredfreleasejob.c b/cpukit/score/src/scheduleredfreleasejob.c index 911c0a3d0a..35097dc919 100644 --- a/cpukit/score/src/scheduleredfreleasejob.c +++ b/cpukit/score/src/scheduleredfreleasejob.c @@ -59,7 +59,11 @@ Priority_Control _Scheduler_EDF_Unmap_priority( { (void) scheduler; - return SCHEDULER_PRIORITY_UNMAP( priority & ~SCHEDULER_EDF_PRIO_MSB ); + return SCHEDULER_PRIORITY_UNMAP( + priority & SCHEDULER_EDF_PRIO_MSB + ? priority & ~SCHEDULER_EDF_PRIO_MSB + : 0 + ); } void _Scheduler_EDF_Release_job( diff --git a/spec/build/testsuites/sptests/grp.yml b/spec/build/testsuites/sptests/grp.yml index 2c9de9a128..871dabae6e 100644 --- a/spec/build/testsuites/sptests/grp.yml +++ b/spec/build/testsuites/sptests/grp.yml @@ -204,6 +204,8 @@ links: uid: spedfsched03 - role: build-dependency uid: spedfsched04 +- role: build-dependency + uid: spedfsched05 - role: build-dependency uid: sperror01 - role: build-dependency diff --git a/spec/build/testsuites/sptests/spedfsched05.yml b/spec/build/testsuites/sptests/spedfsched05.yml new file mode 100644 index 0000000000..6b29eb8a86 --- /dev/null +++ b/spec/build/testsuites/sptests/spedfsched05.yml @@ -0,0 +1,19 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +build-type: test-program +cflags: [] +copyrights: +- Copyright (C) 2025 Gedare Bloom +cppflags: [] +cxxflags: [] +enabled-by: true +features: c cprogram +includes: [] +ldflags: [] +links: [] +source: +- testsuites/sptests/spedfsched05/init.c +stlib: [] +target: testsuites/sptests/spedfsched05.exe +type: build +use-after: [] +use-before: [] diff --git a/testsuites/sptests/spedfsched05/init.c b/testsuites/sptests/spedfsched05/init.c new file mode 100644 index 0000000000..3894f41506 --- /dev/null +++ b/testsuites/sptests/spedfsched05/init.c @@ -0,0 +1,763 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/* + * Copyright (C) 2025 Gedare Bloom + * Copyright (C) 2014, 2020 embedded brains GmbH & Co. KG + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#define _GNU_SOURCE + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include +#include +#include +#include + +#include "tmacros.h" + +const char rtems_test_name[] = "SPEDFSCHED 5"; + +#define BLUE rtems_build_name('b', 'l', 'u', 'e') + +#define RED rtems_build_name('r', 'e', 'd', ' ') + +#define BIG_NUM_CPUS (2 * CHAR_BIT * sizeof(cpu_set_t)) + +static const rtems_id invalid_id = 1; + +static rtems_id master_id; + +static rtems_id sema_id; + +static void assert_eno(rtems_status_code sc, int eno) +{ + switch (sc) { + case RTEMS_SUCCESSFUL: + rtems_test_assert(eno == 0); + break; + case RTEMS_INVALID_ADDRESS: + rtems_test_assert(eno == EFAULT); + break; + case RTEMS_INVALID_ID: + rtems_test_assert(eno == ESRCH); + break; + case RTEMS_INVALID_NUMBER: + case RTEMS_INVALID_SIZE: + rtems_test_assert(eno == EINVAL); + break; + default: + rtems_test_assert(0); + } +} + +static rtems_status_code task_get_affinity( + rtems_id id, + size_t cpusetsize, + cpu_set_t *cpuset +) +{ + rtems_status_code sc; + int eno; + cpu_set_t *cpusetbig; + + sc = rtems_task_get_affinity(id, cpusetsize, cpuset); + + if (cpuset != NULL) { + cpusetbig = CPU_ALLOC(BIG_NUM_CPUS); + rtems_test_assert(cpusetbig != NULL); + + memcpy(cpusetbig, cpuset, cpusetsize); + } else { + cpusetbig = NULL; + } + + eno = pthread_getaffinity_np(id, cpusetsize, cpusetbig); + + if (cpuset != NULL) { + rtems_test_assert(CPU_EQUAL_S(cpusetsize, cpusetbig, cpuset)); + CPU_FREE(cpusetbig); + } + + assert_eno(sc, eno); + + return sc; +} + +static rtems_status_code task_set_affinity( + rtems_id id, + size_t cpusetsize, + const cpu_set_t *cpuset +) +{ + rtems_status_code sc; + int eno; + + sc = rtems_task_set_affinity(id, cpusetsize, cpuset); + eno = pthread_setaffinity_np(id, cpusetsize, cpuset); + assert_eno(sc, eno); + + return sc; +} + +static void test_task_get_set_affinity(void) +{ + rtems_id self_id = rtems_task_self(); + rtems_id task_id; + rtems_status_code sc; + cpu_set_t cpusetone; + cpu_set_t cpusetall; + cpu_set_t cpuset; + size_t cpusetbigsize = CPU_ALLOC_SIZE(BIG_NUM_CPUS); + cpu_set_t *cpusetbigone; + cpu_set_t *cpusetbig; + + CPU_ZERO(&cpusetone); + CPU_SET(0, &cpusetone); + + CPU_FILL(&cpusetall); + + sc = rtems_task_create( + rtems_build_name('T', 'A', 'S', 'K'), + 2, + RTEMS_MINIMUM_STACK_SIZE, + RTEMS_DEFAULT_MODES, + RTEMS_DEFAULT_ATTRIBUTES, + &task_id + ); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = task_get_affinity(RTEMS_SELF, sizeof(cpuset), NULL); + rtems_test_assert(sc == RTEMS_INVALID_ADDRESS); + + sc = task_set_affinity(RTEMS_SELF, sizeof(cpuset), NULL); + rtems_test_assert(sc == RTEMS_INVALID_ADDRESS); + + sc = task_get_affinity(RTEMS_SELF, 0, &cpuset); + rtems_test_assert(sc == RTEMS_INVALID_SIZE); + + sc = task_set_affinity(RTEMS_SELF, 0, &cpuset); + rtems_test_assert(sc == RTEMS_INVALID_NUMBER); + + sc = task_get_affinity(invalid_id, sizeof(cpuset), &cpuset); + rtems_test_assert(sc == RTEMS_INVALID_ID); + + sc = task_set_affinity(invalid_id, sizeof(cpuset), &cpuset); + rtems_test_assert(sc == RTEMS_INVALID_ID); + + sc = task_get_affinity(RTEMS_SELF, sizeof(cpuset), &cpuset); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + rtems_test_assert(CPU_EQUAL(&cpuset, &cpusetone)); + + sc = task_set_affinity(RTEMS_SELF, sizeof(cpuset), &cpuset); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = task_set_affinity(self_id, sizeof(cpuset), &cpuset); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = task_set_affinity(task_id, sizeof(cpuset), &cpuset); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = task_get_affinity(task_id, sizeof(cpuset), &cpuset); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + rtems_test_assert(CPU_EQUAL(&cpuset, &cpusetone)); + + sc = task_set_affinity(RTEMS_SELF, sizeof(cpusetall), &cpusetall); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = task_get_affinity(task_id, sizeof(cpuset), &cpuset); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + rtems_test_assert(CPU_EQUAL(&cpuset, &cpusetone)); + + cpusetbigone = CPU_ALLOC(BIG_NUM_CPUS); + rtems_test_assert(cpusetbigone != NULL); + + cpusetbig = CPU_ALLOC(BIG_NUM_CPUS); + rtems_test_assert(cpusetbig != NULL); + + CPU_ZERO_S(cpusetbigsize, cpusetbigone); + CPU_SET_S(0, cpusetbigsize, cpusetbigone); + + sc = task_get_affinity(task_id, cpusetbigsize, cpusetbig); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + rtems_test_assert(CPU_EQUAL_S(cpusetbigsize, cpusetbig, cpusetbigone)); + + sc = task_set_affinity(task_id, cpusetbigsize, cpusetbig); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_task_delete(task_id); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + CPU_FREE(cpusetbig); + CPU_FREE(cpusetbigone); +} + +static rtems_task_priority set_prio(rtems_id id, rtems_task_priority prio) +{ + rtems_status_code sc; + rtems_task_priority old_prio; + + old_prio = 0xffffffff; + sc = rtems_task_set_priority(id, prio, &old_prio); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + return old_prio; +} + +static void forbidden_task(rtems_task_argument arg) +{ + (void) arg; + + rtems_test_assert(0); +} + +static void restart_task(rtems_task_argument arg) +{ + (void) arg; + + rtems_status_code sc; + + if (arg == 0) { + rtems_test_assert(set_prio(RTEMS_SELF, 3) == 2); + + rtems_task_restart(RTEMS_SELF, 1); + } else if (arg == 1) { + rtems_id scheduler_id; + + rtems_test_assert(set_prio(RTEMS_SELF, 3) == 2); + + sc = rtems_task_get_scheduler(RTEMS_SELF, &scheduler_id); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_task_set_scheduler(RTEMS_SELF, scheduler_id, 4); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + rtems_test_assert(set_prio(RTEMS_SELF, 3) == 4); + + rtems_task_restart(RTEMS_SELF, 2); + } else { + rtems_test_assert(set_prio(RTEMS_SELF, 3) == 4); + + rtems_task_resume(master_id); + } + + rtems_test_assert(0); +} + +static void sema_task(rtems_task_argument arg) +{ + (void) arg; + + rtems_status_code sc; + + sc = rtems_semaphore_obtain(sema_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + rtems_test_assert(0); +} + +static void test_task_get_set_scheduler(void) +{ + rtems_status_code sc; + rtems_id self_id = rtems_task_self(); + rtems_name name = BLUE; + rtems_id scheduler_id; + rtems_id scheduler_by_name; + rtems_id task_id; + rtems_id mtx_id; + + sc = rtems_scheduler_ident(name, &scheduler_by_name); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_task_get_scheduler(RTEMS_SELF, NULL); + rtems_test_assert(sc == RTEMS_INVALID_ADDRESS); + + sc = rtems_task_get_scheduler(invalid_id, &scheduler_id); + rtems_test_assert(sc == RTEMS_INVALID_ID); + + scheduler_id = 0; + sc = rtems_task_get_scheduler(RTEMS_SELF, &scheduler_id); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + rtems_test_assert(scheduler_id == scheduler_by_name); + + scheduler_id = 0; + sc = rtems_task_get_scheduler(self_id, &scheduler_id); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + rtems_test_assert(scheduler_id == scheduler_by_name); + + sc = rtems_task_set_scheduler(invalid_id, scheduler_id, 1); + rtems_test_assert(sc == RTEMS_INVALID_ID); + + sc = rtems_task_set_scheduler(self_id, invalid_id, 1); + rtems_test_assert(sc == RTEMS_INVALID_ID); + + sc = rtems_task_set_scheduler(self_id, scheduler_id, UINT32_C(0x80000000)); + rtems_test_assert(sc == RTEMS_INVALID_PRIORITY); + + sc = rtems_task_set_scheduler(self_id, scheduler_id, 1); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_semaphore_create( + rtems_build_name(' ', 'M', 'T', 'X'), + 0, + RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_INHERIT_PRIORITY, + 0, + &mtx_id + ); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_task_set_scheduler(self_id, scheduler_id, 1); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_semaphore_release(mtx_id); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + rtems_test_assert(set_prio(self_id, RTEMS_CURRENT_PRIORITY) == 1); + + sc = rtems_task_set_scheduler(self_id, scheduler_id, 2); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + rtems_test_assert(set_prio(self_id, RTEMS_CURRENT_PRIORITY) == 2); + + sc = rtems_task_set_scheduler(self_id, scheduler_id, 1); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + rtems_test_assert(set_prio(self_id, RTEMS_CURRENT_PRIORITY) == 1); + + sc = rtems_semaphore_delete(mtx_id); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_task_create( + rtems_build_name('T', 'A', 'S', 'K'), + 2, + RTEMS_MINIMUM_STACK_SIZE, + RTEMS_DEFAULT_MODES, + RTEMS_DEFAULT_ATTRIBUTES, + &task_id + ); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + scheduler_id = 0; + sc = rtems_task_get_scheduler(task_id, &scheduler_id); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + rtems_test_assert(scheduler_id == scheduler_by_name); + + sc = rtems_task_set_scheduler(task_id, scheduler_id, 2); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_task_start(task_id, forbidden_task, 0); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_task_set_scheduler(task_id, scheduler_id, 2); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_task_delete(task_id); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_task_create( + rtems_build_name('T', 'A', 'S', 'K'), + 2, + RTEMS_MINIMUM_STACK_SIZE, + RTEMS_DEFAULT_MODES, + RTEMS_DEFAULT_ATTRIBUTES, + &task_id + ); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_task_start(task_id, restart_task, 0); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_task_suspend(self_id); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_task_delete(task_id); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_semaphore_create( + rtems_build_name('S', 'E', 'M', 'A'), + 0, + RTEMS_COUNTING_SEMAPHORE, + 0, + &sema_id + ); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_task_create( + rtems_build_name('T', 'A', 'S', 'K'), + 1, + RTEMS_MINIMUM_STACK_SIZE, + RTEMS_DEFAULT_MODES, + RTEMS_DEFAULT_ATTRIBUTES, + &task_id + ); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_task_start(task_id, sema_task, 0); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_task_wake_after(1); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_task_set_scheduler(task_id, scheduler_id, 1); + rtems_test_assert(sc == RTEMS_RESOURCE_IN_USE); + + sc = rtems_semaphore_delete(sema_id); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_task_delete(task_id); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); +} + +static void test_scheduler_ident(void) +{ + rtems_status_code sc; + rtems_id expected_id = rtems_build_id(7, 1, 1, 1); + rtems_id scheduler_id; + rtems_name name = BLUE; + rtems_name invalid_name = RED; + cpu_set_t s; + + sc = rtems_scheduler_ident(name, NULL); + rtems_test_assert(sc == RTEMS_INVALID_ADDRESS); + + sc = rtems_scheduler_ident(invalid_name, &scheduler_id); + rtems_test_assert(sc == RTEMS_INVALID_NAME); + + scheduler_id = 0; + sc = rtems_scheduler_ident(name, &scheduler_id); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + rtems_test_assert(scheduler_id == expected_id); + + sc = rtems_scheduler_ident_by_processor(1, NULL); + rtems_test_assert(sc == RTEMS_INVALID_ADDRESS); + + sc = rtems_scheduler_ident_by_processor(1, &scheduler_id); + rtems_test_assert(sc == RTEMS_INVALID_NAME); + + scheduler_id = 0; + sc = rtems_scheduler_ident_by_processor(0, &scheduler_id); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + rtems_test_assert(scheduler_id == expected_id); + + CPU_ZERO(&s); + CPU_SET(1, &s); + sc = rtems_scheduler_ident_by_processor_set(sizeof(s), &s, NULL); + rtems_test_assert(sc == RTEMS_INVALID_ADDRESS); + + sc = rtems_scheduler_ident_by_processor_set(1, &s, &scheduler_id); + rtems_test_assert(sc == RTEMS_INVALID_SIZE); + + sc = rtems_scheduler_ident_by_processor_set(sizeof(s), &s, &scheduler_id); + rtems_test_assert(sc == RTEMS_INVALID_NAME); + + CPU_SET(0, &s); + scheduler_id = 0; + sc = rtems_scheduler_ident_by_processor_set(sizeof(s), &s, &scheduler_id); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + rtems_test_assert(scheduler_id == expected_id); +} + +static void test_scheduler_get_max_prio(void) +{ + rtems_status_code sc; + rtems_task_priority priority; + rtems_id scheduler_id; + + priority = 0; + sc = rtems_scheduler_get_maximum_priority(invalid_id, &priority); + rtems_test_assert(sc == RTEMS_INVALID_ID); + rtems_test_assert(priority == 0); + + sc = rtems_task_get_scheduler(RTEMS_SELF, &scheduler_id); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_scheduler_get_maximum_priority(scheduler_id, NULL); + rtems_test_assert(sc == RTEMS_INVALID_ADDRESS); + + priority = 0; + sc = rtems_scheduler_get_maximum_priority(scheduler_id, &priority); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + rtems_test_assert(priority == 255); +} + +static void test_scheduler_map_to_posix(void) +{ + rtems_status_code sc; + int posix_priority; + rtems_id scheduler_id; + + posix_priority = 123; + sc = rtems_scheduler_map_priority_to_posix(invalid_id, 1, &posix_priority); + rtems_test_assert(sc == RTEMS_INVALID_ID); + rtems_test_assert(posix_priority == 123); + + sc = rtems_task_get_scheduler(RTEMS_SELF, &scheduler_id); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_scheduler_map_priority_to_posix(scheduler_id, 1, NULL); + rtems_test_assert(sc == RTEMS_INVALID_ADDRESS); + + posix_priority = 123; + sc = rtems_scheduler_map_priority_to_posix(scheduler_id, 0, &posix_priority); + rtems_test_assert(sc == RTEMS_INVALID_PRIORITY); + rtems_test_assert(posix_priority == 123); + + posix_priority = 123; + sc = rtems_scheduler_map_priority_to_posix(scheduler_id, 255, &posix_priority); + rtems_test_assert(sc == RTEMS_INVALID_PRIORITY); + rtems_test_assert(posix_priority == 123); + + posix_priority = 123; + sc = rtems_scheduler_map_priority_to_posix(scheduler_id, 256, &posix_priority); + rtems_test_assert(sc == RTEMS_INVALID_PRIORITY); + rtems_test_assert(posix_priority == 123); + + posix_priority = 123; + sc = rtems_scheduler_map_priority_to_posix(scheduler_id, 1, &posix_priority); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + rtems_test_assert(posix_priority == 254); + + posix_priority = 123; + sc = rtems_scheduler_map_priority_to_posix(scheduler_id, 254, &posix_priority); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + rtems_test_assert(posix_priority == 1); +} + +static void test_scheduler_map_from_posix(void) +{ + rtems_status_code sc; + rtems_task_priority priority; + rtems_id scheduler_id; + + priority = 123; + sc = rtems_scheduler_map_priority_from_posix(invalid_id, 1, &priority); + rtems_test_assert(sc == RTEMS_INVALID_ID); + rtems_test_assert(priority == 123); + + sc = rtems_task_get_scheduler(RTEMS_SELF, &scheduler_id); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_scheduler_map_priority_from_posix(scheduler_id, 1, NULL); + rtems_test_assert(sc == RTEMS_INVALID_ADDRESS); + + priority = 123; + sc = rtems_scheduler_map_priority_from_posix(scheduler_id, -1, &priority); + rtems_test_assert(sc == RTEMS_INVALID_PRIORITY); + rtems_test_assert(priority == 123); + + priority = 123; + sc = rtems_scheduler_map_priority_from_posix(scheduler_id, 0, &priority); + rtems_test_assert(sc == RTEMS_INVALID_PRIORITY); + rtems_test_assert(priority == 123); + + priority = 123; + sc = rtems_scheduler_map_priority_from_posix(scheduler_id, 255, &priority); + rtems_test_assert(sc == RTEMS_INVALID_PRIORITY); + rtems_test_assert(priority == 123); + + priority = 123; + sc = rtems_scheduler_map_priority_from_posix(scheduler_id, 1, &priority); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + rtems_test_assert(priority == 254); + + priority = 123; + sc = rtems_scheduler_map_priority_from_posix(scheduler_id, 254, &priority); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + rtems_test_assert(priority == 1); +} + +static void test_scheduler_get_processors(void) +{ + rtems_status_code sc; + rtems_name name = BLUE; + rtems_id scheduler_id; + cpu_set_t cpusetone; + cpu_set_t cpuset; + size_t cpusetbigsize = CPU_ALLOC_SIZE(BIG_NUM_CPUS); + cpu_set_t *cpusetbigone; + cpu_set_t *cpusetbig; + + CPU_ZERO(&cpusetone); + CPU_SET(0, &cpusetone); + + sc = rtems_scheduler_ident(name, &scheduler_id); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_scheduler_get_processor_set(scheduler_id, sizeof(cpuset), NULL); + rtems_test_assert(sc == RTEMS_INVALID_ADDRESS); + + sc = rtems_scheduler_get_processor_set(invalid_id, sizeof(cpuset), &cpuset); + rtems_test_assert(sc == RTEMS_INVALID_ID); + + sc = rtems_scheduler_get_processor_set(scheduler_id, 0, &cpuset); + rtems_test_assert(sc == RTEMS_INVALID_SIZE); + + sc = rtems_scheduler_get_processor_set(scheduler_id, sizeof(cpuset), &cpuset); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + rtems_test_assert(CPU_EQUAL(&cpuset, &cpusetone)); + + cpusetbigone = CPU_ALLOC(BIG_NUM_CPUS); + rtems_test_assert(cpusetbigone != NULL); + + cpusetbig = CPU_ALLOC(BIG_NUM_CPUS); + rtems_test_assert(cpusetbig != NULL); + + CPU_ZERO_S(cpusetbigsize, cpusetbigone); + CPU_SET_S(0, cpusetbigsize, cpusetbigone); + + sc = rtems_scheduler_get_processor_set(scheduler_id, cpusetbigsize, cpusetbig); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + rtems_test_assert(CPU_EQUAL_S(cpusetbigsize, cpusetbig, cpusetbigone)); + + CPU_FREE(cpusetbig); + CPU_FREE(cpusetbigone); +} + +static void test_scheduler_add_remove_processors(void) +{ + rtems_status_code sc; + rtems_id scheduler_id; + + sc = rtems_scheduler_ident(BLUE, &scheduler_id); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_scheduler_add_processor(invalid_id, 0); + rtems_test_assert(sc == RTEMS_INVALID_ID); + + sc = rtems_scheduler_remove_processor(invalid_id, 0); + rtems_test_assert(sc == RTEMS_INVALID_ID); + + sc = rtems_scheduler_add_processor(scheduler_id, 1); + rtems_test_assert(sc == RTEMS_NOT_CONFIGURED); + + sc = rtems_scheduler_remove_processor(scheduler_id, 1); + rtems_test_assert(sc == RTEMS_INVALID_NUMBER); + + sc = rtems_scheduler_add_processor(scheduler_id, 0); + rtems_test_assert(sc == RTEMS_RESOURCE_IN_USE); + + sc = rtems_scheduler_remove_processor(scheduler_id, 0); + rtems_test_assert(sc == RTEMS_RESOURCE_IN_USE); +} + +static void test_task_get_priority(void) +{ + rtems_status_code sc; + rtems_id scheduler_id; + rtems_task_priority priority; + rtems_task_priority priority_2; + + sc = rtems_task_get_scheduler(RTEMS_SELF, &scheduler_id); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_task_get_priority(RTEMS_SELF, scheduler_id, NULL); + rtems_test_assert(sc == RTEMS_INVALID_ADDRESS); + + priority = 0; + + sc = rtems_task_get_priority(RTEMS_SELF, invalid_id, &priority); + rtems_test_assert(sc == RTEMS_INVALID_ID); + rtems_test_assert(priority == 0); + + sc = rtems_task_get_priority(invalid_id, scheduler_id, &priority); + rtems_test_assert(sc == RTEMS_INVALID_ID); + rtems_test_assert(priority == 0); + + sc = rtems_task_set_priority(RTEMS_SELF, RTEMS_CURRENT_PRIORITY, &priority); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + rtems_test_assert(priority != 0); + + priority_2 = 0; + sc = rtems_task_get_priority(RTEMS_SELF, scheduler_id, &priority_2); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + rtems_test_assert(priority_2 == priority); + + priority_2 = 0; + sc = rtems_task_get_priority(rtems_task_self(), scheduler_id, &priority_2); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + rtems_test_assert(priority_2 == priority); +} + +static void Init(rtems_task_argument arg) +{ + (void) arg; + + rtems_resource_snapshot snapshot; + + TEST_BEGIN(); + + rtems_resource_snapshot_take(&snapshot); + + master_id = rtems_task_self(); + + test_task_get_set_affinity(); + test_task_get_set_scheduler(); + test_scheduler_ident(); + test_scheduler_get_max_prio(); + test_scheduler_map_to_posix(); + test_scheduler_map_from_posix(); + test_scheduler_get_processors(); + test_scheduler_add_remove_processors(); + test_task_get_priority(); + + rtems_test_assert(rtems_resource_snapshot_check(&snapshot)); + + TEST_END(); + rtems_test_exit(0); +} + +#define CONFIGURE_SCHEDULER_EDF + +#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER + +#define CONFIGURE_MAXIMUM_TASKS 2 +#define CONFIGURE_MAXIMUM_SEMAPHORES 1 + +#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION + +#define CONFIGURE_RTEMS_INIT_TASKS_TABLE + +#define CONFIGURE_SCHEDULER_NAME BLUE + +#define CONFIGURE_INIT + +#include diff --git a/testsuites/sptests/spedfsched05/spedfsched05.doc b/testsuites/sptests/spedfsched05/spedfsched05.doc new file mode 100644 index 0000000000..c552c332a8 --- /dev/null +++ b/testsuites/sptests/spedfsched05/spedfsched05.doc @@ -0,0 +1,26 @@ +This file describes the directives and concepts tested by this test set. + +test set name: spedfsched05 + +directives: + + - rtems_task_get_affinity() + - rtems_task_set_affinity() + - pthread_getaffinity_np() + - pthread_setaffinity_np() + - rtems_task_get_scheduler() + - rtems_task_set_scheduler() + - rtems_scheduler_ident() + - rtems_scheduler_get_processor_set() + - rtems_task_get_priority() + +concepts: + + - Ensure that the task set/get affinity functions work on uni-processor + configurations with the EDF scheduler. + - Ensure that the task set/get scheduler functions work on uni-processor + configurations with the EDF scheduler. + - Ensure that the scheduler functions work on uni-processor configurations + with the EDF scheduler. + - Ensure that the task get priority function works on uni-processor + configurations with the EDF scheduler. diff --git a/testsuites/sptests/spedfsched05/spedfsched05.scn b/testsuites/sptests/spedfsched05/spedfsched05.scn new file mode 100644 index 0000000000..cf41e93536 --- /dev/null +++ b/testsuites/sptests/spedfsched05/spedfsched05.scn @@ -0,0 +1,2 @@ +*** BEGIN OF TEST SPEDFSCHED 5 *** +*** END OF TEST SPSEDFSCHED 5 ***