From 431e87f95cf28e7b610c7bb4a65a190f8c043d17 Mon Sep 17 00:00:00 2001
From: Andrew Johnson
Date: Tue, 9 Sep 2014 18:06:09 -0500
Subject: [PATCH] libCom/posix: Drop SCHED_FIFO before exec() in child process
osiSpawnDetachedProcess() switches to SCHED_OTHER after fork() so
the new program will not be real-time unless is requests it itself.
Only happens when USE_POSIX_THREAD_PRIORITY_SCHEDULING = YES
---
documentation/RELEASE_NOTES.html | 47 +++++++++++++++++-----------
src/libCom/osi/os/posix/osdProcess.c | 24 +++++++++++---
2 files changed, 48 insertions(+), 23 deletions(-)
diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html
index db20d167c..4dcbf7c96 100644
--- a/documentation/RELEASE_NOTES.html
+++ b/documentation/RELEASE_NOTES.html
@@ -15,28 +15,39 @@ EPICS Base 3.15.0.x releases are not intended for use in production systems.
Changes between 3.15.0.1 and 3.15.0.2
-On POSIX, attempt to lock all memory when running with FIFO scheduler
+Posix: Drop SCHED_FIFO before exec() in child process
+
+If Base is compiled with USE_POSIX_THREAD_PRIORITY_SCHEDULING = YES
+in configure/CONFIG_SITE or related files, the Posix implementation of the
+libCom osiSpawnDetachedProcess() routine will switch the child process
+to use the normal SCHED_OTHER (non real-time) scheduler before executing the
+named executable program. If it needs to use the real-time scheduler the new
+program can request that for itself.
+
+Posix: Lock all memory when running with FIFO scheduler
+
+On Posix systems, an IOC application's ability to meet timing deadlines is
+often dependent on its ability to lock part or all of the process's virtual
+address space into RAM, preventing that memory from being paged to the swap
+area. This change will attempt to lock the process's virtual address space into
+RAM if the process has the ability to run threads with different priorities. If
+unsuccessful, it prints an message to stderr and continues.
-On POSIX systems, an IOC application's ability to meet timing deadlines is often
-dependent on its ability to lock part or all of the process's virtual address space
-into RAM, preventing that memory from being paged to the swap area. This change will
-attempt to lock the process's virtual address space into RAM if the process has the
-ability to run threads with different priorities. If unsuccessful, it prints an
-message to stderr and continues.
-
On Linux, one can grant a process the ability to run threads with different
-priorities by using the command ulimit -r unlimited. To use the FIFO
-scheduler for an IOC, use a command like this:
+priorities by using the command ulimit -r unlimited. To use the
+FIFO scheduler for an IOC, use a command like this:
chrt -f 1 softIoc -d test.db
-
-On Linux, one can grant a process the ability to lock memory using the command
-ulimit -l unlimited. These limits can also be configured on a per
-user/per group basis by changing /etc/security/limits.conf or its equivalent.
-
-In Linux, a child process created via fork inherits its parent's resource
-limits. Thus, it is probably a good idea to start the caRepeater before
-starting the IOC.
+
+On Linux, one can grant a process the ability to lock itself into memory
+using the command ulimit -l unlimited. These limits can also be
+configured on a per user/per group basis by changing /etc/security/limits.conf
+or its equivalent.
+
+A child process created via fork() normally inherits its parent's resource
+limits, so a child of a real-time soft-IOC will get its parent's real-time
+priority and memlock limits. The memory locks themselves however are not
+inherited by child processes.
Implement EPICS_CAS_INTF_ADDR_LIST in rsrv
diff --git a/src/libCom/osi/os/posix/osdProcess.c b/src/libCom/osi/os/posix/osdProcess.c
index ccc8412d3..33f9f7892 100644
--- a/src/libCom/osi/os/posix/osdProcess.c
+++ b/src/libCom/osi/os/posix/osdProcess.c
@@ -24,6 +24,7 @@
#include
#include
#include
+#include
#include
#include
@@ -63,7 +64,7 @@ epicsShareFunc osiSpawnDetachedProcessReturn epicsShareAPI osiSpawnDetachedProce
(const char *pProcessName, const char *pBaseExecutableName)
{
int status;
-
+
/*
* create a duplicate process
*/
@@ -74,15 +75,16 @@ epicsShareFunc osiSpawnDetachedProcessReturn epicsShareAPI osiSpawnDetachedProce
/*
* return to the caller
- * if its in the initiating process
+ * in the initiating (parent) process
*/
if (status) {
return osiSpawnDetachedProcessSuccess;
}
/*
- * close all open files except for STDIO so they will not
- * be inherited by the spawned process.
+ * This is executed only by the new child process.
+ * Close all open files except for STDIO, so they will not
+ * be inherited by the new program.
*/
{
int fd, maxfd = sysconf ( _SC_OPEN_MAX );
@@ -94,8 +96,20 @@ epicsShareFunc osiSpawnDetachedProcessReturn epicsShareAPI osiSpawnDetachedProce
}
}
+#if defined (_POSIX_THREAD_PRIORITY_SCHEDULING)
/*
- * overlay the specified executable
+ * Drop real-time SCHED_FIFO priority
+ */
+ {
+ struct sched_param p;
+
+ p.sched_priority = 0;
+ status = sched_setscheduler(0, SCHED_OTHER, &p);
+ }
+#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
+
+ /*
+ * Run the specified executable
*/
status = execlp (pBaseExecutableName, pBaseExecutableName, (char *)NULL);
if ( status < 0 ) {