sb_request_t memory_get_request(int tid) { sb_request_t req; sb_mem_request_t *mem_req = &req.u.mem_request; (void)tid; /* unused */ SB_THREAD_MUTEX_LOCK(); if (total_bytes >= memory_total_size) { req.type = SB_REQ_TYPE_NULL; SB_THREAD_MUTEX_UNLOCK(); return req; } total_ops++; total_bytes += memory_block_size; SB_THREAD_MUTEX_UNLOCK(); req.type = SB_REQ_TYPE_MEMORY; mem_req->block_size = memory_block_size; mem_req->scope = memory_scope; mem_req->type = memory_oper; return req; }
sb_request_t threads_get_request(void) { sb_request_t sb_req; sb_threads_request_t *threads_req = &sb_req.u.threads_request; SB_THREAD_MUTEX_LOCK(); if (req_performed >= sb_globals.max_requests) { sb_req.type = SB_REQ_TYPE_NULL; SB_THREAD_MUTEX_UNLOCK(); return sb_req; } sb_req.type = SB_REQ_TYPE_THREADS; threads_req->lock_num = req_performed % thread_locks; req_performed++; SB_THREAD_MUTEX_UNLOCK(); return sb_req; }
sb_request_t cpu_get_request(int thread_id) { sb_request_t req; (void) thread_id; /* unused */ if (sb_globals.max_requests > 0) { SB_THREAD_MUTEX_LOCK(); if (req_performed >= sb_globals.max_requests) { req.type = SB_REQ_TYPE_NULL; SB_THREAD_MUTEX_UNLOCK(); return req; } req_performed++; SB_THREAD_MUTEX_UNLOCK(); } req.type = SB_REQ_TYPE_CPU; return req; }
void memory_print_stats(sb_stat_t type) { double seconds; const double megabyte = 1024.0 * 1024.0; switch (type) { case SB_STAT_INTERMEDIATE: SB_THREAD_MUTEX_LOCK(); seconds = NS2SEC(sb_timer_split(&sb_globals.exec_timer)); log_timestamp(LOG_NOTICE, &sb_globals.exec_timer, "%4.2f MB/sec,", (double)(total_bytes - last_bytes) / megabyte / seconds); last_bytes = total_bytes; SB_THREAD_MUTEX_UNLOCK(); break; case SB_STAT_CUMULATIVE: seconds = NS2SEC(sb_timer_split(&sb_globals.cumulative_timer1)); log_text(LOG_NOTICE, "Operations performed: %d (%8.2f ops/sec)\n", total_ops, total_ops / seconds); if (memory_oper != SB_MEM_OP_NONE) log_text(LOG_NOTICE, "%4.2f MB transferred (%4.2f MB/sec)\n", total_bytes / megabyte, total_bytes / megabyte / seconds); total_ops = 0; total_bytes = 0; /* So that intermediate stats are calculated from the current moment rather than from the previous intermediate report */ if (sb_timer_initialized(&sb_globals.exec_timer)) sb_timer_split(&sb_globals.exec_timer); break; } }
int file_execute_request(sb_request_t *sb_req, int thread_id) { FILE_DESCRIPTOR fd; sb_file_request_t *file_req = &sb_req->u.file_request; log_msg_t msg; log_msg_oper_t op_msg; if (sb_globals.debug) { log_text(LOG_DEBUG, "Executing request, operation: %d, file_id: %d, pos: %d, " "size: %d", file_req->operation, file_req->file_id, (int)file_req->pos, (int)file_req->size); } /* Check request parameters */ if (file_req->file_id > num_files) { log_text(LOG_FATAL, "Incorrect file discovered in request"); return 1; } if (file_req->pos + file_req->size > file_size) { log_text(LOG_FATAL, "Too large position discovered in request!"); return 1; } fd = files[file_req->file_id]; /* Prepare log message */ msg.type = LOG_MSG_TYPE_OPER; msg.data = &op_msg; switch (file_req->operation) { case FILE_OP_TYPE_NULL: log_text(LOG_FATAL, "Execute of NULL request called !, aborting"); return 1; case FILE_OP_TYPE_WRITE: /* Store checksum and offset in a buffer when in validation mode */ if (sb_globals.validate) file_fill_buffer(buffer, file_req->size, file_req->pos); LOG_EVENT_START(msg, thread_id); if(file_pwrite(file_req->file_id, buffer, file_req->size, file_req->pos, thread_id) != (ssize_t)file_req->size) { log_errno(LOG_FATAL, "Failed to write file! file: " FD_FMT " pos: %lld", fd, (long long)file_req->pos); return 1; } /* Check if we have to fsync each write operation */ if (file_fsync_all) { if (file_fsync(file_req->file_id, thread_id)) { log_errno(LOG_FATAL, "Failed to fsync file! file: " FD_FMT, fd); return 1; } } LOG_EVENT_STOP(msg, thread_id); SB_THREAD_MUTEX_LOCK(); write_ops++; real_write_ops++; bytes_written += file_req->size; if (file_fsync_all) other_ops++; SB_THREAD_MUTEX_UNLOCK(); break; case FILE_OP_TYPE_READ: LOG_EVENT_START(msg, thread_id); if(file_pread(file_req->file_id, buffer, file_req->size, file_req->pos, thread_id) != (ssize_t)file_req->size) { log_errno(LOG_FATAL, "Failed to read file! file: " FD_FMT " pos: %lld", fd, (long long)file_req->pos); return 1; } LOG_EVENT_STOP(msg, thread_id); /* Validate block if run with validation enabled */ if (sb_globals.validate && file_validate_buffer(buffer, file_req->size, file_req->pos)) { log_text(LOG_FATAL, "Validation failed on file " FD_FMT ", block offset 0x%x, exiting...", file_req->file_id, file_req->pos); return 1; } SB_THREAD_MUTEX_LOCK(); read_ops++; real_read_ops++; bytes_read += file_req->size; SB_THREAD_MUTEX_UNLOCK(); break; case FILE_OP_TYPE_FSYNC: /* Ignore fsync requests if we are already fsync'ing each operation */ if (file_fsync_all) break; if(file_fsync(file_req->file_id, thread_id)) { log_errno(LOG_FATAL, "Failed to fsync file! file: " FD_FMT, fd); return 1; } SB_THREAD_MUTEX_LOCK(); other_ops++; SB_THREAD_MUTEX_UNLOCK(); break; default: log_text(LOG_FATAL, "Execute of UNKNOWN file request type called (%d)!, " "aborting", file_req->operation); return 1; } return 0; }
sb_request_t file_get_rnd_request(void) { sb_request_t sb_req; sb_file_request_t *file_req = &sb_req.u.file_request; unsigned int randnum; unsigned long long tmppos; int real_mode = test_mode; int mode = test_mode; static unsigned long long ag_pos = 0; static int ag_group = 0; sb_req.type = SB_REQ_TYPE_FILE; /* Convert mode for combined tests. Locking to get consistent values We have to use "real" values for mixed test */ if (test_mode==MODE_RND_RW) { SB_THREAD_MUTEX_LOCK(); if ((double)(real_read_ops + 1) / (real_write_ops + 1) < file_rw_ratio) mode=MODE_RND_READ; else mode=MODE_RND_WRITE; SB_THREAD_MUTEX_UNLOCK(); } /* fsync all files (if requested by user) as soon as we are done */ if (req_performed == sb_globals.max_requests && sb_globals.max_requests > 0) { if (file_fsync_end != 0 && (real_mode == MODE_RND_WRITE || real_mode == MODE_RND_RW || real_mode == MODE_AG4_WRITE || real_mode == MODE_MIXED)) { pthread_mutex_lock(&fsync_mutex); if(fsynced_file2 < num_files) { file_req->file_id = fsynced_file2; file_req->operation = FILE_OP_TYPE_FSYNC; file_req->pos = 0; file_req->size = 0; fsynced_file2++; pthread_mutex_unlock(&fsync_mutex); return sb_req; } pthread_mutex_unlock(&fsync_mutex); } sb_req.type = SB_REQ_TYPE_NULL; return sb_req; } /* is_dirty is only set if writes are done and cleared after all files are synced */ if(file_fsync_freq != 0 && is_dirty) { if (req_performed % file_fsync_freq == 0) { file_req->operation = FILE_OP_TYPE_FSYNC; file_req->file_id = fsynced_file; file_req->pos = 0; file_req->size = 0; fsynced_file++; if (fsynced_file == num_files) { fsynced_file = 0; is_dirty = 0; } return sb_req; } } randnum=sb_rnd(); if (mode==MODE_RND_WRITE) /* mode shall be WRITE or RND_WRITE only */ file_req->operation = FILE_OP_TYPE_WRITE; else file_req->operation = FILE_OP_TYPE_READ; if (mode==MODE_AG4_WRITE) { if (++ag_group == 4) { ag_pos += file_block_size*2; ag_pos %= total_size / 4; ag_group = 0; } tmppos = ag_pos + total_size / 4 * ag_group; file_req->operation = FILE_OP_TYPE_WRITE; } else { tmppos = (long long)((double)randnum / (double)SB_MAX_RND * (double)(total_size)); } tmppos = tmppos - (tmppos % (long long)file_block_size); file_req->file_id = (int)(tmppos / (long long)file_size); file_req->pos = (long long)(tmppos % (long long)file_size); file_req->size = file_block_size; req_performed++; if (file_req->operation == FILE_OP_TYPE_WRITE) is_dirty = 1; return sb_req; }