MBDyn-1.7.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups
rtposixsolver.cc
Go to the documentation of this file.
1 /* $Header: /var/cvs/mbdyn/mbdyn/mbdyn-1.0/mbdyn/base/rtposixsolver.cc,v 1.20 2017/01/12 14:46:10 masarati Exp $ */
2 /*
3  * MBDyn (C) is a multibody analysis code.
4  * http://www.mbdyn.org
5  *
6  * Copyright (C) 1996-2017
7  *
8  * Pierangelo Masarati <masarati@aero.polimi.it>
9  * Paolo Mantegazza <mantegazza@aero.polimi.it>
10  *
11  * Dipartimento di Ingegneria Aerospaziale - Politecnico di Milano
12  * via La Masa, 34 - 20156 Milano, Italy
13  * http://www.aero.polimi.it
14  *
15  * Changing this copyright notice is forbidden.
16  *
17  * This program is free software; you can redistribute it and/or modify
18  * it under the terms of the GNU General Public License as published by
19  * the Free Software Foundation (version 2 of the License).
20  *
21  *
22  * This program is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25  * GNU General Public License for more details.
26  *
27  * You should have received a copy of the GNU General Public License
28  * along with this program; if not, write to the Free Software
29  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30  */
31 
32 #include "mbconfig.h" /* This goes first in every *.c,*.cc file */
33 
34 #include <cerrno>
35 #include "myassert.h"
36 #include "solver.h"
37 #include "solver_impl.h"
38 #include "rtsolver.h"
39 #include "rtposixsolver.h"
40 
41 #ifdef USE_RT
42 
43 /* RTPOSIXSolver - begin */
44 
45 RTPOSIXSolver::RTPOSIXSolver(Solver *pS,
46  RTMode eRTMode,
47  unsigned long lRTPeriod,
48  unsigned long RTStackSize,
49  bool bRTAllowNonRoot,
50  int RTCpuMap,
51  bool bNoOutput)
52 : RTSolverBase(pS, eRTMode, lRTPeriod, RTStackSize, bRTAllowNonRoot, RTCpuMap, bNoOutput),
53 clock_flags(TIMER_ABSTIME)
54 {
55  NO_OP;
56 }
57 
58 RTPOSIXSolver::~RTPOSIXSolver(void)
59 {
60  NO_OP;
61 }
62 
63 // write contribution to restart file
64 std::ostream&
65 RTPOSIXSolver::Restart(std::ostream& out) const
66 {
67  return out;
68 }
69 
70 // very first setup, to be always performed
71 void
72 RTPOSIXSolver::Setup(void)
73 {
74  // allow-nonroot should go here; something like
75  // capset(CAP_SYS_NICE);
76 
77  struct sched_param sched;
78  int policy = SCHED_FIFO;
79  int priority = 1;
80  int min_priority = sched_get_priority_min(policy);
81 
82  sched.sched_priority = sched_get_priority_max(policy) - priority;
83 
84  if (sched.sched_priority < min_priority) {
85  sched.sched_priority = min_priority;
86  }
87 
88  if (sched_setscheduler(0, policy, &sched) < 0) {
89  silent_cerr("RTPOSIXSolver: sched_setscheduler failed" << std::endl);
90  if (bRTAllowNonRoot) {
91  // FIXME: hack (let it run without priority)
92  return;
93  }
95  }
96 
97 #ifdef HAVE_SCHED_SETAFFINITY
98  if (RTCpuMap != 0xFF) {
99  cpu_set_t cpuset;
100 
101  CPU_ZERO(&cpuset);
102  for (int cpu = 0; cpu < 8; cpu++) {
103  if ((RTCpuMap >> cpu) & 0x1) {
104  CPU_SET(cpu, &cpuset);
105  }
106  }
107 
108  if (sched_setaffinity(0, sizeof(cpu_set_t), &cpuset)) {
109  silent_cerr("RTPOSIXSolver: sched_setaffinity failed" << std::endl);
111  }
112  }
113 #endif // HAVE_SCHED_SETAFFINITY
114 }
115 
116 // to be performed when stop is commanded by someone else
117 void
118 RTPOSIXSolver::StopCommanded(void)
119 {
120  // do nothing
121  NO_OP;
122 }
123 
124 // write real-time related message when stop commanded by someone else
125 void
126 RTPOSIXSolver::Log(void)
127 {
128  // TODO: print info about overruns?
129  NO_OP;
130 }
131 
132 // wait for period to expire
133 void
134 RTPOSIXSolver::Wait(void)
135 {
136  if (RTWaitPeriod()) {
137  if (RTSteps == 0) {
138  clock_gettime(CLOCK_MONOTONIC, &t0);
139  t = t0;
140  }
141 
142  t.tv_nsec += lRTPeriod;
143  if (t.tv_nsec >= 1000000000L) {
144  t.tv_nsec -= 1000000000L;
145  t.tv_sec++;
146  }
147 
148  int rc = clock_nanosleep(CLOCK_MONOTONIC, clock_flags, &t, NULL);
149  switch (rc) {
150  case 0:
151  break;
152 
153  case EINTR:
154  silent_cerr("RTPOSIXSolver: clock_nanosleep interrupted" << std::endl);
155  break;
156 
157  default:
158  silent_cerr("RTPOSIXSolver: clock_nanosleep failed "
159  "(rc=" << rc << ")" << std::endl);
161  }
162 
163 #if 0
164  } else if (RTSemWait()) {
165 #endif
166  } /* else RTBlockingIO(): do nothing */
167 
168  RTSteps++;
169 }
170 
171 #endif // USE_RT
172 
173 RTSolverBase *
175 {
176 #ifdef USE_RT
177  RTSolverBase::RTMode eRTMode;
178  unsigned long lRTPeriod;
179  unsigned long RTStackSize;
180  bool bRTAllowNonRoot;
181  int RTCpuMap;
182  ReadRTParams(pS, HP, eRTMode, lRTPeriod, RTStackSize, bRTAllowNonRoot, RTCpuMap);
183 
184  bool bNoOutput = true;
185  if (HP.IsKeyWord("output")) {
186  bNoOutput = HP.GetYesNoOrBool(bNoOutput);
187  }
188 
189  RTSolverBase *pRTSolver(0);
190  SAFENEWWITHCONSTRUCTOR(pRTSolver, RTPOSIXSolver,
191  RTPOSIXSolver(pS, eRTMode, lRTPeriod,
192  RTStackSize, bRTAllowNonRoot, RTCpuMap,
193  bNoOutput));
194  return pRTSolver;
195 
196 #else // !USE_RT
197  silent_cerr("ReadRTPOSIXSolver: need to configure --with-rt "
198  "to use POSIX realtime" << std::endl);
200 
201  return 0;
202 #endif // USE_RT
203 }
204 
205 /* RTPOSIXSolver - end */
206 
RTSolverBase * ReadRTPOSIXSolver(Solver *pS, MBDynParser &HP)
#define MBDYN_EXCEPT_ARGS
Definition: except.h:63
#define NO_OP
Definition: myassert.h:74
virtual bool GetYesNoOrBool(bool bDefval=false)
Definition: parser.cc:1038
virtual bool IsKeyWord(const char *sKeyWord)
Definition: parser.cc:910
#define SAFENEWWITHCONSTRUCTOR(pnt, item, constructor)
Definition: mynewmem.h:698
void ReadRTParams(Solver *pS, MBDynParser &HP, RTSolverBase::RTMode &eRTMode, unsigned long &lRTPeriod, unsigned long &RTStackSize, bool &bRTAllowNonRoot, int &RTCpuMap)
Definition: rtsolver.cc:89
Definition: solver.h:78