Main Page | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

rk_stubby.c

Go to the documentation of this file.
00001 /*
00002  * rk_stubby.c
00003  *
00004  * Copyright (c) 2003 The University of Utah and the Flux Group.
00005  * All rights reserved.
00006  *
00007  * This file is licensed under the terms of the GNU Public License.  
00008  * See the file "license.terms" for restrictions on redistribution 
00009  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
00010  */
00011 
00012 /**
00013  * @file rk_stubby.c
00014  *
00015  * A simple tool for simulating real-time processes using rk_stub.
00016  */
00017 
00018 #include "config.h"
00019 
00020 #include <stdio.h>
00021 #include <string.h>
00022 
00023 #include <rk.h>
00024 
00025 #if !defined(RK_STUB)
00026 #error "This file only works with the rk_stub library"
00027 #endif
00028 
00029 #include <rk_stub.h>
00030 #include "time_util.h"
00031 
00032 /**
00033  * Enumeration of the different verbosity levels.
00034  */
00035 typedef enum {
00036     VERBOSITY_NONE,
00037     VERBOSITY_DELEGATE,
00038 } rk_stubby_verbosity_t;
00039 
00040 /**
00041  * The current verbosity level.
00042  */
00043 static rk_stubby_verbosity_t verbosity = VERBOSITY_NONE;
00044 
00045 /**
00046  * The object that holds the CPU reservation parameters.
00047  */
00048 static struct cpu_reserve_attr cra = {
00049     { 1, 0 },
00050     { 2, 0 },
00051     { 2, 0 },
00052     { 0, 0 },
00053     { 0, 0 },
00054     { RSV_SOFT, RSV_SOFT, RSV_SOFT },
00055     RK_ANY_CPU,
00056 };
00057 
00058 /**
00059  * The name of the resource set that will be created.
00060  */
00061 static char *test_name = "test";
00062 
00063 /**
00064  * Flag that indicates that all data should be dropped.
00065  */
00066 static int drop_all = 0;
00067 
00068 /**
00069  * Flag that indicates that data should be dropped when the process is behind.
00070  */
00071 static int drop_behind = 0;
00072 
00073 /**
00074  * The ending time for the simulation run.
00075  */
00076 static struct timespec run_end = { 4, 0 };
00077 
00078 /**
00079  * Interpret a string as a boolean value.
00080  *
00081  * @param str The string to interpret.
00082  * @return True if the string case insensitively matches one of the following
00083  *         values: true, yes, 1, on.  Otherwise, the function returns false.
00084  */
00085 static int parse_boolean(char *str)
00086 {
00087     static char *trueValues[] = {
00088         "true",
00089         "yes",
00090         "1",
00091         "on",
00092         0
00093     };
00094     
00095     int lpc, retval = 0;
00096 
00097     for( lpc = 0; !retval && trueValues[lpc]; lpc++ )
00098     {
00099         if( strcasecmp(trueValues[lpc], str) == 0 )
00100             retval = 1;
00101     }
00102     return retval;
00103 }
00104 
00105 /**
00106  * The fake process' data.
00107  */
00108 static struct {
00109     struct timespec start;
00110     int data_period;
00111     int time_period;
00112 } c1_data;
00113 
00114 /**
00115  * The function that will be called by the simulator when a new data period
00116  * is started.
00117  *
00118  * @param data The process' data.
00119  * @return RKSP_OK if drop_all == false and drop_behind == false or the process
00120  *         is making its deadlines.  Otherwise, it returns RKSP_DROP.
00121  */
00122 static rk_stub_precall_retval_t c1_pre(void *data)
00123 {
00124     rk_stub_precall_retval_t retval = RKSP_OK;
00125     struct timespec ts;
00126 
00127     clock_gettime(CLOCK_REALTIME, &ts);
00128     if( verbosity >= VERBOSITY_DELEGATE )
00129     {
00130         printf("%s { %ld, %ld }\n",
00131                __PRETTY_FUNCTION__,
00132                ts.tv_sec,
00133                ts.tv_nsec);
00134     }
00135     {
00136         unsigned long long period_us, curr_us;
00137 
00138         period_us = timespec_to_microsec(&cra.period);
00139         curr_us = timespec_to_microsec(&ts);
00140         /* Compute which 'time' period we're in. */
00141         c1_data.time_period = (curr_us + (period_us - 1)) / period_us;
00142     }
00143     c1_data.start = ts;
00144     if( drop_all )
00145     {
00146         retval = RKSP_DROP;
00147     }
00148     if( drop_behind && (c1_data.data_period < c1_data.time_period) )
00149     {
00150         /* We're dropping it, advance to the next data period. */
00151         c1_data.data_period += 1;
00152         if( verbosity >= VERBOSITY_DELEGATE )
00153         {
00154             printf("Dropping at %d, %d\n",
00155                    c1_data.data_period,
00156                    c1_data.time_period);
00157         }
00158         retval = RKSP_DROP;
00159     }
00160     else
00161     {
00162         if( verbosity >= VERBOSITY_DELEGATE )
00163         {
00164             printf("No drop at %d, %d\n",
00165                    c1_data.data_period,
00166                    c1_data.time_period);
00167         }
00168     }
00169     return( retval );
00170 }
00171 
00172 /**
00173  * The function that will be called by the simulator when a data period
00174  * is finished.
00175  *
00176  * @param data The process' data.
00177  */
00178 void c1_post(void *data)
00179 {
00180     struct timespec ts;
00181 
00182     c1_data.data_period += 1;
00183     clock_gettime(CLOCK_REALTIME, &ts);
00184     if( verbosity >= VERBOSITY_DELEGATE )
00185     {
00186         printf("%s { %ld, %ld }\n",
00187                __PRETTY_FUNCTION__,
00188                ts.tv_sec,
00189                ts.tv_nsec);
00190     }
00191 }
00192 
00193 int main(int argc, char *argv[])
00194 {
00195     int lpc, retval = EXIT_SUCCESS;
00196     pid_t c1;
00197 
00198     rk_stub_set_mode(RK_STUB_SIM);
00199 
00200     if( ((argc - 1) % 2) != 0 )
00201     {
00202         fprintf(stderr, "Error: Odd number of arguments");
00203         retval = EXIT_FAILURE;
00204     }
00205     else
00206     {
00207         for( lpc = 1; (lpc < argc) && (retval == EXIT_SUCCESS); lpc += 2 )
00208         {
00209             if( strcmp(argv[lpc], "-name") == 0 )
00210             {
00211                 test_name = argv[lpc + 1];
00212             }
00213             else if( strcmp(argv[lpc], "-verbosity") == 0 )
00214             {
00215                 if( sscanf(argv[lpc + 1],
00216                            "%d",
00217                            (int *)&verbosity) == 0 )
00218                 {
00219                     fprintf(stderr,
00220                             "-verbosity value is not a number: %s\n",
00221                             argv[lpc + 1]);
00222                 }
00223             }
00224             else if( strcmp(argv[lpc], "-compute_sec") == 0 )
00225             {
00226                 if( sscanf(argv[lpc + 1],
00227                            "%d",
00228                            (int *)&cra.compute_time.tv_sec)
00229                     == 0 )
00230                 {
00231                     fprintf(stderr,
00232                             "-compute_sec value is not a number: %s\n",
00233                             argv[lpc + 1]);
00234                     retval = EXIT_FAILURE;
00235                 }
00236             }
00237             else if( strcmp(argv[lpc], "-compute_ns") == 0 )
00238             {
00239                 if( sscanf(argv[lpc + 1],
00240                            "%d",
00241                            (int *)&cra.compute_time.tv_nsec)
00242                     == 0 )
00243                 {
00244                     fprintf(stderr,
00245                             "-compute_ns value is not a number: %s\n",
00246                             argv[lpc + 1]);
00247                     retval = EXIT_FAILURE;
00248                 }
00249             }
00250             else if( strcmp(argv[lpc], "-period_sec") == 0 )
00251             {
00252                 if( sscanf(argv[lpc + 1], "%d", (int *)&cra.period.tv_sec)
00253                     == 0 )
00254                 {
00255                     fprintf(stderr,
00256                             "-period_sec value is not a number: %s\n",
00257                             argv[lpc + 1]);
00258                     retval = EXIT_FAILURE;
00259                 }
00260             }
00261             else if( strcmp(argv[lpc], "-period_ns") == 0 )
00262             {
00263                 if( sscanf(argv[lpc + 1], "%d", (int *)&cra.period.tv_nsec)
00264                     == 0 )
00265                 {
00266                     fprintf(stderr,
00267                             "-period_ns value is not a number: %s\n",
00268                             argv[lpc + 1]);
00269                     retval = EXIT_FAILURE;
00270                 }
00271             }
00272             else if( strcmp(argv[lpc], "-deadline_sec") == 0 )
00273             {
00274                 if( sscanf(argv[lpc + 1], "%d", (int *)&cra.deadline.tv_sec)
00275                     == 0 )
00276                 {
00277                     fprintf(stderr,
00278                             "-deadline_sec value is not a number: %s\n",
00279                             argv[lpc + 1]);
00280                     retval = EXIT_FAILURE;
00281                 }
00282             }
00283             else if( strcmp(argv[lpc], "-deadline_ns") == 0 )
00284             {
00285                 if( sscanf(argv[lpc + 1], "%d", (int *)&cra.deadline.tv_nsec)
00286                     == 0 )
00287                 {
00288                     fprintf(stderr,
00289                             "-deadline_ns value is not a number: %s\n",
00290                             argv[lpc + 1]);
00291                     retval = EXIT_FAILURE;
00292                 }
00293             }
00294             else if( strcmp(argv[lpc], "-start_sec") == 0 )
00295             {
00296                 if( sscanf(argv[lpc + 1],
00297                            "%d",
00298                            (int *)&cra.start_time.tv_sec)
00299                     == 0 )
00300                 {
00301                     fprintf(stderr,
00302                             "-start_sec value is not a number: %s\n",
00303                             argv[lpc + 1]);
00304                     retval = EXIT_FAILURE;
00305                 }
00306             }
00307             else if( strcmp(argv[lpc], "-start_ns") == 0 )
00308             {
00309                 if( sscanf(argv[lpc + 1],
00310                            "%d",
00311                            (int *)&cra.start_time.tv_nsec)
00312                     == 0 )
00313                 {
00314                     fprintf(stderr,
00315                             "-start_ns value is not a number: %s\n",
00316                             argv[lpc + 1]);
00317                     retval = EXIT_FAILURE;
00318                 }
00319             }
00320             else if( strcmp(argv[lpc], "-for") == 0 )
00321             {
00322                 if( sscanf(argv[lpc + 1], "%d", (int *)&run_end.tv_sec)
00323                     == 0 )
00324                 {
00325                     fprintf(stderr,
00326                             "-for value is not a number: %s\n",
00327                             argv[lpc + 1]);
00328                     retval = EXIT_FAILURE;
00329                 }
00330             }
00331             else if( strcmp(argv[lpc], "-drop_all") == 0 )
00332             {
00333                 drop_all = parse_boolean(argv[lpc + 1]);
00334             }
00335             else if( strcmp(argv[lpc], "-drop_behind") == 0 )
00336             {
00337                 drop_behind = parse_boolean(argv[lpc + 1]);
00338             }
00339             else
00340             {
00341                 fprintf(stderr,
00342                         "Unknown argument: %s\n",
00343                         argv[lpc]);
00344                 retval = EXIT_FAILURE;
00345             }
00346         }
00347         if( (retval == EXIT_SUCCESS) &&
00348             (c1 = rk_stub_mk_pid(test_name, &c1_data, c1_pre, c1_post)) >= 0 )
00349         {
00350             rk_resource_set_t rs;
00351 
00352             if( (rs = rk_resource_set_create(test_name)) != NULL )
00353             {
00354                 int rc;
00355                 
00356                 if( (rc = rk_resource_set_attach_process(rs, c1)) == 0 )
00357                 {
00358                     rk_reserve_t cr;
00359                     
00360                     if( (rc = rk_cpu_reserve_create(rs, &cr, &cra)) == 0 )
00361                     {
00362                         struct timespec curr = { 0, 0 };
00363                         
00364                         do {
00365                             rk_stub_next_tick();
00366                             clock_gettime(CLOCK_REALTIME, &curr);
00367                         } while( curr.tv_sec < run_end.tv_sec );
00368                     }
00369                     else
00370                     {
00371                         fprintf(stderr,
00372                                 "rk_cpu_reserve_create: %s\n",
00373                                 strerror(rc));
00374                     }
00375                 }
00376                 else
00377                 {
00378                     fprintf(stderr,
00379                             "rk_resource_set_attach_process: %s\n",
00380                             strerror(rc));
00381                 }
00382                 rk_resource_set_destroy(rs);
00383             }
00384             else
00385             {
00386                 perror("rk_resource_set_create");
00387             }
00388         }
00389         else
00390         {
00391             perror("rk_stub_mk_pid");
00392         }
00393     }
00394     return( retval );
00395 }

Generated on Tue Jun 22 14:50:10 2004 for CPU Broker by doxygen 1.3.6