diff options
author | Mohan Srinivasan <srmohan@google.com> | 2017-01-19 21:27:36 +0000 |
---|---|---|
committer | Mohan Srinivasan <srmohan@google.com> | 2017-01-19 21:27:36 +0000 |
commit | f2f5b6165a4b107f79a7e709f63fb66118a72477 (patch) | |
tree | 1efc2c2685ca028f31e20efce1fcfdec9297237c /ioshark | |
parent | a5dc6d6fcab8dfe719c437e8a9111ba962df1c15 (diff) | |
download | extras-f2f5b6165a4b107f79a7e709f63fb66118a72477.tar.gz |
Revert "ioshark: A Repeatable Application Workload Based Storage Benchmark." (Broke the MacOS build - will commit after I test that this builds for MacOS).
This reverts commit a5dc6d6fcab8dfe719c437e8a9111ba962df1c15.
Change-Id: I53bc71eeb1bc3ad7706baae589cef8a80ef94c35
Diffstat (limited to 'ioshark')
-rw-r--r-- | ioshark/Android.mk | 32 | ||||
-rw-r--r-- | ioshark/README | 27 | ||||
-rwxr-xr-x | ioshark/collect-straces.sh | 93 | ||||
-rw-r--r-- | ioshark/compile_ioshark.c | 577 | ||||
-rw-r--r-- | ioshark/compile_ioshark.h | 78 | ||||
-rw-r--r-- | ioshark/compile_ioshark_subr.c | 102 | ||||
-rw-r--r-- | ioshark/ioshark.h | 108 | ||||
-rw-r--r-- | ioshark/ioshark_bench.c | 739 | ||||
-rw-r--r-- | ioshark/ioshark_bench.h | 153 | ||||
-rw-r--r-- | ioshark/ioshark_bench_mmap.c | 202 | ||||
-rw-r--r-- | ioshark/ioshark_bench_subr.c | 493 | ||||
-rw-r--r-- | ioshark/wl.tar | bin | 1566720 -> 0 bytes |
12 files changed, 0 insertions, 2604 deletions
diff --git a/ioshark/Android.mk b/ioshark/Android.mk deleted file mode 100644 index 2152c06d..00000000 --- a/ioshark/Android.mk +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright (C) 2016 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -LOCAL_PATH:= $(call my-dir) - -include $(CLEAR_VARS) -#LOCAL_32_BIT_ONLY = true -LOCAL_SRC_FILES := ioshark_bench.c ioshark_bench_subr.c ioshark_bench_mmap.c -LOCAL_CFLAGS := -g -O2 -Wall -Werror -LOCAL_MODULE := ioshark_bench -include $(BUILD_EXECUTABLE) - -include $(CLEAR_VARS) -#LOCAL_32_BIT_ONLY = true -LOCAL_SRC_FILES := compile_ioshark.c compile_ioshark_subr.c -LOCAL_CFLAGS := -g -O2 -Wall -Werror -D_GNU_SOURCE -LOCAL_MODULE := compile_ioshark -include $(BUILD_HOST_EXECUTABLE) - - - diff --git a/ioshark/README b/ioshark/README deleted file mode 100644 index ee2f426b..00000000 --- a/ioshark/README +++ /dev/null @@ -1,27 +0,0 @@ -IOshark is a repeatable application workload storage benchmark. You -can find more documentation on IOshark at : -https://docs.google.com/a/google.com/document/d/1Bhq7iNPVc_JzwRrkmZqcPjMvWgpHX0r3Ncq-ZsRNOBA/edit?usp=sharing - -The short summary of what IOshark is : IOshark has 2 components, one -is a strace compiler that takes straces fed into it and compiles this -into bytecodes (stored in *.wl files). The compiler runs on a Linux -host. The second component (which runs on the device) is the tester -that takes as input the bytecode files (*.wl files) and executes them -on the device. - -How to Run : ----------- -- First collect straces and compile these into bytecodes. The wrapper -script provided (collect-straces.sh) collects straces, ships them to -the host where the script runs, compiles and packages up the bytecode -files into a wl.tar file. -- Ship the wl.tar file and the iostark_bench binaries to the target -device (on /data/local/tmp say). Explode the tarfile. -- Run the tester. "ioshark_bench *.wl" runs the test with default -options. Supported ioshark_bench options : --d : Preserve the delays between successive filesystem syscalls as -seen in the original straces. --n <N> : Run for N iterations --t <N> : Limit to N threads. By default (without this option), IOshark -will launch as many threads as there are input files, so 1 thread/file. --v : verbose. Chatty mode. diff --git a/ioshark/collect-straces.sh b/ioshark/collect-straces.sh deleted file mode 100755 index 1071a33e..00000000 --- a/ioshark/collect-straces.sh +++ /dev/null @@ -1,93 +0,0 @@ -# Copyright (C) 2016 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# # Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -#!/bin/sh - -# When signal is received, the stracer will get killed -# Call this (just to make sure anyway) -kill_strace() { - ps_line=`ps -ef | grep strace | grep adb ` - if [ $? == 0 ]; then - echo Killing `echo $ps_line | awk '{s = ""; for (i=8; i <= NF ; i++) s = s \ -$i " "; print s}' ` - kill `echo $ps_line | awk '{print $2}' ` - fi -} - -catch_sigint() -{ - echo "signal INT received, killing streaming trace capture" - kill_strace -} - -compile_tracefiles() -{ - for i in trace.* - do - if [ $i != trace.begin ] && [ $i != trace.tar ]; - then - egrep '\/system\/|\/data\/|\/vendor\/' $i > bar -# parse out /sys/devices/system/... - egrep -v '\/sys\/devices\/system\/' bar > bar0 - mv bar0 bar - fgrep -v '= -1' bar > foo - mv foo bar - if [ -s bar ] - then - echo parsing $i - compile_ioshark bar $i.wl - rm -f bar - else - rm -f $i bar - fi - fi - done -} - -# main() starts here - -adb root && adb wait-for-device - -#adb shell 'ps -ef' | grep zygote > zygote_pids -adb shell 'ps' | grep zygote > zygote_pids - -fgrep -v grep zygote_pids > bar -mv bar zygote_pids -pid1=`grep -w zygote zygote_pids | awk '{print $2}' ` -pid2=`grep -w zygote64 zygote_pids | awk '{print $2}' ` -rm -f zygote_pids - -trap 'catch_sigint' INT - -echo "^C this script once you finish running your test" - -adb shell "date +%s > /data/local/tmp/trace.begin ; strace -p $pid1,$pid2 -o /data/local/tmp/trace -q -qq -f -ff -y -ttt -e trace=mmap2,read,write,pread64,pwrite64,fsync,fdatasync,openat,close,lseek,_llseek" - -# Remove any remnant tracefiles first -rm -f trace.* - -# Get the tracefiles from the device -adb shell 'cd /data/local/tmp ; tar cvf trace.tar trace.*' -adb pull /data/local/tmp/trace.tar - -# Extract the tracefiles from the device -rm -f *.wl -tar xf trace.tar - -# Compile the tracefiles -compile_tracefiles - -# tar up the .wl files just created -tar zcf wl.tgz *.wl - - diff --git a/ioshark/compile_ioshark.c b/ioshark/compile_ioshark.c deleted file mode 100644 index 683b5975..00000000 --- a/ioshark/compile_ioshark.c +++ /dev/null @@ -1,577 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <stdio.h> -#include <sys/time.h> -#include <sys/types.h> -#include <unistd.h> -#include <stdlib.h> -#include <signal.h> -#include <string.h> -#include <sys/stat.h> -#include <sys/errno.h> -#include <fcntl.h> -#include <ctype.h> -#include "ioshark.h" -#include "compile_ioshark.h" - -char *progname; - -char in_buf[2048]; - -struct flags_map_s { - char *flag_str; - int flag; -}; - -#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) - -struct flags_map_s open_flags_map[] = { - { "O_RDONLY", O_RDONLY }, - { "O_WRONLY", O_WRONLY }, - { "O_RDWR", O_RDWR }, - { "O_CREAT", O_CREAT }, - { "O_SYNC", O_SYNC }, - { "O_TRUNC", O_TRUNC }, - { "O_EXCL", O_EXCL }, - { "O_APPEND", O_APPEND }, - { "O_NOATIME", O_NOATIME }, - { "O_ASYNC", O_ASYNC }, - { "O_CLOEXEC", O_CLOEXEC }, - { "O_DIRECT", O_DIRECT }, - { "O_DIRECTORY", O_DIRECTORY }, - { "O_LARGEFILE", O_LARGEFILE }, - { "O_NOCTTY", O_NOCTTY }, - { "O_NOFOLLOW", O_NOFOLLOW }, - { "O_NONBLOCK", O_NONBLOCK }, - { "O_NDELAY", O_NDELAY }, - { "O_PATH", O_PATH } -}; - -struct flags_map_s lseek_action_map[] = { - { "SEEK_SET", SEEK_SET }, - { "SEEK_CUR", SEEK_CUR }, - { "SEEK_END", SEEK_END } -}; - -struct flags_map_s fileop_map[] = { - { "lseek", IOSHARK_LSEEK }, - { "_llseek", IOSHARK_LLSEEK }, - { "pread64", IOSHARK_PREAD64 }, - { "pwrite64", IOSHARK_PWRITE64 }, - { "read", IOSHARK_READ }, - { "write", IOSHARK_WRITE }, - { "mmap", IOSHARK_MMAP }, - { "mmap2", IOSHARK_MMAP2 }, - { "openat", IOSHARK_OPEN }, - { "fsync", IOSHARK_FSYNC }, - { "fdatasync", IOSHARK_FDATASYNC }, - { "close", IOSHARK_CLOSE } -}; - -struct in_mem_file_op { - struct ioshark_file_operation disk_file_op; - struct in_mem_file_op *next; -}; - -struct in_mem_file_op *in_mem_file_op_head = NULL, *in_mem_file_op_tail = NULL; - -void usage(void) -{ - fprintf(stderr, "%s in_file out_file\n", progname); -} - -u_int64_t -get_delta_ts(char *buf, struct timeval *start_tv) -{ - struct timeval op_tv, tv_res; - - sscanf(buf, "%lu.%lu", &op_tv.tv_sec, &op_tv.tv_usec); - timersub(&op_tv, start_tv, &tv_res); - return (tv_res.tv_usec + (tv_res.tv_sec * 1000000)); -} - -void -get_pathname(char *buf, char *pathname, enum file_op file_op) -{ - char *s, *s2, save; - - if (file_op == IOSHARK_OPEN) - s = strchr(buf, '"'); - else - s = strchr(buf, '<'); - if (s == NULL) { - fprintf(stderr, "%s: Malformed line: %s\n", - __func__, buf); - exit(EXIT_FAILURE); - } - s += 1; - if (file_op == IOSHARK_OPEN) - s2 = strchr(s, '"'); - else - s2 = strchr(s, '>'); - if (s2 == NULL) { - fprintf(stderr, "%s: Malformed line: %s\n", - __func__, buf); - exit(EXIT_FAILURE); - } - save = *s2; - *s2 = '\0'; - strcpy(pathname, s); - *s2 = save; -} - -void -get_syscall(char *buf, char *syscall) -{ - char *s, *s2; - - s = strchr(buf, ' '); - if (s == NULL) { - fprintf(stderr, "%s: Malformed line: %s\n", - __func__, buf); - exit(EXIT_FAILURE); - } - s += 1; - s2 = strchr(s, '('); - if (s2 == NULL) { - fprintf(stderr, "%s: Malformed line: %s\n", - __func__, buf); - exit(EXIT_FAILURE); - } - *s2 = '\0'; - strcpy(syscall, s); - *s2 = '('; -} - -void -get_mmap_offset_len_prot(char *buf, int *prot, off_t *offset, u_int64_t *len) -{ - char *s, *s1; - int i; - char protstr[128]; - - s = strchr(buf, ','); - if (s == NULL) { - fprintf(stderr, "%s: Malformed line: %s\n", - __func__, buf); - exit(EXIT_FAILURE); - } - s += 2; - sscanf(s, "%ju", len); - s1 = strchr(s, ','); - if (s1 == NULL) { - fprintf(stderr, "%s: Malformed line: %s\n", - __func__, buf); - exit(EXIT_FAILURE); - } - s1 += 2; - s = strchr(s1, ','); - if (s == NULL) { - fprintf(stderr, "%s: Malformed line: %s\n", - __func__, buf); - exit(EXIT_FAILURE); - } - *s = '\0'; - strcpy(protstr, s1); - *prot = 0; - if (strstr(protstr, "PROT_READ")) - *prot |= IOSHARK_PROT_READ; - if (strstr(protstr, "PROT_WRITE")) - *prot |= IOSHARK_PROT_WRITE; - *s = ','; - s += 2; - for (i = 0 ; i < 2 ; i++) { - s = strchr(s, ','); - if (s == NULL) { - fprintf(stderr, "%s: Malformed line: %s\n", - __func__, buf); - exit(EXIT_FAILURE); - } - s += 2; - } - sscanf(s, "%jx", offset); -} - -void -get_lseek_offset_action(char *buf, enum file_op op, - off_t *offset, char *action) -{ - char *s, *s2; - - s = strchr(buf, ','); - if (s == NULL) { - fprintf(stderr, "%s: Malformed line: %s\n", - __func__, buf); - exit(EXIT_FAILURE); - } - s += 2; - sscanf(s, "%ju", offset); - s = strchr(s, ','); - if (s == NULL) { - fprintf(stderr, "%s: Malformed line: %s\n", - __func__, buf); - exit(EXIT_FAILURE); - } - s += 2; - if (op == IOSHARK_LLSEEK) { - s = strchr(s, ','); - if (s == NULL) { - fprintf(stderr, "%s: Malformed line: %s\n", - __func__, buf); - exit(EXIT_FAILURE); - } - s += 2; - } - s2 = strchr(s, ')'); - if (s2 == NULL) { - fprintf(stderr, "%s: Malformed line: %s\n", - __func__, buf); - exit(EXIT_FAILURE); - } - *s2 = '\0'; - strcpy(action, s); - *s2 = ')'; -} - -void -get_rw_len(char *buf, - u_int64_t *len) -{ - char *s_len; - - s_len = strrchr(buf, ','); - if (s_len == NULL) { - fprintf(stderr, "%s: Malformed line: %s\n", - __func__, buf); - exit(EXIT_FAILURE); - } - sscanf(s_len + 2, "%ju", len); -} - -void -get_prw64_offset_len(char *buf, - off_t *offset, - u_int64_t *len) -{ - char *s_offset, *s_len; - - s_offset = strrchr(buf, ','); - if (s_offset == NULL) { - fprintf(stderr, "%s: Malformed line 1: %s\n", - __func__, buf); - exit(EXIT_FAILURE); - } - *s_offset = '\0'; - s_len = strrchr(buf, ','); - if (s_len == NULL) { - fprintf(stderr, "%s: Malformed line 2: %s\n", - __func__, buf); - exit(EXIT_FAILURE); - } - *s_offset = ','; - sscanf(s_len + 2, "%ju", len); - sscanf(s_offset + 2, "%ju", offset); -} - -void -get_openat_flags_mode(char *buf, char *flags, mode_t *mode) -{ - char *s, *s2, lookfor; - - s = strchr(buf, ','); - if (s == NULL) { - fprintf(stderr, "%s: Malformed line: %s\n", - __func__, buf); - exit(EXIT_FAILURE); - } - s += 2; - s = strchr(s, ','); - if (s == NULL) { - fprintf(stderr, "%s: Malformed line: %s\n", - __func__, buf); - exit(EXIT_FAILURE); - } - s += 2; - if (strstr(s, "O_CREAT") == NULL) - lookfor = ')'; - else - lookfor = ','; - s2 = strchr(s, lookfor); - if (s2 == NULL) { - fprintf(stderr, "%s: Malformed line: %s\n", - __func__, buf); - exit(EXIT_FAILURE); - } - *s2 = '\0'; - strcpy(flags, s); - *s2 = lookfor; - if (strstr(s, "O_CREAT") != NULL) { - s = s2 + 2; - s2 = strchr(s, ')'); - if (s2 == NULL) { - fprintf(stderr, "%s: Malformed line: %s\n", - __func__, buf); - exit(EXIT_FAILURE); - } - *s2 = '\0'; - sscanf(s, "%o", mode); - *s2 = ')'; - } -} - -int -lookup_map(char *s, struct flags_map_s *flags_map, int maplen) -{ - int found = 0, flag = 0; - int i; - - while (isspace(*s)) - s++; - for (i = 0 ; i < maplen ; i++) { - if (strcmp(flags_map[i].flag_str, s) == 0) { - flag = flags_map[i].flag; - found = 1; - break; - } - } - if (found == 0) { - fprintf(stderr, "%s: Unknown syscall %s\n", - __func__, s); - exit(1); - } - return flag; -} - -int -map_open_flags(char *s) -{ - int flags = 0; - char *s1; - - while ((s1 = strchr(s, '|'))) { - *s1 = '\0'; - flags |= lookup_map(s, open_flags_map, - ARRAY_SIZE(open_flags_map)); - *s1 = '|'; - s = s1 + 1; - } - /* Last option */ - flags |= lookup_map(s, open_flags_map, - ARRAY_SIZE(open_flags_map)); - return flags; -} - -int -map_lseek_action(char *s) -{ - int flags = 0; - char *s1; - - while ((s1 = strchr(s, '|'))) { - *s1 = '\0'; - flags |= lookup_map(s, lseek_action_map, - ARRAY_SIZE(lseek_action_map)); - *s1 = '|'; - s = s1 + 1; - } - /* Last option */ - flags |= lookup_map(s, lseek_action_map, - ARRAY_SIZE(lseek_action_map)); - return flags; -} - -enum file_op -map_syscall(char *syscall) -{ - return lookup_map(syscall, fileop_map, - ARRAY_SIZE(fileop_map)); -} - -void -get_start_time(struct timeval *tv) -{ - FILE *fp; - - tv->tv_usec = 0; - fp = fopen("trace.begin", "r"); - if (fp == NULL) { - fprintf(stderr, "%s Can't open trace.begin\n", - __func__); - exit(EXIT_FAILURE); - } - if (fscanf(fp, "%lu", &tv->tv_sec) != 1) { - fprintf(stderr, "%s Can't read seconds from trace.begin\n", - __func__); - exit(EXIT_FAILURE); - } -} - -/* - * For each tracefile, we first create in-memory structures, then once - * we've processed each tracefile completely, we write out the in-memory - * structures and free them. - */ -int main(int argc, char **argv) -{ - FILE *fp; - char path[512]; - char syscall[512]; - char lseek_action_str[512]; - char *s; - char open_flags_str[64]; - void *db_node; - int num_io_operations = 0; - struct ioshark_header header; - struct ioshark_file_operation *disk_file_op; - struct in_mem_file_op *in_mem_fop; - struct stat st; - char *infile, *outfile; - struct timeval start_time; - - progname = argv[0]; - if (argc != 3) { - usage(); - exit(EXIT_FAILURE); - } - infile = argv[1]; - outfile = argv[2]; - if (stat(infile, &st) < 0) { - fprintf(stderr, "%s Can't stat %s\n", - progname, infile); - exit(EXIT_FAILURE); - } - if (st.st_size == 0) { - fprintf(stderr, "%s Empty file %s\n", - progname, infile); - exit(EXIT_FAILURE); - } - get_start_time(&start_time); - fp = fopen(infile, "r"); - if (fp == NULL) { - fprintf(stderr, "%s Can't open %s\n", - progname, infile); - exit(EXIT_FAILURE); - } - while (fgets(in_buf, 2048, fp)) { - s = in_buf; - while (isspace(*s)) - s++; - in_mem_fop = malloc(sizeof(struct in_mem_file_op)); - disk_file_op = &in_mem_fop->disk_file_op; - disk_file_op->delta_us = get_delta_ts(s, &start_time); - get_syscall(s, syscall); - disk_file_op->file_op = map_syscall(syscall); - get_pathname(s, path, disk_file_op->file_op); - db_node = files_db_add(path); - disk_file_op->fileno = files_db_get_fileno(db_node); - switch (disk_file_op->file_op) { - case IOSHARK_LLSEEK: - case IOSHARK_LSEEK: - get_lseek_offset_action(s, - disk_file_op->file_op, - &disk_file_op->lseek_offset, - lseek_action_str); - disk_file_op->lseek_action = - map_lseek_action(lseek_action_str); - if (disk_file_op->lseek_action == SEEK_SET) - files_db_update_size(db_node, - disk_file_op->lseek_offset); - break; - case IOSHARK_PREAD64: - case IOSHARK_PWRITE64: - get_prw64_offset_len(s, - &disk_file_op->prw_offset, - (u_int64_t *)&disk_file_op->prw_len); - files_db_update_size(db_node, - disk_file_op->prw_offset + - disk_file_op->prw_len); - break; - case IOSHARK_READ: - case IOSHARK_WRITE: - get_rw_len(s, (u_int64_t *)&disk_file_op->rw_len); - files_db_add_to_size(db_node, - disk_file_op->rw_len); - break; - case IOSHARK_MMAP: - case IOSHARK_MMAP2: - get_mmap_offset_len_prot(s, - &disk_file_op->mmap_prot, - &disk_file_op->mmap_offset, - (u_int64_t *)&disk_file_op->mmap_len); - files_db_update_size(db_node, - disk_file_op->mmap_offset + - disk_file_op->mmap_len); - break; - case IOSHARK_OPEN: - disk_file_op->open_mode = 0; - get_openat_flags_mode(s, open_flags_str, - &disk_file_op->open_mode); - disk_file_op->open_flags = - map_open_flags(open_flags_str); - break; - case IOSHARK_FSYNC: - case IOSHARK_FDATASYNC: - break; - case IOSHARK_CLOSE: - break; - default: - break; - } - /* Chain at the end */ - num_io_operations++; - in_mem_fop->next = NULL; - if (in_mem_file_op_head == NULL) { - in_mem_file_op_tail = in_mem_fop; - in_mem_file_op_head = in_mem_fop; - } else { - in_mem_file_op_tail->next = in_mem_fop; - in_mem_file_op_tail = in_mem_fop; - } - } - fclose(fp); - /* - * Now we can write everything out to the output tracefile. - */ - fp = fopen(outfile, "w+"); - if (fp == NULL) { - fprintf(stderr, "%s Can't open trace.outfile\n", - progname); - exit(EXIT_FAILURE); - } - header.num_io_operations = num_io_operations; - header.num_files = files_db_get_total_obj(); - if (fwrite(&header, sizeof(struct ioshark_header), 1, fp) != 1) { - fprintf(stderr, "%s Write error trace.outfile\n", - progname); - exit(EXIT_FAILURE); - } - files_db_write_objects(fp); - while (in_mem_file_op_head != NULL) { - struct in_mem_file_op *temp; - - disk_file_op = &in_mem_file_op_head->disk_file_op; - if (fwrite(disk_file_op, - sizeof(struct ioshark_file_operation), 1, fp) != 1) { - fprintf(stderr, "%s Write error trace.outfile\n", - progname); - exit(EXIT_FAILURE); - } - temp = in_mem_file_op_head; - in_mem_file_op_head = in_mem_file_op_head->next; - free(temp); - } -} diff --git a/ioshark/compile_ioshark.h b/ioshark/compile_ioshark.h deleted file mode 100644 index 13095bf6..00000000 --- a/ioshark/compile_ioshark.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define FILE_DB_HASHSIZE 8192 - -struct files_db_s { - char *filename; - int fileno; - struct files_db_s *next; - size_t size; -}; - -/* Lifted from Wikipedia Jenkins Hash function page */ -static inline u_int32_t -jenkins_one_at_a_time_hash(char *key, size_t len) -{ - u_int32_t hash, i; - - for(hash = i = 0; i < len; ++i) { - hash += key[i]; - hash += (hash << 10); - hash ^= (hash >> 6); - } - hash += (hash << 3); - hash ^= (hash >> 11); - hash += (hash << 15); - return hash; -} - -static inline void -files_db_update_size(void *node, u_int64_t new_size) -{ - struct files_db_s *db_node = (struct files_db_s *)node; - - if (db_node->size < new_size) - db_node->size = new_size; -} - -static inline void -files_db_add_to_size(void *node, u_int64_t size_incr) -{ - ((struct files_db_s *)node)->size += size_incr; -} - -static inline int -files_db_get_fileno(void *node) -{ - return (((struct files_db_s *)node)->fileno); -} - -static inline char * -files_db_get_filename(void *node) -{ - return (((struct files_db_s *)node)->filename); -} - - -void *files_db_create_handle(void); -void files_db_write_objects(FILE *fp); -void *files_db_add(char *filename); -void *files_db_lookup(char *filename); -int files_db_get_total_obj(void); - - - diff --git a/ioshark/compile_ioshark_subr.c b/ioshark/compile_ioshark_subr.c deleted file mode 100644 index e2b6b891..00000000 --- a/ioshark/compile_ioshark_subr.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <fcntl.h> -#include <stdio.h> -#include <sys/types.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <sys/stat.h> -#include <sys/errno.h> -#include "ioshark.h" -#include "compile_ioshark.h" - -extern char *progname; - -static struct files_db_s *files_db_buckets[FILE_DB_HASHSIZE]; -static int current_fileno = 1; -static int num_objects = 0; - -void -files_db_write_objects(FILE *fp) -{ - int i; - struct ioshark_file_state st; - - for (i = 0 ; i < FILE_DB_HASHSIZE ; i++) { - struct files_db_s *db_node, *s; - - db_node = files_db_buckets[i]; - while (db_node != NULL) { - st.fileno = db_node->fileno; - st.size = db_node->size; - if (fwrite(&st, sizeof(st), 1, fp) != 1) { - fprintf(stderr, "%s Write error trace.outfile\n", - progname); - exit(EXIT_FAILURE); - } - s = db_node; - db_node = db_node->next; - free(s->filename); - free(s); - } - } -} - -void *files_db_lookup(char *pathname) -{ - u_int32_t hash; - struct files_db_s *db_node; - - hash = jenkins_one_at_a_time_hash(pathname, strlen(pathname)); - hash %= FILE_DB_HASHSIZE; - db_node = files_db_buckets[hash]; - while (db_node != NULL) { - if (strcmp(db_node->filename, pathname) == 0) - break; - db_node = db_node->next; - } - return db_node; -} - -void *files_db_add(char *filename) -{ - u_int32_t hash; - struct files_db_s *db_node; - - if ((db_node = files_db_lookup(filename))) - return db_node; - hash = jenkins_one_at_a_time_hash(filename, strlen(filename)); - hash %= FILE_DB_HASHSIZE; - db_node = malloc(sizeof(struct files_db_s)); - db_node->filename = strdup(filename); - db_node->fileno = current_fileno++; - db_node->next = files_db_buckets[hash]; - db_node->size = 0; - files_db_buckets[hash] = db_node; - num_objects++; - return db_node; -} - -int -files_db_get_total_obj(void) -{ - return num_objects; -} - - - diff --git a/ioshark/ioshark.h b/ioshark/ioshark.h deleted file mode 100644 index f0a715f7..00000000 --- a/ioshark/ioshark.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * Format of the parsed workload files. - * 1) Header - * 2) Table of the entries, each entry describes 1 file - * 3) Table of IO operations to perform on the files - */ - -/* - * The parsed workload file starts off with the header, which - * contains the count of the total # of files that are operated on. - * and the total number of IO operations. - */ -struct ioshark_header { - int num_files; - int num_io_operations; -}; - -/* - * After the header, we have a table of #files entries. Each entry - * in this table describes 1 file, indexed by fileno and with the - * specified size. - * Before the tests starts, these files are pre-created. - */ -struct ioshark_file_state { - int fileno; /* 1..num_files, with files name ioshark.<fileno> */ - size_t size; -}; - -enum file_op { - IOSHARK_LSEEK = 0, - IOSHARK_LLSEEK, - IOSHARK_PREAD64, - IOSHARK_PWRITE64, - IOSHARK_READ, - IOSHARK_WRITE, - IOSHARK_MMAP, - IOSHARK_MMAP2, - IOSHARK_OPEN, - IOSHARK_FSYNC, - IOSHARK_FDATASYNC, - IOSHARK_CLOSE, - IOSHARK_MAPPED_PREAD, - IOSHARK_MAPPED_PWRITE, - IOSHARK_MAX_FILE_OP -}; - -/* mmap prot flags */ -#define IOSHARK_PROT_READ 0x1 -#define IOSHARK_PROT_WRITE 0x2 - -/* - * Next we have the table of IO operatiosn to perform. Each - * IO operation is described by this entry. - */ -struct ioshark_file_operation { - /* delta us between previous file op and this */ - u_int64_t delta_us; - enum file_op file_op; - int fileno; - union { - struct lseek_args { -#define lseek_offset u.lseek_a.offset -#define lseek_action u.lseek_a.action - off_t offset; - int action; - } lseek_a; - struct prw_args { -#define prw_offset u.prw_a.offset -#define prw_len u.prw_a.len - off_t offset; - size_t len; - } prw_a; -#define rw_len u.rw_a.len - struct rw_args { - size_t len; - } rw_a; -#define mmap_offset u.mmap_a.offset -#define mmap_len u.mmap_a.len -#define mmap_prot u.mmap_a.prot - struct mmap_args { - off_t offset; - size_t len; - int prot; - } mmap_a; -#define open_flags u.open_a.flags -#define open_mode u.open_a.mode - struct open_args { - int flags; - mode_t mode; - } open_a; - } u; -}; diff --git a/ioshark/ioshark_bench.c b/ioshark/ioshark_bench.c deleted file mode 100644 index 5b19d2a9..00000000 --- a/ioshark/ioshark_bench.c +++ /dev/null @@ -1,739 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <stdio.h> -#include <sys/time.h> -#include <sys/types.h> -#include <unistd.h> -#include <sys/syscall.h> -#include <stdlib.h> -#include <string.h> -#include <pthread.h> -#include <sys/stat.h> -#include <sys/errno.h> -#include <fcntl.h> -#include <string.h> -#include <assert.h> -#include <pthread.h> -#include <sys/statfs.h> -#include "ioshark.h" -#define IOSHARK_MAIN -#include "ioshark_bench.h" - -char *progname; - -#define MAX_INPUT_FILES 1024 -#define MAX_THREADS 1024 - -struct thread_state_s { - char *filename; - FILE *fp; - int num_files; - void *db_handle; -}; - -struct thread_state_s thread_state[MAX_INPUT_FILES]; -int num_input_files = 0; -int next_input_file; - -pthread_t tid[MAX_THREADS]; - -/* - * Global options - */ -int do_delay = 0; -int verbose = 0; - -#if 0 -static long gettid() -{ - return syscall(__NR_gettid); -} -#endif - -void usage() -{ - fprintf(stderr, "%s [-d preserve_delays] [-n num_iterations] [-t num_threads] <list of parsed input files>\n", - progname); - exit(EXIT_FAILURE); -} - -pthread_mutex_t time_mutex = PTHREAD_MUTEX_INITIALIZER; -pthread_mutex_t stats_mutex = PTHREAD_MUTEX_INITIALIZER; -pthread_mutex_t work_mutex = PTHREAD_MUTEX_INITIALIZER; -struct timeval aggregate_file_create_time; -struct timeval debug_file_create_time; -struct timeval aggregate_file_remove_time; -struct timeval aggregate_IO_time; -struct timeval aggregate_delay_time; - -u_int64_t aggr_op_counts[IOSHARK_MAX_FILE_OP]; -struct rw_bytes_s aggr_io_rw_bytes; -struct rw_bytes_s aggr_create_rw_bytes; - -/* - * Locking needed here because aggregate_delay_time is updated - * from multiple threads concurrently. - */ -static void -update_time(struct timeval *aggr_time, - struct timeval *delta_time) -{ - struct timeval tmp; - - pthread_mutex_lock(&time_mutex); - timeradd(aggr_time, delta_time, &tmp); - *aggr_time = tmp; - pthread_mutex_unlock(&time_mutex); -} - -static void -update_op_counts(u_int64_t *op_counts) -{ - int i; - - pthread_mutex_lock(&stats_mutex); - for (i = IOSHARK_LSEEK ; i < IOSHARK_MAX_FILE_OP ; i++) - aggr_op_counts[i] += op_counts[i]; - pthread_mutex_unlock(&stats_mutex); -} - -static void -update_byte_counts(struct rw_bytes_s *dest, struct rw_bytes_s *delta) -{ - pthread_mutex_lock(&stats_mutex); - dest->bytes_read += delta->bytes_read; - dest->bytes_written += delta->bytes_written; - pthread_mutex_unlock(&stats_mutex); -} - -static int work_next_file; -static int work_num_files; - -void -init_work(int next_file, int num_files) -{ - pthread_mutex_lock(&work_mutex); - work_next_file = next_file; - work_num_files = work_next_file + num_files; - pthread_mutex_unlock(&work_mutex); -} - -/* Dole out the next file to work on to the thread */ -static struct thread_state_s * -get_work() -{ - struct thread_state_s *work = NULL; - - pthread_mutex_lock(&work_mutex); - if (work_next_file < work_num_files) - work = &thread_state[work_next_file++]; - pthread_mutex_unlock(&work_mutex); - return work; -} - -static void -create_files(struct thread_state_s *state) -{ - int i; - struct ioshark_file_state file_state; - char path[512]; - void *db_node; - struct rw_bytes_s rw_bytes; - - memset(&rw_bytes, 0, sizeof(struct rw_bytes_s)); - for (i = 0 ; i < state->num_files ; i++) { - if (fread(&file_state, sizeof(struct ioshark_file_state), - 1, state->fp) != 1) { - fprintf(stderr, "%s read error tracefile\n", - progname); - exit(EXIT_FAILURE); - } - sprintf(path, "file.%d.%d", - (int)(state - thread_state), - file_state.fileno); - create_file(path, file_state.size, - &rw_bytes); - db_node = files_db_add_byfileno(state->db_handle, - file_state.fileno); - files_db_update_size(db_node, file_state.size); - files_db_update_filename(db_node, path); - } - update_byte_counts(&aggr_create_rw_bytes, &rw_bytes); -} - -static void -do_one_io(void *db_node, - struct ioshark_file_operation *file_op, - u_int64_t *op_counts, - struct rw_bytes_s *rw_bytes, - char **bufp, int *buflen) -{ - assert(file_op->file_op < IOSHARK_MAX_FILE_OP); - op_counts[file_op->file_op]++; - switch (file_op->file_op) { - int ret; - char *p; - int fd; - - case IOSHARK_LSEEK: - case IOSHARK_LLSEEK: - ret = lseek(files_db_get_fd(db_node), - file_op->lseek_offset, - file_op->lseek_action); - if (ret < 0) { - fprintf(stderr, - "%s: lseek(%s %lu %d) returned error %d\n", - progname, files_db_get_filename(db_node), - file_op->lseek_offset, - file_op->lseek_action, errno); - exit(EXIT_FAILURE); - } - break; - case IOSHARK_PREAD64: - p = get_buf(bufp, buflen, file_op->prw_len, 0); - ret = pread(files_db_get_fd(db_node), p, - file_op->prw_len, file_op->prw_offset); - rw_bytes->bytes_read += file_op->prw_len; - if (ret < 0) { - fprintf(stderr, - "%s: pread(%s %zu %lu) error %d\n", - progname, - files_db_get_filename(db_node), - file_op->prw_len, - file_op->prw_offset, errno); - exit(EXIT_FAILURE); - } - break; - case IOSHARK_PWRITE64: - p = get_buf(bufp, buflen, file_op->prw_len, 1); - ret = pwrite(files_db_get_fd(db_node), p, - file_op->prw_len, file_op->prw_offset); - rw_bytes->bytes_written += file_op->prw_len; - if (ret < 0) { - fprintf(stderr, - "%s: pwrite(%s %zu %lu) error %d\n", - progname, - files_db_get_filename(db_node), - file_op->prw_len, - file_op->prw_offset, errno); - exit(EXIT_FAILURE); - } - break; - case IOSHARK_READ: - p = get_buf(bufp, buflen, file_op->rw_len, 0); - ret = read(files_db_get_fd(db_node), p, - file_op->rw_len); - rw_bytes->bytes_read += file_op->rw_len; - if (ret < 0) { - fprintf(stderr, - "%s: read(%s %zu) error %d\n", - progname, - files_db_get_filename(db_node), - file_op->rw_len, - errno); - exit(EXIT_FAILURE); - } - break; - case IOSHARK_WRITE: - p = get_buf(bufp, buflen, file_op->rw_len, 1); - ret = write(files_db_get_fd(db_node), p, - file_op->rw_len); - rw_bytes->bytes_written += file_op->rw_len; - if (ret < 0) { - fprintf(stderr, - "%s: write(%s %zu) error %d\n", - progname, - files_db_get_filename(db_node), - file_op->rw_len, - errno); - exit(EXIT_FAILURE); - } - break; - case IOSHARK_MMAP: - case IOSHARK_MMAP2: - ioshark_handle_mmap(db_node, file_op, - bufp, buflen, op_counts, - rw_bytes); - break; - case IOSHARK_OPEN: - if (file_op->open_flags & O_CREAT) { - fd = open(files_db_get_filename(db_node), - file_op->open_flags, - file_op->open_mode); - if (fd < 0) { - /* - * EEXIST error acceptable, others are fatal. - * Although we failed to O_CREAT the file (O_EXCL) - * We will force an open of the file before any - * IO. - */ - if (errno == EEXIST) { - return; - } else { - fprintf(stderr, - "%s: O_CREAT open(%s %x %o) error %d\n", - progname, - files_db_get_filename(db_node), - file_op->open_flags, - file_op->open_mode, errno); - exit(EXIT_FAILURE); - } - } - } else { - fd = open(files_db_get_filename(db_node), - file_op->open_flags); - if (fd < 0) { - if (file_op->open_flags & O_DIRECTORY) { - /* O_DIRECTORY open()s should fail */ - return; - } else { - fprintf(stderr, - "%s: open(%s %x) error %d\n", - progname, - files_db_get_filename(db_node), - file_op->open_flags, - errno); - exit(EXIT_FAILURE); - } - } - } - files_db_close_fd(db_node); - files_db_update_fd(db_node, fd); - break; - case IOSHARK_FSYNC: - case IOSHARK_FDATASYNC: - if (file_op->file_op == IOSHARK_FSYNC) { - ret = fsync(files_db_get_fd(db_node)); - if (ret < 0) { - fprintf(stderr, - "%s: fsync(%s) error %d\n", - progname, - files_db_get_filename(db_node), - errno); - exit(EXIT_FAILURE); - } - } else { - ret = fdatasync(files_db_get_fd(db_node)); - if (ret < 0) { - fprintf(stderr, - "%s: fdatasync(%s) error %d\n", - progname, - files_db_get_filename(db_node), - errno); - exit(EXIT_FAILURE); - } - } - break; - case IOSHARK_CLOSE: - ret = close(files_db_get_fd(db_node)); - if (ret < 0) { - fprintf(stderr, - "%s: close(%s) error %d\n", - progname, - files_db_get_filename(db_node), errno); - exit(EXIT_FAILURE); - } - files_db_update_fd(db_node, -1); - break; - default: - fprintf(stderr, "%s: unknown FILE_OP %d\n", - progname, file_op->file_op); - exit(EXIT_FAILURE); - break; - } -} - -static void -do_io(struct thread_state_s *state) -{ - void *db_node; - struct ioshark_header header; - struct ioshark_file_operation file_op; - u_int64_t prev_delay = 0; - int fd; - int i; - char *buf = NULL; - int buflen = 0; - struct timeval total_delay_time; - u_int64_t op_counts[IOSHARK_MAX_FILE_OP]; - struct rw_bytes_s rw_bytes; - - rewind(state->fp); - if (fread(&header, sizeof(struct ioshark_header), 1, state->fp) != 1) { - fprintf(stderr, "%s read error %s\n", - progname, state->filename); - exit(EXIT_FAILURE); - } - /* - * First open and pre-create all the files. Indexed by fileno. - */ - timerclear(&total_delay_time); - memset(&rw_bytes, 0, sizeof(struct rw_bytes_s)); - memset(op_counts, 0, sizeof(op_counts)); - fseek(state->fp, - sizeof(struct ioshark_header) + - header.num_files * sizeof(struct ioshark_file_state), - SEEK_SET); - /* - * Loop over all the IOs, and launch each - */ - for (i = 0 ; i < header.num_io_operations ; i++) { - if (fread(&file_op, sizeof(struct ioshark_file_operation), - 1, state->fp) != 1) { - fprintf(stderr, "%s read error trace.outfile\n", - progname); - exit(EXIT_FAILURE); - } - if (do_delay) { - struct timeval start; - - (void)gettimeofday(&start, (struct timezone *)NULL); - usleep(file_op.delta_us - prev_delay); - update_delta_time(&start, &total_delay_time); - prev_delay = file_op.delta_us; - } - db_node = files_db_lookup_byfileno(state->db_handle, - file_op.fileno); - if (db_node == NULL) { - fprintf(stderr, - "%s Can't lookup fileno %d, fatal error\n", - progname, file_op.fileno); - exit(EXIT_FAILURE); - } - if (file_op.file_op != IOSHARK_OPEN && - files_db_get_fd(db_node) == -1) { - /* - * This is a hack to workaround the fact that we did not - * see an open() for this file until now. open() the file - * O_RDWR, so that we can perform the IO. - */ - fd = open(files_db_get_filename(db_node), O_RDWR); - if (fd < 0) { - fprintf(stderr, "%s: open(%s O_RDWR) error %d\n", - progname, files_db_get_filename(db_node), - errno); - exit(EXIT_FAILURE); - } - files_db_update_fd(db_node, fd); - } - do_one_io(db_node, &file_op, - op_counts, &rw_bytes, &buf, &buflen); - } - files_db_fsync_discard_files(state->db_handle); - files_db_close_files(state->db_handle); - update_time(&aggregate_delay_time, &total_delay_time); - update_op_counts(op_counts); - update_byte_counts(&aggr_io_rw_bytes, &rw_bytes); -} - -void * -io_thread(void *unused __attribute__((unused))) -{ - struct thread_state_s *state; - - srand(gettid()); - while ((state = get_work())) - do_io(state); - pthread_exit(NULL); - return(NULL); -} - -static void -do_create(struct thread_state_s *state) -{ - struct ioshark_header header; - - if (fread(&header, sizeof(struct ioshark_header), 1, state->fp) != 1) { - fprintf(stderr, "%s read error %s\n", - progname, state->filename); - exit(EXIT_FAILURE); - } - state->num_files = header.num_files; - state->db_handle = files_db_create_handle(); - create_files(state); -} - -void * -create_files_thread(void *unused __attribute__((unused))) -{ - struct thread_state_s *state; - - while ((state = get_work())) - do_create(state); - pthread_exit(NULL); - return(NULL); -} - -int -get_start_end(int *start_ix) -{ - int i, j, ret_numfiles; - u_int64_t free_fs_bytes; - char *infile; - FILE *fp; - struct ioshark_header header; - struct ioshark_file_state file_state; - struct statfs fsstat; - static int fssize_clamp_next_index = 0; - static int chunk = 0; - - if (fssize_clamp_next_index == num_input_files) - return 0; - if (statfs("/data/local/tmp", &fsstat) < 0) { - fprintf(stderr, "%s: Can't statfs /data/local/tmp\n", - progname); - exit(EXIT_FAILURE); - } - free_fs_bytes = (fsstat.f_bavail * fsstat.f_bsize) * 9 /10; - for (i = fssize_clamp_next_index; i < num_input_files; i++) { - infile = thread_state[i].filename; - fp = fopen(infile, "r"); - if (fp == NULL) { - fprintf(stderr, "%s: Can't open %s\n", - progname, infile); - exit(EXIT_FAILURE); - } - if (fread(&header, sizeof(struct ioshark_header), - 1, fp) != 1) { - fprintf(stderr, "%s read error %s\n", - progname, infile); - exit(EXIT_FAILURE); - } - for (j = 0 ; j < header.num_files ; j++) { - if (fread(&file_state, sizeof(struct ioshark_file_state), - 1, fp) != 1) { - fprintf(stderr, "%s read error tracefile\n", - progname); - exit(EXIT_FAILURE); - } - if (file_state.size > free_fs_bytes) { - fclose(fp); - goto out; - } - free_fs_bytes -= file_state.size; - } - fclose(fp); - } -out: - if (verbose) { - if (chunk > 0 || i < num_input_files) { - printf("Breaking up input files, Chunk %d: %d to %d\n", - chunk++, fssize_clamp_next_index, i - 1); - } else { - printf("Entire Dataset fits start = %d to %d, free_bytes = %ju\n", - fssize_clamp_next_index, - i - fssize_clamp_next_index, - free_fs_bytes); - } - } - *start_ix = fssize_clamp_next_index; - ret_numfiles = i - fssize_clamp_next_index; - fssize_clamp_next_index = i; - return ret_numfiles; -} - -int -ioshark_pthread_create(pthread_t *tidp, void *(*start_routine)(void *)) -{ - pthread_attr_t attr; - - pthread_attr_init(&attr); - pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM); - pthread_attr_setstacksize(&attr, (size_t)(1024*1024)); - return pthread_create(tidp, &attr, start_routine, (void *)NULL); -} - -void -wait_for_threads(int num_threads) -{ - int i; - - for (i = 0; i < num_threads; i++) { - pthread_join(tid[i], NULL); - tid[i] = 0; - } -} - -int -main(int argc, char **argv) -{ - int i; - FILE *fp; - struct stat st; - char *infile; - int num_threads = 0; - int num_iterations = 1; - int c; - int num_files, start_file; - struct thread_state_s *state; - - progname = argv[0]; - while ((c = getopt(argc, argv, "dn:t:v")) != EOF) { - switch (c) { - case 'd': - do_delay = 1; - break; - case 'n': - num_iterations = atoi(optarg); - break; - case 't': - num_threads = atoi(optarg); - break; - case 'v': - verbose = 1; - break; - default: - usage(); - } - } - - if (num_threads > MAX_THREADS) - usage(); - - if (optind == argc) - usage(); - - for (i = optind; i < argc; i++) { - infile = argv[i]; - if (stat(infile, &st) < 0) { - fprintf(stderr, "%s: Can't stat %s\n", - progname, infile); - exit(EXIT_FAILURE); - continue; - } - if (st.st_size == 0) { - fprintf(stderr, "%s: Empty file %s\n", - progname, infile); - continue; - } - fp = fopen(infile, "r"); - if (fp == NULL) { - fprintf(stderr, "%s: Can't open %s\n", - progname, infile); - continue; - } - thread_state[num_input_files].filename = infile; - thread_state[num_input_files].fp = fp; - num_input_files++; - } - - if (num_input_files == 0) { - exit(EXIT_SUCCESS); - } - if (verbose) { - printf("Total Input Files = %d\n", num_input_files); - printf("Num Iterations = %d\n", num_iterations); - } - timerclear(&aggregate_file_create_time); - timerclear(&aggregate_file_remove_time); - timerclear(&aggregate_IO_time); - - capture_util_state_before(); - - /* - * We pre-create the files that we need once and then we - * loop around N times doing IOs on the pre-created files. - * - * get_start_end() breaks up the total work here to make sure - * that all the files we need to pre-create fit into the - * available space in /data/local/tmp (hardcoded for now). - * - * If it won't fit, then we do several sweeps. - */ - while ((num_files = get_start_end(&start_file))) { - struct timeval time_for_pass; - - /* Create files once */ - printf("Doing Pre-creation of Files\n"); - if (num_threads == 0 || num_threads > num_files) - num_threads = num_files; - (void)system("echo 3 > /proc/sys/vm/drop_caches"); - init_work(start_file, num_files); - (void)gettimeofday(&time_for_pass, - (struct timezone *)NULL); - for (i = 0; i < num_threads; i++) { - if (ioshark_pthread_create(&(tid[i]), - create_files_thread)) { - fprintf(stderr, - "%s: Can't create creator thread %d\n", - progname, i); - exit(EXIT_FAILURE); - } - } - wait_for_threads(num_threads); - update_delta_time(&time_for_pass, &aggregate_file_create_time); - - /* Do the IOs N times */ - for (i = 0 ; i < num_iterations ; i++) { - (void)system("echo 3 > /proc/sys/vm/drop_caches"); - if (num_iterations > 1) - printf("Starting Test. Iteration %d...\n", - i); - else - printf("Starting Test...\n"); - init_work(start_file, num_files); - (void)gettimeofday(&time_for_pass, - (struct timezone *)NULL); - for (c = 0; c < num_threads; c++) { - if (ioshark_pthread_create(&(tid[c]), - io_thread)) { - fprintf(stderr, - "%s: Can't create thread %d\n", - progname, c); - exit(EXIT_FAILURE); - } - } - wait_for_threads(num_threads); - update_delta_time(&time_for_pass, - &aggregate_IO_time); - } - - /* - * We are done with the N iterations of IO. - * Destroy the files we pre-created. - */ - init_work(start_file, num_files); - while ((state = get_work())) { - struct timeval start; - - (void)gettimeofday(&start, (struct timezone *)NULL); - files_db_unlink_files(state->db_handle); - update_delta_time(&start, &aggregate_file_remove_time); - files_db_free_memory(state->db_handle); - } - } - printf("Total Creation time = %ju.%ju (msecs.usecs)\n", - get_msecs(&aggregate_file_create_time), - get_usecs(&aggregate_file_create_time)); - printf("Total Remove time = %ju.%ju (msecs.usecs)\n", - get_msecs(&aggregate_file_remove_time), - get_usecs(&aggregate_file_remove_time)); - if (do_delay) - printf("Total delay time = %ju.%ju (msecs.usecs)\n", - get_msecs(&aggregate_delay_time), - get_usecs(&aggregate_delay_time)); - printf("Total Test (IO) time = %ju.%ju (msecs.usecs)\n", - get_msecs(&aggregate_IO_time), - get_usecs(&aggregate_IO_time)); - if (verbose) - print_bytes("Upfront File Creation bytes", - &aggr_create_rw_bytes); - print_bytes("Total Test (IO) bytes", &aggr_io_rw_bytes); - if (verbose) - print_op_stats(aggr_op_counts); - report_cpu_disk_util(); -} diff --git a/ioshark/ioshark_bench.h b/ioshark/ioshark_bench.h deleted file mode 100644 index 95e6a317..00000000 --- a/ioshark/ioshark_bench.h +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifdef IOSHARK_MAIN -const char *IO_op[] = { - "LSEEK", - "LLSEEK", - "PREAD64", - "PWRITE64", - "READ", - "WRITE", - "MMAP", - "MMAP2", - "OPEN", - "FSYNC", - "FDATASYNC", - "CLOSE", - "MAPPED_PREAD", - "MAPPED_PWRITE", - "MAX_FILE_OP" -}; -#endif - -#define MAX(A, B) ((A) > (B) ? (A) : (B)) -#define MIN(A, B) ((A) < (B) ? (A) : (B)) - -#define MINBUFLEN (16*1024) - -#define FILE_DB_HASHSIZE 8192 - -struct files_db_s { - char *filename; - int fileno; - size_t size; - int fd; - int debug_open_flags; - struct files_db_s *next; -}; - -struct files_db_handle { - struct files_db_s *files_db_buckets[FILE_DB_HASHSIZE]; -}; - -struct IO_operation_s { - char *IO_op; -}; - -struct rw_bytes_s { - u_int64_t bytes_read; - u_int64_t bytes_written; -}; - -static inline void -files_db_update_size(void *node, u_int64_t new_size) -{ - struct files_db_s *db_node = (struct files_db_s *)node; - - if (db_node->size < new_size) - db_node->size = new_size; -} - -static inline void -files_db_update_filename(void *node, char *filename) -{ - ((struct files_db_s *)node)->filename = strdup(filename); -} - -static inline int -files_db_get_fileno(void *node) -{ - return (((struct files_db_s *)node)->fileno); -} - -static inline int -files_db_get_fd(void *node) -{ - return (((struct files_db_s *)node)->fd); -} - -static inline char * -files_db_get_filename(void *node) -{ - return (((struct files_db_s *)node)->filename); -} - -static inline u_int64_t -get_msecs(struct timeval *tv) -{ - return ((tv->tv_sec * 1000) + (tv->tv_usec / 1000)); -} - -static inline u_int64_t -get_usecs(struct timeval *tv) -{ - return (tv->tv_usec % 1000); -} - -static inline void -update_delta_time(struct timeval *start, - struct timeval *destination) -{ - struct timeval res, finish; - - (void)gettimeofday(&finish, (struct timezone *)NULL); - timersub(&finish, start, &res); - timeradd(destination, &res, &finish); - *destination = finish; -} - -void *files_db_create_handle(void); -void *files_db_lookup_byfileno(void *handle, int fileno); -void *files_db_add_byfileno(void *handle, int fileno); -void files_db_update_fd(void *node, int fd); -void files_db_unlink_files(void *db_handle); -void files_db_close_files(void *handle); -void files_db_close_fd(void *node); -void files_db_free_memory(void *handle); -void create_file(char *path, size_t size, - struct rw_bytes_s *rw_bytes); -char *get_buf(char **buf, int *buflen, int len, int do_fill); -void files_db_fsync_discard_files(void *handle); -void print_op_stats(u_int64_t *op_counts); -void print_bytes(char *desc, struct rw_bytes_s *rw_bytes); -void ioshark_handle_mmap(void *db_node, - struct ioshark_file_operation *file_op, - char **bufp, int *buflen, u_int64_t *op_counts, - struct rw_bytes_s *rw_bytes); -void capture_util_state_before(void); -void report_cpu_disk_util(void); - - - - - - - - - - - diff --git a/ioshark/ioshark_bench_mmap.c b/ioshark/ioshark_bench_mmap.c deleted file mode 100644 index 5eec23c5..00000000 --- a/ioshark/ioshark_bench_mmap.c +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <stdio.h> -#include <sys/time.h> -#include <sys/types.h> -#include <unistd.h> -#include <sys/syscall.h> -#include <stdlib.h> -#include <string.h> -#include <pthread.h> -#include <sys/stat.h> -#include <sys/errno.h> -#include <fcntl.h> -#include <string.h> -#include <assert.h> -#include <pthread.h> -#include "ioshark.h" -#include "ioshark_bench.h" - -/* - * The purpose of this code is to convert mmap() calls into - * a mix of (semi)-random reads and writes. - * PROT_READ => 4KB/8KB/16KB random reads. - * PROT_WRITE => adds 4KB random writes. - */ - -extern char *progname; - -#define IOSHARK_MAX_MMAP_IOLEN (16*1024) - -#define MMAP_ENTS 16 - -struct mmap_io_ent_tab_s { - off_t offset; - size_t len; -}; - -struct mmap_io_ent_s { - int num_entries; - struct mmap_io_ent_tab_s table[MMAP_ENTS + 1]; - size_t resid; -}; - -static void -setup_mmap_io_state(struct mmap_io_ent_s *mio, - size_t total_len, off_t offset) -{ - int slice; - - memset(mio, 0, sizeof(struct mmap_io_ent_s)); - mio->resid = total_len; - slice = MAX(IOSHARK_MAX_MMAP_IOLEN, - total_len / MMAP_ENTS); - while (total_len > 0) { - assert(mio->num_entries < MMAP_ENTS + 1); - mio->table[mio->num_entries].offset = offset; - mio->table[mio->num_entries].len = - MIN((u_int64_t)total_len, (u_int64_t)slice); - total_len -= mio->table[mio->num_entries].len; - offset += mio->table[mio->num_entries].len; - mio->num_entries++; - } -} - -static size_t -mmap_getnext_off_len(struct mmap_io_ent_s *mio, - off_t *offset) -{ - int i; - int find_rand_index[MMAP_ENTS + 1]; - int rand_index_len = 0; - size_t iolength; - - if (mio->resid == 0) - return 0; - /* Pick a slot with residual length > 0 at random first */ - for (i = 0 ; i < MMAP_ENTS + 1 ; i++) { - if (mio->table[i].len > 0) - find_rand_index[rand_index_len++] = i; - } - i = find_rand_index[rand() % rand_index_len]; - /* Randomize iolength 4K-16K */ - iolength = ((rand() % 4) + 1) * 4096; - iolength = MIN(mio->table[i].len, iolength); - *offset = mio->table[i].offset; - mio->table[i].offset += iolength; - mio->table[i].len -= iolength; - mio->resid -= iolength; - return iolength; -} - -static void -mmap_do_io(void *db_node, int prot, off_t offset, size_t len, - char **bufp, int *buflen, u_int64_t *op_counts, - struct rw_bytes_s *rw_bytes) -{ - char *p; - int ret; - - if (!(prot & IOSHARK_PROT_WRITE)) { - /* Only preads */ - p = get_buf(bufp, buflen, len, 0); - ret = pread(files_db_get_fd(db_node), - p, len, offset); - rw_bytes->bytes_read += len; - if (ret < 0) { - fprintf(stderr, - "%s: mapped pread(%s %zu %lu) error fd=%d %s\n", - progname, files_db_get_filename(db_node), - len, offset, files_db_get_fd(db_node), - strerror(errno)); - exit(EXIT_FAILURE); - } - op_counts[IOSHARK_MAPPED_PREAD]++; - } else { - /* 50-50 R/W */ - if ((rand() % 2) == 1) { - p = get_buf(bufp, buflen, len, 1); - ret = pwrite(files_db_get_fd(db_node), - p, len, offset); - rw_bytes->bytes_written += len; - if (ret < 0) { -#if 0 - fprintf(stderr, - "%s: mapped pwrite failed, file unwriteable ? open_flags=%x\n", - progname, - fcntl(files_db_get_fd(db_node), F_GETFL)); - exit(EXIT_FAILURE); -#endif - } else - op_counts[IOSHARK_MAPPED_PWRITE]++; - } else { - p = get_buf(bufp, buflen, len, 0); - ret = pread(files_db_get_fd(db_node), - p, len, offset); - rw_bytes->bytes_read += len; - if (ret < 0) { - fprintf(stderr, - "%s: mapped pread(%s %zu %lu) error fd=%d %s\n", - progname, files_db_get_filename(db_node), - len, - offset, files_db_get_fd(db_node), - strerror(errno)); - exit(EXIT_FAILURE); - } - op_counts[IOSHARK_MAPPED_PREAD]++; - } - } -} - -void -ioshark_handle_mmap(void *db_node, - struct ioshark_file_operation *file_op, - char **bufp, int *buflen, u_int64_t *op_counts, - struct rw_bytes_s *rw_bytes) -{ - off_t offset = file_op->mmap_offset; - size_t len = file_op->mmap_len; - int prot = file_op->mmap_prot; - struct mmap_io_ent_s mio; - struct stat statbuf; - - if (fstat(files_db_get_fd(db_node), &statbuf) < 0) { - fprintf(stderr, - "%s: fstat failure %s\n", - __func__, strerror(errno)); - exit(EXIT_FAILURE); - } - /* - * The size of the file better accomodate offset + len - * Else there is an issue with pre-creation - */ - assert(offset + len <= statbuf.st_size); - if (len <= IOSHARK_MAX_MMAP_IOLEN) { - mmap_do_io(db_node, prot, offset, len, - bufp, buflen, op_counts, - rw_bytes); - return; - } - setup_mmap_io_state(&mio, len, offset); - assert(mio.num_entries > 0); - while ((len = mmap_getnext_off_len(&mio, &offset))) { - assert((offset + len) <= - (file_op->mmap_offset + file_op->mmap_len)); - mmap_do_io(db_node, prot, offset, len, bufp, buflen, - op_counts, rw_bytes); - } -} diff --git a/ioshark/ioshark_bench_subr.c b/ioshark/ioshark_bench_subr.c deleted file mode 100644 index 4083e053..00000000 --- a/ioshark/ioshark_bench_subr.c +++ /dev/null @@ -1,493 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <stdio.h> -#include <sys/time.h> -#include <sys/types.h> -#include <unistd.h> -#include <stdlib.h> -#include <signal.h> -#include <string.h> -#include <sys/stat.h> -#include <sys/errno.h> -#include <fcntl.h> -#include <string.h> -#include <assert.h> -#include "ioshark.h" -#include "ioshark_bench.h" - -extern char *progname; - -void * -files_db_create_handle(void) -{ - struct files_db_handle *h; - int i; - - h = malloc(sizeof(struct files_db_handle)); - for (i = 0 ; i < FILE_DB_HASHSIZE ; i++) - h->files_db_buckets[i] = NULL; - return h; -} - -void *files_db_lookup_byfileno(void *handle, int fileno) -{ - u_int32_t hash; - struct files_db_handle *h = (struct files_db_handle *)handle; - struct files_db_s *db_node; - - hash = fileno % FILE_DB_HASHSIZE; - db_node = h->files_db_buckets[hash]; - while (db_node != NULL) { - if (db_node->fileno == fileno) - break; - db_node = db_node->next; - } - return db_node; -} - -void *files_db_add_byfileno(void *handle, int fileno) -{ - u_int32_t hash = fileno % FILE_DB_HASHSIZE; - struct files_db_handle *h = (struct files_db_handle *)handle; - struct files_db_s *db_node; - - db_node = (struct files_db_s *) - files_db_lookup_byfileno(handle, fileno); - if (db_node == NULL) { - db_node = malloc(sizeof(struct files_db_s)); - db_node->fileno = fileno; - db_node->filename = NULL; - db_node->size = 0; - db_node->fd = -1; - db_node->next = h->files_db_buckets[hash]; - h->files_db_buckets[hash] = db_node; - } else { - fprintf(stderr, - "%s: Node to be added already exists fileno = %d\n\n", - __func__, fileno); - exit(EXIT_FAILURE); - } - return db_node; -} - -void -files_db_fsync_discard_files(void *handle) -{ - struct files_db_handle *h = (struct files_db_handle *)handle; - struct files_db_s *db_node; - int i; - - for (i = 0 ; i < FILE_DB_HASHSIZE ; i++) { - db_node = h->files_db_buckets[i]; - while (db_node != NULL) { - int do_close = 0; - - if (db_node->fd == -1) { - int fd; - - /* - * File was closed, let's open it so we can - * fsync and fadvise(DONTNEED) it. - */ - do_close = 1; - fd = open(files_db_get_filename(db_node), - O_RDWR); - if (fd < 0) { - fprintf(stderr, - "%s: open(%s O_RDWR) error %d\n", - progname, db_node->filename, - errno); - exit(EXIT_FAILURE); - } - db_node->fd = fd; - } - if (fsync(db_node->fd) < 0) { - fprintf(stderr, "%s: Cannot fsync %s\n", - __func__, db_node->filename); - exit(1); - } - if (posix_fadvise(db_node->fd, 0, 0, - POSIX_FADV_DONTNEED) < 0) { - fprintf(stderr, - "%s: Cannot fadvise(DONTNEED) %s\n", - __func__, db_node->filename); - exit(1); - } - if (do_close) { - close(db_node->fd); - db_node->fd = -1; - } - db_node = db_node->next; - } - } -} - -void -files_db_update_fd(void *node, int fd) -{ - struct files_db_s *db_node = (struct files_db_s *)node; - - db_node->fd = fd; -} - -void -files_db_close_fd(void *node) -{ - struct files_db_s *db_node = (struct files_db_s *)node; - - if (db_node->fd != -1) - close(db_node->fd); - db_node->fd = -1; -} - -void -files_db_close_files(void *handle) -{ - struct files_db_handle *h = (struct files_db_handle *)handle; - struct files_db_s *db_node; - int i; - - for (i = 0 ; i < FILE_DB_HASHSIZE ; i++) { - db_node = h->files_db_buckets[i]; - while (db_node != NULL) { - if ((db_node->fd != -1) && close(db_node->fd) < 0) { - fprintf(stderr, "%s: Cannot close %s\n", - __func__, db_node->filename); - exit(1); - } - db_node->fd = -1; - db_node = db_node->next; - } - } -} - -void -files_db_unlink_files(void *handle) -{ - struct files_db_handle *h = (struct files_db_handle *)handle; - struct files_db_s *db_node; - int i; - - for (i = 0 ; i < FILE_DB_HASHSIZE ; i++) { - db_node = h->files_db_buckets[i]; - while (db_node != NULL) { - if ((db_node->fd != -1) && close(db_node->fd) < 0) { - fprintf(stderr, "%s: Cannot close %s\n", - __func__, db_node->filename); - exit(1); - } - db_node->fd = -1; - if (unlink(db_node->filename) < 0) { - fprintf(stderr, "%s: Cannot unlink %s:%s\n", - __func__, db_node->filename, strerror(errno)); - exit(1); - } - db_node = db_node->next; - } - } -} - -void -files_db_free_memory(void *handle) -{ - struct files_db_handle *h = (struct files_db_handle *)handle; - struct files_db_s *db_node, *tmp; - int i; - - for (i = 0 ; i < FILE_DB_HASHSIZE ; i++) { - db_node = h->files_db_buckets[i]; - while (db_node != NULL) { - tmp = db_node; - db_node = db_node->next; - free(tmp->filename); - free(tmp); - } - } - free(h); -} - -char * -get_buf(char **buf, int *buflen, int len, int do_fill __attribute__((unused))) -{ - if (len == 0 && *buf == NULL) { - /* - * If we ever get a zero len - * request, start with MINBUFLEN - */ - if (*buf == NULL) - len = MINBUFLEN / 2; - } - if (*buflen < len) { - *buflen = MAX(MINBUFLEN, len * 2); - if (*buf) - free(*buf); - *buf = malloc(*buflen); - if (do_fill) { - u_int32_t *s; - int count; - - s = (u_int32_t *)*buf; - count = *buflen / sizeof(u_int32_t); - while (count > 0) { - *s++ = rand(); - count--; - } - } - } - assert(*buf != NULL); - return *buf; -} - -void -create_file(char *path, size_t size, struct rw_bytes_s *rw_bytes) -{ - int fd, n; - char *buf = NULL; - int buflen = 0; - - fd = open(path, O_WRONLY|O_CREAT|O_TRUNC, 0644); - if (fd < 0) { - fprintf(stderr, "%s Cannot create file %s, error = %d\n", - progname, path, errno); - exit(EXIT_FAILURE); - } - while (size > 0) { - n = MIN(size, MINBUFLEN); - buf = get_buf(&buf, &buflen, n, 1); - if (write(fd, buf, n) < n) { - fprintf(stderr, - "%s Cannot write file %s, error = %d\n", - progname, path, errno); - exit(EXIT_FAILURE); - } - rw_bytes->bytes_written += n; - size -= n; - } - if (fsync(fd) < 0) { - fprintf(stderr, "%s Cannot fsync file %s, error = %d\n", - progname, path, errno); - exit(EXIT_FAILURE); - } - if (posix_fadvise(fd, 0, 0, POSIX_FADV_DONTNEED) < 0) { - fprintf(stderr, - "%s Cannot fadvise(DONTNEED) file %s, error = %d\n", - progname, path, errno); - exit(EXIT_FAILURE); - } - close(fd); -} - -void -print_op_stats(u_int64_t *op_counts) -{ - int i; - extern char *IO_op[]; - - printf("IO Operation counts :\n"); - for (i = IOSHARK_LSEEK ; i < IOSHARK_MAX_FILE_OP ; i++) { - printf("%s: %ju\n", - IO_op[i], op_counts[i]); - } -} - -void -print_bytes(char *desc, struct rw_bytes_s *rw_bytes) -{ - printf("%s: Reads = %dMB, Writes = %dMB\n", - desc, - (int)(rw_bytes->bytes_read / (1024 * 1024)), - (int)(rw_bytes->bytes_written / (1024 * 1024))); -} - -struct cpu_disk_util_stats { - /* CPU util */ - u_int64_t user_cpu_ticks; - u_int64_t nice_cpu_ticks; - u_int64_t system_cpu_ticks; - u_int64_t idle_cpu_ticks; - u_int64_t iowait_cpu_ticks; - u_int64_t hardirq_cpu_ticks; - u_int64_t softirq_cpu_ticks; - /* disk util */ - unsigned long long uptime; - unsigned int tot_ticks; - unsigned long rd_ios; - unsigned long wr_ios; - unsigned long rd_sec; - unsigned long wr_sec; -}; - -static struct cpu_disk_util_stats before; -static struct cpu_disk_util_stats after; - -#define BUFSIZE 8192 - -static int hz; - -static void -get_HZ(void) -{ - if ((hz = sysconf(_SC_CLK_TCK)) == -1) - exit(1); -} - -#if 0 -static int num_cores; - -static void -get_cores(void) -{ - if ((num_cores = sysconf(_SC_NPROCESSORS_ONLN)) == -1) - exit(1); -} -#endif - -static void -read_disk_util_state(struct cpu_disk_util_stats *state) -{ - FILE *fp; - char line[BUFSIZE], dev_name[BUFSIZE]; - unsigned int major, minor; - unsigned int ios_pgr; - unsigned int rq_ticks; - unsigned int wr_ticks; - unsigned long rd_ticks; - unsigned long rd_merges; - unsigned long wr_merges; - unsigned long up_sec, up_cent; - - /* Read and parse /proc/uptime */ - fp = fopen("/proc/uptime", "r"); - if (fgets(line, sizeof(line), fp) == NULL) { - fprintf(stderr, "%s: Cannot read /proc/uptime\n", - progname); - exit(1); - } - fclose(fp); - sscanf(line, "%lu.%lu", &up_sec, &up_cent); - state->uptime = (unsigned long long) up_sec * hz + - (unsigned long long) up_cent * hz / 100; - /* Read and parse /proc/diskstats */ - fp = fopen("/proc/diskstats", "r"); - while (fgets(line, sizeof(line), fp)) { - sscanf(line, - "%u %u %s %lu %lu %lu %lu %lu %lu %lu %u %u %u %u", - &major, &minor, dev_name, - &state->rd_ios, &rd_merges, &state->rd_sec, - &rd_ticks, &state->wr_ios, &wr_merges, - &state->wr_sec, &wr_ticks, - &ios_pgr, &state->tot_ticks, &rq_ticks); - if (strcmp(dev_name, "sda") == 0) { - /* - * tot_ticks is "number of milliseconds spent - * doing I/Os". Look at Documentation/iostats.txt. - * Or at genhd.c:diskstats_show(), which calls - * jiffies_to_msecs() on this field before printing - * it. Convert this to hz, so we can do all our math - * in ticks. - */ - state->tot_ticks /= 1000; /* to seconds */ - state->tot_ticks *= hz; /* to hz */ - fclose(fp); - return; - } - } - fprintf(stderr, "%s: Did not find device sda in /proc/diskstats\n", - progname); - exit(1); -} - -static void -read_cpu_util_state(struct cpu_disk_util_stats *state) -{ - FILE *fp; - char line[BUFSIZE], cpu[BUFSIZE]; - - /* Read and parse /proc/stat */ - fp = fopen("/proc/stat", "r"); - if (fgets(line, sizeof(line), fp) == NULL) { - fprintf(stderr, "%s: Cannot read /proc/stat\n", - progname); - exit(1); - } - fclose(fp); - sscanf(line, "%s %ju %ju %ju %ju %ju %ju %ju", - cpu, - &state->user_cpu_ticks, - &state->nice_cpu_ticks, - &state->system_cpu_ticks, - &state->idle_cpu_ticks, - &state->iowait_cpu_ticks, - &state->hardirq_cpu_ticks, - &state->softirq_cpu_ticks); -} - -void -capture_util_state_before(void) -{ - get_HZ(); - read_disk_util_state(&before); - read_cpu_util_state(&before); -} - -extern int verbose; - -void -report_cpu_disk_util(void) -{ - double disk_util, cpu_util; - u_int64_t tot1, tot2, delta1, delta2; - - read_disk_util_state(&after); - read_cpu_util_state(&after); - /* CPU Util */ - tot2 = after.user_cpu_ticks + after.nice_cpu_ticks + - after.system_cpu_ticks + after.hardirq_cpu_ticks + - after.softirq_cpu_ticks; - tot1 = before.user_cpu_ticks + before.nice_cpu_ticks + - before.system_cpu_ticks + before.hardirq_cpu_ticks + - before.softirq_cpu_ticks; - delta1 = tot2 - tot1; - tot2 += after.iowait_cpu_ticks + after.idle_cpu_ticks; - tot1 += before.iowait_cpu_ticks + before.idle_cpu_ticks; - delta2 = tot2 - tot1; - cpu_util = delta1 * 100.0 / delta2; - printf("CPU util = %.2f%%\n", cpu_util); - /* Next compute system (incl irq/softirq) and user cpu util */ - delta1 = (after.user_cpu_ticks + after.nice_cpu_ticks) - - (before.user_cpu_ticks + before.nice_cpu_ticks); - cpu_util = delta1 * 100.0 / delta2; - printf("User CPU util = %.2f%%\n", cpu_util); - delta1 = (after.system_cpu_ticks + after.hardirq_cpu_ticks + - after.softirq_cpu_ticks) - - (before.system_cpu_ticks + before.hardirq_cpu_ticks + - before.softirq_cpu_ticks); - cpu_util = delta1 * 100.0 / delta2; - printf("System CPU util = %.2f%%\n", cpu_util); - /* Disk Util */ - disk_util = (after.tot_ticks - before.tot_ticks) * 100.0 / - (after.uptime - before.uptime); - if (verbose) { - printf("Reads : nr_ios %lu, MB read %lu\n", - (after.rd_ios - before.rd_ios), - (after.rd_sec - before.rd_sec) / 2048); - printf("Writes : nr_ios %lu, MB written %lu\n", - (after.wr_ios - before.wr_ios), - (after.wr_sec - before.wr_sec) / 2048); - } - printf("Disk util = %.2f%%\n", disk_util); -} diff --git a/ioshark/wl.tar b/ioshark/wl.tar Binary files differdeleted file mode 100644 index af7d964e..00000000 --- a/ioshark/wl.tar +++ /dev/null |