see http://mbed.org/users/no2chem/notebook/mbed-clock-control--benchmarks/

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers core_state.c Source File

core_state.c

00001 /*
00002 Author : Shay Gal-On, EEMBC
00003 
00004 This file is part of  EEMBC(R) and CoreMark(TM), which are Copyright (C) 2009 
00005 All rights reserved.                            
00006 
00007 EEMBC CoreMark Software is a product of EEMBC and is provided under the terms of the
00008 CoreMark License that is distributed with the official EEMBC COREMARK Software release. 
00009 If you received this EEMBC CoreMark Software without the accompanying CoreMark License, 
00010 you must discontinue use and download the official release from www.coremark.org.  
00011 
00012 Also, if you are publicly displaying scores generated from the EEMBC CoreMark software, 
00013 make sure that you are in compliance with Run and Reporting rules specified in the accompanying readme.txt file.
00014 
00015 EEMBC 
00016 4354 Town Center Blvd. Suite 114-200
00017 El Dorado Hills, CA, 95762 
00018 */ 
00019 #include "coremark.h"
00020 /* local functions */
00021 enum CORE_STATE core_state_transition( ee_u8 **instr , ee_u32 *transition_count);
00022 
00023 /*
00024 Topic: Description
00025     Simple state machines like this one are used in many embedded products.
00026     
00027     For more complex state machines, sometimes a state transition table implementation is used instead, 
00028     trading speed of direct coding for ease of maintenance.
00029     
00030     Since the main goal of using a state machine in CoreMark is to excercise the switch/if behaviour,
00031     we are using a small moore machine. 
00032     
00033     In particular, this machine tests type of string input,
00034     trying to determine whether the input is a number or something else.
00035     (see core_state.png).
00036 */
00037 
00038 /* Function: core_bench_state
00039     Benchmark function
00040 
00041     Go over the input twice, once direct, and once after introducing some corruption. 
00042 */
00043 ee_u16 core_bench_state(ee_u32 blksize, ee_u8 *memblock, 
00044         ee_s16 seed1, ee_s16 seed2, ee_s16 step, ee_u16 crc) 
00045 {
00046     ee_u32 final_counts[NUM_CORE_STATES];
00047     ee_u32 track_counts[NUM_CORE_STATES];
00048     ee_u8 *p=memblock;
00049     ee_u32 i;
00050 
00051 
00052 #if CORE_DEBUG
00053     ee_printf("State Bench: %d,%d,%d,%04x\n",seed1,seed2,step,crc);
00054 #endif
00055     for (i=0; i<NUM_CORE_STATES; i++) {
00056         final_counts[i]=track_counts[i]=0;
00057     }
00058     /* run the state machine over the input */
00059     while (*p!=0) {
00060         enum CORE_STATE fstate=core_state_transition(&p,track_counts);
00061         final_counts[fstate]++;
00062 #if CORE_DEBUG
00063     ee_printf("%d,",fstate);
00064     }
00065     ee_printf("\n");
00066 #else
00067     }
00068 #endif
00069     p=memblock;
00070     while (p < (memblock+blksize)) { /* insert some corruption */
00071         if (*p!=',')
00072             *p^=(ee_u8)seed1;
00073         p+=step;
00074     }
00075     p=memblock;
00076     /* run the state machine over the input again */
00077     while (*p!=0) {
00078         enum CORE_STATE fstate=core_state_transition(&p,track_counts);
00079         final_counts[fstate]++;
00080 #if CORE_DEBUG
00081     ee_printf("%d,",fstate);
00082     }
00083     ee_printf("\n");
00084 #else
00085     }
00086 #endif
00087     p=memblock;
00088     while (p < (memblock+blksize)) { /* undo corruption is seed1 and seed2 are equal */
00089         if (*p!=',')
00090             *p^=(ee_u8)seed2;
00091         p+=step;
00092     }
00093     /* end timing */
00094     for (i=0; i<NUM_CORE_STATES; i++) {
00095         crc=crcu32(final_counts[i],crc);
00096         crc=crcu32(track_counts[i],crc);
00097     }
00098     return crc;
00099 }
00100 
00101 /* Default initialization patterns */
00102 static ee_u8 *intpat[4]  ={(ee_u8 *)"5012",(ee_u8 *)"1234",(ee_u8 *)"-874",(ee_u8 *)"+122"};
00103 static ee_u8 *floatpat[4]={(ee_u8 *)"35.54400",(ee_u8 *)".1234500",(ee_u8 *)"-110.700",(ee_u8 *)"+0.64400"};
00104 static ee_u8 *scipat[4]  ={(ee_u8 *)"5.500e+3",(ee_u8 *)"-.123e-2",(ee_u8 *)"-87e+832",(ee_u8 *)"+0.6e-12"};
00105 static ee_u8 *errpat[4]  ={(ee_u8 *)"T0.3e-1F",(ee_u8 *)"-T.T++Tq",(ee_u8 *)"1T3.4e4z",(ee_u8 *)"34.0e-T^"};
00106 
00107 /* Function: core_init_state
00108     Initialize the input data for the state machine.
00109 
00110     Populate the input with several predetermined strings, interspersed.
00111     Actual patterns chosen depend on the seed parameter.
00112     
00113     Note:
00114     The seed parameter MUST be supplied from a source that cannot be determined at compile time
00115 */
00116 void core_init_state(ee_u32 size, ee_s16 seed, ee_u8 *p) {
00117     ee_u32 total=0,next=0,i;
00118     ee_u8 *buf=0;
00119 #if CORE_DEBUG
00120     ee_u8 *start=p;
00121     ee_printf("State: %d,%d\n",size,seed);
00122 #endif
00123     size--;
00124     next=0;
00125     while ((total+next+1)<size) {
00126         if (next>0) {
00127             for(i=0;i<next;i++)
00128                 *(p+total+i)=buf[i];
00129             *(p+total+i)=',';
00130             total+=next+1;
00131         }
00132         seed++;
00133         switch (seed & 0x7) {
00134             case 0: /* int */
00135             case 1: /* int */
00136             case 2: /* int */
00137                 buf=intpat[(seed>>3) & 0x3];
00138                 next=4;
00139             break;
00140             case 3: /* float */
00141             case 4: /* float */
00142                 buf=floatpat[(seed>>3) & 0x3];
00143                 next=8;
00144             break;
00145             case 5: /* scientific */
00146             case 6: /* scientific */
00147                 buf=scipat[(seed>>3) & 0x3];
00148                 next=8;
00149             break;
00150             case 7: /* invalid */
00151                 buf=errpat[(seed>>3) & 0x3];
00152                 next=8;
00153             break;
00154             default: /* Never happen, just to make some compilers happy */
00155             break;
00156         }
00157     }
00158     size++;
00159     while (total<size) { /* fill the rest with 0 */
00160         *(p+total)=0;
00161         total++;
00162     }
00163 #if CORE_DEBUG
00164     ee_printf("State Input: %s\n",start);
00165 #endif
00166 }
00167 
00168 static ee_u8 ee_isdigit(ee_u8 c) {
00169     ee_u8 retval;
00170     retval = ((c>='0') & (c<='9')) ? 1 : 0;
00171     return retval;
00172 }
00173 
00174 /* Function: core_state_transition
00175     Actual state machine.
00176 
00177     The state machine will continue scanning until either:
00178     1 - an invalid input is detcted.
00179     2 - a valid number has been detected.
00180     
00181     The input pointer is updated to point to the end of the token, and the end state is returned (either specific format determined or invalid).
00182 */
00183 
00184 enum CORE_STATE core_state_transition( ee_u8 **instr , ee_u32 *transition_count) {
00185     ee_u8 *str=*instr;
00186     ee_u8 NEXT_SYMBOL;
00187     enum CORE_STATE state=CORE_START;
00188     for( ; *str && state != CORE_INVALID; str++ ) {
00189         NEXT_SYMBOL = *str;
00190         if (NEXT_SYMBOL==',') /* end of this input */ {
00191             str++;
00192             break;
00193         }
00194         switch(state) {
00195         case CORE_START:
00196             if(ee_isdigit(NEXT_SYMBOL)) {
00197                 state = CORE_INT;
00198             }
00199             else if( NEXT_SYMBOL == '+' || NEXT_SYMBOL == '-' ) {
00200                 state = CORE_S1;
00201             }
00202             else if( NEXT_SYMBOL == '.' ) {
00203                 state = CORE_FLOAT;
00204             }
00205             else {
00206                 state = CORE_INVALID;
00207                 transition_count[CORE_INVALID]++;
00208             }
00209             transition_count[CORE_START]++;
00210             break;
00211         case CORE_S1:
00212             if(ee_isdigit(NEXT_SYMBOL)) {
00213                 state = CORE_INT;
00214                 transition_count[CORE_S1]++;
00215             }
00216             else if( NEXT_SYMBOL == '.' ) {
00217                 state = CORE_FLOAT;
00218                 transition_count[CORE_S1]++;
00219             }
00220             else {
00221                 state = CORE_INVALID;
00222                 transition_count[CORE_S1]++;
00223             }
00224             break;
00225         case CORE_INT:
00226             if( NEXT_SYMBOL == '.' ) {
00227                 state = CORE_FLOAT;
00228                 transition_count[CORE_INT]++;
00229             }
00230             else if(!ee_isdigit(NEXT_SYMBOL)) {
00231                 state = CORE_INVALID;
00232                 transition_count[CORE_INT]++;
00233             }
00234             break;
00235         case CORE_FLOAT:
00236             if( NEXT_SYMBOL == 'E' || NEXT_SYMBOL == 'e' ) {
00237                 state = CORE_S2;
00238                 transition_count[CORE_FLOAT]++;
00239             }
00240             else if(!ee_isdigit(NEXT_SYMBOL)) {
00241                 state = CORE_INVALID;
00242                 transition_count[CORE_FLOAT]++;
00243             }
00244             break;
00245         case CORE_S2:
00246             if( NEXT_SYMBOL == '+' || NEXT_SYMBOL == '-' ) {
00247                 state = CORE_EXPONENT;
00248                 transition_count[CORE_S2]++;
00249             }
00250             else {
00251                 state = CORE_INVALID;
00252                 transition_count[CORE_S2]++;
00253             }
00254             break;
00255         case CORE_EXPONENT:
00256             if(ee_isdigit(NEXT_SYMBOL)) {
00257                 state = CORE_SCIENTIFIC;
00258                 transition_count[CORE_EXPONENT]++;
00259             }
00260             else {
00261                 state = CORE_INVALID;
00262                 transition_count[CORE_EXPONENT]++;
00263             }
00264             break;
00265         case CORE_SCIENTIFIC:
00266             if(!ee_isdigit(NEXT_SYMBOL)) {
00267                 state = CORE_INVALID;
00268                 transition_count[CORE_INVALID]++;
00269             }
00270             break;
00271         default:
00272             break;
00273         }
00274     }
00275     *instr=str;
00276     return state;
00277 }