Set real-time priority. The version in source/platform/linux/scheduler.cpp
authorbruceperens <bruceperens@01035d8c-6547-0410-b346-abe4f91aad63>
Tue, 21 Jan 2014 21:21:55 +0000 (21:21 +0000)
committerbruceperens <bruceperens@01035d8c-6547-0410-b346-abe4f91aad63>
Tue, 21 Jan 2014 21:21:55 +0000 (21:21 +0000)
is (of course) Linux-specific.

git-svn-id: https://svn.code.sf.net/p/freetel/code@1383 01035d8c-6547-0410-b346-abe4f91aad63

freedv-server/CMakeLists.txt
freedv-server/source/big_main.cpp
freedv-server/source/drivers.h
freedv-server/source/platform/linux/.gitignore [deleted file]
freedv-server/source/platform/linux/scheduler.cpp [new file with mode: 0644]
freedv-server/source/run.cpp

index 0460ef75765727a4469195e26a4d322f49069926..35f2369be82624d7259da2da0dd85994f32e3795 100644 (file)
@@ -86,7 +86,18 @@ message(STATUS "${Param.build-type} ${Version.major}.${Version.minor}.${Version.
 #
 # Set cmake internal variables from parameters.
 #
+
+set(Compile.linux.sources
+  source/platform/linux/scheduler.cpp
+)
+
+# FIX: Add other platforms.
+if(Platform.name STREQUAL Linux)
+  set(Compile.platform.sources ${Compile.linux.sources})
+endif(Platform.name STREQUAL Linux)
+
 set(Compile.sources
+  ${Compile.platform.sources}
   source/audio_device.cpp
   source/audio_input.cpp
   source/audio_output.cpp
index 742397170c080077da01628f246edcef11823e70..b60cc0e005b03c38fc18d982813981f00ef4bce6 100644 (file)
@@ -182,6 +182,7 @@ main(int argc, char * * argv)
     help(argv[0]);
     exit(1);
   }
+  set_scheduler();
   return run(&i);
 }
 #endif
index 25b3766439c2779199a38f404b09edc3abb41c51..65a0a57d8a6f6f6b2896b2dca810e989f8cc7ed1 100644 (file)
@@ -17,7 +17,11 @@ namespace FreeDV {
   /// \param s The string to be copied.
   /// \return The new copy. It's the caller's responsibility to free this data,
   ///  or a memory leak will occurr.
-  char * copy_string(const char * s);
+  char *       copy_string(const char * s);
+
+  /// Set the real-time parameters in the scheduler before running our main
+  /// loop.
+  void         set_scheduler();
 
   /// Virtual base class for all driver classes.
   class Base {
diff --git a/freedv-server/source/platform/linux/.gitignore b/freedv-server/source/platform/linux/.gitignore
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/freedv-server/source/platform/linux/scheduler.cpp b/freedv-server/source/platform/linux/scheduler.cpp
new file mode 100644 (file)
index 0000000..cd01dc4
--- /dev/null
@@ -0,0 +1,35 @@
+#include <unistd.h>
+#ifdef _POSIX_PRIORITY_SCHEDULING
+#include <errno.h>
+#include <sched.h>
+#include <cstring>
+#include <iostream>
+#endif
+#include "drivers.h"
+
+namespace FreeDV {
+  void
+  set_scheduler()
+  {
+#ifdef _POSIX_PRIORITY_SCHEDULING
+    sched_param        p;
+    int                policy = SCHED_RR;
+
+    p.sched_priority = sched_get_priority_min(policy);
+    const int result = sched_setscheduler(0, policy, &p);
+    if ( result < 0 ) {
+      if ( errno == EPERM ) {
+        std::cerr << "Insufficient privilege to set real-time priority. "
+        "Try runing as root." << std::endl;
+      }
+      else if ( errno == EINVAL ) {
+        std::cerr << "This kernel doesn't seem to have real-time facilities. "
+         "If audio is sometimes interrupted, try a newer kernel." << std::endl;
+      }
+      else {
+        std::cerr << "sched_setscheduler: " << strerror(errno) << std::endl;
+      }
+    }
+  }
+#endif
+}
index 8a8933701ed73bf3f48026f95a0ef50fccdfb238..dfe996554fab3cf8760b143f3af025ee58b5867f 100644 (file)
@@ -68,7 +68,7 @@ namespace FreeDV {
       else {
         receive(i);
       }
-      usleep(10000);
+      usleep(20000);
     }
   }