/* * Scheduler live-adjustment test. * * Copyright (c) Siemens AG 2016 * * Authors: * Jan Kiszka * * Released under the terms of GPLv2. */ #include #include #include #include #include #include #include #include #include smokey_test_plugin(setsched, SMOKEY_NOARGS, "Validate correct application of scheduling parameters to running threads." ); static pid_t thread_pid; static void __check_linux_schedparams(int expected_policy, int expected_prio, int line) { struct sched_param linux_param; int linux_policy; linux_policy = syscall(SYS_sched_getscheduler, thread_pid); if (smokey_check_status(syscall(SYS_sched_getparam, thread_pid, &linux_param))) pthread_exit((void *)(long)-EINVAL); if (!smokey_assert(linux_policy == expected_policy) || !smokey_assert(linux_param.sched_priority == expected_prio)) { smokey_warning("called from line %d", line); pthread_exit((void *)(long)-EINVAL); } } #define check_linux_schedparams(pol, prio) \ __check_linux_schedparams(pol, prio, __LINE__) static void __check_rt_schedparams(int expected_policy, int expected_prio, int line) { struct sched_param cobalt_param; int cobalt_policy; if (smokey_check_status(pthread_getschedparam(pthread_self(), &cobalt_policy, &cobalt_param))) pthread_exit((void *)(long)-EINVAL); if (!smokey_assert(cobalt_policy == expected_policy) || !smokey_assert(cobalt_param.sched_priority == expected_prio)) { smokey_warning("called from line %d", line); pthread_exit((void *)(long)-EINVAL); } } #define check_rt_schedparams(pol, prio) \ __check_rt_schedparams(pol, prio, __LINE__) static void *thread_body(void *arg) { struct sched_param param; #ifdef CONFIG_XENO_LAZY_SETSCHED struct cobalt_threadstat stats; unsigned long long msw; #endif thread_pid = syscall(SYS_gettid); check_rt_schedparams(SCHED_FIFO, 1); check_linux_schedparams(SCHED_FIFO, 1); cobalt_thread_harden(); #ifdef CONFIG_XENO_LAZY_SETSCHED if (smokey_check_status(cobalt_thread_stat(thread_pid, &stats))) pthread_exit((void *)(long)-EINVAL); msw = stats.msw; #endif param.sched_priority = 2; if (smokey_check_status(pthread_setschedparam(pthread_self(), SCHED_FIFO, ¶m))) pthread_exit((void *)(long)-EINVAL); check_rt_schedparams(SCHED_FIFO, 2); #ifdef CONFIG_XENO_LAZY_SETSCHED if (smokey_check_status(cobalt_thread_stat(thread_pid, &stats)) || !smokey_assert(stats.msw == msw)) pthread_exit((void *)(long)-EINVAL); #endif check_linux_schedparams(SCHED_FIFO, 2); cobalt_thread_harden(); #ifdef CONFIG_XENO_LAZY_SETSCHED if (smokey_check_status(cobalt_thread_stat(thread_pid, &stats))) pthread_exit((void *)(long)-EINVAL); msw = stats.msw; #endif if (smokey_check_status(pthread_setschedprio(pthread_self(), 3))) pthread_exit((void *)(long)-EINVAL); check_rt_schedparams(SCHED_FIFO, 3); #ifdef CONFIG_XENO_LAZY_SETSCHED if (smokey_check_status(cobalt_thread_stat(thread_pid, &stats)) || !smokey_assert(stats.msw == msw)) pthread_exit((void *)(long)-EINVAL); #endif check_linux_schedparams(SCHED_FIFO, 3); return (void *)0L; } static int run_setsched(struct smokey_test *t, int argc, char *const argv[]) { struct sched_param param; pthread_attr_t attr; pthread_t thread; void *retval; int ret; pthread_attr_init(&attr); pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); pthread_attr_setschedpolicy(&attr, SCHED_FIFO); param.sched_priority = 1; pthread_attr_setschedparam(&attr, ¶m); ret = pthread_create(&thread, &attr, thread_body, NULL); if (ret) error(1, ret, "pthread_create"); pthread_join(thread, &retval); return (long)retval; }