root/trunk/libffado/tests/systemtests/test-sysload.cpp

Revision 2803, 5.9 kB (checked in by jwoithe, 3 years ago)

Cosmetic: capitalise "L" in "Linux".

"Linux" is a proper noun so it should start with a capital letter. These
changes are almost all within comments.

This patch was originally proposed by pander on the ffado-devel mailing
list. It has been expanded to cover all similar cases to maintain
consistency throughout the source tree.

Line 
1 /*
2  * Parts Copyright (C) 2005-2008 by Pieter Palmers
3  *
4  * This file is part of FFADO
5  * FFADO = Free FireWire (pro-)audio drivers for Linux
6  *
7  * FFADO is based upon FreeBoB
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 2 of the License, or
12  * (at your option) version 3 of the License.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  *
22  */
23
24 /*
25  * based on howdyget.c (unknown source, maybe Maas Digital LLC)
26  */
27
28 #include <stdio.h>
29 #include <errno.h>
30 #include <unistd.h>
31 #include <signal.h>
32
33 #include <argp.h>
34
35 #ifndef __STDC_FORMAT_MACROS
36 #define __STDC_FORMAT_MACROS
37 #endif
38 #include <inttypes.h>
39
40 #include "debugmodule/debugmodule.h"
41 #include "realtimetools.h"
42 #include <cstdlib>
43
44 uint32_t count = 0;
45
46 DECLARE_GLOBAL_DEBUG_MODULE;
47
48 #define MAX_EXTRA_ARGS 2
49 // Program documentation.
50 // Program documentation.
51 static char doc[] = "FFADO -- simple RT system loader\n\n";
52
53 // A description of the arguments we accept.
54 static char args_doc[] = "";
55
56 struct arguments
57 {
58     long int verbose;
59     long int rtprio;
60     long int period;
61     long int countdown;
62     long int cpu_pct;
63     char* args[MAX_EXTRA_ARGS];
64 };
65
66 // The options we understand.
67 static struct argp_option options[] = {
68     {"verbose",  'v', "level",    0,  "Verbose level" },
69     {"rtprio",  'P', "prio",  0,  "real time priority of the iterator process/thread (0 = no RT)" },
70     {"period",  'p', "usecs",  0,  "period duration (in usecs)" },
71     {"countdown",  'u', "count",  0,  "number of times to run the load loop" },
72     {"cpu_pct",  'c', "count",  0,  "target CPU use (in percent)" },
73     { 0 }
74 };
75
76 // Parse a single option.
77 #define PARSE_ARG_LONG(XXletterXX, XXvarXX, XXdescXX) \
78     case XXletterXX: \
79         if (arg) { \
80             XXvarXX = strtol( arg, &tail, 0 ); \
81             if ( errno ) { \
82                 fprintf( stderr,  "Could not parse '%s' argument\n", XXdescXX ); \
83                 return ARGP_ERR_UNKNOWN; \
84             } \
85         } \
86         break;
87
88 static error_t
89 parse_opt( int key, char* arg, struct argp_state* state )
90 {
91     // Get the input argument from `argp_parse', which we
92     // know is a pointer to our arguments structure.
93     struct arguments* arguments = ( struct arguments* ) state->input;
94     char* tail;
95
96     errno = 0;
97     switch (key) {
98     PARSE_ARG_LONG('v', arguments->verbose, "verbose");
99     PARSE_ARG_LONG('P', arguments->rtprio, "rtprio");
100     PARSE_ARG_LONG('p', arguments->period, "period");
101     PARSE_ARG_LONG('u', arguments->countdown, "countdown");
102     PARSE_ARG_LONG('c', arguments->cpu_pct, "cpu_pct");
103
104     case ARGP_KEY_ARG:
105         break;
106     case ARGP_KEY_END:
107         break;
108     default:
109         return ARGP_ERR_UNKNOWN;
110     }
111     return 0;
112 }
113
114 // Our argp parser.
115 static struct argp argp = { options, parse_opt, args_doc, doc };
116
117 // the global arguments struct
118 struct arguments arguments;
119
120 // signal handler
121 int run;
122 static void sighandler (int sig)
123 {
124     run = 0;
125 }
126
127 // the load function
128 float global;
129 void load_function() {
130     int cnt = 10;
131     while(cnt--) {
132         int global_int = (int)global;
133         global = global / 7.0;
134         global_int++;
135         global += (float)global_int;
136     }
137 }
138
139 int main(int argc, char **argv)
140 {
141     // register signal handler
142     run = 1;
143     signal (SIGINT, sighandler);
144     signal (SIGPIPE, sighandler);
145
146     // Default values.
147     arguments.verbose = DEBUG_LEVEL_VERBOSE;
148     arguments.rtprio = 0;
149     arguments.countdown = 1000;
150     arguments.period = 1000;
151     arguments.cpu_pct = 50;
152
153     // Parse our arguments; every option seen by `parse_opt' will
154     // be reflected in `arguments'.
155     if ( argp_parse ( &argp, argc, argv, 0, 0, &arguments ) ) {
156         debugError("Could not parse command line\n" );
157         return -1;
158     }
159
160     debugOutput(DEBUG_LEVEL_INFO, "Simple RT system loader\n");
161     debugOutput(DEBUG_LEVEL_INFO, " Arguments:\n");
162     debugOutput(DEBUG_LEVEL_INFO, "  RT priority : %ld\n", arguments.rtprio);
163     debugOutput(DEBUG_LEVEL_INFO, "  Countdown   : %ld\n", arguments.countdown);
164     debugOutput(DEBUG_LEVEL_INFO, "  Period      : %ld usec\n", arguments.period);
165     debugOutput(DEBUG_LEVEL_INFO, "  CPU load    : %ld%%\n", arguments.cpu_pct);
166
167     debugOutput(DEBUG_LEVEL_INFO, "Setting RT priority (%ld)...\n", arguments.rtprio);
168     set_realtime_priority(arguments.rtprio);
169
170     debugOutput(DEBUG_LEVEL_INFO, "Starting iterate loop...\n");
171     flushDebugOutput();
172    
173     int countdown = arguments.countdown;
174     uint64_t sleep_time = rt_gettime_usecs();
175     while(countdown-- && run)
176     {
177         // figure out when to stop calling the load function
178         uint64_t run_until = sleep_time + arguments.period * arguments.cpu_pct / 100;
179        
180 //         uint64_t tic = rt_gettime_usecs();
181         while(rt_gettime_usecs() < run_until) load_function();
182         uint64_t toc = rt_gettime_usecs();
183
184         // now wait for the period to end
185         sleep_time += arguments.period;
186         rt_sleep_absolute_usecs(sleep_time);
187        
188         // check if we are late
189         toc = rt_gettime_usecs();
190         int64_t usecs_late = toc - sleep_time;
191         if(usecs_late > 1000) {
192             debugWarning("late wakeup: %" PRId64 " usecs\n", usecs_late);
193         }
194
195         // try and detect lockup ()
196         if(usecs_late > 100000) {
197             debugWarning("very late wakeup: %" PRId64 " usecs\n", usecs_late);
198             // force exit, since this is a loop out of control
199             run=0;
200         }
201     }
202
203     if(run) {
204         debugOutput(DEBUG_LEVEL_INFO, "Clean exit...\n");
205     } else {
206         debugOutput(DEBUG_LEVEL_INFO, "Forced exit...\n");
207     }
208     return 0;
209 }
Note: See TracBrowser for help on using the browser.