// // Setting access specifications for next test. // Note that Iometer will call Set_Access before testing starts to ensure that // Dynamo can run the spec with the largest transfer request. // BOOL Manager::Set_Access( int target, const Test_Spec *spec ) { int g; // loop control variable // Recursively assign all workers the same access specification. if ( target == ALL_WORKERS ) { cout << "All workers running Access Spec: " << spec->name << endl; for ( g = 0; g < grunt_count; g++ ) { if ( !Set_Access( g, spec ) ) return FALSE; } return TRUE; } cout << "Worker " << target << " running Access Spec: " << spec->name << endl; // If the grunt could not set the access spec properly, return. // The grunt may not have been able to grow its data buffer. if ( !grunts[target]->Set_Access( spec ) ) return FALSE; // If the grunt is not using the manager's data buffer or the manager's // buffer is already large enough, just return. if ( grunts[target]->data_size || data_size >= grunts[target]->access_spec.max_transfer ) { return TRUE; } // Grow the manager's data buffer and update all grunts using it. #if _DEBUG cout << "Growing manager data buffer from " << data_size << " to " << grunts[target]->access_spec.max_transfer << endl << flush; #endif // Align all data transfers on a page boundary. This will work for all disks // with sector sizes that divide evenly into the page size - which is always // the case. #if defined (_WIN32) || defined (_WIN64) VirtualFree( data, 0, MEM_RELEASE ); if ( !(data = VirtualAlloc( NULL, grunts[target]->access_spec.max_transfer, MEM_COMMIT, PAGE_READWRITE )) ) #else // UNIX free(data); errno = 0; if ( !(data = valloc(grunts[target]->access_spec.max_transfer) )) #endif { // Could not allocate a larger buffer. Signal failure. cout << "*** Manager could not allocate data buffer for I/O transfers." << endl << flush; data_size = 0; return FALSE; } data_size = grunts[target]->access_spec.max_transfer; // Update all grunts using the manager's data buffer. for ( g = 0; g < grunt_count; g++ ) { if ( !grunts[g]->data_size ) { grunts[g]->read_data = data; grunts[g]->write_data = data; } } return TRUE; }
// // Processing messages from Iometer based on their purpose and // returns TRUE if the manager can process additional messages. // BOOL Manager::Process_Message() { switch ( msg.purpose ) { case ADD_WORKERS: #ifdef _DETAILS cout << "in Process_Message() : ADD_WORKERS" << endl; #endif Add_Workers( msg.data ); break; // Signaling to reset all workers case RESET: // Remove all workers. #ifdef _DETAILS cout << "in Process_Message() : RESET" << endl; #endif Remove_Workers( ALL_WORKERS ); prt->Disconnect(); break; // Received call to end program or thread execution. case EXIT: #ifdef _DETAILS cout << "in Process_Message() : EXIT" << endl; #endif Remove_Workers( msg.data ); return ( msg.data != MANAGER ); // Preparing drives for access. case PREP_DISKS: #ifdef _DETAILS cout << "in Process_Message() : PREP_DISKS" << endl; #endif Prepare_Disks( msg.data ); break; // Signalling to stop disk preparation. case STOP_PREPARE: #ifdef _DETAILS cout << "in Process_Message() : STOP_PREPARE" << endl; #endif Stop_Prepare( msg.data ); break; // Reporting all targets accessible by this manager. case REPORT_TARGETS: #ifdef _DETAILS cout << "in Process_Message() : REPORT_TARGETS" << endl; #endif data_msg.count = Report_Disks( data_msg.data.targets ); #ifdef BIG_ENDIAN_ARCH (void) reorder(data_msg, DATA_MESSAGE_TARGET_SPEC, SEND); #endif prt->Send( &data_msg, DATA_MESSAGE_SIZE ); data_msg.count = Report_TCP( data_msg.data.targets ); #ifdef BIG_ENDIAN_ARCH (void) reorder(data_msg, DATA_MESSAGE_TARGET_SPEC, SEND); #endif prt->Send( &data_msg, DATA_MESSAGE_SIZE ); data_msg.count = Report_VIs( data_msg.data.targets ); #ifdef BIG_ENDIAN_ARCH (void) reorder(data_msg, DATA_MESSAGE_TARGET_SPEC, SEND); #endif prt->Send( &data_msg, DATA_MESSAGE_SIZE ); break; // Setting targets for a given grunt and reporting back. case SET_TARGETS: #ifdef _DETAILS cout << "in Process_Message() : SET_TARGETS" << endl; #endif prt->Receive( &data_msg, DATA_MESSAGE_SIZE ); #ifdef BIG_ENDIAN_ARCH (void) reorder(data_msg, DATA_MESSAGE_TARGET_SPEC, RECV); #endif msg.data = Set_Targets( msg.data, data_msg.count, data_msg.data.targets ); // Send back success/failure indication along with additional error // information or target settings (such as TCP port). #ifdef BIG_ENDIAN_ARCH (void) reorder(msg); #endif prt->Send( &msg ); #ifdef BIG_ENDIAN_ARCH (void) reorder(data_msg, DATA_MESSAGE_TARGET_SPEC, SEND); #endif prt->Send( &data_msg, DATA_MESSAGE_SIZE ); break; // Setting access specifications for next test. case SET_ACCESS: #ifdef _DETAILS cout << "in Process_Message() : SET_ACCESS" << endl; #endif prt->Receive( &data_msg, DATA_MESSAGE_SIZE ); #ifdef BIG_ENDIAN_ARCH (void) reorder(data_msg, DATA_MESSAGE_TEST_SPEC, RECV); #endif msg.data = (int)Set_Access( msg.data, &(data_msg.data.spec) ); #ifdef BIG_ENDIAN_ARCH (void) reorder(msg); #endif prt->Send( &msg ); // notify Iometer of success break; // Signalling start of test. case START: #ifdef _DETAILS cout << "in Process_Message() : START" << endl; #endif Start_Test( msg.data ); break; // Beginning to perform I/O. case BEGIN_IO: #ifdef _DETAILS cout << "in Process_Message() : BEGIN_IO" << endl; #endif Begin_IO( msg.data ); break; // Beginning recording of test results. case RECORD_ON: #ifdef _DETAILS cout << "in Process_Message() : RECORD_ON" << endl; #endif Record_On( msg.data ); break; // Stopping recording of test results. case RECORD_OFF: #ifdef _DETAILS cout << "in Process_Message() : RECORD_OFF" << endl; #endif Record_Off( msg.data ); break; // Signalling to stop testing. case STOP: #ifdef _DETAILS cout << "in Process_Message() : STOP" << endl; #endif Stop_Test( msg.data ); break; // Reporting results of whole test to Iometer. case REPORT_RESULTS: #ifdef _DETAILS cout << "in Process_Message() : REPORT_RESULTS" << endl; #endif Report_Results( WHOLE_TEST_PERF ); break; // Reporting results since last update to Iometer. case REPORT_UPDATE: #ifdef _DETAILS cout << "in Process_Message() : REPORT_UPDATE" << endl; #endif Report_Results( LAST_UPDATE_PERF ); break; default: cout << "*** Unknown purpose found in message." << endl << flush; return FALSE; } return TRUE; }
void cWaypoint::Create_From_Stream(XMLElement* attributes) { int x, y; waypoint_type = WAYPOINT_NORMAL; std::string destination; std::string _direction_backward = "left"; std::string _direction_forward = "right"; bool _access = true; for (XMLElement* node = attributes->FirstChildElement(); node; node = node->NextSiblingElement()) { const char* name = node->Attribute("name"); const char* value = node->Attribute("value"); if (!strcmp(name, "x")) { x = atoi(value); } else if (!strcmp(name, "y")) { y = atoi(value); } else if (!strcmp(name, "type")) { waypoint_type = static_cast<Waypoint_type>(atoi(value)); } else if (!strcmp(name, "world")) { destination = value; } else if (!strcmp(name, "level")) { destination = value; } else if (!strcmp(name, "destination")) { destination = value; } else if (!strcmp(name, "direction_backward")) { _direction_backward = value; } else if (!strcmp(name, "direction_forward")) { _direction_forward = value; } else if (!strcmp(name, "access")) { if (value[0] == '0') { _access = false; } else { _access = true; } } } Set_Pos(static_cast<float>(x), static_cast<float>(y), 1); Set_Destination(destination); direction_backward = Get_Direction_Id(_direction_backward.c_str()); direction_forward = Get_Direction_Id(_direction_forward.c_str()); Set_Access(_access, 1); }