Laelaps  2.3.5
RoadNarrows Robotics Small Outdoor Mobile Robot Project
utThread.cxx
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // Package: Laelaps
4 //
5 // Program: utThread
6 //
7 // File: utThread.cxx
8 //
9 /*! \file
10  *
11  * $LastChangedDate: 2015-01-15 12:45:22 -0700 (Thu, 15 Jan 2015) $
12  * $Rev: 3857 $
13  *
14  * \brief Unit test liblaelaps thread base class.
15  *
16  * \author Robin Knight (robin.knight@roadnarrows.com)
17  *
18  * \par Copyright
19  * \h_copy 2015-2017. RoadNarrows LLC.\n
20  * http://www.roadnarrows.com\n
21  * All Rights Reserved
22  */
23 /*
24  * @EulaBegin@
25  *
26  * Unless otherwise stated explicitly, all materials contained are copyrighted
27  * and may not be used without RoadNarrows LLC's written consent,
28  * except as provided in these terms and conditions or in the copyright
29  * notice (documents and software) or other proprietary notice provided with
30  * the relevant materials.
31  *
32  * IN NO EVENT SHALL THE AUTHOR, ROADNARROWS LLC, OR ANY
33  * MEMBERS/EMPLOYEES/CONTRACTORS OF ROADNARROWS OR DISTRIBUTORS OF THIS SOFTWARE
34  * BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR
35  * CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
36  * DOCUMENTATION, EVEN IF THE AUTHORS OR ANY OF THE ABOVE PARTIES HAVE BEEN
37  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38  *
39  * THE AUTHORS AND ROADNARROWS LLC SPECIFICALLY DISCLAIM ANY WARRANTIES,
40  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
41  * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN
42  * "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO
43  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
44  *
45  * @EulaEnd@
46  */
47 ////////////////////////////////////////////////////////////////////////////////
48 
49 #include <unistd.h>
50 #include <termios.h>
51 #include <string.h>
52 #include <stdio.h>
53 #include <stdlib.h>
54 #include <stdarg.h>
55 
56 #include <iostream>
57 #include <fstream>
58 #include <string>
59 
60 #include "rnr/rnrconfig.h"
61 #include "rnr/log.h"
62 #include "rnr/opts.h"
63 #include "rnr/pkg.h"
64 
65 #include "rnr/appkit/Random.h"
66 
67 #include "Laelaps/laelaps.h"
68 #include "Laelaps/laeThread.h"
69 
70 #include "version.h"
71 
72 using namespace std;
73 using namespace rnr;
74 using namespace laelaps;
75 
76 /*!
77  * \ingroup apps
78  * \defgroup unittest utThread
79  * \{
80  */
81 
82 #define APP_EC_OK 0 ///< success exit code
83 #define APP_EC_ARGS 2 ///< command-line options/arguments error exit code
84 #define APP_EC_EXEC 4 ///< execution exit code
85 
86 static char *Argv0; ///< the command
87 static double OptsHz = 2; ///< thread hertz rate
88 static bool_t OptsRand = false; ///< thread random jitter
89 
90 /*!
91  * \brief Program information.
92  */
93 static OptsPgmInfo_T PgmInfo =
94 {
95  // usage_args
96  NULL,
97 
98  // synopsis
99  "Unit test liblaelaps LaeThread base class.",
100 
101  // long_desc =
102  "The %P command unit tests the liblaelap LaeThread base class operation.",
103 
104  // diagnostics
105  NULL
106 };
107 
108 /*!
109  * \brief Command line options information.
110  */
111 static OptsInfo_T OptsInfo[] =
112 {
113  // -h, --hertz`
114  {
115  "hertz`", // long_opt
116  'u', // short_opt
117  required_argument, // has_arg
118  true, // has_default
119  &OptsHz, // opt_addr
120  OptsCvtArgFloat, // fn_cvt
121  OptsFmtFloat, // fn_fmt
122  NULL, // arg_name
123  // opt desc
124  "Thread execution cycle hertz run rate."
125  },
126 
127  // -r, --random`
128  {
129  "random`", // long_opt
130  'r', // short_opt
131  no_argument, // has_arg
132  true, // has_default
133  &OptsRand, // opt_addr
134  OptsCvtArgBool, // fn_cvt
135  OptsFmtBool, // fn_fmt
136  NULL, // arg_name
137  // opt desc
138  "Do [not] randomly jitter the scheduled execution."
139  },
140 
141  {NULL, }
142 };
143 
144 class UTThread : public LaeThread
145 {
146 public:
147  UTThread() : LaeThread("UnitTest")
148  {
149  }
150 
151  virtual ~UTThread()
152  {
153  }
154 
155 protected:
156  Random m_rand;
157 
158  virtual void transToReady()
159  {
160  printf("UTThread::transToReady, state=%d\n", m_eState);
161  }
162 
163  virtual void transToRunning()
164  {
165  printf("UTThread::transToRunning, state=%d\n", m_eState);
166  }
167 
168  virtual void transToExit()
169  {
170  printf("UTThread::transToExit, state=%d\n", m_eState);
171  }
172 
173  virtual void exec()
174  {
175  ulong_t usec;
176  double f;
177 
178  LaeThread::exec();
179 
180  if( OptsRand )
181  {
182  f = (double)m_rand.uniform(0.0, 2.0);
183  usec = (ulong_t)(f * m_fTExec * 1000000);
184  usleep(usec);
185  }
186  }
187 };
188 
189 int getch()
190 {
191  struct termios old = {0};
192  char c = 0;
193 
194  if( tcgetattr(0, &old) < 0 )
195  {
196  return EOF;
197  }
198 
199  old.c_lflag &= ~ICANON;
200  old.c_lflag &= ~ECHO;
201  old.c_cc[VMIN] = 1;
202  old.c_cc[VTIME] = 0;
203 
204  if( tcsetattr(0, TCSANOW, &old) < 0 )
205  {
206  return EOF;
207  }
208 
209  if( read(0, &c, 1) < 0 )
210  {
211  return EOF;
212  }
213 
214  old.c_lflag |= ICANON;
215  old.c_lflag |= ECHO;
216 
217  if( tcsetattr(0, TCSADRAIN, &old) < 0 )
218  {
219  }
220 
221  return c;
222 }
223 
224 int kbhit()
225 {
226  int c;
227 
228  while( (c = getch()) == 0 );
229 
230  return c;
231 }
232 
233 /*!
234  * \brief Main initialization.
235  *
236  * \param argc Command-line argument count.
237  * \param argv Command-line argument list.
238  *
239  * \par Exits:
240  * Program terminates on conversion error.
241  */
242 static void mainInit(int argc, char *argv[])
243 {
244  // name of this process
245  Argv0 = basename(argv[0]);
246 
247  // parse input options
248  argv = OptsGet(Argv0, &PkgInfo, &PgmInfo, OptsInfo, true, &argc, argv);
249 }
250 
251 /*!
252  * \brief Main.
253  *
254  * \param argc Command-line argument count.
255  * \param argv Command-line argument list.
256  *
257  * \return Returns 0 on succes, non-zero on failure.
258  */
259 int main(int argc, char* argv[])
260 {
261  UTThread th;
262 
263  mainInit(argc, argv);
264 
265  printf("Press any key to terminate.\n\n");
266 
267  th.createThread(15);
268  th.runThread(OptsHz);
269 
270  while( true )
271  {
272  //usleep(1000);
273  //break;
274  if( kbhit() )
275  {
276  break;
277  }
278  }
279 
280  th.terminateThread();
281 
282  return APP_EC_OK;
283 }
284 
285 /*!
286  * \}
287  */
Laelaps thread base class interface.
static bool_t OptsRand
thread random jitter
Definition: utThread.cxx:88
virtual int terminateThread()
Terminate the thread.
Definition: laeThread.cxx:202
static char * Argv0
the command
Definition: utThread.cxx:86
virtual void transToReady()
Uninitialized to Ready state transition function.
Definition: utThread.cxx:158
virtual void transToRunning()
Ready to Running state transition function.
Definition: utThread.cxx:163
virtual void exec()
Execute task(s) within scheduled [sub]cycle.
Definition: utThread.cxx:173
static double OptsHz
thread hertz rate
Definition: utThread.cxx:87
#define APP_EC_OK
success exit code
Definition: utThread.cxx:82
static OptsInfo_T OptsInfo[]
Command line options information.
Definition: utThread.cxx:111
The <b><i>Laelaps</i></b> namespace encapsulates all <b><i>Laelaps</i></b> related constructs...
Definition: laeAlarms.h:64
static const PkgInfo_T PkgInfo
Definition: version.h:45
Package version information.
virtual int createThread(int nPriority)
Create the thread.
Definition: laeThread.cxx:107
virtual void transToExit()
Any to Exit state transition function.
Definition: utThread.cxx:168
static void mainInit(int argc, char *argv[])
Main initialization.
Definition: utThread.cxx:242
int main(int argc, char *argv[])
Main.
Definition: utRobot.cxx:138
virtual int runThread(const double fHz)
Run the thread.
Definition: laeThread.cxx:174
static OptsPgmInfo_T PgmInfo
Program information.
Definition: utThread.cxx:93
Top-level package include file.