From 2b05be870a3b4d75ad7db46c894e6799bb170ea6 Mon Sep 17 00:00:00 2001 From: darkeye Date: Wed, 20 Dec 2000 12:36:47 +0000 Subject: [PATCH] added POSIX real-time scheduling --- darkice/trunk/configure.h.in | 3 + darkice/trunk/configure.in | 1 + darkice/trunk/src/DarkIce.cpp | 105 ++++++++++++++++++++++++++++++++-- darkice/trunk/src/DarkIce.h | 31 ++++++++++ 4 files changed, 136 insertions(+), 4 deletions(-) diff --git a/darkice/trunk/configure.h.in b/darkice/trunk/configure.h.in index 138e711..f6ec2bc 100644 --- a/darkice/trunk/configure.h.in +++ b/darkice/trunk/configure.h.in @@ -30,6 +30,9 @@ /* Define if you have the header file. */ #undef HAVE_NETINET_IN_H +/* Define if you have the header file. */ +#undef HAVE_SCHED_H + /* Define if you have the header file. */ #undef HAVE_SIGNAL_H diff --git a/darkice/trunk/configure.in b/darkice/trunk/configure.in index e23abe4..99a60bf 100644 --- a/darkice/trunk/configure.in +++ b/darkice/trunk/configure.in @@ -11,6 +11,7 @@ dnl AC_STDC_HEADERS AC_HAVE_HEADERS(errno.h fcntl.h stdio.h stdlib.h string.h unistd.h limits.h) AC_HAVE_HEADERS(getopt.h signal.h time.h sys/time.h sys/types.h sys/soundcard.h) AC_HAVE_HEADERS(netdb.h netinet/in.h sys/ioctl.h sys/socket.h sys/stat.h) +AC_HAVE_HEADERS(sched.h) AC_HEADER_SYS_WAIT() AC_TYPE_PID_T() diff --git a/darkice/trunk/src/DarkIce.cpp b/darkice/trunk/src/DarkIce.cpp index 24ab35e..a0e7b67 100644 --- a/darkice/trunk/src/DarkIce.cpp +++ b/darkice/trunk/src/DarkIce.cpp @@ -40,6 +40,12 @@ #error need stdlib.h #endif +#ifdef HAVE_UNISTD_H +#include +#else +#error need unistd.h +#endif + #ifdef HAVE_SYS_TYPES_H #include #else @@ -58,6 +64,12 @@ #error need errno.h #endif +#ifdef HAVE_SCHED_H +#include +#else +#error need sched.h +#endif + #include #include @@ -264,6 +276,89 @@ DarkIce :: init ( const Config & config ) throw ( Exception ) } +/*------------------------------------------------------------------------------ + * Set POSIX real-time scheduling, if super-user + *----------------------------------------------------------------------------*/ +void +DarkIce :: setRealTimeScheduling ( void ) throw ( Exception ) +{ + uid_t euid; + + euid = geteuid(); + + if ( euid == 0 ) { + int high_priority; + struct sched_param param; + + /* store the old scheduling parameters */ + if ( (origSchedPolicy = sched_getscheduler(0)) == -1 ) { + throw Exception( __FILE__, __LINE__, "sched_getscheduler", errno); + } + + if ( sched_getparam( 0, ¶m) == -1 ) { + throw Exception( __FILE__, __LINE__, "sched_getparam", errno); + } + origSchedPriority = param.sched_priority; + + /* set SCHED_FIFO with max - 1 priority */ + if ( (high_priority = sched_get_priority_max(SCHED_FIFO)) == -1 ) { + throw Exception(__FILE__,__LINE__,"sched_get_priority_max",errno); + } + reportEvent( 8, "scheduler high priority", high_priority); + + param.sched_priority = high_priority - 1; + + if ( sched_setscheduler( 0, SCHED_FIFO, ¶m) == -1 ) { + throw Exception( __FILE__, __LINE__, "sched_setscheduler", errno); + } + + /* ask the new priortiy and report it */ + if ( sched_getparam( 0, ¶m) == -1 ) { + throw Exception( __FILE__, __LINE__, "sched_getparam", errno); + } + + reportEvent( 1, + "Using POSIX real-time scheduling, priority", + param.sched_priority ); + } else { + reportEvent( 1, + "Not running as super-user, unable to use POSIX real-time scheduling" ); + reportEvent( 1, + "It is recommended that you run this program as super-user"); + } +} + + +/*------------------------------------------------------------------------------ + * Set the original scheduling of the process, the one prior to the + * setRealTimeScheduling call. + * WARNING: make sure you don't call this before setRealTimeScheduling!! + *----------------------------------------------------------------------------*/ +void +DarkIce :: setOriginalScheduling ( void ) throw ( Exception ) +{ + uid_t euid; + + euid = geteuid(); + + if ( euid == 0 ) { + struct sched_param param; + + if ( sched_getparam( 0, ¶m) == -1 ) { + throw Exception( __FILE__, __LINE__, "sched_getparam", errno); + } + + param.sched_priority = origSchedPriority; + + if ( sched_setscheduler( 0, origSchedPolicy, ¶m) == -1 ) { + throw Exception( __FILE__, __LINE__, "sched_setscheduler", errno); + } + + reportEvent( 5, "reverted to original scheduling"); + } +} + + /*------------------------------------------------------------------------------ * Run the encoder *----------------------------------------------------------------------------*/ @@ -289,10 +384,7 @@ DarkIce :: encode ( void ) throw ( Exception ) dsp->getChannel() * duration; - len = encConnector->transfer( bytes, - 4096, - 1, - 0 ); + len = encConnector->transfer( bytes, 4096, 1, 0 ); reportEvent( 1, len, "bytes transfered to the encoders"); @@ -364,7 +456,9 @@ DarkIce :: run ( void ) throw ( Exception ) // this is the parent reportEvent( 3, "encoding"); + setRealTimeScheduling(); encode(); + setOriginalScheduling(); reportEvent( 3, "encoding ends"); for ( u = 0; u < noOutputs; ++u ) { @@ -387,6 +481,9 @@ DarkIce :: run ( void ) throw ( Exception ) $Source$ $Log$ + Revision 1.12 2000/12/20 12:36:47 darkeye + added POSIX real-time scheduling + Revision 1.11 2000/11/18 11:13:27 darkeye removed direct reference to cout, except from main.cpp all class use the Reporter interface to report events diff --git a/darkice/trunk/src/DarkIce.h b/darkice/trunk/src/DarkIce.h index 15ebe29..d2eee28 100644 --- a/darkice/trunk/src/DarkIce.h +++ b/darkice/trunk/src/DarkIce.h @@ -125,6 +125,16 @@ class DarkIce : public virtual Referable, public virtual Reporter */ unsigned int noOutputs; + /** + * Original scheduling policy + */ + int origSchedPolicy; + + /** + * Original scheduling priority + */ + int origSchedPriority; + /** * Initialize the object. * @@ -135,6 +145,24 @@ class DarkIce : public virtual Referable, public virtual Reporter void init ( const Config & config ) throw ( Exception ); + /** + * Set POSIX real-time scheduling for the encoding process, + * if user permissions enable it. + * + * @exception Exception + */ + void + setRealTimeScheduling ( void ) throw ( Exception ); + + /** + * Set the scheduling that was before setting real-time scheduling. + * This function must be called _only_ after setRealTimeScheduling. + * + * @exception Exception + */ + void + setOriginalScheduling ( void ) throw ( Exception ); + /** * Start encoding. Spawns all encoders, opens the dsp and * starts sending data to the encoders. @@ -236,6 +264,9 @@ class DarkIce : public virtual Referable, public virtual Reporter $Source$ $Log$ + Revision 1.7 2000/12/20 12:36:47 darkeye + added POSIX real-time scheduling + Revision 1.6 2000/11/15 18:08:43 darkeye added multiple verbosity-level event reporting and verbosity command line option