#include #include #include #include #include #include #include #include "inc/mob.h" #include "inc/routines.h" #include "inc/zone.h" #include "inc/cfgParser.h" struct vZoneOps zoneOps[MAX_ZONE_OBJS]={CACHEOPS, TLBOPS, {NULL,NULL,NULL,NULL}}; extern struct globalSystem sys; /* This function will be called every time a new parse zone is found in the config file. It will allocate a new zone struct, calling the "create" function of the specific zone, and filling the data field with the value that the this (create) function returns */ void openZone( struct parseZone * pZone, char * zoneName ){ struct vZoneOps * zOps; /* Get the zone operations and fill the parseZone struct */ zOps = getZoneOps( zoneName ); if(! zOps ) handleError( "zone not registered", Ezone ); pZone->addPair = zOps->addPair; pZone->flushObject = zOps->flushObject; pZone->printObject = zOps->printObject; pZone->object = (zOps->createObject)(); /* Create a blank object */ if(! pZone->object ) handleError( "creating zone object", Ezone ); return; } /* Function called when a parse zone is finished. It will call the flush object function. If parse zone not initialized, it does nothing and returns success. The object is not freed, it's up to the "flushObject" function to do it if needed (i.e: in case object is duplicated ) Returns 0 on success or <> otherwise */ int closeZone( struct parseZone * zoneObj ){ int error=0 ; if( zoneObj->object != NULL ){/* If zone initialized */ error = (zoneObj->flushObject( zoneObj->object )); if( error ){ show(VERB_WARN,"Error closing zone...skipping it\n"); free(zoneObj->object);/* Free it if not successfully flushed */ } } return error; } /* Function that given a file handle, it will parse it and create the specified zone objects, fill them with as much information as provided and place them in the global system structure. If more than one object of the same type and level (say two data L1 caches) are defined in the file, the last one will override the previous ones */ int parseConfig( FILE * cFile ){ char symbol[MAX_SYMBOL_LEN]; char value[MAX_VALUE_LEN]; char line[MAX_LINE_LEN]={0,}; struct parseZone pZone={0,}; fscanf(cFile,"%[^\n]\n",line);/* read a line */ while( !feof(cFile) || strlen(line) ){ symbol[0]='\x0'; value[0]='\x0'; if(line[0]=='['){ /* Start of a zone */ closeZone(&pZone);/*Close the previous zone*/ sscanf(line,"[ %[^]] ]",symbol);/* get the zone name */ openZone(&pZone,trim(symbol));/* init the zone object */ }else{/* symbol,value pair of the opened zone */ sscanf(line,"%[^=]=%s ",symbol,value); trim(symbol); trim(value); if( pZone.object != NULL && symbol[0]!='#' ){ /* We have a valid opened zone and it's not a comment try to get a symb/value pair*/ if( symbol[0]!='\x0' && value[0]!='\x0' ){ /* Good pair of values...add them */ if( pZone.addPair(pZone.object,symbol,value) ) show(VERB_WARN,"Error adding line [%s:%s] \n",symbol,value); } } } /* Read a new line to parse */ line[0]='\x0'; fscanf(cFile,"%[^\n]\n",line); } closeZone(&pZone);/* close the last created zone, if any */ return 0; } /* It will update the cache counts of the gobal system */ void updateSystem(){ int i; sys.numDataCaches=0; sys.numInstCaches=0; for(i=0;izOps.printObject( out, sys.dataCaches[i] ); for(i=0;itype != TYPE_SHARED ) sys.instCaches[i]->zOps.printObject( out, sys.instCaches[i] ); /* We want to print the shared TLBs only once */ if( sys.dataTLB ) sys.dataTLB->zOps.printObject( out, sys.dataTLB ); if( sys.instTLB && sys.instTLB->type != TYPE_SHARED ) sys.instTLB->zOps.printObject( out, sys.instTLB ); /* close the output file */ fclose(out); }