diff options
Diffstat (limited to 'gruel/src/lib')
-rw-r--r-- | gruel/src/lib/Makefile.am | 2 | ||||
-rw-r--r-- | gruel/src/lib/realtime.cc | 93 | ||||
-rw-r--r-- | gruel/src/lib/sys_pri.cc | 61 |
3 files changed, 115 insertions, 41 deletions
diff --git a/gruel/src/lib/Makefile.am b/gruel/src/lib/Makefile.am index 7181c9418..c2a008e48 100644 --- a/gruel/src/lib/Makefile.am +++ b/gruel/src/lib/Makefile.am @@ -31,11 +31,11 @@ libgruel_la_LDFLAGS = $(NO_UNDEFINED) $(BOOST_LDFLAGS) -version-info 0:0:0 # These are the source files that go into the gruel shared library libgruel_la_SOURCES = \ realtime.cc \ + sys_pri.cc \ thread_body_wrapper.cc \ thread_group.cc libgruel_la_LIBADD = \ $(BOOST_THREAD_LIB) - -lstdc++ noinst_HEADERS = diff --git a/gruel/src/lib/realtime.cc b/gruel/src/lib/realtime.cc index b84117fb2..1de8b6dc0 100644 --- a/gruel/src/lib/realtime.cc +++ b/gruel/src/lib/realtime.cc @@ -30,94 +30,107 @@ #include <sched.h> #endif +#include <algorithm> +#include <math.h> #include <string.h> #include <errno.h> #include <stdio.h> -#if defined(HAVE_SCHED_SETSCHEDULER) +#if defined(HAVE_PTHREAD_SETSCHEDPARAM) || defined(HAVE_SCHED_SETSCHEDULER) +#include <pthread.h> namespace gruel { - rt_status_t - enable_realtime_scheduling() + /*! + * Rescale our virtual priority so that it maps to the middle 1/2 of + * the priorities given by min_real_pri and max_real_pri. + */ + static int + rescale_virtual_pri(int virtual_pri, int min_real_pri, int max_real_pri) { - int policy = SCHED_FIFO; - int pri = (sched_get_priority_max (policy) + sched_get_priority_min (policy)) / 2; - int pid = 0; // this process + float rmin = min_real_pri + (0.25 * (max_real_pri - min_real_pri)); + float rmax = min_real_pri + (0.75 * (max_real_pri - min_real_pri)); + float m = (rmax - rmin) / (rt_priority_max() - rt_priority_min()); + float y = m * (virtual_pri - rt_priority_min()) + rmin; + int y_int = static_cast<int>(rint(y)); + return std::max(min_real_pri, std::min(max_real_pri, y_int)); + } - if (0){ - fprintf(stderr, "sched_setscheduler version\n"); - fprintf(stderr, "pri_min(SCHED_FIFO) = %d\n", sched_get_priority_min(SCHED_FIFO)); - fprintf(stderr, "pri_max(SCHED_FIFO) = %d\n", sched_get_priority_max(SCHED_FIFO)); - fprintf(stderr, "pri = %d\n", pri); - } +} // namespace gruel + +#endif + + +#if defined(HAVE_PTHREAD_SETSCHEDPARAM) + +namespace gruel { + rt_status_t + enable_realtime_scheduling(rt_sched_param p) + { + int policy = p.policy == RT_SCHED_FIFO ? SCHED_FIFO : SCHED_RR; + int min_real_pri = sched_get_priority_min(policy); + int max_real_pri = sched_get_priority_min(policy); + int pri = rescale_virtual_pri(p.priority, min_real_pri, max_real_pri); + + pthread_t this_thread = pthread_self (); // this process struct sched_param param; - memset(¶m, 0, sizeof(param)); + memset (¶m, 0, sizeof (param)); param.sched_priority = pri; - int result = sched_setscheduler(pid, policy, ¶m); - if (result != 0){ + int result = pthread_setschedparam (this_thread, policy, ¶m); + if (result != 0) { if (errno == EPERM) return RT_NO_PRIVS; else { - perror ("sched_setscheduler: failed to set real time priority"); + perror ("pthread_setschedparam: failed to set real time priority"); return RT_OTHER_ERROR; } } - + //printf("SCHED_FIFO enabled with priority = %d\n", pri); return RT_OK; } - } // namespace gruel -#elif defined(HAVE_PTHREAD_SETSCHEDPARAM) -#include <pthread.h> -#include <stdio.h> +#elif defined(HAVE_SCHED_SETSCHEDULER) namespace gruel { rt_status_t - enable_realtime_scheduling() + enable_realtime_scheduling(rt_sched_param p) { - int policy = SCHED_FIFO; - int pri = (sched_get_priority_max (policy) + sched_get_priority_min (policy)) / 2; - - if (0){ - fprintf(stderr, "pthread_setschedparam version\n"); - fprintf(stderr, "pri_min(SCHED_FIFO) = %d\n", sched_get_priority_min(SCHED_FIFO)); - fprintf(stderr, "pri_max(SCHED_FIFO) = %d\n", sched_get_priority_max(SCHED_FIFO)); - fprintf(stderr, "pri = %d\n", pri); - } + int policy = p.policy == RT_SCHED_FIFO ? SCHED_FIFO : SCHED_RR; + int min_real_pri = sched_get_priority_min(policy); + int max_real_pri = sched_get_priority_min(policy); + int pri = rescale_virtual_pri(p.priority, min_real_pri, max_real_pri); - pthread_t this_thread = pthread_self (); // this process + int pid = 0; // this process struct sched_param param; - memset (¶m, 0, sizeof (param)); + memset(¶m, 0, sizeof(param)); param.sched_priority = pri; - int result = pthread_setschedparam (this_thread, policy, ¶m); - if (result != 0) { + int result = sched_setscheduler(pid, policy, ¶m); + if (result != 0){ if (errno == EPERM) return RT_NO_PRIVS; else { - perror ("pthread_setschedparam: failed to set real time priority"); + perror ("sched_setscheduler: failed to set real time priority"); return RT_OTHER_ERROR; } } - + //printf("SCHED_FIFO enabled with priority = %d\n", pri); return RT_OK; } -} // namespace gruel -// #elif // could try negative niceness +} // namespace gruel #else namespace gruel { rt_status_t - enable_realtime_scheduling() + enable_realtime_scheduling(rt_sched_param p) { return RT_NOT_IMPLEMENTED; } diff --git a/gruel/src/lib/sys_pri.cc b/gruel/src/lib/sys_pri.cc new file mode 100644 index 000000000..dc0164d70 --- /dev/null +++ b/gruel/src/lib/sys_pri.cc @@ -0,0 +1,61 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <gruel/sys_pri.h> + +namespace gruel { + + /* + * These may need per-OS tweaking. + * + * Under linux virtual_pri -> system_pri + * 0 -> 0 + * 1 -> 5 + * 2 -> 10 + * 3 -> 15 + * 4 -> 20 // typically used by jack and pulse audio + * 5 -> 25 + * 6 -> 30 + * 7 -> 35 + * 8 -> 40 + * 9 -> 45 + * 10 -> 50 + * 11 -> 54 + * 12 -> 59 + * 13 -> 64 + * 14 -> 69 + * 15 -> 74 + */ + rt_sched_param + sys_pri::python() { return rt_sched_param(0, RT_SCHED_RR); } + + rt_sched_param + sys_pri::normal() { return rt_sched_param(2, RT_SCHED_RR); } + + rt_sched_param + sys_pri::gcell_event_handler(){ return rt_sched_param(5, RT_SCHED_FIFO); } + + rt_sched_param + sys_pri::usrp2_backend() { return rt_sched_param(6, RT_SCHED_FIFO); } +} |