// Read/write a block of data double ZcavRead::access_data(int skip) { #ifdef _LARGEFILE64_SOURCE if(skip) { OFF_TYPE real_offset = OFF_TYPE(skip) * OFF_TYPE(m_block_size) * OFF_TYPE(1<<20); if(file_lseek(m_fd, real_offset, SEEK_CUR) == OFF_TYPE(-1)) return -1.0; } #endif m_dur.start(); for(int i = 0; i < m_block_size; i+= m_chunk_size) { int access_size = m_chunk_size; if(i + m_chunk_size > m_block_size) access_size = m_block_size - i; int rc = access_all(access_size); if(rc != access_size) return -1.0; } return m_dur.stop(); }
int CFileOp::seek(int offset, int whence) { OFF_TYPE rc; OFF_TYPE real_offset = offset; real_offset *= m_chunk_size; rc = file_lseek(m_fd, real_offset, whence); if(rc == OFF_TYPE(-1)) { sprintf(m_buf, "Error in lseek to chunk %d(" OFF_T_PRINTF ")", offset, real_offset); perror(m_buf); return rc; } return 0; }
int ZcavRead::Read(int max_loops, int max_size, int writeCom, int skip_rate, int start_offset) { bool exiting = false; if(max_loops == 1) fprintf(m_log, "#block offset (GiB), MiB/s, time\n"); for(int loops = 0; !exiting && loops < max_loops; loops++) { int i = 0; #ifdef _LARGEFILE64_SOURCE if(start_offset) { OFF_TYPE real_offset = OFF_TYPE(start_offset) * OFF_TYPE(m_block_size) * OFF_TYPE(1<<20); if(file_lseek(m_fd, real_offset, SEEK_CUR) == OFF_TYPE(-1)) { fprintf(stderr, "Can't lseek().\n"); writeStatus(writeCom, eSEEK); return 1; } i = start_offset; } else #endif if(lseek(m_fd, 0, SEEK_SET)) { fprintf(stderr, "Can't lseek().\n"); writeStatus(writeCom, eSEEK); return 1; } // i is block index double total_read_time = 0.0; bool nextLoop = false; for( ; !nextLoop && (!max_size || i < max_size) && (loops == 0 || (m_times[i] && m_times[i][0] != -1.0)) && (!max_size || i < max_size); i++) { double read_time = access_data(i ? skip_rate - 1 : 0); if(read_time < 0.0) { if(i == 0) { fprintf(stderr, "Data file/device \"%s\" too small.\n", m_name); writeStatus(writeCom, eSIZE); return 1; } nextLoop = true; break; } total_read_time += read_time; if(max_loops == 1) { printavg(i * skip_rate, read_time, m_block_size); } else { if(loops == 0) { m_times.push_back(new double[max_loops]); m_count.push_back(0); } m_times[i][loops] = read_time; m_count[i]++; } } // end loop for reading blocks time_t now = time(NULL); struct tm *cur_time = localtime(&now); fprintf(stderr, "# Finished loop %d, on device %s at %d:%02d:%02d\n" , loops + 1, m_name, cur_time->tm_hour, cur_time->tm_min , cur_time->tm_sec); fprintf(m_log, "# Read %d megs in %d seconds, %d megabytes per second.\n" , i * m_block_size, int(total_read_time) , int(double(i * m_block_size) / total_read_time)); if(exiting) return 1; } // end loop for multiple disk reads if(max_loops > 1) { fprintf(m_log, "#loops: %d\n", max_loops); fprintf(m_log, "#block offset (GiB), MiB/s, time\n"); for(int i = 0; m_times[i]; i++) printavg(i * skip_rate, average(m_times[i], m_count[i]), m_block_size); } writeStatus(writeCom, eEND); return 0; }